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

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. * 2005.1.4 CloudWu<sywu@sohu.com> modify diamond_search() 
  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 "stdio.h"
  24. #include "T264.h"
  25. #include "estimation.h"
  26. #ifndef CHIP_DM642
  27. #include "memory.h"
  28. #endif
  29. #include "assert.h"
  30. #include "bitstream.h"
  31. #include "inter.h"
  32. //overlapped check points 
  33. static int32_t
  34. check_vec(int32_t i, T264_vector_t* vec)
  35. {
  36.     int32_t j;
  37.     for(j = 0 ; j < i ; j ++)
  38.     {
  39.         if (vec[i].x == vec[j].x && vec[i].y == vec[j].y && vec[i].refno == vec[j].refno)
  40.             return 1;
  41.     }
  42.     return 0;
  43. }
  44. uint32_t
  45. T264_search(T264_t* t, T264_search_context_t* context)
  46. {
  47.     uint32_t sad = -1;
  48.     int32_t i;
  49.     int32_t best = 0;
  50.     T264_vector_t mv_pred;
  51.     int32_t limit_x = context->limit_x;
  52.     int32_t limit_y = context->limit_y;
  53.     int32_t stride_cur = t->stride;
  54.     int32_t stride_ref = t->edged_stride;
  55.     int32_t list_index = context->list_index;
  56.     // start point of current and reference block 
  57.     int32_t row = context->offset / t->edged_stride;
  58.     int32_t col = context->offset % t->edged_stride;
  59.     uint8_t* cur = t->cur.Y[0] + row * stride_cur + col;
  60.     uint8_t* ref_st;
  61.     uint8_t* ref;
  62.     int8_t best_ref_no;
  63.     //adaptive thresholds
  64.     uint32_t th0;
  65.     th0 = context->height * context->width; //256 for median predictor (16x16)
  66.     // try median vector
  67.     if (context->vec[0].refno >= 0)
  68.     {
  69.         // check this predictor
  70.         mv_pred.refno = context->vec[0].refno;
  71.         mv_pred.x = context->vec[0].x >> 2;
  72.         mv_pred.y = context->vec[0].y >> 2;
  73.         ref_st = t->ref[list_index][mv_pred.refno]->Y[0] + context->offset;
  74.         ref = ref_st + mv_pred.y * stride_ref + mv_pred.x;
  75.         sad = t->sad[context->mb_part](cur, stride_cur, ref, stride_ref) +
  76.             t->mb.lambda * (eg_size_se(t->bs, (mv_pred.x << 2) - context->vec[0].x) + 
  77.             eg_size_se(t->bs, (mv_pred.y << 2) - context->vec[0].y));
  78.         if (sad < th0)
  79.         {
  80.             context->vec_best = context->vec[0];
  81.             return sad;
  82.         }
  83.     }
  84.     // try other predictors (set A)
  85.     for (i = 1 ; i < context->vec_num ; i ++)
  86.     {
  87.         if (context->vec[i].refno >= 0)
  88.         {
  89.             if (!check_vec(i, context->vec)) //not checked before
  90.             {
  91.                 uint32_t cursad;
  92.                 // check this predictor
  93.                 mv_pred.refno = context->vec[i].refno;
  94.                 mv_pred.x = context->vec[i].x >> 2;
  95.                 mv_pred.y = context->vec[i].y >> 2;
  96.                 ref_st = t->ref[list_index][mv_pred.refno]->Y[0] + context->offset;
  97.                 ref = ref_st + mv_pred.y * stride_ref + mv_pred.x;
  98.                 cursad = t->sad[context->mb_part](cur, stride_cur, ref, stride_ref) +
  99.                     t->mb.lambda * (eg_size_se(t->bs, (mv_pred.x << 2) - context->vec[0].x) + 
  100.                     eg_size_se(t->bs, (mv_pred.y << 2) - context->vec[0].y));
  101.                 if (cursad < sad)
  102.                 {
  103.                     best = i;
  104.                     sad = cursad;
  105.                 }
  106.             }
  107.         }
  108.     }
  109.     context->vec_best = context->vec[best];
  110.     if (sad < th0)
  111.         return sad;
  112.     // ref_st of best reference frame
  113.     if (context->vec[best].refno >= 0)
  114.     {
  115.         best_ref_no = context->vec[best].refno;
  116.     }
  117.     else
  118.     {
  119.         context->vec_best.refno = 0;
  120.         context->vec_best.x = context->vec_best.y = best_ref_no = 0;
  121.     }
  122.     ref_st = t->ref[list_index][best_ref_no]->Y[0] + context->offset;
  123.     // diamond search 
  124.     /* small diamond is the fastest, square diamond has slightly gain lower bitrate and
  125.           pull the speed down severely. LDSP + SDSP maybe have some problem... */
  126. //*/
  127.     sad = small_diamond_search(t, cur, ref_st, context, stride_cur, stride_ref, sad);
  128. /*/
  129.     sad = square_diamond_search(t, cur, ref_st, context, stride_cur, stride_ref, sad);
  130. /*//*
  131.     sad = diamond_search(t, cur, ref_st, context, stride_cur, stride_ref, sad);
  132. //*/
  133.     return sad;
  134. }
  135. uint32_t
  136. small_diamond_search(T264_t* t, uint8_t* cur, uint8_t* ref_st, T264_search_context_t* context, int32_t stride_cur, int32_t stride_ref, uint32_t sad)
  137. {
  138.     int32_t limit_x = context->limit_x;
  139.     int32_t limit_y = context->limit_y;
  140.     //start mv
  141.     int32_t mvx = context->vec_best.x >> 2;
  142.     int32_t mvy = context->vec_best.y >> 2;
  143.     // sad for start mv
  144.     uint8_t* ref;
  145.     uint8_t* better_ref;
  146.     int32_t better_mvx;
  147.     int32_t better_mvy;
  148.     uint32_t cursad;
  149.     uint8_t stop = 0;
  150.     ref_st += mvy * stride_ref + mvx;
  151.     better_mvx = mvx;
  152.     better_mvy = mvy;
  153.     better_ref = ref_st;
  154.     while(!stop)
  155.     {
  156.         stop = 1;
  157.         // search 4 points of sdsp
  158.         {
  159. #define CHECK_CANDIDATE(x_offset, y_offset, ref_offset) ref = ref_st + ref_offset;  
  160.                         cursad = t->sad[context->mb_part](cur, stride_cur, ref, stride_ref) +   
  161.                                  t->mb.lambda * (eg_size_se(t->bs, ((mvx + x_offset) << 2) - context->vec[0].x) +   
  162.                                  eg_size_se(t->bs, ((mvy + y_offset) << 2) - context->vec[0].y));   
  163.                         if (cursad < sad)   
  164.                         {   
  165.                             sad = cursad;   
  166.                             better_ref = ref;   
  167.                             better_mvx = mvx + x_offset;    
  168.                             better_mvy = mvy + y_offset;    
  169.                             /* need search more*/   
  170.                             stop = 0;   
  171.                         }
  172.             // left
  173.             CHECK_CANDIDATE(-1, 0, -1);
  174.             // right
  175.             CHECK_CANDIDATE(1, 0, 1);
  176.             // top
  177.             CHECK_CANDIDATE(0, -1, -stride_ref);
  178.             // bottom
  179.             CHECK_CANDIDATE(0, 1, stride_ref);
  180.         }
  181.         mvx = better_mvx;
  182.         mvy = better_mvy;
  183.         ref_st = better_ref;
  184.         if (ABS(mvx) > limit_x || ABS(mvy) > limit_y)
  185.         {
  186.             break;
  187.         }
  188.     }
  189.     // final mv
  190.     context->vec_best.x = mvx << 2;
  191.     context->vec_best.y = mvy << 2;
  192.     // mostly we use sad as cmp function
  193.     if (t->cmp[context->mb_part] == t->sad[context->mb_part])
  194.         return sad;
  195.     ref = ref_st + mvy * stride_ref + mvx;
  196.     sad = t->cmp[context->mb_part](cur, stride_cur, ref, stride_ref) +
  197.         t->mb.lambda * (eg_size_se(t->bs, context->vec_best.x - context->vec[0].x) + 
  198.         eg_size_se(t->bs, context->vec_best.y - context->vec[0].y));
  199.     return sad;
  200. }
  201. uint32_t 
  202. square_diamond_search(T264_t* t, uint8_t* cur, uint8_t* ref_st, T264_search_context_t* context, int32_t stride_cur, int32_t stride_ref, uint32_t sad)
  203. {
  204.     int32_t limit_x = context->limit_x;
  205.     int32_t limit_y = context->limit_y;
  206.     //start mv
  207.     int32_t mvx = context->vec_best.x >> 2;
  208.     int32_t mvy = context->vec_best.y >> 2;
  209.     // sad for start mv
  210.     uint32_t cursad;
  211.     uint8_t* ref;
  212.     uint8_t stop = 0;
  213.     uint8_t* better_ref;
  214.     int32_t better_mvx;
  215.     int32_t better_mvy;
  216.     // start mv is zero?
  217.     if(mvx == 0 && mvy == 0)
  218.         return small_diamond_search(t, cur, ref_st, context, stride_cur, stride_ref, sad);
  219.     ref_st += mvy * stride_ref + mvx;
  220.     better_mvx = mvx;
  221.     better_mvy = mvy;
  222.     better_ref = ref_st;
  223.     while(!stop)
  224.     {
  225.         stop = 1;
  226.         // search 8 points of sdsp
  227.         {
  228.             // left
  229.             CHECK_CANDIDATE(-1, 0, -1);
  230.             // right
  231.             CHECK_CANDIDATE(1, 0, 1);
  232.             // top-left
  233.             CHECK_CANDIDATE(-1, -1, -stride_ref - 1);
  234.             // top
  235.             CHECK_CANDIDATE(0, -1, -stride_ref);
  236.             // top-right
  237.             CHECK_CANDIDATE(1, -1, -stride_ref + 1);
  238.             // bottom-left
  239.             CHECK_CANDIDATE(-1, 1, stride_ref - 1);
  240.             // bottom
  241.             CHECK_CANDIDATE(0, 1, stride_ref);
  242.             // bottom-right
  243.             CHECK_CANDIDATE(1, 1, stride_ref + 1);
  244.         }
  245.         mvx = better_mvx;
  246.         mvy = better_mvy;
  247.         ref_st = better_ref;
  248.         if (ABS(mvx) > limit_x || ABS(mvy) > limit_y)
  249.         {
  250.             break;
  251.         }
  252.     }
  253.     // final mv
  254.     context->vec_best.x = mvx << 2;
  255.     context->vec_best.y = mvy << 2;
  256.     // mostly we use sad as cmp function
  257.     if (t->cmp[context->mb_part] == t->sad[context->mb_part])
  258.         return sad;
  259.     ref = ref_st + mvy * stride_ref + mvx;
  260.     sad = t->cmp[context->mb_part](cur, stride_cur, ref, stride_ref) +
  261.         t->mb.lambda * (eg_size_se(t->bs, context->vec_best.x - context->vec[0].x) + 
  262.         eg_size_se(t->bs, context->vec_best.y - context->vec[0].y));
  263.     return sad;
  264. }
  265. uint32_t
  266. diamond_search(T264_t* t, uint8_t* cur, uint8_t* ref_st, T264_search_context_t* context, int32_t stride_cur, int32_t stride_ref, uint32_t sad)
  267. {
  268.     int32_t limit_x = context->limit_x;
  269.     int32_t limit_y = context->limit_y;
  270.     //start mv
  271.     int32_t mvx = context->vec_best.x >> 2;
  272.     int32_t mvy = context->vec_best.y >> 2;
  273.     // sad for start mv
  274.     uint8_t* ref;
  275.     uint8_t* better_ref;
  276.     int32_t better_mvx;
  277.     int32_t better_mvy;
  278.     uint32_t cursad;
  279.     uint8_t stop = 0;
  280.     ref_st += mvy * stride_ref + mvx;
  281.     better_mvx = mvx;
  282.     better_mvy = mvy;
  283.     better_ref = ref_st;
  284.     // large diamond
  285.     while(!stop)
  286.     {
  287.         stop = 1;
  288.         // search 8 points of ldsp
  289.         {
  290.             // left
  291.             CHECK_CANDIDATE(-2, 0, -2);
  292.             // right
  293.             CHECK_CANDIDATE(2, 0, 2);
  294.             // top
  295.             CHECK_CANDIDATE(0, -2, -(stride_ref << 1));
  296.             // bottom
  297.             CHECK_CANDIDATE(0, 2, (stride_ref << 1));
  298.             // top-left
  299.             CHECK_CANDIDATE(-1, -1, -stride_ref - 1);
  300.             // top-right
  301.             CHECK_CANDIDATE(1, -1, -stride_ref + 1);
  302.             // bottom-left
  303.             CHECK_CANDIDATE(-1, 1, stride_ref - 1);
  304.             // bottom-right
  305.             CHECK_CANDIDATE(1, 1, stride_ref + 1);
  306.         }
  307.         mvx = better_mvx;
  308.         mvy = better_mvy;
  309.         ref_st = better_ref;
  310.         if (ABS(mvx) > limit_x || ABS(mvy) > limit_y)
  311.         {
  312.             break;
  313.         }
  314.     }
  315.     // small diamond
  316. stop = 0;
  317.     while(!stop)
  318.     {
  319.         stop = 1;
  320.         // search 4 points of sdsp
  321.         {
  322.             // left
  323.             CHECK_CANDIDATE(-1, 0, -1);
  324.             // right
  325.             CHECK_CANDIDATE(1, 0, 1);
  326.             // top
  327.             CHECK_CANDIDATE(0, -1, -stride_ref);
  328.             // bottom
  329.             CHECK_CANDIDATE(0, 1, stride_ref);
  330.         }
  331.         mvx = better_mvx;
  332.         mvy = better_mvy;
  333.         ref_st = better_ref;
  334.         if (ABS(mvx) > limit_x || ABS(mvy) > limit_y)
  335.         {
  336.             break;
  337.         }
  338.     }
  339.     // final mv
  340.     context->vec_best.x = mvx << 2;
  341.     context->vec_best.y = mvy << 2;
  342.     // mostly we use sad as cmp function
  343.     if (t->cmp[context->mb_part] == t->sad[context->mb_part])
  344.         return sad;
  345.     ref = ref_st + mvy * stride_ref + mvx;
  346.     sad = t->cmp[context->mb_part](cur, stride_cur, ref, stride_ref) +
  347.         t->mb.lambda * (eg_size_se(t->bs, context->vec_best.x - context->vec[0].x) + 
  348.         eg_size_se(t->bs, context->vec_best.y - context->vec[0].y));
  349.     return sad;
  350. }
  351. /*
  352. * Full Search
  353. */
  354. uint32_t
  355. T264_search_full(T264_t* t, T264_search_context_t* context)
  356. {
  357.     uint32_t sad;
  358.     uint32_t cursad;
  359.     int32_t i, j;
  360.     int16_t mb_xy = t->mb.mb_xy;
  361.     int16_t mb_x = t->mb.mb_x;
  362.     int16_t mb_y = t->mb.mb_y;
  363.     int32_t height = context->height;
  364.     int32_t width = context->width;
  365.     int32_t limit_x = context->limit_x;
  366.     int32_t limit_y = context->limit_y;
  367.     int32_t stride_cur = t->stride;
  368.     int32_t stride_ref = t->edged_stride;
  369.     int32_t list_index = context->list_index;
  370.     // start point of current and reference block 
  371.     int32_t row = context->offset / t->edged_stride;
  372.     int32_t col = context->offset % t->edged_stride;
  373.     uint8_t* cur = t->cur.Y[0] + row * stride_cur + col;
  374.     uint8_t* ref_st = t->ref[list_index][0]->Y[0] + row * stride_ref + col;
  375.     uint8_t* ref;
  376.     context->vec_best.refno = 0;
  377.     // full search
  378.     sad = width * height * 255;
  379.     for(i = -limit_y + (context->vec[0].y >> 2); i <= (limit_y + (context->vec[0].y >> 2)) ; i++)
  380.         for(j = -limit_x + (context->vec[0].x >> 2); j <= (limit_x + (context->vec[0].x >> 2)) ; j++)
  381.         {
  382.             ref = ref_st + i * stride_ref + j;
  383.             cursad = t->sad[context->mb_part](cur, stride_cur, ref, stride_ref) +
  384.                 t->mb.lambda * (eg_size_se(t->bs, (j << 2) - context->vec[0].x) + 
  385.                 eg_size_se(t->bs, (i << 2) - context->vec[0].y));
  386.             if(cursad < sad)
  387.             {
  388.                 sad = cursad;
  389.                 context->vec_best.y = i;
  390.                 context->vec_best.x = j;
  391.             }
  392.         }
  393.         ref = ref_st + context->vec_best.y * stride_ref + context->vec_best.x;
  394.         context->vec_best.y <<= 2;
  395.         context->vec_best.x <<= 2;
  396.         sad = t->cmp[context->mb_part](cur, t->stride, ref, t->edged_stride) +
  397.             t->mb.lambda * (eg_size_se(t->bs, context->vec_best.x - context->vec[0].x) + 
  398.             eg_size_se(t->bs, context->vec_best.y - context->vec[0].y));
  399.         return sad;
  400. }
  401. // xxx, never used, just for compare to jm80.
  402. uint32_t
  403. T264_spiral_search_full(T264_t* t, T264_search_context_t* context)
  404. {
  405.     uint32_t sad;
  406.     uint32_t cursad;
  407.     int32_t i, j, k, l;
  408.     int16_t mb_xy = t->mb.mb_xy;
  409.     int16_t mb_x = t->mb.mb_x;
  410.     int16_t mb_y = t->mb.mb_y;
  411.     int32_t height = context->height;
  412.     int32_t width = context->width;
  413.     int32_t limit_x = context->limit_x;
  414.     int32_t limit_y = context->limit_y;
  415.     int32_t stride_cur = t->stride;
  416.     int32_t stride_ref = t->edged_stride;
  417.     int32_t list_index = context->list_index;
  418.     // start point of current and reference block 
  419.     int32_t row = context->offset / t->edged_stride;
  420.     int32_t col = context->offset % t->edged_stride;
  421.     uint8_t* cur = t->cur.Y[0] + row * stride_cur + col;
  422.     uint8_t* ref_st = t->ref[list_index][context->vec[0].refno]->Y[0] + row * stride_ref + col;
  423.     uint8_t* ref;
  424.     int32_t spiral_search_x[33 * 33];
  425.     int32_t spiral_search_y[33 * 33];
  426.     context->vec_best.refno = context->vec[0].refno;
  427.     spiral_search_x[0] = spiral_search_y[0] = 0;
  428.     for (k=1, l=1; l<=T264_MAX(1,16); l++)
  429.     {
  430.         for (i=-l+1; i< l; i++)
  431.         {
  432.             spiral_search_x[k] = l;  spiral_search_y[k++] =  i;
  433.             spiral_search_x[k] =  -l;  spiral_search_y[k++] =  i;
  434.         }
  435.         for (i=-l;   i<=l; i++)
  436.         {
  437.             spiral_search_x[k] =  i;  spiral_search_y[k++] = l;
  438.             spiral_search_x[k] =  i;  spiral_search_y[k++] =  -l;
  439.         }
  440.     }
  441.     // full search
  442.     sad = width * height * 255;
  443.     for(k = 0 ; k < 33 * 33 ; k ++)
  444.     {
  445.         i = (context->vec[0].y / 4) + spiral_search_y[k];
  446.         j = (context->vec[0].x / 4) + spiral_search_x[k];
  447.         ref = ref_st + i * stride_ref + j;
  448.         cursad = t->sad[context->mb_part](cur, stride_cur, ref, stride_ref) +
  449.             t->mb.lambda * (eg_size_se(t->bs, (j << 2) - context->vec[0].x) + 
  450.             eg_size_se(t->bs, (i << 2) - context->vec[0].y));
  451.         if(cursad < sad)
  452.         {
  453.             sad = cursad;
  454.             context->vec_best.y = i;
  455.             context->vec_best.x = j;
  456.         }
  457.     }
  458.     ref = ref_st + context->vec_best.y * stride_ref + context->vec_best.x;
  459.     context->vec_best.y <<= 2;
  460.     context->vec_best.x <<= 2;
  461.     sad = t->cmp[context->mb_part](cur, t->stride, ref, t->edged_stride) +
  462.         t->mb.lambda * (eg_size_se(t->bs, context->vec_best.x - context->vec[0].x) + 
  463.         eg_size_se(t->bs, context->vec_best.y - context->vec[0].y));
  464.     return sad;
  465. }