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

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.  *  This program is free software ; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation ; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program ; if not, write to the Free Software
  20.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21.  *
  22.  ****************************************************************************/
  23. #include "portab.h"
  24. #include "stdio.h"
  25. #ifndef CHIP_DM642
  26. #include "memory.h"
  27. #endif
  28. #include "T264.h"
  29. #include "inter.h"
  30. #include "intra.h"
  31. #include "estimation.h"
  32. #include "utility.h"
  33. #include "interpolate.h"
  34. #include "bitstream.h"
  35. //#define USE_PREV_DETECT
  36. uint32_t
  37. T264_predict_sad(T264_t* t, int32_t list)
  38. {
  39.     return T264_median(t->mb.sad_ref[0], t->mb.sad_ref[1], t->mb.sad_ref[2]);
  40. }
  41. void
  42. T264_predict_mv(T264_t* t, int32_t list, int32_t i, int32_t width, T264_vector_t* vec)
  43. {
  44.     int32_t n;
  45.     int32_t count = 0;
  46.     int32_t idx;
  47.     int32_t row;
  48.     int32_t col;
  49.     int32_t org;
  50.     T264_vector_t vec_n[3];
  51.     n = vec->refno;
  52.     org = i;
  53.     i = luma_index[i];
  54.     col = org % 4;
  55.     row = org / 4;
  56.     vec_n[0] = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec[list];
  57.     vec_n[1] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec[list];
  58.     vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec[list];
  59.     if (vec_n[2].refno == -2)
  60.     {
  61.         vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list];
  62.     }
  63.     if (((i & 3) == 3) || ((i & 3) == 2 && width == 2))
  64.     {
  65.         vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list];
  66.     }
  67.     if (t->mb.mb_part == MB_16x8)
  68.     {
  69.         if (i == 0 && n == vec_n[1].refno)
  70.         {
  71.             vec[0].x = vec_n[1].x;
  72.             vec[0].y = vec_n[1].y;
  73.             return;
  74.         }
  75.         else if (i != 0 && n == vec_n[0].refno)
  76.         {
  77.             vec[0].x = vec_n[0].x;
  78.             vec[0].y = vec_n[0].y;
  79.             return;
  80.         }
  81.     }
  82.     else if (t->mb.mb_part == MB_8x16)
  83.     {
  84.         if (i == 0 && n == vec_n[0].refno)
  85.         {
  86.             vec[0].x = vec_n[0].x;
  87.             vec[0].y = vec_n[0].y;
  88.             return;
  89.         }
  90.         else if (i != 0 && n == vec_n[2].refno)
  91.         {
  92.             vec[0].x = vec_n[2].x;
  93.             vec[0].y = vec_n[2].y;
  94.             return;
  95.         }
  96.     }
  97.     if (vec_n[0].refno == n)
  98.     {
  99.         count ++;
  100.         idx = 0;
  101.     }
  102.     if (vec_n[1].refno == n)
  103.     {
  104.         count ++;
  105.         idx = 1;
  106.     }
  107.     if (vec_n[2].refno == n)
  108.     {
  109.         count ++;
  110.         idx = 2;
  111.     }
  112.     if (count > 1)
  113.     {
  114.         vec[0].x = T264_median(vec_n[0].x, vec_n[1].x, vec_n[2].x);
  115.         vec[0].y = T264_median(vec_n[0].y, vec_n[1].y, vec_n[2].y);
  116.         return;
  117.     }
  118.     else if (count == 1)
  119.     {
  120.         vec[0].x = vec_n[idx].x;
  121.         vec[0].y = vec_n[idx].y;
  122.         return;
  123.     }
  124.     else if (vec_n[1].refno == -2 && vec_n[2].refno == -2 && vec_n[0].refno != -2)
  125.     {
  126.         vec[0].x = vec_n[0].x;
  127.         vec[0].y = vec_n[0].y;
  128.     }
  129.     else
  130.     {
  131.         vec[0].x = T264_median(vec_n[0].x, vec_n[1].x, vec_n[2].x);
  132.         vec[0].y = T264_median(vec_n[0].y, vec_n[1].y, vec_n[2].y);
  133.         return;        
  134.     }
  135. }
  136. void
  137. T264_predict_mv_skip(T264_t* t, int32_t list, T264_vector_t* vec)
  138. {
  139.     T264_vector_t vec_n[2];
  140.     int32_t zero_left, zero_top;
  141.     vec_n[0] = t->mb.vec_ref[VEC_LUMA - 1].vec[0];
  142.     vec_n[1] = t->mb.vec_ref[VEC_LUMA - 8].vec[0];
  143.     vec[0].refno = 0;
  144.     zero_left = vec_n[0].refno == -2 ? 1 : vec_n[0].refno == 0 && vec_n[0].x == 0 && vec_n[0].y == 0 ? 1 : 0;
  145.     zero_top  = vec_n[1].refno == -2 ? 1 : vec_n[1].refno == 0 && vec_n[1].x == 0 && vec_n[1].y == 0 ? 1 : 0;
  146.     if (zero_left || zero_top)
  147.     {
  148.         vec[0].x = vec[0].y = 0;
  149.     }
  150.     else
  151.     {
  152.         T264_predict_mv(t, 0, 0, 4, vec);
  153.     }
  154. }
  155. int32_t 
  156. T264_median(int32_t x, int32_t y, int32_t z)
  157. {
  158.     int32_t min, max;
  159.     if (x < y)
  160.     {
  161.         min = x;
  162.         max = y;
  163.     }
  164.     else
  165.     {
  166.         min = y;
  167.         max = x;
  168.     }
  169.     if (z < min)
  170.     {
  171.         min = z;
  172.     }
  173.     else if (z > max)
  174.     {
  175.         max = z;
  176.     }
  177.     return x + y + z - min - max;
  178. }
  179. void
  180. copy_nvec(T264_vector_t* src, T264_vector_t* dst, int32_t width, int32_t height, int32_t stride)
  181. {
  182.     int32_t i, j;
  183.     for(i = 0 ; i < height ; i ++)
  184.     {
  185.         for(j = 0 ; j < width ; j ++)
  186.         {
  187.             dst[j] = src[0];
  188.         }
  189.         dst += stride;
  190.     }
  191. }
  192. void
  193. T264_inter_p16x16_mode_available(T264_t* t, int32_t preds[], int32_t* modes)
  194. {
  195.     if (t->flags & USE_FORCEBLOCKSIZE)
  196.     {
  197.         *modes = 0;
  198.       
  199.         preds[(*modes) ++] = MB_16x16;
  200.         if (t->param.block_size & SEARCH_16x8P)
  201.             preds[(*modes) ++] = MB_16x8;
  202.         if (t->param.block_size & SEARCH_8x16P)
  203.             preds[(*modes) ++] = MB_8x16;
  204.         return ;
  205.     }
  206.     if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  207.     {
  208.         *modes = 0;
  209.         preds[(*modes) ++] = MB_16x16;
  210.         if (t->mb.vec_ref[VEC_LUMA - 1].part == MB_16x8)
  211.         {
  212.             preds[(*modes) ++] = MB_16x8;
  213.         }
  214.         if (t->mb.vec_ref[VEC_LUMA - 8].part == MB_8x16)
  215.         {
  216.             preds[(*modes) ++] = MB_8x16;
  217.         }
  218.     }
  219.     else
  220.     {
  221.         // try all
  222.         preds[0] = MB_16x16;
  223.         preds[1] = MB_16x8;
  224.         preds[2] = MB_8x16;
  225.         *modes = 3;
  226.     }
  227. }
  228. void
  229. T264_inter_p8x8_mode_available(T264_t* t, int32_t preds[], int32_t* modes, int32_t sub_no)
  230. {
  231.     static const int32_t neighbour[] = 
  232.     {
  233.         0, MB_LEFT, MB_TOP, MB_LEFT| MB_TOP
  234.     };
  235.     int32_t mb_neighbour = t->mb.mb_neighbour| neighbour[sub_no];
  236.     if (t->flags & USE_FORCEBLOCKSIZE)
  237.     {
  238.         *modes = 0;
  239.         if (t->param.block_size & SEARCH_8x8P)
  240.             preds[(*modes) ++] = MB_8x8;
  241.         if (t->param.block_size & SEARCH_8x4P)
  242.             preds[(*modes) ++] = MB_8x4;
  243.         if (t->param.block_size & SEARCH_4x8P)
  244.             preds[(*modes) ++] = MB_4x8;
  245.         if (t->param.block_size & SEARCH_4x4P)
  246.             preds[(*modes) ++] = MB_4x4;
  247.         return ;
  248.     }
  249.     if ((mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  250.     {
  251.         *modes = 0;
  252.         preds[*modes ++] = MB_8x8;
  253.         if (t->mb.vec_ref[VEC_LUMA - 8 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_8x4)
  254.         {
  255.             preds[*modes ++] = MB_8x4;
  256.         }
  257.         if (t->mb.vec_ref[VEC_LUMA - 1 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x8)
  258.         {
  259.             preds[*modes ++] = MB_4x8;
  260.         }
  261.         if (t->mb.vec_ref[VEC_LUMA - 8 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x4 || 
  262.             t->mb.vec_ref[VEC_LUMA - 1 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x4)
  263.         {
  264.             preds[*modes ++] = MB_4x4;
  265.         }
  266.     }
  267.     else
  268.     {
  269.         // try all
  270.         preds[0] = MB_8x8;
  271.         preds[1] = MB_8x4;
  272.         preds[2] = MB_4x8;
  273.         preds[3] = MB_4x4;
  274.         *modes = 4;
  275.     }
  276. }
  277. int32_t
  278. T264_get_pos_sad(T264_t* t, uint8_t* ref, T264_vector_t* vec)
  279. {
  280.     uint8_t* tmp;
  281.     int32_t x, y;
  282.     int32_t list_index = 0;
  283.     uint32_t sad;
  284.     static const int8_t index[4][4][6] = 
  285.     {
  286.         {{0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 0}},
  287.         {{0, 2, 0, 0, 0, 0}, {1, 2, 0, 0, 0, 0}, {1, 3, 0, 0, 0, 0}, {1, 2, 0, 0, 1, 0}},
  288.         {{2, 2, 0, 0, 0, 0}, {2, 3, 0, 0, 0, 0}, {3, 3, 0, 0, 0, 0}, {3, 2, 0, 0, 1, 0}},
  289.         {{2, 0, 0, 0, 0, 1}, {2, 1, 0, 0, 0, 1}, {3, 1, 0, 0, 0, 1}, {1, 2, 0, 1, 1, 0}}
  290.     };
  291.     // need subpel
  292.     if ((t->flags & (USE_QUARTPEL)) == (USE_QUARTPEL))
  293.     {
  294.         x = (vec->x & 3);
  295.         y = (vec->y & 3);
  296.         if (index[y][x][0] == index[y][x][1])
  297.         {
  298.             tmp = t->ref[list_index][vec->refno]->Y[index[y][x][0]] + ((t->mb.mb_y << 4) + (vec->y >> 2)) * t->edged_stride + 
  299.                 ((t->mb.mb_x << 4) + (vec->x >> 2));
  300.             t->memcpy_stride_u(tmp, 16, 16, t->edged_stride, ref, 16);
  301.         }
  302.         else
  303.         {
  304.             t->pia[MB_16x16](t->ref[list_index][vec->refno]->Y[index[y][x][0]] + ((t->mb.mb_y << 4) + (vec->y >> 2) + index[y][x][3]) * t->edged_stride + (t->mb.mb_x << 4) + (vec->x >> 2) + index[y][x][2], 
  305.                 t->ref[list_index][vec->refno]->Y[index[y][x][1]] + ((t->mb.mb_y << 4) + (vec->y >> 2) + index[y][x][5]) * t->edged_stride + (t->mb.mb_x << 4) + (vec->x >> 2) + index[y][x][4],
  306.                 t->edged_stride, t->edged_stride, ref, 16);
  307.         }
  308.         // rc will use sad value
  309.         sad = t->cmp[MB_16x16](t->mb.src_y, t->stride, ref, 16);
  310.         return sad;
  311.     }
  312.     return -1;
  313. }
  314. int32_t
  315. T264_detect_pskip(T264_t* t, uint32_t sad_t)
  316. {
  317.     // detect p skip has a two-step process. here try to find suitable skip mv
  318.     //  and encode post will decide if use skip mode or not
  319.     DECLARE_ALIGNED_MATRIX(ref, 16, 16, uint8_t, CACHE_SIZE);
  320.     T264_vector_t vec;
  321.     uint8_t* tmp;
  322.     int32_t x, y;
  323.     int32_t i, j;
  324.     int32_t list_index = 0;
  325.     static const int8_t index[4][4][6] = 
  326.     {
  327.         {{0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 0}},
  328.         {{0, 2, 0, 0, 0, 0}, {1, 2, 0, 0, 0, 0}, {1, 3, 0, 0, 0, 0}, {1, 2, 0, 0, 1, 0}},
  329.         {{2, 2, 0, 0, 0, 0}, {2, 3, 0, 0, 0, 0}, {3, 3, 0, 0, 0, 0}, {3, 2, 0, 0, 1, 0}},
  330.         {{2, 0, 0, 0, 0, 1}, {2, 1, 0, 0, 0, 1}, {3, 1, 0, 0, 0, 1}, {1, 2, 0, 1, 1, 0}}
  331.     };
  332.     T264_predict_mv_skip(t, 0, &vec);
  333.     // need subpel
  334.     if ((t->flags & (USE_QUARTPEL)) == (USE_QUARTPEL))
  335.     {
  336.         x = (vec.x & 3);
  337.         y = (vec.y & 3);
  338.         if (index[y][x][0] == index[y][x][1])
  339.         {
  340.             tmp = t->ref[list_index][vec.refno]->Y[index[y][x][0]] + ((t->mb.mb_y << 4) + (vec.y >> 2)) * t->edged_stride + 
  341.                 ((t->mb.mb_x << 4) + (vec.x >> 2));
  342.             t->memcpy_stride_u(tmp, 16, 16, t->edged_stride, ref, 16);
  343.         }
  344.         else
  345.         {
  346.             t->pia[MB_16x16](t->ref[list_index][vec.refno]->Y[index[y][x][0]] + ((t->mb.mb_y << 4) + (vec.y >> 2) + index[y][x][3]) * t->edged_stride + (t->mb.mb_x << 4) + (vec.x >> 2) + index[y][x][2], 
  347.                         t->ref[list_index][vec.refno]->Y[index[y][x][1]] + ((t->mb.mb_y << 4) + (vec.y >> 2) + index[y][x][5]) * t->edged_stride + (t->mb.mb_x << 4) + (vec.x >> 2) + index[y][x][4],
  348.                         t->edged_stride, t->edged_stride, ref, 16);
  349.         }
  350.         // rc will use sad value
  351.         t->mb.sad = t->cmp[MB_16x16](t->mb.src_y, t->stride, ref, 16);
  352.         if (t->mb.sad < sad_t)
  353.         {
  354.             return FALSE;
  355.         }
  356.         {
  357.             // use foreman.cif, qp = 30, waste 35497 times encode vs. total times 80266
  358.             DECLARE_ALIGNED_MATRIX(dct, 16, 16, int16_t, 16);
  359.             int32_t qp = t->qp_y;
  360.             int32_t i, j;
  361.             int16_t* curdct;
  362.             // we will count coeff cost, from jm80
  363.             int32_t run, k;
  364.             int32_t coeff_cost, total_cost;
  365.             total_cost = 0;
  366.             t->expand8to16sub(ref, 16 / 4, 16 / 4, dct, t->mb.src_y, t->stride);
  367.             for(i = 0 ; i < 4 ; i ++)
  368.             {
  369.                 coeff_cost = 0;
  370.                 for(j = 0 ; j < 4 ; j ++)
  371.                 {
  372.                     int32_t idx = 4 * i + j;
  373.                     int32_t idx_r = luma_index[idx];
  374.                     curdct = dct + 16 * idx_r;
  375.                     t->fdct4x4(curdct);
  376.                     t->quant4x4(curdct, qp, FALSE);
  377.                     scan_zig_4x4(t->mb.dct_y_z[idx], curdct);
  378.                     {
  379.                         run = -1;
  380.                         for(k = 0 ; k < 16 ; k ++)
  381.                         {
  382.                             run ++;
  383.                             if (t->mb.dct_y_z[idx][k] != 0)
  384.                             {
  385.                                 if (ABS(t->mb.dct_y_z[idx][k]) > 1)
  386.                                 {
  387.                                     return FALSE;
  388.                                 }
  389.                                 else
  390.                                 {
  391.                                     coeff_cost += COEFF_COST[run];
  392.                                     run = -1;
  393.                                 }
  394.                             }
  395.                         }
  396.                     }
  397.                 }
  398.                 if (coeff_cost <= t->param.luma_coeff_cost)
  399.                 {
  400.                     int32_t idx_r = luma_index[4 * i];
  401.                     memset(t->mb.dct_y_z[4 * i], 0, 16 * sizeof(int16_t));
  402.                     memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  403.                     idx_r = luma_index[4 * i + 1];
  404.                     memset(t->mb.dct_y_z[4 * i + 1], 0, 16 * sizeof(int16_t));
  405.                     memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  406.                     idx_r = luma_index[4 * i + 2];
  407.                     memset(t->mb.dct_y_z[4 * i + 2], 0, 16 * sizeof(int16_t));
  408.                     memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  409.                     idx_r = luma_index[4 * i + 3];
  410.                     memset(t->mb.dct_y_z[4 * i + 3], 0, 16 * sizeof(int16_t));
  411.                     memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  412.                     coeff_cost = 0;
  413.                 }
  414.                 else
  415.                 {
  416.                     total_cost += coeff_cost;
  417.                     if (total_cost > 5)
  418.                         return FALSE;
  419.                 }
  420.             }
  421.             memset(dct, 0, 16 * 16 * sizeof(int16_t));
  422.             memset(t->mb.dct_y_z, 0, sizeof(int16_t) * 16 * 16);
  423.             t->contract16to8add(dct, 16 / 4, 16 / 4, ref, t->mb.dst_y, t->edged_stride);
  424.         }
  425.         {
  426.             DECLARE_ALIGNED_MATRIX(pred_u, 8, 8, uint8_t, CACHE_SIZE);
  427.             DECLARE_ALIGNED_MATRIX(pred_v, 8, 8, uint8_t, CACHE_SIZE);
  428.             DECLARE_ALIGNED_MATRIX(dct, 10, 8, int16_t, CACHE_SIZE);
  429.             int32_t qp = t->qp_uv;
  430.             int16_t* curdct;
  431.             uint8_t* start;
  432.             uint8_t* dst;
  433.             uint8_t* src;
  434.             // we will count coeff cost, from jm80
  435.             int32_t run, k;
  436.             int32_t coeff_cost;
  437.             src = t->ref[0][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  438.             t->eighth_pixel_mc_u(src, t->edged_stride_uv, pred_u, vec.x, vec.y, 8, 8);
  439.             src = t->ref[0][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  440.             t->eighth_pixel_mc_u(src, t->edged_stride_uv, pred_v, vec.x, vec.y, 8, 8);
  441.             start = pred_u;
  442.             src   = t->mb.src_u;
  443.             dst   = t->mb.dst_u;
  444.             for(j = 0 ; j < 2 ; j ++)
  445.             {
  446.                 coeff_cost = 0;
  447.                 t->expand8to16sub(start, 8 / 4, 8 / 4, dct, src, t->stride_uv);
  448.                 curdct = dct;
  449.                 for(i = 0 ; i < 4 ; i ++)
  450.                 {
  451.                     run = -1;
  452.                     t->fdct4x4(curdct);
  453.                     dct[64 + i] = curdct[0];
  454.                     t->quant4x4(curdct, qp, FALSE);
  455.                     scan_zig_4x4(t->mb.dct_uv_z[j][i], curdct);
  456.                     {
  457.                         for(k = 1 ; k < 16 ; k ++)
  458.                         {
  459.                             run ++;
  460.                             if (t->mb.dct_uv_z[j][i][k] != 0)
  461.                             {
  462.                                 if (ABS(t->mb.dct_uv_z[j][i][k]) > 1)
  463.                                 {
  464.                                     coeff_cost += 16 * 16 * 256;
  465.                                     return FALSE;
  466.                                 }
  467.                                 else
  468.                                 {
  469.                                     coeff_cost += COEFF_COST[run];
  470.                                     run = -1;
  471.                                 }
  472.                             }
  473.                         }
  474.                     }
  475.                     curdct += 16;
  476.                 }
  477.                 if (coeff_cost < CHROMA_COEFF_COST)
  478.                 {
  479.                     memset(&t->mb.dct_uv_z[j][0][0], 0, 4 * 16 * sizeof(int16_t));
  480.                     memset(dct, 0, 8 * 8 * sizeof(int16_t));
  481.                 }
  482.                 else
  483.                 {
  484.                     return FALSE;
  485.                 }
  486.                 t->fdct2x2dc(curdct);
  487.                 t->quant2x2dc(curdct, qp, FALSE);
  488.                 scan_zig_2x2(t->mb.dc2x2_z[j], curdct);
  489.                 if (array_non_zero_count(t->mb.dc2x2_z[j], 4) != 0)
  490.                 {
  491.                     return FALSE;
  492.                 }
  493.                 t->iquant2x2dc(curdct, qp);
  494.                 t->idct2x2dc(curdct);
  495.                 curdct = dct;
  496.                 for(i = 0 ; i < 4 ; i ++)
  497.                 {
  498.                     curdct[0] = dct[64 + i];
  499.                     t->idct4x4(curdct);
  500.                     curdct += 16;
  501.                 }
  502.                 t->contract16to8add(dct, 8 / 4, 8 / 4, start, dst, t->edged_stride_uv);
  503.                 //
  504.                 // change to v
  505.                 //
  506.                 start = pred_v;
  507.                 dst   = t->mb.dst_v;
  508.                 src   = t->mb.src_v;
  509.             }
  510.         }
  511.         t->mb.mb_mode = P_SKIP;
  512.         t->mb.mb_part = MB_16x16;
  513.         memcpy(t->mb.pred_p16x16, ref, sizeof(uint8_t) * 16 * 16);
  514.         copy_nvec(&vec, &t->mb.vec[0][0], 4, 4, 4);
  515.         return TRUE;
  516.     }
  517.     
  518.     return FALSE;
  519. }
  520. uint32_t
  521. T264_mode_decision_interp_y(_RW T264_t* t)
  522. {
  523.     uint32_t sad;
  524.     uint32_t sad_min = -1;
  525.     uint8_t best_mode;
  526.     uint8_t sub_part[4];
  527.     uint8_t part;
  528.     int32_t i, n;
  529.     int32_t preds[9];
  530.     int32_t modes;
  531.     search_data_t s0;
  532.     subpart_search_data_t s1;
  533.     typedef uint32_t (*p16x16_function_t)(T264_t*, search_data_t* s);
  534.     static const p16x16_function_t p16x16_function[] = 
  535.     {
  536.         T264_mode_decision_inter_16x16p,
  537.         T264_mode_decision_inter_16x8p,
  538.         T264_mode_decision_inter_8x16p
  539.     };
  540.     // xxx
  541. #ifdef USE_PREV_DETECT
  542.     uint32_t sad_median;    // for skip detect
  543.     sad_median = T264_predict_sad(t, 0);
  544.     // p skip detection
  545.     if (T264_detect_pskip(t, sad_median))
  546.         return t->mb.sad;
  547. #endif
  548.     T264_inter_p16x16_mode_available(t, preds, &modes);
  549.     best_mode = P_MODE;
  550.     s0.list_index = 0;
  551.     s1.list_index = 0;
  552.     for(n = 0 ; n < modes ; n ++)
  553.     {
  554.         int32_t mode = preds[n];
  555.         sad = p16x16_function[mode](t, &s0);
  556.         if (sad < sad_min)
  557.         {
  558. part = mode;
  559.             sad_min = sad;
  560.         }
  561.     }
  562.     if (t->flags & USE_SUBBLOCK)
  563.     {
  564.         uint32_t sub_sad_all = 0;
  565.         typedef uint32_t (*p8x8_function_t)(T264_t*, int32_t, subpart_search_data_t* s);
  566.         static const p8x8_function_t p8x8_function[] = 
  567.         {
  568.             T264_mode_decision_inter_8x8p,
  569.             T264_mode_decision_inter_8x8p,
  570.             T264_mode_decision_inter_8x4p,
  571.             T264_mode_decision_inter_4x8p,
  572.             T264_mode_decision_inter_4x4p
  573.         };
  574.         s1.vec[0][0].refno = s0.vec[0].refno;
  575.         for(i = 0 ; i < 4 ; i ++)
  576.         {
  577.             uint32_t sub_sad;
  578.             uint32_t sub_sad_min = -1;
  579.             T264_inter_p8x8_mode_available(t, preds, &modes, i);
  580.             for(n = 0 ; n < modes ; n ++)
  581.             {
  582.                 int32_t mode = preds[n];
  583.                 T264_vector_t vec_bak[4];
  584.                 vec_bak[0] = t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0];
  585.                 vec_bak[1] = t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0];
  586.                 vec_bak[2] = t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0];
  587.                 vec_bak[3] = t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0];
  588.                 sub_sad = p8x8_function[mode - MB_8x8](t, i, &s1);
  589.                 if (sub_sad < sub_sad_min)
  590.                 {
  591.                     sub_part[i] = mode;
  592.                     sub_sad_min = sub_sad;
  593.                 }
  594.                 else
  595.                 {
  596.                     // restore current best mode
  597.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] = vec_bak[0];
  598.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] = vec_bak[1];
  599.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] = vec_bak[2];
  600.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = vec_bak[3];
  601.                 }
  602.             }
  603.             sub_sad_all += sub_sad_min;
  604.         }
  605.         if (sub_sad_all < sad_min)
  606.         {
  607.             part = MB_8x8;
  608.             sad_min = sub_sad_all;
  609.         }
  610.     }
  611.     switch (part)
  612.     {
  613.     case MB_16x8:
  614.         sad_min  = T264_quarter_pixel_search(t, 0, s0.src[1], s0.ref[1], s0.offset[1], &s0.vec[1], &s0.vec_median[1], s0.sad[1], 16, 8, t->mb.pred_p16x16, MB_16x8);
  615.         sad_min += T264_quarter_pixel_search(t, 0, s0.src[2], s0.ref[2], s0.offset[2], &s0.vec[2], &s0.vec_median[2], s0.sad[2], 16, 8, t->mb.pred_p16x16 + 16 * 8, MB_16x8);
  616.         copy_nvec(&s0.vec[1], &t->mb.vec[0][0], 4, 2, 4);
  617.         copy_nvec(&s0.vec[2], &t->mb.vec[0][8], 4, 2, 4);
  618.         break;
  619.     case MB_8x16:
  620.         sad_min  = T264_quarter_pixel_search(t, 0, s0.src[3], s0.ref[3], s0.offset[3], &s0.vec[3], &s0.vec_median[3], s0.sad[3], 8, 16, t->mb.pred_p16x16, MB_8x16);
  621.         sad_min += T264_quarter_pixel_search(t, 0, s0.src[4], s0.ref[4], s0.offset[4], &s0.vec[4], &s0.vec_median[4], s0.sad[4], 8, 16, t->mb.pred_p16x16 + 8, MB_8x16);
  622.         copy_nvec(&s0.vec[3], &t->mb.vec[0][0], 2, 4, 4);
  623.         copy_nvec(&s0.vec[4], &t->mb.vec[0][2], 2, 4, 4);
  624.         break;
  625.     case MB_8x8:
  626.     case MB_8x8ref0:
  627.         sad_min = 0;
  628.         for(i = 0 ; i < 4 ; i ++)
  629.         {
  630.             switch(sub_part[i])
  631.             {
  632.             case MB_8x8:
  633.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][0], s1.ref[i][0], s1.offset[i][0], &s1.vec[i][0], &s1.vec_median[i][0], s1.sad[i][0], 8, 8, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8, MB_8x8);
  634.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s1.vec[i][0];
  635.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s1.vec[i][0];
  636.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s1.vec[i][0];
  637.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s1.vec[i][0];
  638.                 sad_min += eg_size_ue(t->bs, MB_8x8);
  639.              break;
  640.             case MB_8x4:
  641.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][1], s1.ref[i][1], s1.offset[i][1], &s1.vec[i][1], &s1.vec_median[i][1], s1.sad[i][1], 8, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8, MB_8x4);
  642.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][2], s1.ref[i][2], s1.offset[i][2], &s1.vec[i][2], &s1.vec_median[i][2], s1.sad[i][2], 8, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4, MB_8x4);
  643.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s1.vec[i][1];
  644.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s1.vec[i][1];
  645.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s1.vec[i][2];
  646.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s1.vec[i][2];
  647.                 sad_min += eg_size_ue(t->bs, MB_8x4);
  648.              break;
  649.             case MB_4x8:
  650.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][3], s1.ref[i][3], s1.offset[i][3], &s1.vec[i][3], &s1.vec[i][3], s1.sad[i][3], 4, 8, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8, MB_4x8);
  651.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][4], s1.ref[i][4], s1.offset[i][4], &s1.vec[i][4], &s1.vec[i][4], s1.sad[i][4], 4, 8, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8 + 4, MB_4x8);
  652.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s1.vec[i][3];
  653.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s1.vec[i][4];
  654.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s1.vec[i][3];
  655.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s1.vec[i][4];
  656.                 sad_min += eg_size_ue(t->bs, MB_4x8);
  657.                 break;
  658.             case MB_4x4:
  659.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][5], s1.ref[i][5], s1.offset[i][5], &s1.vec[i][5], &s1.vec[i][5], s1.sad[i][5], 4, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8, MB_4x4);
  660.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][6], s1.ref[i][6], s1.offset[i][6], &s1.vec[i][6], &s1.vec[i][6], s1.sad[i][6], 4, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8 + 4, MB_4x4);
  661.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][7], s1.ref[i][7], s1.offset[i][7], &s1.vec[i][7], &s1.vec[i][7], s1.sad[i][7], 4, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4, MB_4x4);
  662.                 sad_min += T264_quarter_pixel_search(t, 0, s1.src[i][8], s1.ref[i][8], s1.offset[i][8], &s1.vec[i][8], &s1.vec[i][8], s1.sad[i][8], 4, 4, t->mb.pred_p16x16 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4 + 4, MB_4x4);
  663.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s1.vec[i][5];
  664.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s1.vec[i][6];
  665.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s1.vec[i][7];
  666.                 t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s1.vec[i][8];
  667.                 sad_min += eg_size_ue(t->bs, MB_4x4);
  668.                 break;
  669.             default:
  670.                 break;
  671.             }
  672.             t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 0] = sub_part[i];
  673.             t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 1] = sub_part[i];
  674.             t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 4] = sub_part[i];
  675.             t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 5] = sub_part[i];
  676.         }
  677.      break;
  678.     default:
  679.         break;
  680.     }
  681.     // 3ks chenm
  682.     if (t->flags & USE_INTRAININTER)
  683.         sad = T264_mode_decision_intra_y(t);
  684.     else
  685.         sad = -1;
  686.     if (sad <= sad_min)
  687.     {
  688.         best_mode = t->mb.mb_mode;
  689.         sad_min = sad;
  690.     }
  691.     else
  692.     {
  693.         t->mb.mb_part = part;
  694.     }
  695.     t->mb.mb_mode = best_mode;
  696.     t->mb.sad = sad_min;
  697.     return t->mb.sad;
  698. }
  699. /*
  700.   0   median
  701.     1   left
  702.     2   top
  703.     3   topright
  704.     4   topleft
  705.     5   0, 0
  706.     6   last frame
  707.  */
  708. void
  709. get_pmv(T264_t* t, int32_t list, T264_vector_t* vec, int32_t part, int32_t idx, int32_t width, int32_t* n)
  710. {
  711.     int32_t count = 0;
  712.     int32_t row;
  713.     int32_t col;
  714.     T264_predict_mv(t, list, idx, width, vec);
  715.     
  716.     col = idx % 4;
  717.     row = idx / 4;
  718.     vec[1].x = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec[list].x;
  719.     vec[1].y = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec[list].y;
  720.     vec[1].refno = vec[0].refno;
  721.     vec[2].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec[list].x;
  722.     vec[2].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec[list].y;
  723.     vec[2].refno = vec[0].refno;
  724.     vec[3].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec[list].x;
  725.     vec[3].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec[list].y;
  726.     vec[3].refno = vec[0].refno;
  727.     vec[4].x = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list].x;
  728.     vec[4].y = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec[list].y;
  729.     vec[4].refno = vec[0].refno;
  730.     vec[5 + 0].x = 0;
  731.     vec[5 + 0].y = 0;
  732.     vec[5 + 0].refno = 0;
  733.     *n = 5 + 1;
  734. }
  735. uint32_t
  736. T264_mode_decision_inter_16x16p(_RW T264_t* t, search_data_t* s)
  737. {
  738.     DECLARE_ALIGNED_MATRIX(pred_16x16, 16, 16, uint8_t, 16);
  739.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  740.     T264_search_context_t context;
  741.     T264_vector_t vec_skip;
  742.     int32_t num;
  743.     int32_t i;
  744.     uint32_t sad;
  745.     uint8_t* p_min = t->mb.pred_p16x16;
  746.     uint8_t* p_buf = pred_16x16;
  747.     vec[0].refno = 0;
  748.     get_pmv(t, 0, vec, MB_16x16, 0, 4, &num);
  749.     context.height = 16;
  750.     context.width  = 16;
  751.     context.limit_x= t->param.search_x;
  752.     context.limit_y= t->param.search_y;
  753.     context.vec    = vec;
  754.     context.vec_num= num;
  755.     context.mb_part= MB_16x16;
  756.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  757.     context.list_index = s->list_index;
  758.     s->src[0] = t->mb.src_y;
  759.     s->sad[0] = t->search(t, &context);
  760.     s->vec[0] = context.vec_best;
  761.     s->ref[0] = t->ref[context.list_index][s->vec[0].refno];
  762.     s->offset[0] = context.offset;
  763.     s->vec_median[0] = vec[0];
  764.     s->sad[0] = T264_quarter_pixel_search(t, 0, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, p_min, MB_16x16);
  765.     for(i = 1 ; i < t->refl0_num ; i ++)
  766.     {
  767.         vec[0].refno = i;
  768.         get_pmv(t, 0, vec, MB_16x16, 0, 4, &num);
  769.         context.vec_num = 1;
  770.         sad = t->search(t, &context);
  771.         sad+= REFCOST(context.vec_best.refno);
  772.         sad = T264_quarter_pixel_search(t, 0, s->src[0], t->ref[0][i], 
  773.             s->offset[0], &context.vec_best, &vec[0], sad, 16, 16, p_buf, MB_16x16);
  774.         if (sad < s->sad[0])
  775.         {
  776.             SWAP(uint8_t, p_buf, p_min);
  777.             s->sad[0] = sad;
  778.             s->vec[0] = context.vec_best;
  779.             s->ref[0] = t->ref[0][i];
  780.             s->vec_median[0] = vec[0];
  781.         }
  782.     }
  783.     // xxx
  784. #ifndef USE_PREV_DETECT
  785.     T264_predict_mv_skip(t, 0, &vec_skip);
  786.     sad = T264_get_pos_sad(t, p_buf, &vec_skip);
  787.     sad += t->mb.lambda * (eg_size_se(t->bs, (t->mb.vec[0][0].x - vec[0].x)) +
  788.                            eg_size_se(t->bs, (t->mb.vec[0][0].y - vec[0].y)));
  789. #else
  790.     sad = -1;
  791. #endif
  792.     if (sad < s->sad[0] + (uint32_t)8 * t->mb.lambda)
  793.     {
  794.         s->sad[0] = sad;
  795.         SWAP(uint8_t, p_buf, p_min);
  796.         copy_nvec(&vec_skip, &t->mb.vec[0][0], 4, 4, 4);
  797.     }
  798.     else
  799.     {
  800.         copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
  801.     }
  802.     if (p_min != t->mb.pred_p16x16)
  803.     {
  804.         memcpy(t->mb.pred_p16x16, p_min, sizeof(uint8_t) * 16 * 16);
  805.     }
  806.     return s->sad[0];
  807. }
  808. uint32_t
  809. T264_mode_decision_inter_16x8p(_RW T264_t* t, search_data_t* s)
  810. {
  811.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  812.     T264_search_context_t context;
  813.     int32_t num;
  814.     uint8_t old_part = t->mb.mb_part;
  815.     t->mb.mb_part = MB_16x8;
  816.     vec[0].refno = s->vec[0].refno;
  817.     get_pmv(t, 0, vec, MB_16x8, 0, 4, &num);
  818.     vec[num ++] = s->vec[0];
  819.     context.height = 8;
  820.     context.width  = 16;
  821.     context.limit_x= t->param.search_x;
  822.     context.limit_y= t->param.search_y;
  823.     context.vec    = vec;
  824.     context.vec_num= num;
  825.     context.mb_part= MB_16x8;
  826.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  827.     context.list_index = s->list_index;
  828.     s->src[1] = t->mb.src_y;
  829.     s->sad[1] = t->search(t, &context);
  830.     s->sad[1]+= REFCOST(context.vec_best.refno);
  831.     s->vec[1] = context.vec_best;
  832.     s->ref[1] = t->ref[context.list_index][s->vec[1].refno];
  833.     s->offset[1] = context.offset;
  834.     s->vec_median[1] = vec[0];
  835.     t->mb.vec_ref[VEC_LUMA + 8].vec[0] = s->vec[1];
  836.     get_pmv(t, 0, vec, MB_16x8, luma_index[8], 4, &num);
  837.     vec[num ++] = s->vec[0];
  838.     s->src[2] = t->mb.src_y + 8 * t->stride;
  839.     context.offset += 8 * t->edged_stride;
  840.     s->sad[2] = t->search(t, &context);
  841.     s->sad[2]+= REFCOST(context.vec_best.refno);
  842.     s->vec[2] = context.vec_best;
  843.     s->ref[2] = t->ref[context.list_index][s->vec[2].refno];
  844.     s->offset[2] = context.offset;
  845.     s->vec_median[2] = vec[0];
  846.     t->mb.mb_part = old_part;
  847.     return s->sad[1] + s->sad[2];
  848. }
  849. uint32_t
  850. T264_mode_decision_inter_8x16p(_RW T264_t * t, search_data_t* s)
  851. {
  852.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  853.     T264_search_context_t context;
  854.     int32_t num;
  855.     uint8_t old_part = t->mb.mb_part;
  856.     t->mb.mb_part = MB_8x16;
  857.     vec[0].refno = s->vec[0].refno;
  858.     get_pmv(t, 0, vec, MB_8x16, 0, 2, &num);
  859.     vec[num ++] = s->vec[0];
  860.     context.height = 16;
  861.     context.width  = 8;
  862.     context.limit_x= t->param.search_x;
  863.     context.limit_y= t->param.search_y;
  864.     context.vec    = vec;
  865.     context.vec_num= num;
  866.     context.mb_part= MB_8x16;
  867.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  868.     context.list_index = s->list_index;
  869.     s->src[3] = t->mb.src_y;
  870.     s->sad[3] = t->search(t, &context);
  871.     s->sad[3]+= REFCOST(context.vec_best.refno);
  872.     s->vec[3] = context.vec_best;
  873.     s->ref[3] = t->ref[context.list_index][s->vec[3].refno];
  874.     s->offset[3] = context.offset;
  875.     s->vec_median[3] = vec[0];
  876.     t->mb.vec_ref[VEC_LUMA + 1].vec[0] = s->vec[3];
  877.     get_pmv(t, 0, vec, MB_8x16, luma_index[4], 2, &num);
  878.     vec[num ++] = s->vec[0];
  879.     s->src[4] = t->mb.src_y + 8;
  880.     context.offset += 8;
  881.     s->sad[4] = t->search(t, &context);
  882.     s->sad[4]+= REFCOST(context.vec_best.refno);
  883.     s->vec[4] = context.vec_best;
  884.     s->ref[4] = t->ref[context.list_index][s->vec[4].refno];
  885.     s->offset[4] = context.offset;
  886.     s->vec_median[4] = vec[0];
  887.     t->mb.mb_part = old_part;
  888.     return s->sad[3] + s->sad[4];
  889. }
  890. uint32_t
  891. T264_mode_decision_inter_8x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  892. {
  893.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  894.     T264_search_context_t context;
  895.     int32_t num;
  896.     vec[0].refno = s->vec[0][0].refno;
  897.     get_pmv(t, 0, vec, MB_8x8, luma_index[4 * i], 2, &num);
  898.     context.height = 8;
  899.     context.width  = 8;
  900.     context.limit_x= t->param.search_x;
  901.     context.limit_y= t->param.search_y;
  902.     context.vec    = vec;
  903.     context.vec_num= num;
  904.     context.mb_part= MB_8x8;
  905.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  906.     context.list_index = s->list_index;
  907.     s->src[i][0] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  908.     s->sad[i][0] = t->search(t, &context);
  909.     s->sad[i][0]+= REFCOST(context.vec_best.refno);
  910.     s->vec[i][0] = context.vec_best;
  911.     s->offset[i][0] = context.offset;
  912.     s->ref[i][0] = t->ref[context.list_index][s->vec[i][0].refno];
  913.     s->vec_median[i][0] = vec[0];
  914.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
  915.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
  916.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
  917.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][0];
  918.     return s->sad[i][0] + eg_size_ue(t->bs, MB_8x8);
  919. }
  920. uint32_t
  921. T264_mode_decision_inter_8x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  922. {
  923.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  924.     T264_search_context_t context;
  925.     int32_t num;
  926.     vec[0].refno = s->vec[0][0].refno;
  927.     get_pmv(t, 0, vec, MB_8x4, luma_index[4 * i + 0], 2, &num);
  928.     context.height = 4;
  929.     context.width  = 8;
  930.     context.limit_x= t->param.search_x;
  931.     context.limit_y= t->param.search_y;
  932.     context.vec    = vec;
  933.     /* because get_pmv maybe return some ref does not equal, and the sub 8x8 ref framenum must be the same, so candidate we use only median vector */
  934.     context.vec_num= 1; 
  935.     context.mb_part= MB_8x4;
  936.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  937.     context.list_index = s->list_index;
  938.     s->src[i][1] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  939.     s->sad[i][1] = t->search(t, &context);
  940.     s->sad[i][1]+= REFCOST(context.vec_best.refno);
  941.     s->vec[i][1] = context.vec_best;
  942.     s->offset[i][1] = context.offset;
  943.     s->ref[i][1] = t->ref[context.list_index][s->vec[i][1].refno];
  944.     s->vec_median[i][1] = vec[0];
  945.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
  946.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] = s->vec[i][1];
  947.     get_pmv(t, 0, vec, MB_8x4, luma_index[4 * i + 2], 2, &num);
  948.     s->src[i][2] = s->src[i][1] + 4 * t->stride;
  949.     context.offset += 4 * t->edged_stride;
  950.     s->sad[i][2] = t->search(t, &context);
  951.     s->sad[i][2]+= REFCOST(context.vec_best.refno);
  952.     s->vec[i][2] = context.vec_best;
  953.     s->offset[i][2] = context.offset;
  954.     s->ref[i][2] = t->ref[context.list_index][s->vec[i][2].refno];
  955.     s->vec_median[i][2] = vec[0];
  956.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
  957.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][2];
  958.     return s->sad[i][1] + s->sad[i][2] + eg_size_ue(t->bs, MB_8x4);
  959. }
  960. uint32_t
  961. T264_mode_decision_inter_4x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  962. {
  963.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  964.     T264_search_context_t context;
  965.     int32_t num;
  966.     vec[0].refno = s->vec[0][0].refno;
  967.     get_pmv(t, 0, vec, MB_4x8, luma_index[4 * i + 0], 1, &num);
  968.     context.height = 8;
  969.     context.width  = 4;
  970.     context.limit_x= t->param.search_x;
  971.     context.limit_y= t->param.search_y;
  972.     context.vec    = vec;
  973.     /* see 4x8 note */
  974.     context.vec_num= 1; /* num; */
  975.     context.mb_part= MB_4x8;
  976.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  977.     context.list_index = s->list_index;
  978.     s->src[i][3] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  979.     s->sad[i][3] = t->search(t, &context);
  980.     s->sad[i][3]+= REFCOST(context.vec_best.refno);
  981.     s->vec[i][3] = context.vec_best;
  982.     s->offset[i][3] = context.offset;
  983.     s->ref[i][3] = t->ref[context.list_index][s->vec[i][3].refno];
  984.     s->vec_median[i][3] = vec[0];
  985.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
  986.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] = s->vec[i][3];
  987.     get_pmv(t, 0, vec, MB_4x8, luma_index[4 * i + 1], 1, &num);
  988.     s->src[i][4] = s->src[i][3] + 4;
  989.     context.offset += 4;
  990.     s->sad[i][4] = t->search(t, &context);
  991.     s->sad[i][4]+= REFCOST(context.vec_best.refno);
  992.     s->vec[i][4] = context.vec_best;
  993.     s->offset[i][4] = context.offset;
  994.     s->ref[i][4] = t->ref[context.list_index][s->vec[i][4].refno];
  995.     s->vec_median[i][4] = vec[0];
  996.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
  997.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][4];
  998.     return s->sad[i][3] + s->sad[i][4] + eg_size_ue(t->bs, MB_4x8);
  999. }
  1000. uint32_t
  1001. T264_mode_decision_inter_4x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  1002. {
  1003.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  1004.     T264_search_context_t context;
  1005.     int32_t num;
  1006.     vec[0].refno = s->vec[0][0].refno;
  1007.     get_pmv(t, 0, vec, MB_4x4, luma_index[4 * i + 0], 1, &num);
  1008.     context.height = 4;
  1009.     context.width  = 4;
  1010.     context.limit_x= t->param.search_x;
  1011.     context.limit_y= t->param.search_y;
  1012.     context.vec    = vec;
  1013.     /* see 4x8 note */
  1014.     context.vec_num= 1; /* num; */
  1015.     context.mb_part= MB_4x4;
  1016.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  1017.     context.list_index = s->list_index;
  1018.     s->src[i][5] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  1019.     s->sad[i][5] = t->search(t, &context);
  1020.     s->sad[i][5]+= REFCOST(context.vec_best.refno);
  1021.     s->vec[i][5] = context.vec_best;
  1022.     s->offset[i][5] = context.offset;
  1023.     s->ref[i][5] = t->ref[context.list_index][s->vec[i][5].refno];
  1024.     s->vec_median[i][5] = vec[0];
  1025.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] = s->vec[i][5];
  1026.     get_pmv(t, 0, vec, MB_4x4, luma_index[4 * i + 1], 1, &num);
  1027.     s->src[i][6] = s->src[i][5] + 4;
  1028.     context.offset += 4;
  1029.     s->sad[i][6] = t->search(t, &context);
  1030.     s->sad[i][6]+= REFCOST(context.vec_best.refno);
  1031.     s->vec[i][6] = context.vec_best;
  1032.     s->offset[i][6] = context.offset;
  1033.     s->ref[i][6] = t->ref[context.list_index][s->vec[i][6].refno];
  1034.     s->vec_median[i][6] = vec[0];
  1035.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] = s->vec[i][6];
  1036.     get_pmv(t, 0, vec, MB_4x4, luma_index[4 * i + 2], 1, &num);
  1037.     s->src[i][7] = s->src[i][5] + 4 * t->stride;
  1038.     context.offset += 4 * t->edged_stride - 4;
  1039.     s->sad[i][7] = t->search(t, &context);
  1040.     s->sad[i][7]+= REFCOST(context.vec_best.refno);
  1041.     s->vec[i][7] = context.vec_best;
  1042.     s->offset[i][7] = context.offset;
  1043.     s->ref[i][7] = t->ref[context.list_index][s->vec[i][7].refno];
  1044.     s->vec_median[i][7] = vec[0];
  1045.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] = s->vec[i][7];
  1046.     get_pmv(t, 0, vec, MB_4x4, luma_index[4 * i + 3], 1, &num);
  1047.     s->src[i][8] = s->src[i][7] + 4;
  1048.     context.offset += 4;
  1049.     s->sad[i][8] = t->search(t, &context);
  1050.     s->sad[i][8]+= REFCOST(context.vec_best.refno);
  1051.     s->vec[i][8] = context.vec_best;
  1052.     s->offset[i][8] = context.offset;
  1053.     s->ref[i][8] = t->ref[context.list_index][s->vec[i][8].refno];
  1054.     s->vec_median[i][8] = vec[0];
  1055.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = s->vec[i][8];
  1056.     return s->sad[i][5] + s->sad[i][6] + s->sad[i][7] + s->sad[i][8] + eg_size_ue(t->bs, MB_4x4);
  1057. }
  1058. void
  1059. T264_encode_inter_16x16p(_RW T264_t* t, uint8_t* pred)
  1060. {
  1061.     DECLARE_ALIGNED_MATRIX(dct, 16, 16, int16_t, 16);
  1062.     int32_t qp = t->qp_y;
  1063.     int32_t i, j;
  1064.     int16_t* curdct;
  1065.     // we will count coeff cost, from jm80
  1066.     int32_t run, k;
  1067.     int32_t coeff_cost, total_cost;
  1068.     total_cost = 0;
  1069.     t->expand8to16sub(pred, 16 / 4, 16 / 4, dct, t->mb.src_y, t->stride);
  1070.     for(i = 0 ; i < 4 ; i ++)
  1071.     {
  1072.         coeff_cost = 0;
  1073.         for(j = 0 ; j < 4 ; j ++)
  1074.         {
  1075.             int32_t idx = 4 * i + j;
  1076.             int32_t idx_r = luma_index[idx];
  1077.             curdct = dct + 16 * idx_r;
  1078.             t->fdct4x4(curdct);
  1079.             t->quant4x4(curdct, qp, FALSE);
  1080.             scan_zig_4x4(t->mb.dct_y_z[idx], curdct);
  1081.             if (coeff_cost <= 5)
  1082.             {
  1083.                 run = -1;
  1084.                 for(k = 0 ; k < 16 ; k ++)
  1085.                 {
  1086.                     run ++;
  1087.                     if (t->mb.dct_y_z[idx][k] != 0)
  1088.                     {
  1089.                         if (ABS(t->mb.dct_y_z[idx][k]) > 1)
  1090.                         {
  1091.                             coeff_cost += 16 * 16 * 256;  // big enough number
  1092.                             break;
  1093.                         }
  1094.                         else
  1095.                         {
  1096.                             coeff_cost += COEFF_COST[run];
  1097.                             run = -1;
  1098.                         }
  1099.                     }
  1100.                 }
  1101.             }
  1102.             else
  1103.             {
  1104.                 coeff_cost = 16 * 16 * 256;
  1105.             }
  1106.             t->iquant4x4(curdct, qp);
  1107.             t->idct4x4(curdct);
  1108.         }
  1109.         if (coeff_cost <= t->param.luma_coeff_cost)
  1110.         {
  1111.             int32_t idx_r = luma_index[4 * i];
  1112.             memset(t->mb.dct_y_z[4 * i], 0, 16 * sizeof(int16_t));
  1113.             memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  1114.             idx_r = luma_index[4 * i + 1];
  1115.             memset(t->mb.dct_y_z[4 * i + 1], 0, 16 * sizeof(int16_t));
  1116.             memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  1117.             idx_r = luma_index[4 * i + 2];
  1118.             memset(t->mb.dct_y_z[4 * i + 2], 0, 16 * sizeof(int16_t));
  1119.             memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  1120.             idx_r = luma_index[4 * i + 3];
  1121.             memset(t->mb.dct_y_z[4 * i + 3], 0, 16 * sizeof(int16_t));
  1122.             memset(dct + 16 * idx_r, 0, 16 * sizeof(int16_t));
  1123.             coeff_cost = 0;
  1124.         }
  1125.         total_cost += coeff_cost;
  1126.     }
  1127.     if (total_cost <= 5)
  1128.     {
  1129.         memset(dct, 0, 16 * 16 * sizeof(int16_t));
  1130.         memset(t->mb.dct_y_z, 0, sizeof(int16_t) * 16 * 16);
  1131.     }
  1132.     t->contract16to8add(dct, 16 / 4, 16 / 4, pred, t->mb.dst_y, t->edged_stride);
  1133. }
  1134. void
  1135. T264_encode_inter_y(_RW T264_t* t)
  1136. {
  1137.     T264_encode_inter_16x16p(t, t->mb.pred_p16x16);
  1138. }
  1139. // NOTE: this routine will merge with T264_encode_intra_uv
  1140. void
  1141. T264_transform_inter_uv(_RW T264_t* t, uint8_t* pred_u, uint8_t* pred_v)
  1142. {
  1143.     DECLARE_ALIGNED_MATRIX(dct, 10, 8, int16_t, CACHE_SIZE);
  1144.     int32_t qp = t->qp_uv;
  1145.     int32_t i, j;
  1146.     int16_t* curdct;
  1147.     uint8_t* start;
  1148.     uint8_t* dst;
  1149.     uint8_t* src;
  1150.     start = pred_u;
  1151.     src   = t->mb.src_u;
  1152.     dst   = t->mb.dst_u;
  1153.     for(j = 0 ; j < 2 ; j ++)
  1154.     {
  1155.         // we will count coeff cost, from jm80
  1156.         int32_t run, k;
  1157.         int32_t coeff_cost;
  1158.         coeff_cost = 0;
  1159.         t->expand8to16sub(start, 8 / 4, 8 / 4, dct, src, t->stride_uv);
  1160.         curdct = dct;
  1161.         for(i = 0 ; i < 4 ; i ++)
  1162.         {
  1163.             run = -1;
  1164.             t->fdct4x4(curdct);
  1165.             dct[64 + i] = curdct[0];
  1166.             t->quant4x4(curdct, qp, FALSE);
  1167.             scan_zig_4x4(t->mb.dct_uv_z[j][i], curdct);
  1168.             {
  1169.                 for(k = 1 ; k < 16 ; k ++)
  1170.                 {
  1171.                     run ++;
  1172.                     if (t->mb.dct_uv_z[j][i][k] != 0)
  1173.                     {
  1174.                         if (ABS(t->mb.dct_uv_z[j][i][k]) > 1)
  1175.                         {
  1176.                             coeff_cost += 16 * 16 * 256;
  1177.                             break;
  1178.                         }
  1179.                         else
  1180.                         {
  1181.                             coeff_cost += COEFF_COST[run];
  1182.                             run = -1;
  1183.                         }
  1184.                     }
  1185.                 }
  1186.             }
  1187.             t->iquant4x4(curdct, qp);
  1188.             curdct += 16;
  1189.         }
  1190.         if (coeff_cost < CHROMA_COEFF_COST)
  1191.         {
  1192.             memset(&t->mb.dct_uv_z[j][0][0], 0, 4 * 16 * sizeof(int16_t));
  1193.             memset(dct, 0, 8 * 8 * sizeof(int16_t));
  1194.         }
  1195.         t->fdct2x2dc(curdct);
  1196.         t->quant2x2dc(curdct, qp, FALSE);
  1197.         scan_zig_2x2(t->mb.dc2x2_z[j], curdct);
  1198.         t->iquant2x2dc(curdct, qp);
  1199.         t->idct2x2dc(curdct);
  1200.         curdct = dct;
  1201.         for(i = 0 ; i < 4 ; i ++)
  1202.         {
  1203.             curdct[0] = dct[64 + i];
  1204.             t->idct4x4(curdct);
  1205.             curdct += 16;
  1206.         }
  1207.         t->contract16to8add(dct, 8 / 4, 8 / 4, start, dst, t->edged_stride_uv);
  1208.         //
  1209.         // change to v
  1210.         //
  1211.         start = pred_v;
  1212.         dst   = t->mb.dst_v;
  1213.         src   = t->mb.src_v;
  1214.     }
  1215. }
  1216. void
  1217. T264_encode_inter_uv(_RW T264_t* t)
  1218. {
  1219.     DECLARE_ALIGNED_MATRIX(pred_u, 8, 8, uint8_t, CACHE_SIZE);
  1220.     DECLARE_ALIGNED_MATRIX(pred_v, 8, 8, uint8_t, CACHE_SIZE);
  1221.     T264_vector_t vec;
  1222.     uint8_t* src, *dst;
  1223.     uint8_t* src_u, *dst_u;
  1224.     int32_t i;
  1225.     int32_t list_index = 0;
  1226.     switch (t->mb.mb_part)
  1227.     {
  1228.     case MB_16x16:
  1229.         vec = t->mb.vec[0][0];
  1230.         src = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1231.         dst = pred_u;
  1232.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 8);
  1233.         src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1234.         dst = pred_v;
  1235.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 8);
  1236.         break;
  1237.     case MB_16x8:
  1238.         vec = t->mb.vec[0][0];
  1239.         src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1240.         dst_u = pred_u;
  1241.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 8, 4);
  1242.         src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1243.         dst = pred_v;
  1244.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 4);
  1245.         vec = t->mb.vec[0][luma_index[8]];
  1246.         src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) +
  1247.             4 * t->edged_stride_uv;
  1248.         dst_u += 4 * 8;
  1249.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 8, 4);
  1250.         src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 
  1251.             4 * t->edged_stride_uv;
  1252.         dst += 4 * 8;
  1253.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 4);
  1254.         break;
  1255.     case MB_8x16:
  1256.         vec = t->mb.vec[0][0];
  1257.         src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1258.         dst_u = pred_u;
  1259.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 8);
  1260.         src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  1261.         dst = pred_v;
  1262.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 8);
  1263.         vec = t->mb.vec[0][luma_index[4]];
  1264.         src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 4;
  1265.         dst_u += 4;
  1266.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 8);
  1267.         src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 4;
  1268.         dst += 4;
  1269.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 8);
  1270.         break;
  1271.     case MB_8x8:
  1272.     case MB_8x8ref0:
  1273.         for(i = 0 ; i < 4 ; i ++)
  1274.         {
  1275.             switch(t->mb.submb_part[luma_index[4 * i]])
  1276.             {
  1277.             case MB_8x8:
  1278.                 vec = t->mb.vec[0][luma_index[4 * i]];
  1279.                 src = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1280.                 dst = pred_u + i / 2 * 32 + i % 2 * 4;
  1281.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 4);
  1282.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1283.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  1284.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 4);
  1285.                 break;
  1286.             case MB_8x4:
  1287.                 vec = t->mb.vec[0][luma_index[4 * i]];
  1288.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1289.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  1290.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 2);
  1291.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1292.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  1293.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 2);
  1294.                 vec = t->mb.vec[0][luma_index[4 * i + 2]];
  1295.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 
  1296.                     2 * t->edged_stride_uv;
  1297.                 dst_u += 2 * 8;
  1298.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 2);
  1299.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) +
  1300.                     2 * t->edged_stride_uv;
  1301.                 dst += 2 * 8;
  1302.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 2);
  1303.                 break;
  1304.             case MB_4x8:
  1305.                 vec = t->mb.vec[0][luma_index[4 * i]];
  1306.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1307.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  1308.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 4);
  1309.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1310.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  1311.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 4);
  1312.                 vec = t->mb.vec[0][luma_index[4 * i + 1]];
  1313.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 2;
  1314.                 dst_u += 2;
  1315.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 4);
  1316.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 2;
  1317.                 dst += 2;
  1318.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 4);
  1319.                 break;
  1320.             case MB_4x4:
  1321.                 vec = t->mb.vec[0][luma_index[4 * i]];
  1322.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1323.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  1324.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  1325.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4);
  1326.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  1327.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  1328.                 vec = t->mb.vec[0][luma_index[4 * i + 1]];
  1329.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 2;
  1330.                 dst_u += 2;
  1331.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  1332.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 2;
  1333.                 dst += 2;
  1334.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  1335.                 vec = t->mb.vec[0][luma_index[4 * i + 2]];
  1336.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 
  1337.                     2 * t->edged_stride_uv;
  1338.                 dst_u += 2 * 8 - 2;
  1339.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  1340.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 
  1341.                     2 * t->edged_stride_uv;
  1342.                 dst += 2 * 8 - 2;
  1343.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  1344.                 vec = t->mb.vec[0][luma_index[4 * i + 3]];
  1345.                 src_u = t->ref[list_index][vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) +
  1346.                     2 * t->edged_stride_uv + 2;
  1347.                 dst_u += 2;
  1348.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  1349.                 src = t->ref[list_index][vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3) + i / 2 * 4) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + (i % 2 * 4) + 
  1350.                     2 * t->edged_stride_uv + 2;
  1351.                 dst += 2;
  1352.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  1353.                 break;
  1354.             default:
  1355.                 break;
  1356.             }
  1357.         }
  1358.         break;
  1359.     default:
  1360.         break;
  1361.     }
  1362.     T264_transform_inter_uv(t, pred_u, pred_v);
  1363. }