intra.c
上传用户:sunbaby
上传日期:2013-05-31
资源大小:242k
文件大小:19k
源码类别:

mpeg/mp3

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  *
  3.  *  T264 AVC CODEC
  4.  *
  5.  *  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
  6.  *               2004-2005 visionany <visionany@yahoo.com.cn>
  7.  *
  8.  * 2004.11.18 Cloud Wu < sywu@sohu.com> Add 4x4 Intrmode 3 and 7
  9.  *  This program is free software ; you can redistribute it and/or modify
  10.  *  it under the terms of the GNU General Public License as published by
  11.  *  the Free Software Foundation ; either version 2 of the License, or
  12.  *  (at your option) any later version.
  13.  *
  14.  *  This program is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  *  GNU General Public License for more details.
  18.  *
  19.  *  You should have received a copy of the GNU General Public License
  20.  *  along with this program ; if not, write to the Free Software
  21.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  22.  *
  23.  ****************************************************************************/
  24. #include "portab.h"
  25. #include "stdio.h"
  26. #ifndef CHIP_DM642
  27. #include "memory.h"
  28. #endif
  29. #include "T264.h"
  30. #include "intra.h"
  31. #include "utility.h"
  32. #include "cavlc.h"
  33. #include "bitstream.h"
  34. //
  35. // NOTE: (t->flags & (INTRA_16x16 | INTRA_4x4)) != 0
  36. //
  37. uint32_t
  38. T264_mode_decision_intra_y(_RW T264_t* t)
  39. {
  40.     uint32_t sad16x16 = -1;
  41.     uint32_t sad4x4   = -1;
  42.     if (t->flags & USE_INTRA16x16)
  43.         sad16x16 = T264_mode_decision_intra_16x16(t);
  44.     if (t->flags & USE_INTRA4x4)
  45.         sad4x4   = T264_mode_decision_intra_4x4(t);
  46.     if (sad16x16 < sad4x4)
  47.     {
  48.         t->mb.mb_mode = I_16x16;
  49.         t->mb.sad = sad16x16;
  50.     }
  51.     else
  52.     {
  53.         t->mb.mb_mode = I_4x4;
  54.         t->mb.sad = sad4x4;
  55.     }
  56.     return t->mb.sad;
  57. }
  58. uint32_t
  59. T264_mode_decision_intra_16x16(_RW T264_t* t)
  60. {
  61.     DECLARE_ALIGNED_MATRIX(pred16x16, 16, 16, uint8_t, CACHE_SIZE);
  62.     DECLARE_ALIGNED_MATRIX(topcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  63.     DECLARE_ALIGNED_MATRIX(leftcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  64.     uint32_t sad16x16 = -1;
  65.     uint8_t* pred16x16free0 = pred16x16;
  66.     uint8_t* pred16x16free1 = t->mb.pred_i16x16;
  67.     int32_t modes;
  68.     int32_t bestmode;
  69.     int32_t preds[9];
  70.     int32_t i;
  71.     uint8_t* top, *left;
  72.     static const uint8_t fixmode[] = 
  73.     {
  74.         Intra_16x16_TOP,
  75.         Intra_16x16_LEFT,
  76.         Intra_16x16_DC,
  77.         Intra_16x16_PLANE,
  78.         Intra_16x16_DC,
  79.         Intra_16x16_DC,
  80.         Intra_16x16_DC
  81.     };
  82.     top  = &topcache[CACHE_SIZE];
  83.     left = &leftcache[CACHE_SIZE];
  84.     T264_intra_16x16_available(t, preds, &modes, top, left);
  85.     for(i = 0 ; i < modes ; i ++)
  86.     {    
  87.         int32_t mode = preds[i];
  88.         uint32_t sad;
  89.         //
  90.         // pred
  91.         //
  92.         t->pred16x16[mode](
  93.             pred16x16free1,
  94.             16,
  95.             top,
  96.             left);
  97.         //  Now use satd for 16x16 Intra
  98.         //  Thomascatlee@163.com
  99.         
  100.         sad = t->T264_satd_16x16_u(t->mb.src_y, t->stride, pred16x16free1, 16) + 
  101.             t->mb.lambda * eg_size_ue(t->bs, fixmode[mode]);
  102.         if (sad < sad16x16)
  103.         {
  104.             SWAP(uint8_t, pred16x16free0, pred16x16free1);
  105.             sad16x16 = sad;
  106.             bestmode = mode;
  107.         }
  108.     }
  109.     if (pred16x16free0 != t->mb.pred_i16x16)
  110.     {
  111.         memcpy(t->mb.pred_i16x16, pred16x16free0, sizeof(uint8_t) * 16 * 16);
  112.     }
  113. //fixed prediction mode DCLEFT DCTOP DC128 = DC
  114.     t->mb.mode_i16x16 = fixmode[bestmode];
  115.     return sad16x16;
  116. }
  117. uint32_t
  118. T264_mode_decision_intra_4x4(T264_t* t)
  119. {
  120.     DECLARE_ALIGNED_MATRIX(pred4x40, 4, 5, uint8_t, CACHE_SIZE);
  121.     DECLARE_ALIGNED_MATRIX(pred4x41, 4, 5, uint8_t, CACHE_SIZE);
  122.     DECLARE_ALIGNED_MATRIX(topcache,  8 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);
  123.     DECLARE_ALIGNED_MATRIX(leftcache, 4 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);
  124.     uint32_t sad_all = 0;
  125.     uint32_t sad4x4;
  126.     int32_t i, j;
  127.     uint8_t* src;
  128.     uint8_t* dst;
  129.     uint8_t* p0, *p1;
  130.     uint8_t* left;
  131.     uint8_t* top;
  132.     int32_t preds[9];
  133.     int32_t modes;
  134.     int32_t bestmode;
  135.     static const uint8_t fixmode[] = 
  136.     {
  137.         Intra_4x4_TOP,
  138.         Intra_4x4_LEFT,
  139.         Intra_4x4_DC,
  140.         Intra_4x4_DIAGONAL_DOWNLEFT,
  141.         Intra_4x4_DIAGONAL_DOWNRIGHT,
  142.         Intra_4x4_VERTICAL_RIGHT,
  143.         Intra_4x4_HORIZONTAL_DOWN,
  144.         Intra_4x4_VERTICAL_LEFT,
  145.         Intra_4x4_HORIZONTAL_UP,
  146.         Intra_4x4_DC,
  147.         Intra_4x4_DC,
  148.         Intra_4x4_DC
  149.     };
  150.     p0 = pred4x40;
  151.     p1 = pred4x41;
  152.     left = &leftcache[CACHE_SIZE];
  153.     top  = &topcache[CACHE_SIZE];
  154.     for(i = 0 ; i < 16 ; i ++)
  155.     {
  156.         int32_t row = i / 4;
  157.         int32_t col = i % 4;
  158.         int32_t pred_mode;
  159.         src = t->mb.src_y + (row * t->stride << 2) + (col << 2);
  160.         dst = t->mb.dst_y + (row * t->edged_stride << 2) + (col << 2);
  161.         pred_mode = T264_mb_predict_intra4x4_mode(t, luma_index[i]);
  162.         T264_intra_4x4_available(t, i, preds, &modes, dst, left, top);
  163.         sad4x4 = -1;
  164.         for(j = 0 ; j < modes ; j ++)
  165.         {
  166.             uint32_t sad;
  167.             int32_t mode = preds[j];
  168.             t->pred4x4[mode](p1, 4, top, left);
  169.             sad = t->cmp[MB_4x4](src, t->stride, p1, 4) +
  170.                 (pred_mode == fixmode[mode] ? 0 : 4 * t->mb.lambda);
  171.                 //t->mb.lambda * (pred_mode == fixmode[mode] ? 1 : 4);
  172.             if (sad < sad4x4)
  173.             {
  174.                 SWAP(uint8_t, p0, p1);
  175.                 sad4x4 = sad;
  176.                 bestmode = mode;
  177.             }
  178.         }
  179. //fixed prediction mode DCLEFT DCTOP DC128 = DC
  180.         t->mb.i4x4_pred_mode_ref[IPM_LUMA + col + row * 8] =
  181.         t->mb.mode_i4x4[luma_index[i]] = fixmode[bestmode];
  182.         sad_all += sad4x4;
  183.         T264_encode_intra_4x4(t, p0, i);
  184.     }
  185.     
  186.     sad_all += t->mb.lambda * 24;
  187.     return sad_all;
  188. }
  189. void
  190. T264_intra_16x16_available(T264_t* t, int32_t preds[], int32_t* modes, uint8_t* top, uint8_t* left)
  191. {
  192.     uint8_t* p;
  193.     int32_t i;
  194.     if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  195.     {
  196.         preds[0] = Intra_16x16_TOP;
  197.         preds[1] = Intra_16x16_LEFT;
  198.         preds[2] = Intra_16x16_DC;
  199.         preds[3] = Intra_16x16_PLANE;
  200.         *modes = 4;
  201.         p = t->mb.dst_y - t->edged_stride;
  202.         for(i = -1 ; i < 16 ; i ++)
  203.         {
  204.             top[i] = p[i];
  205.         }
  206.         p --;
  207.         for(i = -1 ; i < 16 ; i ++)
  208.         {
  209.             left[i] = p[0];
  210.             p += t->edged_stride;
  211.         }
  212.     }
  213.     else if(t->mb.mb_neighbour & MB_LEFT)
  214.     {
  215.         preds[0] = Intra_16x16_LEFT;
  216.         preds[1] = Intra_16x16_DCLEFT;
  217.         *modes = 2;
  218.         p = t->mb.dst_y - 1;
  219.         for(i = 0 ; i < 16 ; i ++)
  220.         {
  221.             left[i] = p[0];
  222.             p += t->edged_stride;
  223.         }
  224.     }
  225.     else if(t->mb.mb_neighbour & MB_TOP)
  226.     {
  227.         preds[0] = Intra_16x16_TOP;
  228.         preds[1] = Intra_16x16_DCTOP;
  229.         *modes = 2;
  230.         p = t->mb.dst_y - t->edged_stride;
  231.         for(i = 0 ; i < 16 ; i ++)
  232.         {
  233.             top[i] = p[i];
  234.         }
  235.     }
  236.     else
  237.     {
  238.         preds[0] = Intra_16x16_DC128;
  239.         *modes = 1;
  240.     }
  241. }
  242. void
  243. T264_intra_4x4_available(T264_t* t, int32_t idx, int32_t preds[], int32_t* modes, uint8_t* dst, uint8_t* left, uint8_t* top)
  244. {
  245.     static const int32_t neighbour[] =
  246.     {
  247.         0, MB_LEFT, MB_LEFT, MB_LEFT,
  248.         MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,              MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
  249.         MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP| MB_TOPRIGHT, MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
  250.         MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,              MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP
  251.     };
  252.     static const int32_t fix[] =
  253.     {
  254.         ~0, ~0, ~0, ~0,
  255.         ~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT,
  256.         ~0, ~0, ~0, ~MB_TOPRIGHT,
  257.         ~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT
  258.     };
  259.     uint8_t* p;
  260.     int32_t i;
  261.     int32_t mb_neighbour = (t->mb.mb_neighbour| neighbour[idx]) & fix[idx];
  262. if((idx & 3) == 3) //if is the right-most sub-block
  263. if(t->mb.mb_x == t->mb_width - 1) //if is th last MB in horizontal
  264. mb_neighbour &= ~MB_TOPRIGHT; //no top-right exist
  265. if ((mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  266.     {
  267.         preds[0] = Intra_4x4_TOP;
  268.         preds[1] = Intra_4x4_LEFT;
  269.         preds[2] = Intra_4x4_DC;
  270.         preds[3] = Intra_4x4_DIAGONAL_DOWNLEFT;
  271.         preds[4] = Intra_4x4_DIAGONAL_DOWNRIGHT;
  272.         preds[5] = Intra_4x4_VERTICAL_RIGHT;
  273.         preds[6] = Intra_4x4_HORIZONTAL_DOWN;
  274.         preds[7] = Intra_4x4_VERTICAL_LEFT;
  275.         preds[8] = Intra_4x4_HORIZONTAL_UP;
  276.         *modes = 9;
  277.         p = dst - t->edged_stride;
  278.         if (mb_neighbour & MB_TOPRIGHT)
  279.         {
  280.             for(i = -1 ; i < 8 ; i ++)
  281.             {
  282.                  top[i] = p[i];
  283.             }
  284.         }
  285.         else
  286.         {
  287.             for(i = -1 ; i < 4 ; i ++)
  288.             {
  289.                  top[i] = p[i];
  290.             }
  291.             //to fill padded 4 positions
  292.             for( ; i < 8 ; ++ i)
  293.                 top[i] = p[3];
  294.         }
  295.         p --;
  296.         for(i = -1 ; i < 4 ; i ++)
  297.         {
  298.             left[i] = p[0];
  299.             p += t->edged_stride;
  300.         }
  301.     }
  302.     else if(mb_neighbour & MB_LEFT)
  303.     {
  304.         preds[0] = Intra_4x4_LEFT;
  305.         preds[1] = Intra_4x4_DCLEFT;
  306.         preds[2] = Intra_4x4_HORIZONTAL_UP;
  307.         *modes = 3;
  308.         p = dst - 1;
  309.         for(i = 0 ; i < 4 ; i ++)
  310.         {
  311.             left[i] = p[0];
  312.             p += t->edged_stride;
  313.         }
  314.     }
  315.     else if(mb_neighbour & MB_TOP)
  316.     {
  317.         preds[0] = Intra_4x4_TOP;
  318.         preds[1] = Intra_4x4_DCTOP;
  319.         
  320.         preds[2] = Intra_4x4_DIAGONAL_DOWNLEFT;
  321.         preds[3] = Intra_4x4_VERTICAL_LEFT;
  322.         *modes = 4;
  323.         p = dst - t->edged_stride;
  324.         if (mb_neighbour & MB_TOPRIGHT)
  325.         {
  326.             for(i = -1 ; i < 8 ; i ++)
  327.             {
  328.                 top[i] = p[i];
  329.             }
  330.         }
  331.         else
  332.         {
  333.             for(i = -1 ; i < 4 ; i ++)
  334.             {
  335.                 top[i] = p[i];
  336.             }
  337.             
  338.             for( ; i < 8 ; ++ i)
  339.                 top[i] = p[3];
  340.         }
  341.     }
  342.     else
  343.     {
  344.         preds[0] = Intra_4x4_DC128;
  345.         *modes = 1;
  346.     }
  347. }
  348. void 
  349. T264_encode_intra_y(_RW T264_t* t)
  350. {
  351.     if (t->mb.mb_mode == I_16x16)
  352.     {
  353.         T264_encode_intra_16x16(t);
  354.     }
  355.     else if (t->mb.mb_mode == I_4x4)
  356.     {
  357.     }
  358. }
  359. void
  360. T264_encode_intra_16x16(_RW T264_t* t)
  361. {
  362.     DECLARE_ALIGNED_MATRIX(dct, 17, 16, int16_t, 16);
  363.     int32_t qp = t->qp_y;
  364.     int32_t i;
  365.     int16_t* curdct;
  366.     t->expand8to16sub(t->mb.pred_i16x16, 16 / 4, 16 / 4, dct, t->mb.src_y, t->stride);
  367.     curdct = dct;
  368.     for(i = 0 ; i < 16 ; i ++)
  369.     {
  370.         t->fdct4x4(curdct);
  371.         dct[256 + i] = curdct[0];
  372.         t->quant4x4(curdct, qp, TRUE);
  373.         scan_zig_4x4(t->mb.dct_y_z[luma_index[i]], curdct);
  374.         t->iquant4x4(curdct, qp);
  375.         curdct += 16;
  376.     }
  377.     t->fdct4x4dc(curdct);
  378.     t->quant4x4dc(curdct, qp);
  379.     scan_zig_4x4(t->mb.dc4x4_z, curdct);
  380.     // i don't know why to do so, if someone knows tell me.
  381.     t->idct4x4dc(curdct);
  382.     t->iquant4x4dc(curdct, qp);
  383.     curdct = dct;
  384.     for(i = 0 ; i < 16 ; i ++)
  385.     {
  386.         curdct[0] = dct[256 + i];
  387.         t->idct4x4(curdct);
  388.         curdct += 16;
  389.     }
  390.     t->contract16to8add(dct, 16 / 4, 16 / 4, t->mb.pred_i16x16, t->mb.dst_y, t->edged_stride);
  391. }
  392. void
  393. T264_encode_intra_4x4(_RW T264_t* t, uint8_t* pred, int32_t i)
  394. {
  395.     DECLARE_ALIGNED_MATRIX(dct, 1, 16, int16_t, 16);
  396.     int32_t qp = t->qp_y;
  397.     int32_t row = i / 4;
  398.     int32_t col = i % 4;
  399.     //residual saved in t->pred_16x16_4x4
  400.     uint8_t* src = t->mb.src_y + (row * t->stride << 2) + (col << 2);
  401.     //reconstructed MB saved in t->dst
  402.     uint8_t* dst = t->mb.dst_y + (row * t->edged_stride << 2) + (col << 2);
  403.     t->expand8to16sub(pred, 4 / 4, 4 / 4, dct, src, t->stride);
  404.     t->fdct4x4(dct);
  405.     t->quant4x4(dct, qp, t->slice_type == SLICE_I);
  406.     scan_zig_4x4(t->mb.dct_y_z[luma_index[i]], dct);
  407.     t->iquant4x4(dct, qp);
  408.     t->idct4x4(dct);
  409.     t->contract16to8add(dct, 4 / 4, 4 / 4, pred, dst, t->edged_stride);
  410. }
  411. uint32_t
  412. T264_mode_decision_intra_uv(_RW T264_t* t)
  413. {
  414.     DECLARE_ALIGNED_MATRIX(pred8x8u, 8, 8, uint8_t, CACHE_SIZE);
  415.     DECLARE_ALIGNED_MATRIX(pred8x8v, 8, 8, uint8_t, CACHE_SIZE);
  416.     DECLARE_ALIGNED_MATRIX(topcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  417.     DECLARE_ALIGNED_MATRIX(leftcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  418.     DECLARE_ALIGNED_MATRIX(topcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  419.     DECLARE_ALIGNED_MATRIX(leftcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
  420.     
  421.     uint32_t sad8x8 = -1;
  422.     uint8_t* pred8x8freeu0 = pred8x8u;
  423.     uint8_t* pred8x8freeu1 = t->mb.pred_i8x8u;
  424.     uint8_t* pred8x8freev0 = pred8x8v;
  425.     uint8_t* pred8x8freev1 = t->mb.pred_i8x8v;
  426.     int32_t modes;
  427.     int32_t bestmode;
  428.     int32_t preds[9];
  429.     int32_t i;
  430.     uint8_t* top_u, *left_u;
  431.     uint8_t* top_v, *left_v;
  432.     static const uint8_t fixmode[] =
  433.     {
  434.         Intra_8x8_DC,
  435.         Intra_8x8_LEFT,
  436.         Intra_8x8_TOP,
  437.         Intra_8x8_PLANE,
  438.         Intra_8x8_DC,
  439.         Intra_8x8_DC,
  440.         Intra_8x8_DC
  441.     };
  442.     top_u  = &topcacheu[CACHE_SIZE];
  443.     top_v  = &topcachev[CACHE_SIZE];
  444.     left_u = &leftcacheu[CACHE_SIZE];
  445.     left_v = &leftcachev[CACHE_SIZE];
  446.     T264_intra_8x8_available(t, preds, &modes, top_u, left_u, top_v, left_v);
  447.     for(i = 0 ; i < modes ; i ++)
  448.     {    
  449.         int32_t mode = preds[i];
  450.         uint32_t sad;
  451.         t->pred8x8[mode](
  452.             pred8x8freeu1,
  453.             8,
  454.             top_u,
  455.             left_u);
  456.         t->pred8x8[mode](
  457.             pred8x8freev1,
  458.             8,
  459.             top_v,
  460.             left_v);
  461.         sad = t->cmp[MB_8x8](t->mb.src_u, t->stride_uv, pred8x8freeu1, 8) + 
  462.               t->cmp[MB_8x8](t->mb.src_v, t->stride_uv, pred8x8freev1, 8) +
  463.               t->mb.lambda * eg_size_ue(t->bs, fixmode[mode]);
  464.         if (sad < sad8x8)
  465.         {
  466.             SWAP(uint8_t, pred8x8freeu0, pred8x8freeu1);
  467.             SWAP(uint8_t, pred8x8freev0, pred8x8freev1);
  468.             sad8x8 = sad;
  469.             bestmode = mode;
  470.         }
  471.     }
  472.     if (pred8x8freeu0 != t->mb.pred_i8x8u)
  473.     {
  474.         memcpy(t->mb.pred_i8x8u, pred8x8freeu0, sizeof(uint8_t) * 8 * 8);
  475.     }
  476.     if (pred8x8freev0 != t->mb.pred_i8x8v)
  477.     {
  478.         memcpy(t->mb.pred_i8x8v, pred8x8freev0, sizeof(uint8_t) * 8 * 8);
  479.     }
  480. //fixed prediction mode DCLEFT DCTOP DC128 = DC
  481.     t->mb.mb_mode_uv = fixmode[bestmode];
  482.     return sad8x8;
  483. }
  484. void
  485. T264_intra_8x8_available(T264_t* t, int32_t preds[], int32_t* modes, uint8_t* top_u, uint8_t* left_u, uint8_t* top_v, uint8_t* left_v)
  486. {
  487.     int32_t i;
  488.     uint8_t* p_u, *p_v;
  489.     if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  490.     {
  491.         preds[0] = Intra_8x8_DC;
  492.         preds[1] = Intra_8x8_TOP;
  493.         preds[2] = Intra_8x8_LEFT;
  494.         preds[3] = Intra_8x8_PLANE;
  495.         *modes = 4;
  496.         p_u = t->mb.dst_u - t->edged_stride_uv;
  497.         p_v = t->mb.dst_v - t->edged_stride_uv;
  498.         for(i = -1 ; i < 8 ; i ++)
  499.         {
  500.             top_u[i] = p_u[i];
  501.             top_v[i] = p_v[i];
  502.         }
  503.         p_u --;
  504.         p_v --;
  505.         for(i = -1 ; i < 8 ; i ++)
  506.         {
  507.             left_u[i] = p_u[0];
  508.             left_v[i] = p_v[0];
  509.             p_u += t->edged_stride_uv;
  510.             p_v += t->edged_stride_uv;
  511.         }
  512.     }
  513.     else if(t->mb.mb_neighbour & MB_LEFT)
  514.     {
  515.         preds[0] = Intra_8x8_DCLEFT;
  516.         preds[1] = Intra_8x8_LEFT;
  517.         *modes = 2;
  518.         p_u = t->mb.dst_u - 1;
  519.         p_v = t->mb.dst_v - 1;
  520.         for(i = 0 ; i < 8 ; i ++)
  521.         {
  522.             left_u[i] = p_u[0];
  523.             left_v[i] = p_v[0];
  524.             p_u += t->edged_stride_uv;
  525.             p_v += t->edged_stride_uv;
  526.         }
  527.     }
  528.     else if(t->mb.mb_neighbour & MB_TOP)
  529.     {
  530.         preds[0] = Intra_8x8_DCTOP;
  531.         preds[1] = Intra_8x8_TOP;
  532.         *modes = 2;
  533.         p_u = t->mb.dst_u - t->edged_stride_uv;
  534.         p_v = t->mb.dst_v - t->edged_stride_uv;
  535.         for(i = 0 ; i < 8 ; i ++)
  536.         {
  537.             top_u[i] = p_u[i];
  538.             top_v[i] = p_v[i];
  539.         }
  540.     }
  541.     else
  542.     {
  543.         preds[0] = Intra_8x8_DC128;
  544.         *modes = 1;
  545.     }
  546. }
  547. void
  548. T264_encode_intra_uv(_RW T264_t* t)
  549. {
  550.     DECLARE_ALIGNED_MATRIX(dct, 10, 8, int16_t, CACHE_SIZE);
  551.     int32_t qp = t->qp_uv;
  552.     int32_t i, j;
  553.     int16_t* curdct;
  554.     uint8_t* start;
  555.     uint8_t* dst;
  556.     uint8_t* src;
  557.     int32_t intra = t->slice_type == SLICE_I ? 1 : 0;
  558.     start = t->mb.pred_i8x8u;
  559.     src   = t->mb.src_u;
  560.     dst   = t->mb.dst_u;
  561.     for(j = 0 ; j < 2 ; j ++)
  562.     {
  563.         int32_t run, k;
  564.         int32_t coeff_cost;
  565.         coeff_cost = 0;
  566.         t->expand8to16sub(start, 8 / 4, 8 / 4, dct, src, t->stride_uv);
  567.         curdct = dct;
  568.         for(i = 0 ; i < 4 ; i ++)
  569.         {
  570.             run = -1;
  571.             // we will count coeff cost, from jm80
  572.             t->fdct4x4(curdct);
  573.             dct[64 + i] = curdct[0];
  574.             t->quant4x4(curdct, qp, intra);
  575.             scan_zig_4x4(t->mb.dct_uv_z[j][i], curdct);
  576.             {
  577.                 for(k = 1 ; k < 16 ; k ++)
  578.                 {
  579.                     run ++;
  580.                     if (t->mb.dct_uv_z[j][i][k] != 0)
  581.                     {
  582.                         if (ABS(t->mb.dct_uv_z[j][i][k]) > 1)
  583.                         {
  584.                             coeff_cost += 16 * 16 * 256;
  585.                             break;
  586.                         }
  587.                         else
  588.                         {
  589.                             coeff_cost += COEFF_COST[run];
  590.                             run = -1;
  591.                         }
  592.                     }
  593.                 }
  594.             }
  595.             t->iquant4x4(curdct, qp);
  596.             curdct += 16;
  597.         }
  598.         if (coeff_cost < CHROMA_COEFF_COST)
  599.         {
  600.             memset(&t->mb.dct_uv_z[j][0][0], 0, 4 * 16 * sizeof(int16_t));
  601.             memset(dct, 0, 8 * 8 * sizeof(int16_t));
  602.         }
  603.         t->fdct2x2dc(curdct);
  604.         t->quant2x2dc(curdct, qp, intra);
  605.         scan_zig_2x2(t->mb.dc2x2_z[j], curdct);
  606.         t->iquant2x2dc(curdct, qp);
  607.         t->idct2x2dc(curdct);
  608.         curdct = dct;
  609.         for(i = 0 ; i < 4 ; i ++)
  610.         {
  611.             curdct[0] = dct[64 + i];
  612.             t->idct4x4(curdct);
  613.             curdct += 16;
  614.         }
  615.         t->contract16to8add(dct, 8 / 4, 8 / 4, start, dst, t->edged_stride_uv);
  616.         //
  617.         // change to v
  618.         //
  619.         start = t->mb.pred_i8x8v;
  620.         dst   = t->mb.dst_v;
  621.         src   = t->mb.src_v;
  622.     }
  623. }