[xiph-cvs] cvs commit: theora/lib dct_decode.c

Timothy Terriberry tterribe at xiph.org
Wed Jun 18 16:00:15 PDT 2003



tterribe    03/06/18 19:00:15

  Modified:    lib      dct_decode.c
  Log:
  Cleaned up DC prediction in a manner similar to that done in encode.c.
  
  We could probably separate out the common parts of these two functions to be shared between the encode and decoder, but it would require some rearchitecting. We definitely should at least consider sharing the lookup tables and constants.

Revision  Changes    Path
1.7       +101 -179  theora/lib/dct_decode.c

Index: dct_decode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/dct_decode.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- dct_decode.c	10 Jun 2003 01:31:33 -0000	1.6
+++ dct_decode.c	18 Jun 2003 23:00:15 -0000	1.7
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-  last mod: $Id: dct_decode.c,v 1.6 2003/06/10 01:31:33 tterribe Exp $
+  last mod: $Id: dct_decode.c,v 1.7 2003/06/18 23:00:15 tterribe Exp $
 
  ********************************************************************/
 
@@ -22,13 +22,13 @@
 
 
 #define GOLDEN_FRAME_THRESH_Q   50
-#define PUL 8
+#define PUR 8
 #define PU 4
-#define PUR 2
+#define PUL 2
 #define PL 1
 #define HIGHBITDUPPED(X) (((signed short) X)  >> 15)
 
