tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 6386

 
 
 

VP8 Data Format and Decoding Guide

Part 8 of 11, p. 193 to 230
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 193 
20.13.  modemv_data.h

   ---- Begin code block --------------------------------------

   /*
    *  Copyright (c) 2010, 2011, Google Inc.  All rights reserved.
    *
    *  Use of this source code is governed by a BSD-style license
    *  that can be found in the LICENSE file in the root of the source
    *  tree.  An additional intellectual property rights grant can be
    *  found in the file PATENTS.  All contributing project authors may
    *  be found in the AUTHORS file in the root of the source tree.
    */

   static const unsigned char kf_y_mode_probs[] = { 145, 156, 163, 128};
   static const unsigned char kf_uv_mode_probs[] = { 142, 114, 183};
   static const unsigned char kf_b_mode_probs[10][10][9] =
   {
     { /* above mode 0 */
       { /* left mode 0 */ 231, 120,  48,  89, 115, 113, 120, 152, 112},
       { /* left mode 1 */ 152, 179,  64, 126, 170, 118,  46,  70,  95},
       { /* left mode 2 */ 175,  69, 143,  80,  85,  82,  72, 155, 103},
       { /* left mode 3 */  56,  58,  10, 171, 218, 189,  17,  13, 152},
       { /* left mode 4 */ 144,  71,  10,  38, 171, 213, 144,  34,  26},
       { /* left mode 5 */ 114,  26,  17, 163,  44, 195,  21,  10, 173},
       { /* left mode 6 */ 121,  24,  80, 195,  26,  62,  44,  64,  85},
       { /* left mode 7 */ 170,  46,  55,  19, 136, 160,  33, 206,  71},
       { /* left mode 8 */  63,  20,   8, 114, 114, 208,  12,   9, 226},
       { /* left mode 9 */  81,  40,  11,  96, 182,  84,  29,  16,  36}
     },
     { /* above mode 1 */
       { /* left mode 0 */ 134, 183,  89, 137,  98, 101, 106, 165, 148},
       { /* left mode 1 */  72, 187, 100, 130, 157, 111,  32,  75,  80},
       { /* left mode 2 */  66, 102, 167,  99,  74,  62,  40, 234, 128},
       { /* left mode 3 */  41,  53,   9, 178, 241, 141,  26,   8, 107},
       { /* left mode 4 */ 104,  79,  12,  27, 217, 255,  87,  17,   7},
       { /* left mode 5 */  74,  43,  26, 146,  73, 166,  49,  23, 157},
       { /* left mode 6 */  65,  38, 105, 160,  51,  52,  31, 115, 128},
       { /* left mode 7 */  87,  68,  71,  44, 114,  51,  15, 186,  23},
       { /* left mode 8 */  47,  41,  14, 110, 182, 183,  21,  17, 194},
       { /* left mode 9 */  66,  45,  25, 102, 197, 189,  23,  18,  22}
     },
     { /* above mode 2 */
       { /* left mode 0 */  88,  88, 147, 150,  42,  46,  45, 196, 205},
       { /* left mode 1 */  43,  97, 183, 117,  85,  38,  35, 179,  61},
       { /* left mode 2 */  39,  53, 200,  87,  26,  21,  43, 232, 171},
       { /* left mode 3 */  56,  34,  51, 104, 114, 102,  29,  93,  77},
       { /* left mode 4 */ 107,  54,  32,  26,  51,   1,  81,  43,  31},

Top      Up      ToC       Page 194 
       { /* left mode 5 */  39,  28,  85, 171,  58, 165,  90,  98,  64},
       { /* left mode 6 */  34,  22, 116, 206,  23,  34,  43, 166,  73},
       { /* left mode 7 */  68,  25, 106,  22,  64, 171,  36, 225, 114},
       { /* left mode 8 */  34,  19,  21, 102, 132, 188,  16,  76, 124},
       { /* left mode 9 */  62,  18,  78,  95,  85,  57,  50,  48,  51}
     },
     { /* above mode 3 */
       { /* left mode 0 */ 193, 101,  35, 159, 215, 111,  89,  46, 111},
       { /* left mode 1 */  60, 148,  31, 172, 219, 228,  21,  18, 111},
       { /* left mode 2 */ 112, 113,  77,  85, 179, 255,  38, 120, 114},
       { /* left mode 3 */  40,  42,   1, 196, 245, 209,  10,  25, 109},
       { /* left mode 4 */ 100,  80,   8,  43, 154,   1,  51,  26,  71},
       { /* left mode 5 */  88,  43,  29, 140, 166, 213,  37,  43, 154},
       { /* left mode 6 */  61,  63,  30, 155,  67,  45,  68,   1, 209},
       { /* left mode 7 */ 142,  78,  78,  16, 255, 128,  34, 197, 171},
       { /* left mode 8 */  41,  40,   5, 102, 211, 183,   4,   1, 221},
       { /* left mode 9 */  51,  50,  17, 168, 209, 192,  23,  25,  82}
     },
     { /* above mode 4 */
       { /* left mode 0 */ 125,  98,  42,  88, 104,  85, 117, 175,  82},
       { /* left mode 1 */  95,  84,  53,  89, 128, 100, 113, 101,  45},
       { /* left mode 2 */  75,  79, 123,  47,  51, 128,  81, 171,   1},
       { /* left mode 3 */  57,  17,   5,  71, 102,  57,  53,  41,  49},
       { /* left mode 4 */ 115,  21,   2,  10, 102, 255, 166,  23,   6},
       { /* left mode 5 */  38,  33,  13, 121,  57,  73,  26,   1,  85},
       { /* left mode 6 */  41,  10,  67, 138,  77, 110,  90,  47, 114},
       { /* left mode 7 */ 101,  29,  16,  10,  85, 128, 101, 196,  26},
       { /* left mode 8 */  57,  18,  10, 102, 102, 213,  34,  20,  43},
       { /* left mode 9 */ 117,  20,  15,  36, 163, 128,  68,   1,  26}
     },
     { /* above mode 5 */
       { /* left mode 0 */ 138,  31,  36, 171,  27, 166,  38,  44, 229},
       { /* left mode 1 */  67,  87,  58, 169,  82, 115,  26,  59, 179},
       { /* left mode 2 */  63,  59,  90, 180,  59, 166,  93,  73, 154},
       { /* left mode 3 */  40,  40,  21, 116, 143, 209,  34,  39, 175},
       { /* left mode 4 */  57,  46,  22,  24, 128,   1,  54,  17,  37},
       { /* left mode 5 */  47,  15,  16, 183,  34, 223,  49,  45, 183},
       { /* left mode 6 */  46,  17,  33, 183,   6,  98,  15,  32, 183},
       { /* left mode 7 */  65,  32,  73, 115,  28, 128,  23, 128, 205},
       { /* left mode 8 */  40,   3,   9, 115,  51, 192,  18,   6, 223},
       { /* left mode 9 */  87,  37,   9, 115,  59,  77,  64,  21,  47}
     },
     { /* above mode 6 */
       { /* left mode 0 */ 104,  55,  44, 218,   9,  54,  53, 130, 226},
       { /* left mode 1 */  64,  90,  70, 205,  40,  41,  23,  26,  57},
       { /* left mode 2 */  54,  57, 112, 184,   5,  41,  38, 166, 213},
       { /* left mode 3 */  30,  34,  26, 133, 152, 116,  10,  32, 134},
       { /* left mode 4 */  75,  32,  12,  51, 192, 255, 160,  43,  51},

Top      Up      ToC       Page 195 
       { /* left mode 5 */  39,  19,  53, 221,  26, 114,  32,  73, 255},
       { /* left mode 6 */  31,   9,  65, 234,   2,  15,   1, 118,  73},
       { /* left mode 7 */  88,  31,  35,  67, 102,  85,  55, 186,  85},
       { /* left mode 8 */  56,  21,  23, 111,  59, 205,  45,  37, 192},
       { /* left mode 9 */  55,  38,  70, 124,  73, 102,   1,  34,  98}
     },
     { /* above mode 7 */
       { /* left mode 0 */ 102,  61,  71,  37,  34,  53,  31, 243, 192},
       { /* left mode 1 */  69,  60,  71,  38,  73, 119,  28, 222,  37},
       { /* left mode 2 */  68,  45, 128,  34,   1,  47,  11, 245, 171},
       { /* left mode 3 */  62,  17,  19,  70, 146,  85,  55,  62,  70},
       { /* left mode 4 */  75,  15,   9,   9,  64, 255, 184, 119,  16},
       { /* left mode 5 */  37,  43,  37, 154, 100, 163,  85, 160,   1},
       { /* left mode 6 */  63,   9,  92, 136,  28,  64,  32, 201,  85},
       { /* left mode 7 */  86,   6,  28,   5,  64, 255,  25, 248,   1},
       { /* left mode 8 */  56,   8,  17, 132, 137, 255,  55, 116, 128},
       { /* left mode 9 */  58,  15,  20,  82, 135,  57,  26, 121,  40}
     },
     { /* above mode 8 */
       { /* left mode 0 */ 164,  50,  31, 137, 154, 133,  25,  35, 218},
       { /* left mode 1 */  51, 103,  44, 131, 131, 123,  31,   6, 158},
       { /* left mode 2 */  86,  40,  64, 135, 148, 224,  45, 183, 128},
       { /* left mode 3 */  22,  26,  17, 131, 240, 154,  14,   1, 209},
       { /* left mode 4 */  83,  12,  13,  54, 192, 255,  68,  47,  28},
       { /* left mode 5 */  45,  16,  21,  91,  64, 222,   7,   1, 197},
       { /* left mode 6 */  56,  21,  39, 155,  60, 138,  23, 102, 213},
       { /* left mode 7 */  85,  26,  85,  85, 128, 128,  32, 146, 171},
       { /* left mode 8 */  18,  11,   7,  63, 144, 171,   4,   4, 246},
       { /* left mode 9 */  35,  27,  10, 146, 174, 171,  12,  26, 128}
     },
     { /* above mode 9 */
       { /* left mode 0 */ 190,  80,  35,  99, 180,  80, 126,  54,  45},
       { /* left mode 1 */  85, 126,  47,  87, 176,  51,  41,  20,  32},
       { /* left mode 2 */ 101,  75, 128, 139, 118, 146, 116, 128,  85},
       { /* left mode 3 */  56,  41,  15, 176, 236,  85,  37,   9,  62},
       { /* left mode 4 */ 146,  36,  19,  30, 171, 255,  97,  27,  20},
       { /* left mode 5 */  71,  30,  17, 119, 118, 255,  17,  18, 138},
       { /* left mode 6 */ 101,  38,  60, 138,  55,  70,  43,  26, 142},
       { /* left mode 7 */ 138,  45,  61,  62, 219,   1,  81, 188,  64},
       { /* left mode 8 */  32,  41,  20, 117, 151, 142,  20,  21, 163},
       { /* left mode 9 */ 112,  19,  12,  61, 195, 128,  48,   4,  24}
     }
   };

