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

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.  *   llcc 2004-9-23
  9.  *
  10.  *   Test for sub-pel search after integer pel search in mode dicision(call mode1)
  11.  *   vs only integer search in mode dicision in orgin design(call mode2).
  12.  *   test result(jm80 have modified to conform to our condition):
  13.  *   (1I + 299P), foreman.cif, qp = 30, no i16x16
  14.  *               8x16(bytes)   16x8(bytes)
  15.  *   jm80        743430        750905
  16.  *   t264        746615        756162
  17.  *   (mode1+spiral full search)
  18.  *   t264        745866        755622
  19.  *   (mode2+spiral full search)
  20.  *   t264        792700        801691
  21.  *   (mode1+pmvfast)
  22.  *   t264        793219        804540
  23.  *   (mode2+pmvfast)
  24.  *   NOTE: if u want to test this file, please change pred_p16x16[16 * 16] in t264.h 
  25.  *   to pred_p16x16[4][16 * 16].
  26.  *   Yes, we will keep our older design.
  27.  *
  28.  *  This program is free software ; you can redistribute it and/or modify
  29.  *  it under the terms of the GNU General Public License as published by
  30.  *  the Free Software Foundation ; either version 2 of the License, or
  31.  *  (at your option) any later version.
  32.  *
  33.  *  This program is distributed in the hope that it will be useful,
  34.  *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
  35.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36.  *  GNU General Public License for more details.
  37.  *
  38.  *  You should have received a copy of the GNU General Public License
  39.  *  along with this program ; if not, write to the Free Software
  40.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  41.  *
  42.  ****************************************************************************/
  43. #include "stdio.h"
  44. #include "memory.h"
  45. #include "T264.h"
  46. #include "inter.h"
  47. #include "intra.h"
  48. #include "estimation.h"
  49. #include "utility.h"
  50. #include "interpolate.h"
  51. void
  52. T264_predict_mv(T264_t* t, int32_t list, int32_t i, int32_t width, T264_vector_t* vec)
  53. {
  54.     int32_t n;
  55.     int32_t count = 0;
  56.     int32_t idx;
  57.     int32_t row;
  58.     int32_t col;
  59.     int32_t org;
  60.     T264_vector_t vec_n[3];
  61.     n = vec->refno;
  62.     org = i;
  63.     i = luma_index[i];
  64.     col = org % 4;
  65.     row = org / 4;
  66.     vec_n[0] = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec;
  67.     vec_n[1] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec;
  68.     vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec;
  69.     if (vec_n[2].refno == -2)
  70.     {
  71.         vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec;
  72.     }
  73.     if (((i & 3) == 3) || ((i & 3) == 2 && width == 2))
  74.     {
  75.         vec_n[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec;
  76.     }
  77.     if (t->mb.mb_part == MB_16x8)
  78.     {
  79.         if (i == 0 && n == vec_n[1].refno)
  80.         {
  81.             vec[0] = vec_n[1];
  82.             return;
  83.         }
  84.         else if (i != 0 && n == vec_n[0].refno)
  85.         {
  86.             vec[0] = vec_n[0];
  87.             return;
  88.         }
  89.     }
  90.     else if (t->mb.mb_part == MB_8x16)
  91.     {
  92.         if (i == 0 && n == vec_n[0].refno)
  93.         {
  94.             vec[0] = vec_n[0];
  95.             return;
  96.         }
  97.         else if (i != 0 && n == vec_n[2].refno)
  98.         {
  99.             vec[0] = vec_n[2];
  100.             return;
  101.         }
  102.     }
  103.     if (vec_n[0].refno == n)
  104.     {
  105.         count ++;
  106.         idx = 0;
  107.     }
  108.     if (vec_n[1].refno == n)
  109.     {
  110.         count ++;
  111.         idx = 1;
  112.     }
  113.     if (vec_n[2].refno == n)
  114.     {
  115.         count ++;
  116.         idx = 2;
  117.     }
  118.     if (count > 1)
  119.     {
  120.         vec[0].x = T264_median(vec_n[0].x, vec_n[1].x, vec_n[2].x);
  121.         vec[0].y = T264_median(vec_n[0].y, vec_n[1].y, vec_n[2].y);
  122.         return;
  123.     }
  124.     else if (count == 1)
  125.     {
  126.         vec[0] = vec_n[idx];
  127.         return;
  128.     }
  129.     else if (vec_n[1].refno == -2 && vec_n[2].refno == -2 && vec_n[0].refno != -2)
  130.     {
  131.         vec[0] = vec_n[0];
  132.     }
  133.     else
  134.     {
  135.         vec[0].x = T264_median(vec_n[0].x, vec_n[1].x, vec_n[2].x);
  136.         vec[0].y = T264_median(vec_n[0].y, vec_n[1].y, vec_n[2].y);
  137.         return;        
  138.     }
  139. }
  140. int32_t 
  141. T264_median(int32_t x, int32_t y, int32_t z)
  142. {
  143.     int32_t min, max;
  144.     if (x < y)
  145.     {
  146.         min = x;
  147.         max = y;
  148.     }
  149.     else
  150.     {
  151.         min = y;
  152.         max = x;
  153.     }
  154.     if (z < min)
  155.     {
  156.         min = z;
  157.     }
  158.     else if (z > max)
  159.     {
  160.         max = z;
  161.     }
  162.     return x + y + z - min - max;
  163. }
  164. void
  165. copy_nvec(T264_vector_t* src, T264_vector_t* dst, int32_t width, int32_t height, int32_t stride)
  166. {
  167.     int32_t i, j;
  168.     for(i = 0 ; i < height ; i ++)
  169.     {
  170.         for(j = 0 ; j < width ; j ++)
  171.         {
  172.             dst[j] = src[0];
  173.         }
  174.         dst += stride;
  175.     }
  176. }
  177. void
  178. T264_inter_p16x16_mode_available(T264_t* t, int32_t preds[], int32_t* modes)
  179. {
  180.     if (t->flags & USE_FORCEBLOCKSIZE)
  181.     {
  182.         *modes = 0;
  183.       
  184.         if (t->param.block_size & SEARCH_16x16P)
  185.             preds[(*modes) ++] = MB_16x16;
  186.         if (t->param.block_size & SEARCH_16x8P)
  187.             preds[(*modes) ++] = MB_16x8;
  188.         if (t->param.block_size & SEARCH_8x16P)
  189.             preds[(*modes) ++] = MB_8x16;
  190.         return ;
  191.     }
  192.     if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  193.     {
  194.         *modes = 0;
  195.         preds[(*modes) ++] = MB_16x16;
  196.         if (t->mb.vec_ref[VEC_LUMA - 1].part == MB_16x8)
  197.         {
  198.             preds[(*modes) ++] = MB_16x8;
  199.         }
  200.         if (t->mb.vec_ref[VEC_LUMA - 8].part == MB_8x16)
  201.         {
  202.             preds[(*modes) ++] = MB_8x16;
  203.         }
  204.     }
  205.     else
  206.     {
  207.         // try all
  208.         preds[0] = MB_16x16;
  209.         preds[1] = MB_16x8;
  210.         preds[2] = MB_8x16;
  211.         *modes = 3;
  212.     }
  213. }
  214. void
  215. T264_inter_p8x8_mode_available(T264_t* t, int32_t preds[], int32_t* modes, int32_t sub_no)
  216. {
  217.     static const int32_t neighbour[] = 
  218.     {
  219.         0, MB_LEFT, MB_TOP, MB_LEFT| MB_TOP
  220.     };
  221.     int32_t mb_neighbour = t->mb.mb_neighbour| neighbour[sub_no];
  222.     if (t->flags & USE_FORCEBLOCKSIZE)
  223.     {
  224.         *modes = 0;
  225.         if (t->param.block_size & SEARCH_8x8P)
  226.             preds[(*modes) ++] = MB_8x8;
  227.         if (t->param.block_size & SEARCH_8x4P)
  228.             preds[(*modes) ++] = MB_8x4;
  229.         if (t->param.block_size & SEARCH_4x8P)
  230.             preds[(*modes) ++] = MB_4x8;
  231.         if (t->param.block_size & SEARCH_4x4P)
  232.             preds[(*modes) ++] = MB_4x4;
  233.         return ;
  234.     }
  235.     if ((mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
  236.     {
  237.         *modes = 0;
  238.         preds[*modes ++] = MB_8x8;
  239.         if (t->mb.vec_ref[VEC_LUMA - 8 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_8x4)
  240.         {
  241.             preds[*modes ++] = MB_8x4;
  242.         }
  243.         if (t->mb.vec_ref[VEC_LUMA - 1 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x8)
  244.         {
  245.             preds[*modes ++] = MB_4x8;
  246.         }
  247.         if (t->mb.vec_ref[VEC_LUMA - 8 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x4 || 
  248.             t->mb.vec_ref[VEC_LUMA - 1 + sub_no / 2 * 16 + sub_no % 2 * 4].part == MB_4x4)
  249.         {
  250.             preds[*modes ++] = MB_4x4;
  251.         }
  252.     }
  253.     else
  254.     {
  255.         // try all
  256.         preds[0] = MB_8x8;
  257.         preds[1] = MB_8x4;
  258.         preds[2] = MB_4x8;
  259.         preds[3] = MB_4x4;
  260.         *modes = 4;
  261.     }
  262. }
  263. uint32_t
  264. T264_mode_decision_inter_y(_RW T264_t* t)
  265. {
  266.     uint32_t sad;
  267.     uint32_t sad_min = -1;
  268.     uint8_t best_mode;
  269.     uint8_t part;
  270.     int32_t i, n;
  271.     int32_t preds[7];
  272.     int32_t modes;
  273.     search_data_t s0;
  274.     subpart_search_data_t s1;
  275.     T264_vector_t vec_bak[16 * 16]; 
  276.     typedef uint32_t (*p16x16_function_t)(T264_t*, search_data_t* s);
  277.     static p16x16_function_t p16x16_function[] = 
  278.     {
  279.         T264_mode_decision_inter_16x16p,
  280.         T264_mode_decision_inter_16x8p,
  281.         T264_mode_decision_inter_8x16p
  282.     };
  283.     T264_inter_p16x16_mode_available(t, preds, &modes);
  284.     best_mode = P_L0;
  285. //SKIP
  286. /* if(modes > 0) 
  287. {
  288. sad = p16x16_function[0](t, &s0);
  289. if(t->mb.mb_mode == P_SKIP)
  290. {
  291. sad_min = sad;
  292. return sad_min;
  293. }
  294. else
  295. {
  296. sad_min = sad;
  297. part = 0;
  298. }
  299. }
  300.  */
  301.     for(n = 0 ; n < modes ; n ++)
  302.     {
  303.         int32_t mode = preds[n];
  304.         memcpy(vec_bak, t->mb.vec, sizeof(vec_bak));
  305.         sad = p16x16_function[mode](t, &s0);
  306.         if (sad < sad_min)
  307.         {
  308.             part = mode;
  309.             sad_min = sad;
  310.         }
  311.         else
  312.         {
  313.             memcpy(t->mb.vec, vec_bak, sizeof(vec_bak));
  314.         }
  315.     }
  316.     if (t->flags & USE_SUBBLOCK)
  317.     {
  318.         uint32_t sub_sad_all = 0;
  319.         typedef uint32_t (*p8x8_function_t)(T264_t*, int32_t, subpart_search_data_t* s);
  320.         static p8x8_function_t p8x8_function[] = 
  321.         {
  322.             T264_mode_decision_inter_8x8p,
  323.             T264_mode_decision_inter_8x8p,
  324.             T264_mode_decision_inter_8x4p,
  325.             T264_mode_decision_inter_4x8p,
  326.             T264_mode_decision_inter_4x4p
  327.         };
  328.         for(i = 0 ; i < 4 ; i ++)
  329.         {
  330.             uint32_t sub_sad;
  331.             uint32_t sub_sad_min = -1;
  332.             T264_inter_p8x8_mode_available(t, preds, &modes, i);
  333.             for(n = 0 ; n < modes ; n ++)
  334.             {
  335.                 int32_t mode = preds[n];
  336.                 T264_vector_t vec_bak[4];
  337.                 vec_bak[0] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0];
  338.                 vec_bak[1] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1];
  339.                 vec_bak[2] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4];
  340.                 vec_bak[3] = t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5];
  341.                 sub_sad = p8x8_function[mode - MB_8x8](t, i, &s1);
  342.                 if (sub_sad < sub_sad_min)
  343.                 {
  344.                     sub_sad_min = sub_sad;
  345.                     t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 0] = mode;
  346.                     t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 1] = mode;
  347.                     t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 4] = mode;
  348.                     t->mb.submb_part[i / 2 * 8 + i % 2 * 2 + 5] = mode;
  349.                 }
  350.                 else
  351.                 {
  352.                     // restore current best mode
  353.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec = vec_bak[0];
  354.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec = vec_bak[1];
  355.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec = vec_bak[2];
  356.                     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec = vec_bak[3];
  357.                     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = vec_bak[0];
  358.                     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = vec_bak[1];
  359.                     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = vec_bak[2];
  360.                     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = vec_bak[3];
  361.                 }
  362.             }
  363.             sub_sad_all += sub_sad_min;
  364.         }
  365.         if (sub_sad_all < sad_min)
  366.         {
  367.             part = MB_8x8;
  368.             sad_min = sub_sad_all;
  369.         }
  370.     }
  371.     sad = T264_mode_decision_intra_y(t);
  372.     // xxx
  373.     if (0 && sad <= sad_min)
  374.     {
  375.         best_mode = t->mb.mb_mode;
  376.         sad_min = sad;
  377.     }
  378.     else
  379.     {
  380.         t->mb.mb_part = part;
  381.     }
  382.     t->mb.mb_mode = best_mode;
  383.     t->mb.sad = sad_min;
  384.     return sad_min;
  385. }
  386. /*
  387.   0   median
  388.     1   left
  389.     2   top
  390.     3   topright
  391.     4   topleft
  392.     5   0, 0
  393.     6   last frame
  394.  */
  395. static void
  396. get_pmv(T264_t* t, T264_vector_t* vec, int32_t part, int32_t idx, int32_t width, int32_t* n)
  397. {
  398.     int32_t count = 0;
  399.     int32_t row;
  400.     int32_t col;
  401.     int32_t i;
  402.     vec->refno = 0;
  403.     T264_predict_mv(t, 0, idx, width, vec);
  404.     
  405.     idx = luma_index[idx];
  406.     col = idx % 4;
  407.     row = idx / 4;
  408.     vec[1] = t->mb.vec_ref[VEC_LUMA - 1 + row * 8 + col].vec;   // left
  409.     vec[2] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col].vec;   // top
  410.     vec[3] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col + width].vec;   // top right
  411.     vec[4] = t->mb.vec_ref[VEC_LUMA - 8 + row * 8 + col - 1].vec;       // left top
  412.     for(i = 0 ; i < t->param.ref_num ; i ++)
  413.     {
  414.         if (i != vec[0].refno)
  415.         {
  416.             vec[5 + i].x = vec[0].x;
  417.             vec[5 + i].y = vec[0].y;
  418.         }
  419.         else
  420.         {
  421.             vec[5 + i].x = vec[5 + i].y = 0;
  422.         }
  423.         vec[5 + i].refno = i;
  424.     }
  425.     *n = 5 + t->param.ref_num;
  426. }
  427. uint32_t
  428. T264_mode_decision_inter_16x16p(_RW T264_t* t, search_data_t* s)
  429. {
  430.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  431.     T264_search_context_t context;
  432.     int32_t num;
  433. uint8_t is_skip = 0;
  434.     get_pmv(t, vec, MB_16x16, 0, 4, &num);
  435.     context.height = 16;
  436.     context.width  = 16;
  437.     context.limit_x= t->param.search_x;
  438.     context.limit_y= t->param.search_y;
  439.     context.vec    = vec;
  440.     context.vec_num= num;
  441.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  442.     s->src[0] = t->mb.src_y;
  443.     s->sad[0] = t->search(t, &context);
  444.     s->vec[0] = context.vec_best;
  445.     s->ref[0] = t->refl0[s->vec[0].refno];
  446.     s->offset[0] = context.offset;
  447.     s->vec_median[0] = vec[0];
  448.     s->sad[0] = T264_quarter_pixel_search(t, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, t->mb.pred_p16x16[0]);
  449.     copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
  450. /*/SKIP
  451. /*
  452. if(t->mb.mb_x == 0 || t->mb.mb_y == 0)
  453. {
  454. if(s->vec[0].x == 0 && s->vec[0].y == 0 && s->vec[0].refno == 0)
  455. is_skip = 1;
  456. }
  457. else
  458. {
  459. if(s->vec[0].x == context.vec[0].x && s->vec[0].y == context.vec[0].y 
  460. && s->vec[0].refno == 0 && context.vec[0].refno == 0)
  461. is_skip = 1;
  462. }
  463. */
  464. /*
  465. //SKIP
  466. if(   ((t->mb.mb_neighbour & MB_LEFT) != MB_LEFT && s->vec[0].x == 0 && s->vec[0].y == 0)
  467.        || ((t->mb.mb_neighbour & MB_TOP) != MB_TOP && s->vec[0].x == 0 && s->vec[0].y == 0)
  468. //    || (t->mb.vec_ref[VEC_LUMA - 1].vec.refno == 0 && t->mb.vec_ref[VEC_LUMA - 1].vec.x == 0 && t->mb.vec_ref[VEC_LUMA - 1].vec.y == 0 && s->vec[0].x == 0 && s->vec[0].y == 0)
  469. //    || (t->mb.vec_ref[VEC_LUMA - 8].vec.refno == 0 && t->mb.vec_ref[VEC_LUMA - 8].vec.x == 0 && t->mb.vec_ref[VEC_LUMA - 8].vec.y == 0 && s->vec[0].x == 0 && s->vec[0].y == 0)
  470.    )
  471. {
  472. sad = T264_quarter_pixel_search(t, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, t->mb.pred_p16x16);
  473.         copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
  474.     t->mb.mb_mode = P_SKIP;
  475. t->mb.mb_part = MB_16x16;
  476. t->mb.sad = sad;
  477. }
  478. else if(s->vec[0].x == context.vec[0].x && s->vec[0].y == context.vec[0].y 
  479. && s->vec[0].refno == 0 && context.vec[0].refno == 0)
  480. {
  481. //All residual zero?
  482. int32_t nz = 0;
  483. int32_t idx;
  484. sad = T264_quarter_pixel_search(t, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, t->mb.pred_p16x16);
  485.         copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
  486. T264_encode_inter_y(t);
  487. for(idx = 0; idx < 16; idx++)
  488. nz += array_non_zero_count(t->mb.dct_y_z[idx], 16);
  489. // T264_encode_inter_uv(t);
  490. // for(idx = 0; idx < 8; idx++)
  491. // nz += array_non_zero_count(t->mb.dct_uv_z[idx / 4][idx % 4], 16);
  492. if(nz == 0)
  493. {
  494. //            if ((t->mb.mb_neighbour & MB_LEFT) != MB_LEFT || (t->mb.mb_neighbour & MB_TOP) != MB_TOP ||
  495. //                (t->mb.vec_ref[VEC_LUMA - 1].vec.refno == 0 && t->mb.vec_ref[VEC_LUMA - 1].vec.x == 0 && t->mb.vec_ref[VEC_LUMA - 1].vec.y == 0) ||
  496. //                (t->mb.vec_ref[VEC_LUMA - 8].vec.refno == 0 && t->mb.vec_ref[VEC_LUMA - 8].vec.x == 0 && t->mb.vec_ref[VEC_LUMA - 8].vec.y == 0))
  497. //            {
  498. //                uint32_t flags = t->flags;
  499. //                s->vec[0].x = s->vec[0].y = s->vec[0].refno = 0;
  500. //                copy_nvec(&s->vec[0], &t->mb.vec[0][0], 4, 4, 4);
  501. //                t->flags &= ~(USE_HALFPEL |USE_QUARTPEL);
  502. //                sad = T264_quarter_pixel_search(t, s->src[0], s->ref[0], s->offset[0], &s->vec[0], &s->vec_median[0], s->sad[0], 16, 16, t->mb.pred_p16x16);
  503. //                t->flags = flags;
  504. //                T264_encode_inter_y(t);
  505. //            }
  506.             T264_encode_inter_uv(t);
  507.     t->mb.mb_mode = P_SKIP;
  508. t->mb.mb_part = MB_16x16;
  509. t->mb.sad = sad;
  510. if(context.vec[0].x !=0 && context.vec[0].y != 0)
  511. printf("MVx=%d,MVy=%dn",context.vec[0].x,context.vec[0].y);
  512. }
  513. else
  514. {
  515. t->mb.mb_mode = P_L0;
  516. t->mb.mb_part = MB_16x16;
  517. }
  518. }
  519. */
  520.     return s->sad[0];
  521. }
  522. uint32_t
  523. T264_mode_decision_inter_16x8p(_RW T264_t* t, search_data_t* s)
  524. {
  525.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  526.     T264_search_context_t context;
  527.     int32_t num;
  528.     uint8_t old_part = t->mb.mb_part;
  529.     t->mb.mb_part = MB_16x8;
  530.     get_pmv(t, vec, MB_16x8, 0, 4, &num);
  531.     context.height = 8;
  532.     context.width  = 16;
  533.     context.limit_x= t->param.search_x;
  534.     context.limit_y= t->param.search_y;
  535.     context.vec    = vec;
  536.     context.vec_num= num;
  537.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  538.     s->src[1] = t->mb.src_y;
  539.     s->sad[1] = t->search(t, &context);
  540.     s->vec[1] = context.vec_best;
  541.     s->ref[1] = t->refl0[s->vec[1].refno];
  542.     s->offset[1] = context.offset;
  543.     s->vec_median[1] = vec[0];
  544.     s->sad[1] = T264_quarter_pixel_search(t, s->src[1], s->ref[1], s->offset[1], &s->vec[1], &s->vec_median[1], s->sad[1], 16, 8, t->mb.pred_p16x16[1]);
  545.     copy_nvec(&s->vec[1], &t->mb.vec[0][0], 4, 2, 4);
  546.     t->mb.vec_ref[VEC_LUMA + 8].vec = s->vec[1];
  547.     get_pmv(t, vec, MB_16x8, luma_index[8], 4, &num);
  548.     s->src[2] = t->mb.src_y + 8 * t->stride;
  549.     context.offset += 8 * t->edged_stride;
  550.     s->sad[2] = t->search(t, &context);
  551.     s->vec[2] = context.vec_best;
  552.     s->ref[2] = t->refl0[s->vec[2].refno];
  553.     s->offset[2] = context.offset;
  554.     s->vec_median[2] = vec[0];
  555.     s->sad[2] = T264_quarter_pixel_search(t, s->src[2], s->ref[2], s->offset[2], &s->vec[2], &s->vec_median[2], s->sad[2], 16, 8, t->mb.pred_p16x16[1] + 16 * 8);
  556.     copy_nvec(&s->vec[2], &t->mb.vec[0][8], 4, 2, 4);
  557.     t->mb.mb_part = old_part;
  558.     return s->sad[1] + s->sad[2];
  559. }
  560. uint32_t
  561. T264_mode_decision_inter_8x16p(_RW T264_t * t, search_data_t* s)
  562. {
  563.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  564.     T264_search_context_t context;
  565.     int32_t num;
  566.     uint8_t old_part = t->mb.mb_part;
  567.     t->mb.mb_part = MB_8x16;
  568.     get_pmv(t, vec, MB_8x16, 0, 2, &num);
  569.     context.height = 16;
  570.     context.width  = 8;
  571.     context.limit_x= t->param.search_x;
  572.     context.limit_y= t->param.search_y;
  573.     context.vec    = vec;
  574.     context.vec_num= num;
  575.     context.offset = (t->mb.mb_y << 4) * t->edged_stride + (t->mb.mb_x << 4);
  576.     s->src[3] = t->mb.src_y;
  577.     s->sad[3] = t->search(t, &context);
  578.     s->vec[3] = context.vec_best;
  579.     s->ref[3] = t->refl0[s->vec[3].refno];
  580.     s->offset[3] = context.offset;
  581.     s->vec_median[3] = vec[0];
  582.     s->sad[3] = T264_quarter_pixel_search(t, s->src[3], s->ref[3], s->offset[3], &s->vec[3], &s->vec_median[3], s->sad[3], 8, 16, t->mb.pred_p16x16[2]);
  583.     copy_nvec(&s->vec[3], &t->mb.vec[0][0], 2, 4, 4);
  584.     t->mb.vec_ref[VEC_LUMA + 1].vec = s->vec[3];
  585.     // xxx
  586.     //printf("mb: %d, x: %d, y: %d, sad: %dn", t->mb.mb_xy, s->vec[3].x, s->vec[3].y, s->sad[3]);
  587.     get_pmv(t, vec, MB_8x16, luma_index[4], 2, &num);
  588.     s->src[4] = t->mb.src_y + 8;
  589.     context.offset += 8;
  590.     s->sad[4] = t->search(t, &context);
  591.     s->vec[4] = context.vec_best;
  592.     s->ref[4] = t->refl0[s->vec[4].refno];
  593.     s->offset[4] = context.offset;
  594.     s->vec_median[4] = vec[0];
  595.     s->sad[4] = T264_quarter_pixel_search(t, s->src[4], s->ref[4], s->offset[4], &s->vec[4], &s->vec_median[4], s->sad[4], 8, 16, t->mb.pred_p16x16[2] + 8);
  596.     copy_nvec(&s->vec[4], &t->mb.vec[0][2], 2, 4, 4);
  597.     t->mb.mb_part = old_part;
  598.     // xxx
  599.     //printf("mb: %d, x: %d, y: %d, sad: %dn", t->mb.mb_xy, s->vec[4].x, s->vec[4].y, s->sad[4]);
  600.     return s->sad[3] + s->sad[4];
  601. }
  602. uint32_t
  603. T264_mode_decision_inter_8x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  604. {
  605.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  606.     T264_search_context_t context;
  607.     int32_t num;
  608.     get_pmv(t, vec, MB_8x8, luma_index[4 * i], 2, &num);
  609.     context.height = 8;
  610.     context.width  = 8;
  611.     context.limit_x= t->param.search_x;
  612.     context.limit_y= t->param.search_y;
  613.     context.vec    = vec;
  614.     context.vec_num= num;
  615.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  616.     s->src[i][0] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  617.     s->sad[i][0] = t->search(t, &context);
  618.     s->vec[i][0] = context.vec_best;
  619.     s->offset[i][0] = context.offset;
  620.     s->ref[i][0] = t->refl0[s->vec[i][0].refno];
  621.     s->vec_median[i][0] = vec[0];
  622.     s->sad[i][0] = T264_quarter_pixel_search(t, s->src[i][0], s->ref[i][0], s->offset[i][0], &s->vec[i][0], &s->vec_median[i][0], s->sad[i][0], 8, 8, t->mb.pred_p16x16[3] + i / 2 * 16 * 8 + i % 2 * 8);
  623.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec =
  624.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec =
  625.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec =
  626.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec = s->vec[i][0];
  627.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s->vec[i][0];
  628.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s->vec[i][0];
  629.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s->vec[i][0];
  630.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s->vec[i][0];
  631.     // xxx
  632.     printf("mb: %d, x: %d, y: %d, mx: %d, my: %d, sad: %dn", t->mb.mb_xy, s->vec[i][0].x, s->vec[i][0].y, vec[0].x, vec[0].y, s->sad[i][0]);
  633.     return s->sad[i][0];
  634. }
  635. uint32_t
  636. T264_mode_decision_inter_8x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  637. {
  638.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  639.     T264_search_context_t context;
  640.     int32_t num;
  641.     get_pmv(t, vec, MB_8x4, luma_index[4 * i + 0], 2, &num);
  642.     context.height = 4;
  643.     context.width  = 8;
  644.     context.limit_x= t->param.search_x;
  645.     context.limit_y= t->param.search_y;
  646.     context.vec    = vec;
  647.     context.vec_num= num;
  648.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  649.     s->src[i][1] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  650.     s->sad[i][1] = t->search(t, &context);
  651.     s->vec[i][1] = context.vec_best;
  652.     s->offset[i][1] = context.offset;
  653.     s->ref[i][1] = t->refl0[s->vec[i][1].refno];
  654.     s->vec_median[i][1] = vec[0];
  655.     s->sad[i][1] = T264_quarter_pixel_search(t, s->src[i][1], s->ref[i][1], s->offset[i][1], &s->vec[i][1], &s->vec_median[i][1], s->sad[i][1], 8, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8);
  656.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec =
  657.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec = s->vec[i][1];
  658.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s->vec[i][1];
  659.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s->vec[i][1];
  660.     get_pmv(t, vec, MB_8x4, luma_index[4 * i + 2], 2, &num);
  661.     s->src[i][2] = s->src[i][1] + 4 * t->stride;
  662.     context.offset += 4 * t->edged_stride;
  663.     s->sad[i][2] = t->search(t, &context);
  664.     s->vec[i][2] = context.vec_best;
  665.     s->offset[i][2] = context.offset;
  666.     s->ref[i][2] = t->refl0[s->vec[i][2].refno];
  667.     s->vec_median[i][2] = vec[0];
  668.     s->sad[i][2] = T264_quarter_pixel_search(t, s->src[i][2], s->ref[i][2], s->offset[i][2], &s->vec[i][2], &s->vec_median[i][2], s->sad[i][2], 8, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4);
  669.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec =
  670.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec = s->vec[i][2];
  671.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s->vec[i][2];
  672.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s->vec[i][2];
  673.     return s->sad[i][1] + s->sad[i][2];
  674. }
  675. uint32_t
  676. T264_mode_decision_inter_4x8p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  677. {
  678.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  679.     T264_search_context_t context;
  680.     int32_t num;
  681.     get_pmv(t, vec, MB_4x8, luma_index[4 * i + 0], 1, &num);
  682.     context.height = 8;
  683.     context.width  = 4;
  684.     context.limit_x= t->param.search_x;
  685.     context.limit_y= t->param.search_y;
  686.     context.vec    = vec;
  687.     context.vec_num= num;
  688.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  689.     s->src[i][3] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  690.     s->sad[i][3] = t->search(t, &context);
  691.     s->vec[i][3] = context.vec_best;
  692.     s->offset[i][3] = context.offset;
  693.     s->ref[i][3] = t->refl0[s->vec[i][3].refno];
  694.     s->vec_median[i][3] = vec[0];
  695.     s->sad[i][3] = T264_quarter_pixel_search(t, s->src[i][3], s->ref[i][3], s->offset[i][3], &s->vec[i][3], &s->vec[i][3], s->sad[i][3], 4, 8, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8);
  696.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec =
  697.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec = s->vec[i][3];
  698.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s->vec[i][3];
  699.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s->vec[i][3];
  700.     get_pmv(t, vec, MB_4x8, luma_index[4 * i + 1], 1, &num);
  701.     s->src[i][4] = s->src[i][3] + 4;
  702.     context.offset += 4;
  703.     s->sad[i][4] = t->search(t, &context);
  704.     s->vec[i][4] = context.vec_best;
  705.     s->offset[i][4] = context.offset;
  706.     s->ref[i][4] = t->refl0[s->vec[i][4].refno];
  707.     s->vec_median[i][4] = vec[0];
  708.     s->sad[i][4] = T264_quarter_pixel_search(t, s->src[i][4], s->ref[i][4], s->offset[i][4], &s->vec[i][4], &s->vec[i][4], s->sad[i][4], 4, 8, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8 + 4);
  709.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec =
  710.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec = s->vec[i][4];
  711.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s->vec[i][4];
  712.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s->vec[i][4];
  713.     return s->sad[i][3] + s->sad[i][4];
  714. }
  715. uint32_t
  716. T264_mode_decision_inter_4x4p(_RW T264_t * t, int32_t i, subpart_search_data_t* s)
  717. {
  718.     T264_vector_t vec[5 + 10];  // NOTE: max 10 refs
  719.     T264_search_context_t context;
  720.     int32_t num;
  721.     get_pmv(t, vec, MB_4x4, luma_index[4 * i + 0], 1, &num);
  722.     context.height = 4;
  723.     context.width  = 4;
  724.     context.limit_x= t->param.search_x;
  725.     context.limit_y= t->param.search_y;
  726.     context.vec    = vec;
  727.     context.vec_num= num;
  728.     context.offset = ((t->mb.mb_y << 4) + i / 2 * 8) * t->edged_stride + (t->mb.mb_x << 4) + i % 2 * 8;
  729.     s->src[i][5] = t->mb.src_y + (i / 2 * 8) * t->stride + i % 2 * 8;
  730.     s->sad[i][5] = t->search(t, &context);
  731.     s->vec[i][5] = context.vec_best;
  732.     s->offset[i][5] = context.offset;
  733.     s->ref[i][5] = t->refl0[s->vec[i][5].refno];
  734.     s->vec_median[i][5] = vec[0];
  735.     s->sad[i][5] = T264_quarter_pixel_search(t, s->src[i][5], s->ref[i][5], s->offset[i][5], &s->vec[i][5], &s->vec[i][5], s->sad[i][5], 4, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8);
  736.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec =
  737.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 0] = s->vec[i][5];
  738.     get_pmv(t, vec, MB_4x4, luma_index[4 * i + 1], 1, &num);
  739.     s->src[i][6] = s->src[i][5] + 4;
  740.     context.offset += 4;
  741.     s->sad[i][6] = t->search(t, &context);
  742.     s->vec[i][6] = context.vec_best;
  743.     s->offset[i][6] = context.offset;
  744.     s->ref[i][6] = t->refl0[s->vec[i][6].refno];
  745.     s->vec_median[i][6] = vec[0];
  746.     s->sad[i][6] = T264_quarter_pixel_search(t, s->src[i][6], s->ref[i][6], s->offset[i][6], &s->vec[i][6], &s->vec[i][6], s->sad[i][6], 4, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8 + 4);
  747.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec =
  748.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 1] = s->vec[i][6];
  749.     get_pmv(t, vec, MB_4x4, luma_index[4 * i + 2], 1, &num);
  750.     s->src[i][7] = s->src[i][5] + 4 * t->stride;
  751.     context.offset += 4 * t->edged_stride - 4;
  752.     s->sad[i][7] = t->search(t, &context);
  753.     s->vec[i][7] = context.vec_best;
  754.     s->offset[i][7] = context.offset;
  755.     s->ref[i][7] = t->refl0[s->vec[i][7].refno];
  756.     s->vec_median[i][7] = vec[0];
  757.     s->sad[i][7] = T264_quarter_pixel_search(t, s->src[i][7], s->ref[i][7], s->offset[i][7], &s->vec[i][7], &s->vec[i][7], s->sad[i][7], 4, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4);
  758.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec =
  759.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 4] = s->vec[i][7];
  760.     get_pmv(t, vec, MB_4x4, luma_index[4 * i + 3], 1, &num);
  761.     s->src[i][8] = s->src[i][7] + 4;
  762.     context.offset += 4;
  763.     s->sad[i][8] = t->search(t, &context);
  764.     s->vec[i][8] = context.vec_best;
  765.     s->offset[i][8] = context.offset;
  766.     s->ref[i][8] = t->refl0[s->vec[i][8].refno];
  767.     s->vec_median[i][8] = vec[0];
  768.     s->sad[i][8] = T264_quarter_pixel_search(t, s->src[i][8], s->ref[i][8], s->offset[i][8], &s->vec[i][8], &s->vec[i][8], s->sad[i][8], 4, 4, t->mb.pred_p8x8 + i / 2 * 16 * 8 + i % 2 * 8 + 16 * 4 + 4);
  769.     t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec =
  770.     t->mb.vec[0][i / 2 * 8 + i % 2 * 2 + 5] = s->vec[i][8];
  771.     return s->sad[i][5] + s->sad[i][6] + s->sad[i][7] + s->sad[i][8];
  772. }
  773. void
  774. T264_encode_inter_16x16p(_RW T264_t* t, uint8_t* pred)
  775. {
  776.     DECLARE_ALIGNED_MATRIX(dct, 16, 16, int16_t, 16);
  777.     int32_t qp = t->qp_y;
  778.     int32_t i;
  779.     int16_t* curdct;
  780.     t->expand8to16sub(pred, 16 / 4, 16 / 4, dct, t->mb.src_y, t->stride);
  781.     curdct = dct;
  782.     for(i = 0 ; i < 16 ; i ++)
  783.     {
  784.         t->fdct4x4(curdct);
  785.         t->quant4x4(curdct, qp, FALSE);
  786.         scan_zig_4x4(t->mb.dct_y_z[luma_index[i]], curdct);
  787.         t->iquant4x4(curdct, qp);
  788.         t->idct4x4(curdct);
  789.         curdct += 16;
  790.     }
  791.     t->contract16to8add(dct, 16 / 4, 16 / 4, pred, t->mb.dst_y, t->edged_stride);
  792. }
  793. void
  794. T264_encode_inter_y(_RW T264_t* t)
  795. {
  796.     T264_encode_inter_16x16p(t, t->mb.pred_p16x16[t->mb.mb_part]);
  797. }
  798. // NOTE: this routine will merge with T264_encode_intra_uv
  799. void
  800. T264_transform_inter_uv(_RW T264_t* t, uint8_t* pred_u, uint8_t* pred_v)
  801. {
  802.     DECLARE_ALIGNED_MATRIX(dct, 10, 8, int16_t, CACHE_SIZE);
  803.     int32_t qp = t->qp_uv;
  804.     int32_t i, j;
  805.     int16_t* curdct;
  806.     uint8_t* start;
  807.     uint8_t* dst;
  808.     uint8_t* src;
  809.     start = pred_u;
  810.     src   = t->mb.src_u;
  811.     dst   = t->mb.dst_u;
  812.     for(j = 0 ; j < 2 ; j ++)
  813.     {
  814.         t->expand8to16sub(start, 8 / 4, 8 / 4, dct, src, t->stride_uv);
  815.         curdct = dct;
  816.         for(i = 0 ; i < 4 ; i ++)
  817.         {
  818.             t->fdct4x4(curdct);
  819.             dct[64 + i] = curdct[0];
  820.             t->quant4x4(curdct, qp, FALSE);
  821.             scan_zig_4x4(t->mb.dct_uv_z[j][i], curdct);
  822.             t->iquant4x4(curdct, qp);
  823.             curdct += 16;
  824.         }
  825.         t->fdct2x2dc(curdct);
  826.         t->quant2x2dc(curdct, qp, FALSE);
  827.         scan_zig_2x2(t->mb.dc2x2_z[j], curdct);
  828.         t->iquant2x2dc(curdct, qp);
  829.         t->idct2x2dc(curdct);
  830.         curdct = dct;
  831.         for(i = 0 ; i < 4 ; i ++)
  832.         {
  833.             curdct[0] = dct[64 + i];
  834.             t->idct4x4(curdct);
  835.             curdct += 16;
  836.         }
  837.         t->contract16to8add(dct, 8 / 4, 8 / 4, start, dst, t->edged_stride_uv);
  838.         //
  839.         // change to v
  840.         //
  841.         start = pred_v;
  842.         dst   = t->mb.dst_v;
  843.         src   = t->mb.src_v;
  844.     }
  845. }
  846. void
  847. T264_encode_inter_uv(_RW T264_t* t)
  848. {
  849.     DECLARE_ALIGNED_MATRIX(pred_u, 8, 8, uint8_t, CACHE_SIZE);
  850.     DECLARE_ALIGNED_MATRIX(pred_v, 8, 8, uint8_t, CACHE_SIZE);
  851.     T264_vector_t vec;
  852.     uint8_t* src, *dst;
  853.     uint8_t* src_u, *dst_u;
  854.     int32_t i;
  855.     switch (t->mb.mb_part)
  856.     {
  857.     case MB_16x16:
  858.         vec = t->mb.vec[0][0];
  859.         src = t->refl0[vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  860.         dst = pred_u;
  861.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 8);
  862.         src = t->refl0[vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  863.         dst = pred_v;
  864.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 8);
  865.         break;
  866.     case MB_16x8:
  867.         vec = t->mb.vec[0][0];
  868.         src_u = t->refl0[vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  869.         dst_u = pred_u;
  870.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 8, 4);
  871.         src = t->refl0[vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  872.         dst = pred_v;
  873.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 4);
  874.         vec = t->mb.vec[0][luma_index[8]];
  875.         src_u = t->refl0[vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) +
  876.             4 * t->edged_stride_uv;
  877.         dst_u += 4 * 8;
  878.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 8, 4);
  879.         src = t->refl0[vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 
  880.             4 * t->edged_stride_uv;
  881.         dst += 4 * 8;
  882.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 8, 4);
  883.         break;
  884.     case MB_8x16:
  885.         vec = t->mb.vec[0][0];
  886.         src_u = t->refl0[vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  887.         dst_u = pred_u;
  888.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 8);
  889.         src = t->refl0[vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3);
  890.         dst = pred_v;
  891.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 8);
  892.         vec = t->mb.vec[0][luma_index[4]];
  893.         src_u = t->refl0[vec.refno]->U + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 4;
  894.         dst_u += 4;
  895.         t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 8);
  896.         src = t->refl0[vec.refno]->V + ((t->mb.mb_y << 3) + (vec.y >> 3)) * t->edged_stride_uv + (t->mb.mb_x << 3) + (vec.x >> 3) + 4;
  897.         dst += 4;
  898.         t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 8);
  899.         break;
  900.     case MB_8x8:
  901.     case MB_8x8ref0:
  902.         for(i = 0 ; i < 4 ; i ++)
  903.         {
  904.             switch(t->mb.submb_part[luma_index[4 * i]])
  905.             {
  906.             case MB_8x8:
  907.                 vec = t->mb.vec[0][luma_index[4 * i]];
  908.                 src = t->refl0[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);
  909.                 dst = pred_u + i / 2 * 32 + i % 2 * 4;
  910.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 4);
  911.                 src = t->refl0[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);
  912.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  913.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 4);
  914.                 break;
  915.             case MB_8x4:
  916.                 vec = t->mb.vec[0][luma_index[4 * i]];
  917.                 src_u = t->refl0[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);
  918.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  919.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 2);
  920.                 src = t->refl0[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);
  921.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  922.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 2);
  923.                 vec = t->mb.vec[0][luma_index[4 * i + 2]];
  924.                 src_u = t->refl0[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) + 
  925.                     2 * t->edged_stride_uv;
  926.                 dst_u += 2 * 8;
  927.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 4, 2);
  928.                 src = t->refl0[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) +
  929.                     2 * t->edged_stride_uv;
  930.                 dst += 2 * 8;
  931.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 4, 2);
  932.                 break;
  933.             case MB_4x8:
  934.                 vec = t->mb.vec[0][luma_index[4 * i]];
  935.                 src_u = t->refl0[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);
  936.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  937.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 4);
  938.                 src = t->refl0[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);
  939.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  940.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 4);
  941.                 vec = t->mb.vec[0][luma_index[4 * i + 1]];
  942.                 src_u = t->refl0[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;
  943.                 dst_u += 2;
  944.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 4);
  945.                 src = t->refl0[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;
  946.                 dst += 2;
  947.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 4);
  948.                 break;
  949.             case MB_4x4:
  950.                 vec = t->mb.vec[0][luma_index[4 * i]];
  951.                 src_u = t->refl0[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);
  952.                 dst_u = pred_u + i / 2 * 32 + i % 2 * 4;
  953.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  954.                 src = t->refl0[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);
  955.                 dst = pred_v + i / 2 * 32 + i % 2 * 4;
  956.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  957.                 vec = t->mb.vec[0][luma_index[4 * i + 1]];
  958.                 src_u = t->refl0[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;
  959.                 dst_u += 2;
  960.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  961.                 src = t->refl0[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;
  962.                 dst += 2;
  963.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  964.                 vec = t->mb.vec[0][luma_index[4 * i + 2]];
  965.                 src_u = t->refl0[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) + 
  966.                     2 * t->edged_stride_uv;
  967.                 dst_u += 2 * 8 - 2;
  968.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  969.                 src = t->refl0[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) + 
  970.                     2 * t->edged_stride_uv;
  971.                 dst += 2 * 8 - 2;
  972.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  973.                 vec = t->mb.vec[0][luma_index[4 * i + 3]];
  974.                 src_u = t->refl0[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) +
  975.                     2 * t->edged_stride_uv + 2;
  976.                 dst_u += 2;
  977.                 t->eighth_pixel_mc_u(src_u, t->edged_stride_uv, dst_u, vec.x, vec.y, 2, 2);
  978.                 src = t->refl0[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) + 
  979.                     2 * t->edged_stride_uv + 2;
  980.                 dst += 2;
  981.                 t->eighth_pixel_mc_u(src, t->edged_stride_uv, dst, vec.x, vec.y, 2, 2);
  982.                 break;
  983.             default:
  984.                 break;
  985.             }
  986.         }
  987.         break;
  988.     default:
  989.         break;
  990.     }
  991.     T264_transform_inter_uv(t, pred_u, pred_v);
  992. }