[xiph-commits] r7658 - in experimental/derf/theora-exp: include/theora lib

tterribe at motherfish-iii.xiph.org tterribe at motherfish-iii.xiph.org
Sat Aug 28 13:42:10 PDT 2004


Author: tterribe
Date: 2004-08-28 13:42:10 -0700 (Sat, 28 Aug 2004)
New Revision: 7658

Modified:
   experimental/derf/theora-exp/include/theora/theora.h
   experimental/derf/theora-exp/lib/decode.c
   experimental/derf/theora-exp/lib/encode.c
   experimental/derf/theora-exp/lib/impmap.c
   experimental/derf/theora-exp/lib/internal.h
   experimental/derf/theora-exp/lib/mcenc.c
   experimental/derf/theora-exp/lib/psych.c
   experimental/derf/theora-exp/lib/state.c
Log:
Various updates and fixes.

Rename macro blocks to quadrants where they refer to part of a super block, and
 not the cross-plane structure of co-located blocks.

Fix some uninitialized values in the importance map code.

Fix per-block qi quantization:
a) when there are fewer than 3 qi levels needed
b) on I frames (bug was forcing qi to 3 for all AC coefficients)

Fix last motion vector update for 4MV mode in the decoder (doesn't affect VP3
 content, but does affect the experimental encoder, which can use 4MV mode even
 when not all 4 luma blocks are coded).

Still some more things to be fixed before the encoder is usable.


Modified: experimental/derf/theora-exp/include/theora/theora.h
===================================================================
--- experimental/derf/theora-exp/include/theora/theora.h	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/include/theora/theora.h	2004-08-28 20:42:10 UTC (rev 7658)
@@ -253,6 +253,9 @@
   int          nbits;
 }theora_huff_code;
 