Top      Up      ToC       Page 196 
   static const int kf_y_mode_tree[] =
   {
     -B_PRED, 2,
     4, 6,
     -DC_PRED, -V_PRED,
     -H_PRED, -TM_PRED
   };
   static const int y_mode_tree[] =
   {
     -DC_PRED, 2,
     4, 6,
     -V_PRED, -H_PRED,
     -TM_PRED, -B_PRED
   };
   static const int uv_mode_tree[6] =
   {
     -DC_PRED, 2,
     -V_PRED, 4,
     -H_PRED, -TM_PRED
   };
   static const int b_mode_tree[18] =
   {
     -B_DC_PRED, 2,               /* 0 = DC_NODE */
     -B_TM_PRED, 4,               /* 1 = TM_NODE */
     -B_VE_PRED, 6,               /* 2 = VE_NODE */
     8, 12,                       /* 3 = COM_NODE */
     -B_HE_PRED, 10,              /* 4 = HE_NODE */
     -B_RD_PRED, -B_VR_PRED,      /* 5 = RD_NODE */
     -B_LD_PRED, 14,              /* 6 = LD_NODE */
     -B_VL_PRED, 16,              /* 7 = VL_NODE */
     -B_HD_PRED, -B_HU_PRED       /* 8 = HD_NODE */
   };
   static const int small_mv_tree[14] =
   {
     2, 8,
     4, 6,
     -0, -1,
     -2, -3,
     10, 12,
     -4, -5,
     -6, -7
   };

Top      Up      ToC       Page 197 
   static const int mv_ref_tree[8] =
   {
     -ZEROMV, 2,
     -NEARESTMV, 4,
     -NEARMV, 6,
     -NEWMV, -SPLITMV
   };
   static const int submv_ref_tree[6] =
   {
     -LEFT4X4, 2,
     -ABOVE4X4, 4,
     -ZERO4X4, -NEW4X4
   };
   static const int split_mv_tree[6] =
   {
     -3, 2,
     -2, 4,
     -0, -1
   };
   static const unsigned char default_b_mode_probs[] =
   { 120,  90,  79, 133,  87,  85,  80, 111, 151};
   static const unsigned char mv_counts_to_probs[6][4] =
   {
     {   7,   1,   1, 143 },
     {  14,  18,  14, 107 },
     { 135,  64,  57,  68 },
     {  60,  56, 128,  65 },
     { 159, 134, 128,  34 },
     { 234, 188, 128,  28 }

   };
   static const unsigned char split_mv_probs[3] =
   { 110, 111, 150};

   static const unsigned char submv_ref_probs2[5][3] =
   {
     { 147, 136, 18 },
     { 106, 145,  1 },
     { 179, 121,  1 },
     { 223,   1, 34 },
     { 208,   1,  1 }
   };

