[xiph-commits] r7391 - experimental/derf/theora-exp/lib

tterribe at dactyl.lonelymoon.com tterribe
Tue Jul 27 22:14:32 PDT 2004


Author: tterribe
Date: Tue Jul 27 22:14:32 2004
New Revision: 7391

Modified:
experimental/derf/theora-exp/lib/decode.c
experimental/derf/theora-exp/lib/internal.h
experimental/derf/theora-exp/lib/state.c
Log:
Fix some nasty corner cases:
0-length EOB runs (previous fix could cause overflow, this should be fixed).
Last zero run in a block doesn't count towards coefficient count.


Modified: experimental/derf/theora-exp/lib/decode.c
===================================================================
--- experimental/derf/theora-exp/lib/decode.c	2004-07-28 05:12:27 UTC (rev 7390)
+++ experimental/derf/theora-exp/lib/decode.c	2004-07-28 05:14:31 UTC (rev 7391)
@@ -824,11 +824,13 @@
_dec->state.frags[*coded_fragi++].dc=0;
}
cfi=0;
-    while(cfi+eobs<_ntoks_left[pli][0]){
+    while(eobs<_ntoks_left[pli][0]-cfi){
int token;
int neb;
int eb;
int skip;
+      cfi+=eobs;
+      run_counts[63]+=eobs;
token=oc_huff_token_decode(&_dec->opb,
_dec->huff_tables[_huff_idxs[pli]]);
_dec->dct_tokens[0][ti++]=(char)token;
@@ -841,8 +843,7 @@
else eb=0;
skip=oc_dct_token_skip(token,eb);
if(skip<0){
-        eobi=-skip;
-        eobs+=eobi;
+        eobs=eobi=-skip;
while(eobi-->0&&coded_fragi<coded_fragi_end){
_dec->state.frags[*coded_fragi++].dc=0;
}
@@ -850,6 +851,7 @@
else{
run_counts[skip-1]++;
cfi++;
+        eobs=0;
_dec->state.frags[*coded_fragi++].dc=oc_dct_token_dec1val(token,eb);
}
}
@@ -857,8 +859,8 @@
/*Set the EOB count to the portion of the last EOB run which extends past
this coefficient.*/
eobs=eobs+cfi-_ntoks_left[pli][0];
-    /*Add the total number of EOBs decoded in this coefficient to the longest
-       run length.*/
+    /*Add the portion of the last EOB which was included in this coefficient to
+       to the longest run length.*/
run_counts[63]+=_ntoks_left[pli][0]-cfi;
/*And convert the run_counts array to a moment table.*/
for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
@@ -892,11 +894,13 @@
for(pli=0;pli<3;pli++){
memset(run_counts,0,sizeof(run_counts));
cfi=0;
-    while(cfi+eobs<_ntoks_left[pli][_zzi]){
+    while(eobs<_ntoks_left[pli][_zzi]-cfi){
int token;
int neb;
int eb;
int skip;
+      cfi+=eobs;
+      run_counts[63]+=eobs;
token=oc_huff_token_decode(&_dec->opb,
_dec->huff_tables[_huff_idxs[pli]]);
_dec->dct_tokens[_zzi][ti++]=(char)token;
@@ -908,10 +912,11 @@
}
else eb=0;
skip=oc_dct_token_skip(token,eb);
-      if(skip<0)eobs-=skip;
+      if(skip<0)eobs=-skip;
else{
run_counts[skip-1]++;
cfi++;
+        eobs=0;
}
}
/*TODO: We don't actually use these values for anything, yet.*/
@@ -919,8 +924,8 @@
/*Set the EOB count to the portion of the last EOB run which extends past
this coefficient.*/
eobs=eobs+cfi-_ntoks_left[pli][_zzi];
-    /*Add the total number of EOBs decoded in this coefficient to the longest
-       run length.*/
+    /*Add the portion of the last EOB which was included in this coefficient to
+       to the longest run length.*/
run_counts[63]+=_ntoks_left[pli][_zzi]-cfi;
/*And convert the run_counts array to a moment table.*/
for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
@@ -1176,11 +1181,13 @@
ogg_int16_t      dct_coeffs[65];
int              fragi;
int              zzi;
+      int              last_zzi;
fragi=*coded_fragi;
frag=_dec->state.frags+fragi;
for(zzi=0;zzi<64;){
int token;
int eb;
+        last_zzi=zzi;
if(eob_runs[zzi]){
eob_runs[zzi]--;
break;
@@ -1202,7 +1209,7 @@
zzi=OC_MINI(zzi,64);
dct_coeffs[0]=(ogg_int16_t)frag->dc;
iquants=_dec->state.dequant_tables[frag->mbmode!=OC_MODE_INTRA][pli];
-      oc_state_frag_recon(&_dec->state,frag,pli,dct_coeffs,zzi,
+      oc_state_frag_recon(&_dec->state,frag,pli,dct_coeffs,last_zzi,zzi,
iquants[_dec->state.qis[0]][0],iquants[frag->qi]);
}
}

Modified: experimental/derf/theora-exp/lib/internal.h
===================================================================
--- experimental/derf/theora-exp/lib/internal.h	2004-07-28 05:12:27 UTC (rev 7390)
+++ experimental/derf/theora-exp/lib/internal.h	2004-07-28 05:14:31 UTC (rev 7391)
@@ -363,8 +363,8 @@
int oc_state_get_mv_offsets(oc_theora_state *_state,int *_offset0,
int *_offset1,int _dx,int _dy,int _ystride,int _pli);
void oc_state_frag_recon(oc_theora_state *_state,const oc_fragment *_frag,
- int _pli,ogg_int16_t _dct_coeffs[64],int _ncoefs,ogg_uint16_t _dc_iquant,
- const ogg_uint16_t _ac_iquant[64]);
+ int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,int _ncoefs,
+ ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]);
void oc_state_frag_copy(const oc_theora_state *_state,const int *_fragis[3],
int _nfragis[3],int _dst_frame,int _src_frame);
void oc_state_loop_filter(oc_theora_state *_state,int _frame);

Modified: experimental/derf/theora-exp/lib/state.c
===================================================================
--- experimental/derf/theora-exp/lib/state.c	2004-07-28 05:12:27 UTC (rev 7390)
+++ experimental/derf/theora-exp/lib/state.c	2004-07-28 05:14:31 UTC (rev 7391)
@@ -735,16 +735,40 @@
}

void oc_state_frag_recon(oc_theora_state *_state,const oc_fragment *_frag,
- int _pli,ogg_int16_t _dct_coeffs[64],int _ncoefs,ogg_uint16_t _dc_iquant,
- const ogg_uint16_t _ac_iquant[64]){
+ int _pli,ogg_int16_t _dct_coeffs[64],int _last_zzi,int _ncoefs,
+ ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]){
ogg_int16_t dct_buf[64];
ogg_int16_t res_buf[64];
int dst_framei;
int dst_ystride;
int zzi;
int ci;
+  /*_last_zzi is subtly different from an actual count of the number of
+     coefficients we decoded for this block.
+    It contains the value of zzi BEFORE the final token in the block was
+     decoded.
+    In most cases this is an EOB token (the continuation of an EOB run from a
+     previous block counts), and so this is the same as the coefficient count.
+    However, in the case that the last token was NOT an EOB token, but filled
+     the block up with exactly 64 coefficients, _last_zzi will be less than 64.
+    Provided the last token was not a pure zero run, the minimum value it can
+     be is 46, and so that doesn't affect any of the cases in this routine.
+    However, if the last token WAS a pure zero run of length 63, then _last_zzi
+     will be 1 while the number of coefficients decoded is 64.
+    Thus, we will trigger the following special case, where a pure coefficient
+     count would not.
+    Note also that a zero run of length 64 will give _last_zzi a value of 0,
+     but we still process the DC coefficient, which might have a non-zero value
+     due to DC prediction.
+    Although convoluted, this is arguably the correct behavior: it allows us to
+     dequantize fewer coefficients and use a smaller transform when the block
+     ends with a long zero run instead of a normal EOB token.
+    It could be smarter... multiple separate zero runs at the end of a block
+     will fool it, but an encoder that generates these really deserves what it
+     gets.
+    Needless to say we inherited this approach from VP3.*/
/*Special case only having a DC component.*/
-  if(_ncoefs<2){
+  if(_last_zzi<2){
ogg_int16_t p;
/*Why is the iquant product rounded in this case and no others?
Who knows.*/
@@ -761,7 +785,7 @@
}
/*Then, fill in the remainder of the coefficients with 0's, and perform
the iDCT.*/
-    if(_ncoefs<10){
+    if(_last_zzi<10){
for(;zzi<10;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
oc_idct8x8_10(res_buf,dct_buf);
}



More information about the commits mailing list