+/*The Huffman tables used by VP3.*/
+const theora_huff_code OC_VP31_HUFF_CODES[OC_NHUFFMAN_TABLES][OC_NDCT_TOKENS];
+
 /*The quantization parameters.
   The quantizer for each coefficient is calculated as:
     Q=MAX(MIN(qmin[qti][ci!=0],scale[ci!=0][qi]*base[qti][pli][qi][ci]/100),
@@ -315,6 +318,9 @@
   theora_quant_ranges qi_ranges[2][3];
 }theora_quant_info;
 
+/*The quantization parameters used by VP3.*/
+const theora_quant_info OC_VP31_QUANT_INFO;
+
 /*The comment information.*/
 typedef struct theora_comment{
   char **user_comments;

Modified: experimental/derf/theora-exp/lib/decode.c
===================================================================
--- experimental/derf/theora-exp/lib/decode.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/decode.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -277,12 +277,12 @@
     fplane=_dec->state.fplanes+pli;
     sb_end+=fplane->nsbs;
     for(;sb<sb_end;sb++){
-      int mbi;
-      for(mbi=0;mbi<4;mbi++)if(sb->mb_valid&1<<mbi){
+      int quadi;
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
         int bi;
         for(bi=0;bi<4;bi++){
           int fragi;
-          fragi=sb->map[mbi][bi];
+          fragi=sb->map[quadi][bi];
           if(fragi>=0){
             oc_fragment *frag;
             frag=_dec->state.frags+fragi;
@@ -399,12 +399,12 @@
     fplane=_dec->state.fplanes+pli;
     sb_end+=fplane->nsbs;
     for(;sb<sb_end;sb++){
-      int mbi;
-      for(mbi=0;mbi<4;mbi++)if(sb->mb_valid&1<<mbi){
+      int quadi;
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
         int bi;
         for(bi=0;bi<4;bi++){
           int fragi;
-          fragi=sb->map[mbi][bi];
+          fragi=sb->map[quadi][bi];
           if(fragi>=0){
             oc_fragment *frag;
             frag=_dec->state.frags+fragi;
@@ -598,8 +598,8 @@
         if(codedi>0){
           last_mv[1][0]=last_mv[0][0];
           last_mv[1][1]=last_mv[0][1];
-          last_mv[0][0]=lbmvs[codedi-1][0];
-          last_mv[0][1]=lbmvs[codedi-1][1];
+          last_mv[0][0]=lbmvs[coded[codedi-1]][0];
+          last_mv[0][1]=lbmvs[coded[codedi-1]][1];
         }
         if(codedi<ncoded){
           (*set_chroma_mvs)(cbmvs,lbmvs);

Modified: experimental/derf/theora-exp/lib/encode.c
===================================================================
--- experimental/derf/theora-exp/lib/encode.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/encode.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -224,7 +224,7 @@
   Finally, scheme 7 just encodes each mode directly in 3 bits.
   Be warned that the number assigned to each mode is slightly different in the
    bitstream than in this implementation, so a translation needs to be done.
-   
+
   Mode name:                 Source-code index;  Bit-stream index:
   OC_MODE_INTRA              0                   1
   OC_MODE_INTER_NOMV         1                   0
@@ -234,7 +234,7 @@
   OC_MODE_INTER_MV_FOUR      5                   6
   OC_MODE_GOLDEN_NOMV        6                   7
   OC_MODE_GOLDEN_MV          7                   5
-  
+
   The bit stream indices come from the constants assigned to each mode in the
    original VP3 source.*/
 static void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser){
@@ -447,6 +447,16 @@
   }
 }
 
+/*Sets the Huffman codes to use for the DCT tokens.
+  This may only be called before the setup header is written.
+  If it is called multiple times, only the last call has any effect.
+  _codes: An array of 80 Huffman tables with 32 elements each.
+          This may be NULL, in which case the default Huffman codes will be
+           used.
+  Return: 0 on success, or a negative value on error.
+          OC_FAULT if _enc is NULL
+          OC_EINVAL if the setup header has already been written, the code is
+           not prefix free, or does not form a full binary tree.*/
 static int oc_enc_set_huffman_codes(oc_enc_ctx *_enc,
  const theora_huff_code _codes[OC_NHUFFMAN_TABLES][OC_NDCT_TOKENS]){
   int ret;
@@ -461,6 +471,18 @@
   return 0;
 }
 
+/*Sets the quantization parameters to use.
+  This may only be called before the setup header is written.
+  If it is called multiple times, only the last call has any effect.
+  _qinfo: The quantization parameters.
+          These are described in more detail in theora.h.
+          This can be NULL, in which case the default quantization parameters
+           will be used.*
+  Return: 0 on success, or a negative value on error.
+          OC_FAULT if _enc is NULL.
+          OC_EINVAL if the setup header has already been written, or it cannot
+           be verified that the quantization level of for a particular qti,
+           pli, and ci never increases as qi increases.*/
 static int oc_enc_set_quant_params(theora_enc_ctx *_enc,
  const theora_quant_info *_qinfo){
   int qti;
@@ -580,23 +602,23 @@
     /*Convert this into a moment table.*/
     for(qi=63;qi-->0;)nqis[qi]+=nqis[qi+1];
     for(qi0=64;qi0-->0&&nqis[qi0]<=0;);
-    for(qi1=qi0;qi1>=0&&nqis[qi1]<=nqis[qi0];qi1--);
+    for(qi1=qi0-1;qi1>=0&&nqis[qi1]<=nqis[qi0];qi1--);
     /*Test to make sure there are even two unique quantizers.*/
-    if(qi1<qi0){
+    if(qi1>=0){
       ogg_int64_t best_metric;
       ogg_int64_t metric;
       int         best_qi1;
       int         best_qi2;
       int         qii;
-      for(qi2=qi1;qi2>=0&&nqis[qi2]<=nqis[qi1];qi2--);
+      for(qi2=qi1-1;qi2>=0&&nqis[qi2]<=nqis[qi1];qi2--);
       /*Test to make sure there are three unique quantizers.*/
-      if(qi2<qi1){
+      if(qi2>=0){
         best_metric=(ogg_int64_t)(nqis[0]-nqis[qi2+1])*
          (nqis[qi2+1]-nqis[qi1+1])*nqis[qi1+1];
         best_qi1=qi1;
         best_qi2=qi2;
-        for(;nqis[qi1]<nqis[0];qi1--){
-          for(qi2=qi1;nqis[qi2--]<nqis[0];){
+        for(;nqis[qi1]<nqis[1];qi1--){
+          for(qi2=qi1-1;nqis[qi2]<nqis[0];qi2--){
             metric=(ogg_int64_t)(nqis[0]-nqis[qi2+1])*
              (nqis[qi2+1]-nqis[qi1+1])*nqis[qi1+1];
             if(metric>=best_metric){
@@ -614,7 +636,7 @@
       else{
         best_metric=(ogg_int64_t)(nqis[0]-nqis[qi1+1])*nqis[qi1+1];
         best_qi1=qi1;
-        while(qi1-->0){
+        if(qi1>0)for(qi1--;nqis[qi1]<nqis[0];qi1--){
           metric=(ogg_int64_t)(nqis[0]-nqis[qi1+1])*nqis[qi1+1];
           if(metric>best_metric){
             best_qi1=qi1;
@@ -690,15 +712,15 @@
     fplane=_enc->state.fplanes+pli;
     sb_end+=fplane->nsbs;
     for(;sb<sb_end;sb++){
-      int mbi;
-      for(mbi=0;mbi<4;mbi++)if(sb->mb_valid&1<<mbi){
+      int quadi;
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
         int bi;
-        for(bi=0;bi<4;bi++)if(sb->map[mbi][bi]>=0){
+        for(bi=0;bi<4;bi++)if(sb->map[quadi][bi]>=0){
           oc_fragment_enc_info *efrag;
           oc_fragment          *frag;
           int                   fragi;
           int                   best_qii;
-          fragi=sb->map[mbi][bi];
+          fragi=sb->map[quadi][bi];
           frag=_enc->state.frags+fragi;
           frag->coded=1;
           frag->mbmode=OC_MODE_INTRA;
@@ -711,7 +733,7 @@
             }
           }
           efrag->qii=(unsigned char)best_qii;
-          frag->qi=_enc->state.qis[qii];
+          frag->qi=_enc->state.qis[best_qii];
           _enc->state.coded_fragis[ncoded_fragis++]=fragi;
 #if defined(OC_BITRATE_STATS)
           /*Compute the error function used for intra mode fragments.
@@ -1781,16 +1803,16 @@
     prev_refi=_enc->state.ref_frame_idx[OC_FRAME_PREV];
     ystride=_enc->state.ref_frame_bufs[prev_refi][pli].ystride;
     for(;sb<sb_end;sb++){
-      int mbi;
+      int quadi;
       sb->coded_fully=1;
       sb->coded_partially=0;
-      for(mbi=0;mbi<4;mbi++)if(sb->mb_valid&1<<mbi){
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
         int bi;
-        for(bi=0;bi<4;bi++)if(sb->map[mbi][bi]>=0){
+        for(bi=0;bi<4;bi++)if(sb->map[quadi][bi]>=0){
           oc_fragment *frag;
           int          fragi;
           int          flag;
-          fragi=sb->map[mbi][bi];
+          fragi=sb->map[quadi][bi];
           frag=_enc->state.frags+fragi;
           if(frag->invalid){
             frag->coded=0;
@@ -2496,7 +2518,7 @@
 
 typedef theora_huff_code theora_huff_table[OC_NDCT_TOKENS];
 
-int theora_encoder_ctl(theora_enc_ctx *_enc,int _req,void *_buf,
+int theora_encode_ctl(theora_enc_ctx *_enc,int _req,void *_buf,
  size_t _buf_sz){
   switch(_req){
     case OC_ENCCTL_SET_HUFFMAN_CODES:{

Modified: experimental/derf/theora-exp/lib/impmap.c
===================================================================
--- experimental/derf/theora-exp/lib/impmap.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/impmap.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -831,6 +831,7 @@
   reg0->link.next->prev=pair->links+1;
   reg0->link.next=pair->links+1;
   pair->heapi=-1;
+  pair->dbic=0;
   return pair;
 }
 
@@ -1766,24 +1767,24 @@
     iregions[regi].nedge++;
   }
   /*Handle the interior edge(s):*/
-  for(x=1;x<_width-2;x++){
+  for(x=1;x<_width-1;x++){
     regi=labels[0][x]=relabels[labels[0][x]];
     iregions[regi].nborder++;
     iregions[regi].nedge++;
   }
-  for(y=1;y<_height-2;y++){
+  for(y=1;y<_height-1;y++){
     regi=labels[y][0]=relabels[labels[y][0]];
     iregions[regi].nborder++;
     iregions[regi].nedge++;
   }
   /*Note: we DON'T store the new label for this edge.
     See below.*/
-  if(_height>1)for(x=1;x<_width-2;x++){
+  if(_height>1)for(x=1;x<_width-1;x++){
     regi=relabels[labels[_height-1][x]];
     iregions[regi].nborder++;
     iregions[regi].nedge++;
   }
-  if(_width>1)for(y=1;y<_height-2;y++){
+  if(_width>1)for(y=1;y<_height-1;y++){
     regi=labels[y][_width-1]=relabels[labels[y][_width-1]];
     iregions[regi].nborder++;
     iregions[regi].nedge++;
@@ -1797,9 +1798,9 @@
     That's why we skipped relabeling the last row above.
     But first, we must relabel the first row of the interior, because that
      was not done above.*/
-  if(_height>1)for(x=1;x<_width-2;x++)labels[1][x]=relabels[labels[1][x]];
+  if(_height>1)for(x=1;x<_width-1;x++)labels[1][x]=relabels[labels[1][x]];
   /*Now we proceed with the main interior loop.*/
-  for(y=1;y<_height-2;y++)for(x=1;x<_width-2;x++){
+  for(y=1;y<_height-1;y++)for(x=1;x<_width-1;x++){
     int border;
     regi=labels[y][x];
     border=regi^labels[y][x-1];

Modified: experimental/derf/theora-exp/lib/internal.h
===================================================================
--- experimental/derf/theora-exp/lib/internal.h	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/internal.h	2004-08-28 20:42:10 UTC (rev 7658)
@@ -106,11 +106,10 @@
 /*Super block information.
   Super blocks are 32x32 segments of pixels in a single color plane indexed
    in image order.
-  Internally, super blocks are broken up into a 2x2 pattern of macro blocks,
-   each of which contains a 2x2 pattern of blocks, each of which is an 8x8
-   block of pixels.
-  Macro blocks, and the blocks within them, are indexed in a special order
-   called a "Hilbert curve" within the super block.
+  Internally, super blocks are broken up into four quadrants, each of which
+   contains a 2x2 pattern of blocks, each of which is an 8x8 block of pixels.
+  Quadrants, and the blocks within them, are indexed in a special order called
+   a "Hilbert curve" within the super block.
 
   In order to differentiate between the Hilbert-curve indexing strategy and
    the regular image order indexing strategy, blocks indexed in image order
@@ -120,16 +119,17 @@
 typedef struct{
   unsigned  coded_fully:1;
   unsigned  coded_partially:1;
-  unsigned  mb_valid:4;
+  unsigned  quad_valid:4;
   oc_sb_map map;
 }oc_sb;
 
 
 
 /*Macro block information.
-  Only macro blocks in the Y plane matter.
-  Fragments in the chroma planes inherit their mode and motion vectors from
-   the co-located macro block in the Y plane.
+  The co-located fragments in all image planes corresponding to the location of
+   a single luma plane super block quadrant forms a macro block.
+  Thus there is only a single set of macro blocks for all planes, which
+   contains between 6 and 12 fragments, depending on the pixel format.
   Therefore macro block information is kept in a separate array from super
    blocks, to avoid unused space in the other planes.*/
 typedef struct{
@@ -242,8 +242,8 @@
   /*The total number of macro blocks.*/
   int                   nmbs;
   /*The list of macro blocks, indexed in super block order.
-    That is, the macro block corresponding to the macro block mbi in super
-     block sbi is (sbi<<2|mbi).*/
+    That is, the macro block corresponding to the macro block mbi in (luma
+     plane) super block sbi is (sbi<<2|mbi).*/
   oc_mb                *mbs;
   /*The list of coded fragments, in coded order.*/
   int                  *coded_fragis;

Modified: experimental/derf/theora-exp/lib/mcenc.c
===================================================================
--- experimental/derf/theora-exp/lib/mcenc.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/mcenc.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -54,11 +54,11 @@
   {3,6,7},
   /*-15.5==dx==15(.5), -15.5==dy*/
   {-1},
-  /* -16<dx<15(.5),           dy==15(.5)*/
+  /*-15.5dx<15(.5),           dy==15(.5)*/
   {0,1,2,3,5},
   /*-15.5==dx,                dy==15(.5)*/
   {1,2,5},
-  /*     dx==15(.5),          dy==15(.5)*/
+  /*       dx==15(.5),        dy==15(.5)*/
   {0,1,3}
 };
 

Modified: experimental/derf/theora-exp/lib/psych.c
===================================================================
--- experimental/derf/theora-exp/lib/psych.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/psych.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -2260,6 +2260,16 @@
           }
           efrag->qi_min[qti]=(unsigned char)qi_min;
         }
+#if 0
+        /*Now undo all the work we did above and just use a constant quantizer
+           value for testing purposes.*/
+        efrag->qi_min[0]=efrag->qi_min[1]=_psych->enc->state.info.quality;
+        for(i=0;i<63;i++){
+          efrag->tols[i]=OC_MINI(
+           _psych->enc->state.dequant_tables[0][_pli][efrag->qi_min[0]][i],
+           _psych->enc->state.dequant_tables[1][_pli][efrag->qi_min[1]][i])>>1;
+        }
+#endif
         /*Remove the parts of the group neighborhoods that are old.*/
         for(i=0;i<OC_MASK_NFULL_GROUPS;i++){
           k=OC_MASK_WINDOW_SIZES[i];

Modified: experimental/derf/theora-exp/lib/state.c
===================================================================
--- experimental/derf/theora-exp/lib/state.c	2004-08-28 20:35:27 UTC (rev 7657)
+++ experimental/derf/theora-exp/lib/state.c	2004-08-28 20:42:10 UTC (rev 7658)
@@ -11,15 +11,15 @@
 
 /*Returns the fragment index of the top-left block in a macro block.
   This can be used to test whether or not the whole macro block is coded.
-  _sb: The super block.
-  _mb: The macro block number.
+  _sb:    The super block.
+  _quadi: The quadrant number.
   Return: The index of the fragment of the upper left block in the macro
    block, or -1 if the block lies outside the coded frame.*/
-static int oc_sb_mb_top_left_frag(const oc_sb *_sb,int _mb){
+static int oc_sb_quad_top_left_frag(const oc_sb *_sb,int _quadi){
   /*It so happens that under the Hilbert curve ordering described below, the
      upper-left block in each macro block is at index 0, except in macro block
      3, where it is at index 2.*/
-  return _sb->map[_mb][_mb&_mb<<1];
+  return _sb->map[_quadi][_quadi&_quadi<<1];
 }
 
 /*Fills in the mapping from block positions to fragment numbers for a single
@@ -62,7 +62,7 @@
     for(x=0;;x+=4,sb++){
       int    xfrag;
       int    jmax;
-      int    mbi;
+      int    quadi;
       int    i;
       /*Figure out how many rows of blocks in this super block lie within the
          image.*/
@@ -80,9 +80,9 @@
         }
         xfrag+=_hfrags;
       }
-      /*Mark which macro blocks in this super block lie within the image.*/
-      for(mbi=0;mbi<4;mbi++){
-        sb->mb_valid|=(oc_sb_mb_top_left_frag(sb,mbi)>=0)<<mbi;
+      /*Mark which quadrants of this super block lie within the image.*/
+      for(quadi=0;quadi<4;quadi++){
+        sb->quad_valid|=(oc_sb_quad_top_left_frag(sb,quadi)>=0)<<quadi;
       }
     }
     yfrag+=_hfrags<<2;
@@ -515,7 +515,7 @@
    _info->pixel_fmt<0||_info->pixel_fmt>=OC_PF_NFORMATS){
     return OC_EINVAL;
   }
-  memset(_state,0,sizeof(_state));
+  memset(_state,0,sizeof(*_state));
   memcpy(&_state->info,_info,sizeof(*_info));
   /*Invert the sense of offset_y to match Theora's right-handed coordinate
      system.*/



More information about the commits mailing list