Top      Up      ToC       Page 198 
   const static int mv_partitions[4][16] =
   {
     {0, 0, 0, 0, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1 },
     {0, 0, 1, 1, 0, 0, 1, 1, 0, 0,  1,  1,  0,  0,  1,  1 },
     {0, 0, 1, 1, 0, 0, 1, 1, 2, 2,  3,  3,  2,  2,  3,  3 },
     {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
   };

   ---- End code block ----------------------------------------

20.14.  predict.c

   ---- Begin code block --------------------------------------

   /*
    *  Copyright (c) 2010, 2011, Google Inc.  All rights reserved.
    *
    *  Use of this source code is governed by a BSD-style license
    *  that can be found in the LICENSE file in the root of the source
    *  tree.  An additional intellectual property rights grant can be
    *  found in the file PATENTS.  All contributing project authors may
    *  be found in the AUTHORS file in the root of the source tree.
    */
   #include "dixie.h"
   #include "predict.h"
   #include "idct_add.h"
   #include "mem.h"
   #include <assert.h>
   #include <string.h>

   enum
   {
       BORDER_PIXELS     = 16,
   };


   static const filter_t sixtap_filters[8] =
   {
       { 0,   0, 128,    0,   0,  0 },
       { 0,  -6, 123,   12,  -1,  0 },
       { 2, -11, 108,   36,  -8,  1 },
       { 0,  -9,  93,   50,  -6,  0 },
       { 3, -16,  77,   77, -16,  3 },
       { 0,  -6,  50,   93,  -9,  0 },
       { 1,  -8,  36,  108, -11,  2 },
       { 0,  -1,  12,  123,  -6,  0 }
   };

Top      Up      ToC       Page 199 
   static const filter_t bilinear_filters[8] =
   {
       { 0,  0,  128,    0,   0,  0 },
       { 0,  0,  112,   16,   0,  0 },
       { 0,  0,   96,   32,   0,  0 },
       { 0,  0,   80,   48,   0,  0 },
       { 0,  0,   64,   64,   0,  0 },
       { 0,  0,   48,   80,   0,  0 },
       { 0,  0,   32,   96,   0,  0 },
       { 0,  0,   16,  112,   0,  0 }
   };


   static void
   predict_h_nxn(unsigned char *predict,
                 int            stride,
                 int            n)
   {
       unsigned char *left = predict - 1;
       int            i, j;

       for (i = 0; i < n; i++)
           for (j = 0; j < n; j++)
               predict[i *stride + j] = left[i * stride];
   }


   static void
   predict_v_nxn(unsigned char *predict,
                 int            stride,
                 int            n)
   {
       unsigned char *above = predict - stride;
       int            i, j;

       for (i = 0; i < n; i++)
           for (j = 0; j < n; j++)
               predict[i *stride + j] = above[j];
   }

Top      Up      ToC       Page 200 
   static void
   predict_tm_nxn(unsigned char *predict,
                  int            stride,
                  int            n)
   {
       /* Transposes the left column to the top row for later
        * consumption by the idct/recon stage
        */
       unsigned char *left = predict - 1;
       unsigned char *above = predict - stride;
       unsigned char  p = above[-1];
       int            i, j;

       for (j = 0; j < n; j++)
       {
           for (i = 0; i < n; i++)
               predict[i] = CLAMP_255(*left + above[i] - p);

           predict += stride;
           left += stride;
       }
   }

   static void
   predict_dc_nxn(unsigned char *predict,
                  int            stride,
                  int            n)
   {
       unsigned char *left = predict - 1;
       unsigned char *above = predict - stride;
       int            i, j, dc = 0;

       for (i = 0; i < n; i++)
       {
           dc += *left + above[i];
           left += stride;
       }

Top      Up      ToC       Page 201 
       switch (n)
       {
       case 16:
           dc = (dc + 16) >> 5;
           break;
       case  8:
           dc = (dc + 8) >> 4;
           break;
       case  4:
           dc = (dc + 4) >> 3;
           break;
       }

       for (i = 0; i < n; i++)
           for (j = 0; j < n; j++)
               predict[i *stride + j] = dc;
   }


   static void
   predict_ve_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *above = predict - stride;
       int            i, j;

       predict[0] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
       predict[1] = (above[ 0] + 2 * above[1] + above[2] + 2) >> 2;
       predict[2] = (above[ 1] + 2 * above[2] + above[3] + 2) >> 2;
       predict[3] = (above[ 2] + 2 * above[3] + above[4] + 2) >> 2;

       for (i = 1; i < 4; i++)
           for (j = 0; j < 4; j++)
               predict[i *stride + j] = predict[j];
   }

Top      Up      ToC       Page 202 
   static void
   predict_he_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *left = predict - 1;

       predict[0] =
       predict[1] =
       predict[2] =
       predict[3] = (left[-stride] + 2 * left[0] +
                     left[stride] + 2) >> 2;
       predict += stride;
       left += stride;

       predict[0] =
       predict[1] =
       predict[2] =
       predict[3] = (left[-stride] + 2 * left[0] +
                     left[stride] + 2) >> 2;
       predict += stride;
       left += stride;

       predict[0] =
       predict[1] =
       predict[2] =
       predict[3] = (left[-stride] + 2 * left[0] +
                     left[stride] + 2) >> 2;
       predict += stride;
       left += stride;

       predict[0] =
       predict[1] =
       predict[2] =
       predict[3] = (left[-stride] + 2 * left[0] + left[0] + 2) >> 2;
   }

Top      Up      ToC       Page 203 
   static void
   predict_ld_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *above = predict - stride;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6;

       predict[0] = pred0 = (above[0] + 2 * above[1] +
                             above[2] + 2) >> 2;
       predict[1] = pred1 = (above[1] + 2 * above[2] +
                             above[3] + 2) >> 2;
       predict[2] = pred2 = (above[2] + 2 * above[3] +
                             above[4] + 2) >> 2;
       predict[3] = pred3 = (above[3] + 2 * above[4] +
                             above[5] + 2) >> 2;
       predict += stride;

       predict[0] = pred1;
       predict[1] = pred2;
       predict[2] = pred3;
       predict[3] = pred4 = (above[4] + 2 * above[5] +
                             above[6] + 2) >> 2;
       predict += stride;

       predict[0] = pred2;
       predict[1] = pred3;
       predict[2] = pred4;
       predict[3] = pred5 = (above[5] + 2 * above[6] +
                             above[7] + 2) >> 2;
       predict += stride;

       predict[0] = pred3;
       predict[1] = pred4;
       predict[2] = pred5;
       predict[3] = pred6 = (above[6] + 2 * above[7] +
                             above[7] + 2) >> 2;
   }