-ogg_uint32_t LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {
+const static ogg_uint32_t LoopFilterLimitValuesV1[Q_TABLE_SIZE] = {
   30, 25, 20, 20, 15, 15, 14, 14,
   13, 13, 12, 12, 11, 11, 10, 10,
   9,  9,  8,  8,  7,  7,  7,  7,
@@ -39,7 +39,7 @@
   0,  0,  0,  0,  0,  0,  0,  0
 };
 
-ogg_uint32_t LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {
+const static ogg_uint32_t LoopFilterLimitValuesV2[Q_TABLE_SIZE] = {
   30, 25, 20, 20, 15, 15, 14, 14,
   13, 13, 12, 12, 11, 11, 10, 10,
   9,  9,  8,  8,  7,  7,  7,  7,
@@ -50,7 +50,7 @@
   1,  1,  1,  1,  1,  1,  1,  1
 };
 
-static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
+static const int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
 
 static void SetupBoundingValueArray_Generic(PB_INSTANCE *pbi,
                                             ogg_int32_t FLimit){
@@ -746,7 +746,8 @@
       LineLength = pbi->UVStride;
       LineFragments = pbi->HFragments / 2;
       break;
-    case 2: /* v */
+    /*case 2:  v */
+    default:
       FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
       ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
       FragsAcross = pbi->HFragments >> 1;
@@ -980,32 +981,71 @@
 
 void ReconRefFrames (PB_INSTANCE *pbi){
   ogg_int32_t i;
-  ogg_int32_t FragIndex;
   unsigned char *SwapReconBuffersTemp;
 
-  short pc[16][6]={
+  /* predictor multiplier up-left, up, up-right,left, shift
+     Entries are packed in the order L, UL, U, UR, with missing entries
+      moved to the end (before the shift parameters). */
+  static const ogg_int16_t pc[16][6]={
     {0,0,0,0,0,0},
-    {0,0,0,1,0,0},
-    {0,0,1,0,0,0},
-    {0,0,53,75,7,127},
-    {0,1,0,0,0,0},
-    {0,1,0,1,1,1},
-    {0,1,0,0,0,0},
-    {0,0,53,75,7,127},
-    {1,0,0,0,0,0},
-    {0,0,0,1,0,0},
-    {1,0,1,0,1,1},
-    {0,0,53,75,7,127},
-    {0,1,0,0,0,0},
-    {-26,29,0,29,5,31},
-    {3,10,3,0,4,15},
-    {-26,29,0,29,5,31}
+    {1,0,0,0,0,0},      /* PL */
+    {1,0,0,0,0,0},      /* PUL */
+    {1,0,0,0,0,0},      /* PUL|PL */
+    {1,0,0,0,0,0},      /* PU */
+    {1,1,0,0,1,1},      /* PU|PL */
+    {0,1,0,0,0,0},      /* PU|PUL */
+    {29,-26,29,0,5,31}, /* PU|PUL|PL */
+    {1,0,0,0,0,0},      /* PUR */
+    {75,53,0,0,7,127},  /* PUR|PL */
+    {1,1,0,0,1,1},      /* PUR|PUL */
+    {75,0,53,0,7,127},  /* PUR|PUL|PL */
+    {1,0,0,0,0,0},      /* PUR|PU */
+    {75,0,53,0,7,127},  /* PUR|PU|PL */
+    {3,10,3,0,4,15},    /* PUR|PU|PUL */
+    {29,-26,29,0,5,31}  /* PUR|PU|PUL|PL */
   };
-  int fl,ful,fu,fur;
-  int vl,vul,vu,vur;
-  int l,ul,u,ur;
+
+  /* boundary case bit masks. */
+  static const int bc_mask[8]={
+    /* normal case no boundary condition */
+    PUR|PU|PUL|PL,
+    /* left column */
+    PUR|PU,
+    /* top row */
+    PL,
+    /* top row, left column */
+    0,
+    /* right column */
+    PU|PUL|PL,
+    /* right and left column */
+    PU,
+    /* top row, right column */
+    PL,
+    /* top row, right and left column */
+    0
+  };
+
+  /* value left value up-left, value up, value up-right, missing
+      values skipped. */
+  int v[4];
+
+  /* fragment number left, up-left, up, up-right */
+  int fn[4];
+
+  /* predictor count. */
+  int pcount;
+
   short wpc;
-  short Mode2Frame[] = { 1,0,1,1,1,2,2,1 };
+  static const short Mode2Frame[] = {
+    1,  /* CODE_INTER_NO_MV     0 => Encoded diff from same MB last frame  */
+    0,  /* CODE_INTRA           1 => DCT Encoded Block */
+    1,  /* CODE_INTER_PLUS_MV   2 => Encoded diff from included MV MB last frame */
+    1,  /* CODE_INTER_LAST_MV   3 => Encoded diff from MRU MV MB last frame */
+    1,  /* CODE_INTER_PRIOR_MV  4 => Encoded diff from included 4 separate MV blocks */
+    2,  /* CODE_USING_GOLDEN    5 => Encoded diff from same MB golden frame */
+    2,  /* CODE_GOLDEN_MV       6 => Encoded diff from included MV MB golden frame */
+    1   /* CODE_INTER_FOUR_MV   7 => Encoded diff from included 4 separate MV blocks */
+  };
   short Last[3];
   short PredictedDC;
   int FragsAcross=pbi->HFragments;
@@ -1016,16 +1056,6 @@
   int WhichCase;
   int j,k,m,n;
 
-  struct SearchPoints{
-    int RowOffset;
-    int ColOffset;
-  } DCSearchPoints[]={
-    {0,-2},{-2,0},{-1,-2},{-2,-1},{-2,1},{-1,2},{-2,-2},{-2,2},{0,-3},
-    {-3,0},{-1,-3},{-3,-1},{-3,1},{-1,3},{-2,-3},{-3,-2},{-3,2},{-2,3},
-    {0,-4},{-4,0},{-1,-4},{-4,-1},{-4,1},{-1,4},{-3,-3},{-3,3}
-  };
-
-  int DCSearchPointCount = 0;
   void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber );
 
   if ( GetFrameType(pbi) == BASE_FRAME )
@@ -1051,7 +1081,8 @@
       FragsAcross = pbi->HFragments >> 1;
       FragsDown = pbi->VFragments >> 1;
       break;
-    case 2: /* v */
+    /*case 2:  v */
+    default:    
       FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
       ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
       FragsAcross = pbi->HFragments >> 1;
@@ -1078,142 +1109,36 @@
           /* Check Borderline Cases */
           WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);
 
-          switch(WhichCase){
-          case 0: /* normal case no border condition */
-
-            /* calculate values left, up, up-right and up-left */
-            l = i-1;
-            u = i - FragsAcross;
-            ur = i - FragsAcross + 1;
-            ul = i - FragsAcross - 1;
-
-            /* calculate values */
-            vl = pbi->QFragData[l][0];
-            vu = pbi->QFragData[u][0];
-            vur = pbi->QFragData[ur][0];
-            vul = pbi->QFragData[ul][0];
-
-            /* fragment valid for prediction use if coded and it comes
-               from same frame as the one we are predicting */
-            fl = pbi->display_fragments[l] &&
-              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
-            fu = pbi->display_fragments[u] &&
-              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
-            fur = pbi->display_fragments[ur] &&
-              (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame);
-            ful = pbi->display_fragments[ul] &&
-              (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame);
-
-            /* calculate which predictor to use */
-            wpc = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR);
-
-            break;
-
-          case 1: /* n == 0 Left Column */
-
-            /* calculate values left, up, up-right and up-left */
-            u = i - FragsAcross;
-            ur = i - FragsAcross + 1;
-
-            /* calculate values */
-            vu = pbi->QFragData[u][0];
-            vur = pbi->QFragData[ur][0];
-
-            /* fragment valid for prediction if coded and it comes
-               from same frame as the one we are predicting */
-            fu = pbi->display_fragments[u] &&
-              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
-            fur = pbi->display_fragments[ur] &&
-              (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame);
-
-            /* calculate which predictor to use */
-            wpc = (fu*PU) | (fur*PUR);
-
-            break;
-
-          case 2: /* m == 0 Top Row */
-          case 6: /* m == 0 and n+1 == FragsAcross or Top Row Right Column */
-
-            /* calculate values left, up, up-right and up-left */
-            l = i-1;
-
-            /* calculate values */
-            vl = pbi->QFragData[l][0];
-
-            /* fragment valid for prediction if coded and it comes
-               from same frame as the one we are predicting */
-            fl = pbi->display_fragments[l] &&
-              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
-
-            /* calculate which predictor to use */
-            wpc = (fl*PL) ;
-
-            break;
-
-          case 3: /* n == 0 & m == 0 Top Row Left Column */
-
-            wpc = 0;
-
-            break;
-
-          case 4: /* n+1 == FragsAcross : Right Column */
-
-            /* calculate values left, up, up-right and up-left */
-            l = i-1;
-            u = i - FragsAcross;
-            ul = i - FragsAcross - 1;
-
-            /* calculate values */
-            vl = pbi->QFragData[l][0];
-            vu = pbi->QFragData[u][0];
-            vul = pbi->QFragData[ul][0];
-
-            /* fragment valid for prediction if coded and it comes
-               from same frame as the one we are predicting */
-            fl = pbi->display_fragments[l] &&
-              (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame);
-            fu = pbi->display_fragments[u] &&
-              (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame);
-            ful = pbi->display_fragments[ul] &&
-              (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame);
-
-            /* calculate which predictor to use */
-            wpc = (fl*PL) | (fu*PU) | (ful*PUL) ;
-
-            break;
-
+          fn[0]=i-1;
+          fn[1]=i-FragsAcross-1;
+          fn[2]=i-FragsAcross;
+          fn[3]=i-FragsAcross+1;
+
+          /* fragment valid for prediction use if coded and it comes
+             from same frame as the one we are predicting */
+          for(k=pcount=wpc=0; k<4; k++) {
+            int pflag;
+            pflag=1<<k;
+            if((bc_mask[WhichCase]&pflag) &&
+               pbi->display_fragments[fn[k]] &&
+               (Mode2Frame[pbi->FragCodingMethod[fn[k]]] == WhichFrame)){
+              v[pcount]=pbi->QFragData[fn[k]][0];
+              wpc|=pflag;
+              pcount++;
+            }
           }
 
           if(wpc==0){
-            FragIndex = 1;
-
-            /* find the nearest one that is coded */
-            for( k = 0; k < DCSearchPointCount ; k++){
-              FragIndex = i + DCSearchPoints[k].RowOffset * FragsAcross +
-                DCSearchPoints[k].ColOffset;
-
-              if( FragIndex - FromFragment > 0 ) {
-                if(pbi->display_fragments[FragIndex] &&
-                   (Mode2Frame[pbi->FragCodingMethod[FragIndex]] ==
-                    WhichFrame)){
-                  pbi->QFragData[i][0] += pbi->QFragData[FragIndex][0];
-                  FragIndex = 0;
-                  break;
-                }
-              }
-            }
-
-
-            /* if none matched fall back to the last one ever */
-            if(FragIndex){
-              pbi->QFragData[i][0] += Last[WhichFrame];
-            }
+            /* fall back to the last coded fragment */
+            pbi->QFragData[i][0] += Last[WhichFrame];
 
           }else{
 
             /* don't do divide if divisor is 1 or 0 */
-            PredictedDC = (pc[wpc][0]*vul + pc[wpc][1] * vu +
-                           pc[wpc][2] * vur + pc[wpc][3] * vl );
+            PredictedDC = pc[wpc][0]*v[0];
+            for(k=1; k<pcount; k++){
+              PredictedDC += pc[wpc][k]*v[k];
+            }
 
             /* if we need to do a shift */
             if(pc[wpc][4] != 0 ){
@@ -1226,17 +1151,14 @@
             }
 
             /* check for outranging on the two predictors that can outrange */
-            switch(wpc){
-            case 13: /* pul pu pl */
-            case 15: /* pul pu pur pl */
-              if( abs(PredictedDC - vu) > 128)
-                PredictedDC = vu;
-              else if( abs(PredictedDC - vl) > 128)
-                PredictedDC = vl;
-              else if( abs(PredictedDC - vul) > 128)
-                PredictedDC = vul;
-
-              break;
+            if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
+              if( abs(PredictedDC - v[2]) > 128) {
+                PredictedDC = v[2];
+              } else if( abs(PredictedDC - v[0]) > 128) {
+                PredictedDC = v[0];
+              } else if( abs(PredictedDC - v[1]) > 128) {
+                PredictedDC = v[1];
+              }
             }
 
             pbi->QFragData[i][0] += PredictedDC;

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list