Top      Up      ToC       Page 204 
   static void
   predict_rd_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *left = predict - 1;
       unsigned char *above = predict - stride;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6;

       predict[0] = pred0 =
           (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2;
       predict[1] = pred1 =
           (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2;
       predict[2] = pred2 =
           (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2;
       predict[3] = pred3 =
           (above[ 1] + 2 * above[ 2] + above[3] + 2) >> 2;
       predict += stride;

       predict[0] = pred4 =
           (left[stride] + 2 * left[0] + above[-1] + 2) >> 2;
       predict[1] = pred0;
       predict[2] = pred1;
       predict[3] = pred2;
       predict += stride;

       predict[0] = pred5 =
           (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2;
       predict[1] = pred4;
       predict[2] = pred0;
       predict[3] = pred1;
       predict += stride;

       predict[0] = pred6 = (left[stride*3] + 2 * left[stride*2] +
                             left[stride] + 2) >> 2;
       predict[1] = pred5;
       predict[2] = pred4;
       predict[3] = pred0;
   }

Top      Up      ToC       Page 205 
   static void
   predict_vr_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *left = predict - 1;
       unsigned char *above = predict - stride;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6,
                      pred7, pred8, pred9;

       predict[0] = pred0 = (above[-1] + above[0] + 1) >> 1;
       predict[1] = pred1 = (above[ 0] + above[1] + 1) >> 1;
       predict[2] = pred2 = (above[ 1] + above[2] + 1) >> 1;
       predict[3] = pred3 = (above[ 2] + above[3] + 1) >> 1;
       predict += stride;

       predict[0] = pred4 = (left[ 0] + 2 * above[-1] +
                             above[0] + 2) >> 2;
       predict[1] = pred5 = (above[-1] + 2 * above[ 0] +
                             above[1] + 2) >> 2;
       predict[2] = pred6 = (above[ 0] + 2 * above[ 1] +
                             above[2] + 2) >> 2;
       predict[3] = pred7 = (above[ 1] + 2 * above[ 2] +
                             above[3] + 2) >> 2;
       predict += stride;

       predict[0] = pred8 =
           (left[stride] + 2 * left[0] + above[-1] + 2) >> 2;
       predict[1] = pred0;
       predict[2] = pred1;
       predict[3] = pred2;
       predict += stride;

       predict[0] = pred9 =
           (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2;
       predict[1] = pred4;
       predict[2] = pred5;
       predict[3] = pred6;
   }

Top      Up      ToC       Page 206 
   static void
   predict_vl_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *above = predict - stride;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6,
                      pred7, pred8, pred9;

       predict[0] = pred0 = (above[0] + above[1] + 1) >> 1;
       predict[1] = pred1 = (above[1] + above[2] + 1) >> 1;
       predict[2] = pred2 = (above[2] + above[3] + 1) >> 1;
       predict[3] = pred3 = (above[3] + above[4] + 1) >> 1;
       predict += stride;

       predict[0] = pred4 = (above[0] + 2 * above[1] +
                             above[2] + 2) >> 2;
       predict[1] = pred5 = (above[1] + 2 * above[2] +
                             above[3] + 2) >> 2;
       predict[2] = pred6 = (above[2] + 2 * above[3] +
                             above[4] + 2) >> 2;
       predict[3] = pred7 = (above[3] + 2 * above[4] +
                             above[5] + 2) >> 2;
       predict += stride;

       predict[0] = pred1;
       predict[1] = pred2;
       predict[2] = pred3;
       predict[3] = pred8 = (above[4] + 2 * above[5] +
                             above[6] + 2) >> 2;
       predict += stride;

       predict[0] = pred5;
       predict[1] = pred6;
       predict[2] = pred7;
       predict[3] = pred9 = (above[5] + 2 * above[6] +
                             above[7] + 2) >> 2;
   }

Top      Up      ToC       Page 207 
   static void
   predict_hd_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *left = predict - 1;
       unsigned char *above = predict - stride;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6,
                      pred7, pred8, pred9;

       predict[0] = pred0 = (left[ 0] + above[-1] + 1) >> 1;
       predict[1] = pred1 = (left[ 0] + 2 * above[-1] +
                             above[0] + 2) >> 2;
       predict[2] = pred2 = (above[-1] + 2 * above[ 0] +
                             above[1] + 2) >> 2;
       predict[3] = pred3 = (above[ 0] + 2 * above[ 1] +
                             above[2] + 2) >> 2;
       predict += stride;

       predict[0] = pred4 = (left[stride] + left[0] + 1) >> 1;
       predict[1] = pred5 = (left[stride] + 2 * left[0] +
                             above[-1] + 2) >> 2;
       predict[2] = pred0;
       predict[3] = pred1;
       predict += stride;

       predict[0] = pred6 = (left[stride*2] + left[stride] + 1) >> 1;
       predict[1] = pred7 = (left[stride*2] + 2 * left[stride] +
                             left[0] + 2) >> 2;
       predict[2] = pred4;
       predict[3] = pred5;
       predict += stride;

       predict[0] = pred8 = (left[stride*3] + left[stride*2] + 1) >> 1;
       predict[1] = pred9 = (left[stride*3] + 2 * left[stride*2] +
                             left[stride] + 2) >> 2;
       predict[2] = pred6;
       predict[3] = pred7;
   }

Top      Up      ToC       Page 208 
   static void
   predict_hu_4x4(unsigned char *predict,
                  int            stride)
   {
       unsigned char *left = predict - 1;
       int            pred0, pred1, pred2, pred3, pred4, pred5, pred6;

       predict[0] = pred0 = (left[stride*0] +
                             left[stride*1] + 1) >> 1;
       predict[1] = pred1 = (left[stride*0] + 2 * left[stride*1] +
                             left[stride*2] + 2) >> 2;
       predict[2] = pred2 = (left[stride*1] + left[stride*2] + 1) >> 1;
       predict[3] = pred3 = (left[stride*1] + 2 * left[stride*2] +
                             left[stride*3] + 2) >> 2;
       predict += stride;

       predict[0] = pred2;
       predict[1] = pred3;
       predict[2] = pred4 = (left[stride*2] + left[stride*3] + 1) >> 1;
       predict[3] = pred5 = (left[stride*2] + 2 * left[stride*3] +
                             left[stride*3] + 2) >> 2;
       predict += stride;

       predict[0] = pred4;
       predict[1] = pred5;
       predict[2] = pred6 = left[stride*3];
       predict[3] = pred6;
       predict += stride;

       predict[0] = pred6;
       predict[1] = pred6;
       predict[2] = pred6;
       predict[3] = pred6;
   }


   static void
   predict_h_16x16(unsigned char *predict, int stride)
   {
       predict_h_nxn(predict, stride, 16);
   }


   static void
   predict_v_16x16(unsigned char *predict, int stride)
   {
       predict_v_nxn(predict, stride, 16);
   }

Top      Up      ToC       Page 209 
   static void
   predict_tm_16x16(unsigned char *predict, int stride)
   {
       predict_tm_nxn(predict, stride, 16);
   }


   static void
   predict_h_8x8(unsigned char *predict, int stride)
   {
       predict_h_nxn(predict, stride, 8);
   }


   static void
   predict_v_8x8(unsigned char *predict, int stride)
   {
       predict_v_nxn(predict, stride, 8);
   }

   static void
   predict_tm_8x8(unsigned char *predict, int stride)
   {
       predict_tm_nxn(predict, stride, 8);
   }


   static void
   predict_tm_4x4(unsigned char *predict, int stride)
   {
       predict_tm_nxn(predict, stride, 4);
   }


   static void
   copy_down(unsigned char           *recon,
             int                      stride)
   {
       /* Copy the four pixels above-right of subblock 3 to
        * above-right of subblocks 7, 11, and 15
        */
       uint32_t tmp, *copy = (void *)(recon + 16 - stride);

Top      Up      ToC       Page 210 
       stride = stride / sizeof(unsigned int);
       tmp = *copy;
       copy += stride * 4;
       *copy = tmp;
       copy += stride * 4;
       *copy = tmp;
       copy += stride * 4;
       *copy = tmp;
   }


   static void
   b_pred(unsigned char  *predict,
          int             stride,
          struct mb_info *mbi,
          short          *coeffs)
   {
       int i;

       copy_down(predict, stride);

       for (i = 0; i < 16; i++)
       {
           unsigned char *b_predict = predict + (i & 3) * 4;

           switch (mbi->split.modes[i])
           {
           case B_DC_PRED:
               predict_dc_nxn(b_predict, stride, 4);
               break;
           case B_TM_PRED:
               predict_tm_4x4(b_predict, stride);
               break;
           case B_VE_PRED:
               predict_ve_4x4(b_predict, stride);
               break;
           case B_HE_PRED:
               predict_he_4x4(b_predict, stride);
               break;
           case B_LD_PRED:
               predict_ld_4x4(b_predict, stride);
               break;
           case B_RD_PRED:
               predict_rd_4x4(b_predict, stride);
               break;
           case B_VR_PRED:
               predict_vr_4x4(b_predict, stride);
               break;

Top      Up      ToC       Page 211 
           case B_VL_PRED:
               predict_vl_4x4(b_predict, stride);
               break;
           case B_HD_PRED:
               predict_hd_4x4(b_predict, stride);
               break;
           case B_HU_PRED:
               predict_hu_4x4(b_predict, stride);
               break;
           default:
               assert(0);
           }

           vp8_dixie_idct_add(b_predict, b_predict, stride, coeffs);
           coeffs += 16;

           if ((i & 3) == 3)
           {
               predict += stride * 4;
           }
       }
   }


   static void

   fixup_dc_coeffs(struct mb_info *mbi,
                   short          *coeffs)
   {
       short y2[16];
       int   i;

       vp8_dixie_walsh(coeffs + 24 * 16, y2);

       for (i = 0; i < 16; i++)
           coeffs[i*16] = y2[i];
   }


   static void
   predict_intra_luma(unsigned char   *predict,
                      int              stride,
                      struct mb_info  *mbi,
                      short           *coeffs)
   {
       if (mbi->base.y_mode == B_PRED)
           b_pred(predict, stride, mbi, coeffs);
       else

Top      Up      ToC       Page 212 
       {
           int i;

           switch (mbi->base.y_mode)
           {
           case DC_PRED:
               predict_dc_nxn(predict, stride, 16);
               break;
           case V_PRED:
               predict_v_16x16(predict, stride);
               break;
           case H_PRED:
               predict_h_16x16(predict, stride);
               break;
           case TM_PRED:
               predict_tm_16x16(predict, stride);
               break;
           default:
               assert(0);
           }

           fixup_dc_coeffs(mbi, coeffs);

           for (i = 0; i < 16; i++)
           {
               vp8_dixie_idct_add(predict, predict, stride, coeffs);
               coeffs += 16;
               predict += 4;

               if ((i & 3) == 3)
                   predict += stride * 4 - 16;
           }
       }
   }


   static void
   predict_intra_chroma(unsigned char   *predict_u,
                        unsigned char   *predict_v,
                        int              stride,
                        struct mb_info  *mbi,
                        short           *coeffs)
   {
       int i;

Top      Up      ToC       Page 213 
       switch (mbi->base.uv_mode)
       {
       case DC_PRED:
           predict_dc_nxn(predict_u, stride, 8);
           predict_dc_nxn(predict_v, stride, 8);
           break;
       case V_PRED:
           predict_v_8x8(predict_u, stride);
           predict_v_8x8(predict_v, stride);
           break;
       case H_PRED:
           predict_h_8x8(predict_u, stride);
           predict_h_8x8(predict_v, stride);
           break;
       case TM_PRED:
           predict_tm_8x8(predict_u, stride);
           predict_tm_8x8(predict_v, stride);
           break;
       default:
           assert(0);
       }

       coeffs += 16 * 16;

       for (i = 16; i < 20; i++)
       {
           vp8_dixie_idct_add(predict_u, predict_u, stride, coeffs);
           coeffs += 16;
           predict_u += 4;

           if (i & 1)
               predict_u += stride * 4 - 8;
       }

       for (i = 20; i < 24; i++)
       {
           vp8_dixie_idct_add(predict_v, predict_v, stride, coeffs);
           coeffs += 16;
           predict_v += 4;

           if (i & 1)
               predict_v += stride * 4 - 8;
       }
   }

Top      Up      ToC       Page 214 
   static void
   sixtap_horiz(unsigned char       *output,
                int                  output_stride,
                const unsigned char *reference,
                int                  reference_stride,
                int                  cols,
                int                  rows,
                const filter_t       filter
               )
   {
       int r, c, temp;

       for (r = 0; r < rows; r++)
       {
           for (c = 0; c < cols; c++)
           {
               temp = (reference[-2] * filter[0]) +
                      (reference[-1] * filter[1]) +
                      (reference[ 0] * filter[2]) +
                      (reference[ 1] * filter[3]) +
                      (reference[ 2] * filter[4]) +
                      (reference[ 3] * filter[5]) +
                      64;
               temp >>= 7;
               output[c] = CLAMP_255(temp);
               reference++;
           }

           reference += reference_stride - cols;
           output += output_stride;
       }
   }


   static void
   sixtap_vert(unsigned char       *output,
               int                  output_stride,
               const unsigned char *reference,
               int                  reference_stride,
               int                  cols,
               int                  rows,
               const filter_t       filter
              )
   {
       int r, c, temp;

       for (r = 0; r < rows; r++)
       {

Top      Up      ToC       Page 215 
           for (c = 0; c < cols; c++)
           {
               temp = (reference[-2*reference_stride] * filter[0]) +
                      (reference[-1*reference_stride] * filter[1]) +
                      (reference[ 0*reference_stride] * filter[2]) +
                      (reference[ 1*reference_stride] * filter[3]) +
                      (reference[ 2*reference_stride] * filter[4]) +
                      (reference[ 3*reference_stride] * filter[5]) +
                      64;
               temp >>= 7;
               output[c] = CLAMP_255(temp);
               reference++;
           }

           reference += reference_stride - cols;
           output += output_stride;
       }
   }


   static void
   sixtap_2d(unsigned char       *output,
             int                  output_stride,
             const unsigned char *reference,
             int                  reference_stride,
             int                  cols,
             int                  rows,
             int                  mx,
             int                  my,
             const filter_t       filters[8]
            )
   {
       DECLARE_ALIGNED(16, unsigned char, temp[16*(16+5)]);

       sixtap_horiz(temp, 16,
                    reference - 2 * reference_stride, reference_stride,
                    cols, rows + 5, filters[mx]);
       sixtap_vert(output, output_stride,
                   temp + 2 * 16, 16,
                   cols, rows, filters[my]);
   }


   struct img_index
   {
       unsigned char *y, *u, *v;
       int            stride, uv_stride;
   };

Top      Up      ToC       Page 216 
   static const unsigned char *
   filter_block(unsigned char        *output,
                const unsigned char  *reference,
                int                   stride,
                const union mv       *mv,
                const filter_t        filters[8])
   {
       int mx, my;

       /* Handle 0,0 as a special case.  TODO: Does this make it any
        * faster?
        */
       if (!mv->raw)
           return reference;

       mx = mv->d.x & 7;
       my = mv->d.y & 7;
       reference += ((mv->d.y >> 3) * stride) + (mv->d.x >> 3);

       if (mx | my)
       {
           sixtap_2d(output, stride, reference, stride, 4, 4, mx, my,
                     filters);
           reference = output;
       }

       return reference;
   }


   static void
   recon_1_block(unsigned char        *output,
                 const unsigned char  *reference,
                 int                   stride,
                 const union mv       *mv,
                 const filter_t        filters[8],
                 short                *coeffs,
                 struct mb_info       *mbi,
                 int                   b
                )
   {
       const unsigned char *predict;

       predict = filter_block(output, reference, stride, mv, filters);
       vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b);
   }

Top      Up      ToC       Page 217 
   static mv_t
   calculate_chroma_splitmv(struct mb_info *mbi,
                            int             b,
                            int             full_pixel)
   {
       int temp;
       union mv mv;

       temp = mbi->split.mvs[b].d.x +
              mbi->split.mvs[b+1].d.x +
              mbi->split.mvs[b+4].d.x +
              mbi->split.mvs[b+5].d.x;

       if (temp < 0)
           temp -= 4;
       else
           temp += 4;

       mv.d.x = temp / 8;

       temp = mbi->split.mvs[b].d.y +
              mbi->split.mvs[b+1].d.y +
              mbi->split.mvs[b+4].d.y +
              mbi->split.mvs[b+5].d.y;

       if (temp < 0)
           temp -= 4;
       else
           temp += 4;

       mv.d.y = temp / 8;

       if (full_pixel)
       {
           mv.d.x &= ~7;
           mv.d.y &= ~7;
       }

       return mv;
   }

Top      Up      ToC       Page 218 
   /* Note: We rely on the reconstructed border having the same stride
    * as the reference buffer because the filter_block can't adjust the
    * stride with its return value, only the reference pointer.
    */
   static void
   build_mc_border(unsigned char       *dst,
                   const unsigned char *src,
                   int                  stride,
                   int                  x,
                   int                  y,
                   int                  b_w,
                   int                  b_h,
                   int                  w,
                   int                  h
                  )
   {
       const unsigned char *ref_row;


       /* Get a pointer to the start of the real data for this row */
       ref_row = src - x - y * stride;

       if (y >= h)
           ref_row += (h - 1) * stride;
       else if (y > 0)
           ref_row += y * stride;

       do
       {
           int left, right = 0, copy;

           left = x < 0 ? -x : 0;

           if (left > b_w)
               left = b_w;

           if (x + b_w > w)
               right = x + b_w - w;

           if (right > b_w)
               right = b_w;

Top      Up      ToC       Page 219 
           copy = b_w - left - right;

           if (left)
               memset(dst, ref_row[0], left);

           if (copy)
               memcpy(dst + left, ref_row + x + left, copy);

           if (right)
               memset(dst + left + copy, ref_row[w-1], right);

           dst += stride;
           y++;

           if (y < h && y > 0)
               ref_row += stride;
       }
       while (--b_h);
   }


   static void
   recon_1_edge_block(unsigned char        *output,
                      unsigned char        *emul_block,
                      const unsigned char  *reference,
                      int                   stride,
                      const union mv       *mv,
                      const filter_t        filters[8],
                      short                *coeffs,
                      struct mb_info       *mbi,
                      int                   x,
                      int                   y,
                      int                   w,
                      int                   h,
                      int                   start_b
                     )
   {
       const unsigned char *predict;
       int                  b = start_b;
       const int            b_w = 4;
       const int            b_h = 4;

       x += mv->d.x >> 3;
       y += mv->d.y >> 3;

Top      Up      ToC       Page 220 
       /* Need two pixels left/above, 3 right/below for 6-tap */
       if (x < 2 || x + b_w - 1 + 3 >= w || y < 2 ||
           y + b_h - 1 + 3 >= h)
       {
           reference += (mv->d.x >> 3) + (mv->d.y >> 3) * stride;
           build_mc_border(emul_block,
                           reference - 2 - 2 * stride, stride,
                           x - 2, y - 2, b_w + 5, b_h + 5, w, h);
           reference = emul_block + 2 * stride + 2;
           reference -= (mv->d.x >> 3) + (mv->d.y >> 3) * stride;
       }

       predict = filter_block(output, reference, stride, mv, filters);
       vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b);
   }


   static void
   predict_inter_emulated_edge(struct vp8_decoder_ctx  *ctx,
                               struct img_index        *img,
                               short                   *coeffs,
                               struct mb_info          *mbi,
                               int                      mb_col,
                               int                      mb_row)
   {
       /* TODO: Move this into its own buffer.  This only works because
        * we still have a border allocated.
        */
       unsigned char *emul_block = ctx->frame_strg[0].img.img_data;
       unsigned char *reference;
       unsigned char *output;
       ptrdiff_t      reference_offset;
       int            w, h, x, y, b;
       union mv       chroma_mv[4];
       unsigned char *u = img->u, *v = img->v;
       int            full_pixel = ctx->frame_hdr.version == 3;


       x = mb_col * 16;
       y = mb_row * 16;
       w = ctx->mb_cols * 16;
       h = ctx->mb_rows * 16;

       output = img->y;
       reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame];
       reference = output + reference_offset;

Top      Up      ToC       Page 221 
       if (mbi->base.y_mode != SPLITMV)
       {
           union mv uvmv;

           uvmv = mbi->base.mv;
           uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2;
           uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2;

           if (full_pixel)
           {
               uvmv.d.x &= ~7;
               uvmv.d.y &= ~7;
           }

           chroma_mv[0] = uvmv;
           chroma_mv[1] = uvmv;
           chroma_mv[2] = uvmv;
           chroma_mv[3] = uvmv;
       }
       else
       {
           chroma_mv[0] = calculate_chroma_splitmv(mbi,  0, full_pixel);
           chroma_mv[1] = calculate_chroma_splitmv(mbi,  2, full_pixel);
           chroma_mv[2] = calculate_chroma_splitmv(mbi,  8, full_pixel);
           chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel);
       }


       /* Luma */
       for (b = 0; b < 16; b++)
       {
           union mv *ymv;

           if (mbi->base.y_mode != SPLITMV)
               ymv = &mbi->base.mv;
           else
               ymv = mbi->split.mvs + b;

           recon_1_edge_block(output, emul_block, reference,
               img->stride, ymv, ctx->subpixel_filters, coeffs,
               mbi, x, y, w, h, b);

           x += 4;
           output += 4;
           reference += 4;

Top      Up      ToC       Page 222 
           if ((b & 3) == 3)
           {
               x -= 16;
               y += 4;
               output += 4 * img->stride - 16;
               reference += 4 * img->stride - 16;
           }
       }

       x = mb_col * 16;
       y = mb_row * 16;

       /* Chroma */
       x >>= 1;
       y >>= 1;
       w >>= 1;
       h >>= 1;

       for (b = 0; b < 4; b++)
       {
           recon_1_edge_block(u, emul_block, u + reference_offset,
                              img->uv_stride,
                              &chroma_mv[b], ctx->subpixel_filters,
                              coeffs, mbi, x, y, w, h, b + 16);
           recon_1_edge_block(v, emul_block, v + reference_offset,
                              img->uv_stride,
                              &chroma_mv[b], ctx->subpixel_filters,
                              coeffs, mbi, x, y, w, h, b + 20);
           u += 4;
           v += 4;
           x += 4;

           if (b & 1)
           {
               x -= 8;
               y += 4;
               u += 4 * img->uv_stride - 8;
               v += 4 * img->uv_stride - 8;
           }
       }

   }

   static void
   predict_inter(struct vp8_decoder_ctx  *ctx,
                 struct img_index        *img,
                 short                   *coeffs,
                 struct mb_info          *mbi)

Top      Up      ToC       Page 223 
   {
       unsigned char *y = img->y;
       unsigned char *u = img->u;
       unsigned char *v = img->v;
       ptrdiff_t      reference_offset;
       union mv       chroma_mv[4];
       int            full_pixel = ctx->frame_hdr.version == 3;
       int b;

       if (mbi->base.y_mode != SPLITMV)
       {
           union mv             uvmv;

           uvmv = mbi->base.mv;
           uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2;
           uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2;

           if (full_pixel)
           {
               uvmv.d.x &= ~7;
               uvmv.d.y &= ~7;
           }

           chroma_mv[0] =
               chroma_mv[1] =
                   chroma_mv[2] =
                       chroma_mv[3] = uvmv;
       }
       else
       {
           chroma_mv[0] = calculate_chroma_splitmv(mbi,  0, full_pixel);
           chroma_mv[1] = calculate_chroma_splitmv(mbi,  2, full_pixel);
           chroma_mv[2] = calculate_chroma_splitmv(mbi,  8, full_pixel);
           chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel);
       }

       reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame];

       for (b = 0; b < 16; b++)
       {
           union mv *ymv;

           if (mbi->base.y_mode != SPLITMV)
               ymv = &mbi->base.mv;
           else
               ymv = mbi->split.mvs + b;
           recon_1_block(y, y + reference_offset, img->stride,
                         ymv, ctx->subpixel_filters, coeffs, mbi, b);

Top      Up      ToC       Page 224 
           y += 4;

           if ((b & 3) == 3)
               y += 4 * img->stride - 16;
       }

       for (b = 0; b < 4; b++)
       {
           recon_1_block(u, u + reference_offset,
                         img->uv_stride, &chroma_mv[b],
                         ctx->subpixel_filters, coeffs, mbi, b + 16);
           recon_1_block(v, v + reference_offset,
                         img->uv_stride, &chroma_mv[b],
                         ctx->subpixel_filters, coeffs, mbi, b + 20);
           u += 4;
           v += 4;

           if (b & 1)
           {
               u += 4 * img->uv_stride - 8;
               v += 4 * img->uv_stride - 8;
           }
       }
   }


   void
   vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg)
   {
       if (rcimg)
       {
           assert(rcimg->ref_cnt);
           rcimg->ref_cnt--;
       }
   }


   struct ref_cnt_img *
   vp8_dixie_ref_frame(struct ref_cnt_img *rcimg)
   {
       rcimg->ref_cnt++;
       return rcimg;
   }

Top      Up      ToC       Page 225 
   struct ref_cnt_img *
   vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames)
   {
       int i;

       for (i = 0; i < NUM_REF_FRAMES; i++)
           if (frames[i].ref_cnt == 0)
           {
               frames[i].ref_cnt = 1;
               return &frames[i];
           }

       assert(0);
       return NULL;
   }


   static void
   fixup_left(unsigned char        *predict,
              int                   width,
              int                   stride,
              unsigned int          row,
              enum prediction_mode  mode)
   {
       /* The left column of out-of-frame pixels is taken to be 129,
        * unless we're doing DC_PRED, in which case we duplicate the
        * above row, unless this is also row 0, in which case we use
        * 129.
        */
       unsigned char *left = predict - 1;
       int i;

       if (mode == DC_PRED && row)
       {
           unsigned char *above = predict - stride;

           for (i = 0; i < width; i++)
           {
               *left = above[i];
               left += stride;
           }
       }
       else
       {
           /* Need to re-set the above row, in case the above MB was
            * DC_PRED.
            */
           left -= stride;

Top      Up      ToC       Page 226 
           for (i = -1; i < width; i++)
           {
               *left = 129;
               left += stride;
           }
       }
   }


   static void
   fixup_above(unsigned char        *predict,
               int                   width,
               int                   stride,
               unsigned int          col,
               enum prediction_mode  mode)
   {
       /* The above row of out-of-frame pixels is taken to be 127,
        * unless we're doing DC_PRED, in which case we duplicate the
        * left col, unless this is also col 0, in which case we use
        * 127.
        */
       unsigned char *above = predict - stride;
       int i;

       if (mode == DC_PRED && col)
       {
           unsigned char *left = predict - 1;

           for (i = 0; i < width; i++)
           {
               above[i] = *left;
               left += stride;
           }
       }
       else
           /* Need to re-set the left col, in case the last MB was
            * DC_PRED.
            */
           memset(above - 1, 127, width + 1);

       memset(above + width, 127, 4); // for above-right subblock modes
   }

Top      Up      ToC       Page 227 
   void
   vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx)
   {

       int i;
       unsigned char *this_frame_base;

       if (ctx->frame_hdr.frame_size_updated)
       {
           for (i = 0; i < NUM_REF_FRAMES; i++)
           {
               unsigned int w = ctx->mb_cols * 16 + BORDER_PIXELS * 2;
               unsigned int h = ctx->mb_rows * 16 + BORDER_PIXELS * 2;

               vpx_img_free(&ctx->frame_strg[i].img);
               ctx->frame_strg[i].ref_cnt = 0;
               ctx->ref_frames[i] = NULL;

               if (!vpx_img_alloc(&ctx->frame_strg[i].img,
                                  IMG_FMT_I420, w, h, 16))
                   vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR,
                                      "Failed to allocate %dx%d"
                                      " framebuffer",
                                      w, h);

               vpx_img_set_rect(&ctx->frame_strg[i].img, BORDER_PIXELS,
                   BORDER_PIXELS, ctx->frame_hdr.kf.w,
                   ctx->frame_hdr.kf.h);

           }

           if (ctx->frame_hdr.version)
               ctx->subpixel_filters = bilinear_filters;
           else
               ctx->subpixel_filters = sixtap_filters;
       }

       /* Find a free framebuffer to predict into */
       if (ctx->ref_frames[CURRENT_FRAME])
           vp8_dixie_release_ref_frame(ctx->ref_frames[CURRENT_FRAME]);

       ctx->ref_frames[CURRENT_FRAME] =
           vp8_dixie_find_free_ref_frame(ctx->frame_strg);
       this_frame_base = ctx->ref_frames[CURRENT_FRAME]->img.img_data;

Top      Up      ToC       Page 228 
       /* Calculate offsets to the other reference frames */
       for (i = 0; i < NUM_REF_FRAMES; i++)
       {
           struct ref_cnt_img  *ref = ctx->ref_frames[i];

           ctx->ref_frame_offsets[i] =
               ref ? ref->img.img_data - this_frame_base : 0;
       }

       /* TODO: No need to do this on every frame... */
   }


   void
   vp8_dixie_predict_destroy(struct vp8_decoder_ctx *ctx)
   {
       int i;

       for (i = 0; i < NUM_REF_FRAMES; i++)
       {
           vpx_img_free(&ctx->frame_strg[i].img);
           ctx->frame_strg[i].ref_cnt = 0;
           ctx->ref_frames[i] = NULL;
       }
   }


   void
   vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx,
                                 unsigned int            row,
                                 unsigned int            start_col,
                                 unsigned int            num_cols)
   {
       struct img_index img;
       struct mb_info *mbi;
       unsigned int    col;
       short          *coeffs;

Top      Up      ToC       Page 229 
       /* Adjust pointers based on row, start_col */
       img.stride =
           ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y];
       img.uv_stride =
           ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U];
       img.y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y];
       img.u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U];
       img.v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V];
       img.y += (img.stride * row + start_col) * 16;
       img.u += (img.uv_stride * row + start_col) * 8;
       img.v += (img.uv_stride * row + start_col) * 8;
       mbi = ctx->mb_info_rows[row] + start_col;
       coeffs = ctx->tokens[row &
           (ctx->token_hdr.partitions - 1)].coeffs +
           25 * 16 * start_col;

       /* Fix up the out-of-frame pixels */

       if (start_col == 0)
       {
           fixup_left(img.y, 16, img.stride, row, mbi->base.y_mode);
           fixup_left(img.u, 8, img.uv_stride, row, mbi->base.uv_mode);
           fixup_left(img.v, 8, img.uv_stride, row, mbi->base.uv_mode);

           if (row == 0)
               *(img.y - img.stride - 1) = 127;
       }

       for (col = start_col; col < start_col + num_cols; col++)
       {
           if (row == 0)
           {
               fixup_above(img.y, 16, img.stride, col,
                           mbi->base.y_mode);
               fixup_above(img.u, 8, img.uv_stride, col,
                           mbi->base.uv_mode);
               fixup_above(img.v, 8, img.uv_stride, col,
                           mbi->base.uv_mode);
           }

           if (mbi->base.y_mode <= B_PRED)
           {
               predict_intra_luma(img.y, img.stride, mbi, coeffs);
               predict_intra_chroma(img.u, img.v, img.uv_stride, mbi,
                                    coeffs);
           }

Top      Up      ToC       Page 230 
           else
           {
               if (mbi->base.y_mode != SPLITMV) // && != BPRED
                   fixup_dc_coeffs(mbi, coeffs);

               if (mbi->base.need_mc_border)
                   predict_inter_emulated_edge(ctx, &img, coeffs, mbi,
                                               col, row);
               else
                   predict_inter(ctx, &img, coeffs, mbi);
           }

           /* Advance to the next macroblock */
           mbi++;
           img.y += 16;
           img.u += 8;
           img.v += 8;
           coeffs += 25 * 16;
       }

       if (col == ctx->mb_cols)
       {
           /* Extend the last row by four pixels for intra-prediction.
            * This will be propagated later by copy_down.
            */
           uint32_t *extend = (uint32_t *)(img.y + 15 * img.stride);
           uint32_t  val = 0x01010101 * img.y[-1 + 15 * img.stride];
           *extend = val;
       }
   }

   ---- End code block ----------------------------------------


Next RFC Part