wp_lms.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:30k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2. *************************************************************************************
  3. * file wp_lms.c
  4. *
  5. * brief
  6. *    Estimate weights for WP using LMS method
  7. *
  8. * author
  9. *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10. *     - Alexis Michael Tourapis         <alexismt@ieee.org>
  11. *     - Athanasios Leontaris            <aleon@dolby.com>
  12. *************************************************************************************
  13. */
  14. #include "contributors.h"
  15. #include "global.h"
  16. #include "image.h"
  17. #include "wp.h"
  18. static inline double ComputeNormMean(imgpel **CurrentImage, double mean_value, int height, int width)
  19. {
  20.   int i, j;
  21.   double sum_value = 0.0;
  22.   for (i = 0; i < height; i++)
  23.   {
  24.     for (j = 0; j < width; j++)
  25.     {
  26.       sum_value += dabs((double) CurrentImage[i][j] - mean_value);
  27.     }
  28.   }
  29.   return sum_value;
  30. }
  31. /*!
  32. ************************************************************************
  33. * brief
  34. *    Estimates reference picture weighting factors for P slices
  35. ************************************************************************
  36. */
  37. void EstimateWPPSliceAlg1(ImageParameters *img, InputParameters *params, int select_offset)
  38. {
  39.   double dc_org = 0.0;
  40.   double dc_org_UV[2] = {0.0};
  41.   double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  42.   double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}};
  43.   double norm_org = 0.0;
  44.   double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  45.   double numer = {0.0};
  46.   double denom[MAX_REFERENCE_PICTURES] = {0.0};  
  47.   int i, n, k;
  48.   int default_weight[3];
  49.   int list_offset   = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
  50.   int weight[2][MAX_REFERENCE_PICTURES][3];
  51.   int offset[2][MAX_REFERENCE_PICTURES][3];
  52.   int clist;
  53.   imgpel **tmpPtr;
  54.   luma_log_weight_denom   = 5;
  55.   chroma_log_weight_denom = 5;
  56.   wp_luma_round           = 1 << (luma_log_weight_denom - 1);
  57.   wp_chroma_round         = 1 << (chroma_log_weight_denom - 1);
  58.   default_weight[0]       = 1 << luma_log_weight_denom;
  59.   default_weight[1]       = default_weight[2] = 1 << chroma_log_weight_denom;
  60.   
  61.   dc_org = ComputeImgSum(pCurImg, img->height, img->width);
  62.   norm_org = dc_org / ((double) img->size);
  63.   numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width);
  64.   if (params->ChromaWeightSupport == 1)
  65.   {
  66.     for (k = 0; k < 2; k++)
  67.     {
  68.       dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr);
  69.     } 
  70.   }
  71.   for (clist = 0; clist < 2 + list_offset; clist++)
  72.   {
  73.     for (n = 0; n < listXsize[clist]; n++)
  74.     {
  75.       if ( wpxDetermineWP( params, img, clist, n ) )
  76.       {
  77.         /* set all values to defaults */
  78.         for (i = 0; i < 3; i++)
  79.         {
  80.           weight[clist][n][i]    = default_weight[i];
  81.           wp_weight[clist][n][i] = default_weight[i];
  82.           wp_offset[clist][n][i] = 0;
  83.           offset[clist][n][i]    = 0;
  84.         }
  85.         // Y
  86.         tmpPtr = listX[clist][n]->p_curr_img;      
  87.         dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width);
  88.         norm_ref[n] = dc_ref[n] / ((double) img->size);
  89.         denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width);
  90.         if (params->ChromaWeightSupport == 1)
  91.         {
  92.           for (k = 0; k < 2; k++)
  93.           {
  94.             // UV
  95.             tmpPtr = listX[clist][n]->imgUV[k];
  96.             dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr);
  97.           }        
  98.         }
  99.         if (select_offset == 0)
  100.         {
  101.           if (denom[n] != 0)
  102.             weight[clist][n][0] = (int) (default_weight[0] * numer / denom[n] + 0.5);
  103.           else
  104.             weight[clist][n][0] = default_weight[0];  // only used when reference picture is black
  105.           weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]);
  106.           offset[clist][n][0] = (int) (norm_org - ((double) weight[clist][n][0] * norm_ref[n] / (double) default_weight[0]) + 0.5);
  107.           offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8);
  108.           offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]);
  109.           offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8);
  110.           if (params->ChromaWeightSupport == 1)
  111.           {
  112.             if (dc_ref_UV[n][0] != 0)
  113.               weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5);
  114.             else
  115.               weight[clist][n][1] = default_weight[1];  // only used when reference picture is black
  116.             weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]);
  117.             if (dc_ref_UV[n][1] != 0)
  118.               weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5);
  119.             else
  120.               weight[clist][n][2] = default_weight[2];  // only used when reference picture is black
  121.             weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]);
  122.           }
  123.         }
  124.         else
  125.         {
  126.           offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5);
  127.           offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8);
  128.           offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]);
  129.           offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8);
  130.           weight[clist][n][0] = default_weight[0];
  131.           if (params->ChromaWeightSupport == 1)
  132.           {
  133.             offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5);
  134.             offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8);
  135.             offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]);
  136.             offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8);
  137.             
  138.             weight[clist][n][1] = default_weight[1];
  139.             offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5);
  140.             offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8);
  141.             offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]);
  142.             offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8);
  143.             weight[clist][n][2] = default_weight[2];
  144.           }
  145.         }
  146.         for (i=0; i < 3; i ++)
  147.         {
  148.           wp_weight[clist][n][i] = weight[clist][n][i];
  149.           wp_offset[clist][n][i] = offset[clist][n][i];
  150. #if DEBUG_WP
  151.           printf("index %d component %d weight %d offset %dn",n,i,weight[0][n][i],offset[0][n][i]);
  152. #endif
  153.         }
  154.       }
  155.     }
  156.   }
  157. }
  158. /*!
  159. ************************************************************************
  160. * brief
  161. *    Estimates reference picture weighting factors for B slices
  162. ************************************************************************
  163. */
  164. void EstimateWPBSliceAlg1(ImageParameters *img, InputParameters *params)
  165. {
  166.   int i, j, n;
  167.   int tx,DistScaleFactor;
  168.   int index;
  169.   int comp;
  170.   double dc_org = 0.0;
  171.   double dc_org_UV[2] = { 0.0 };
  172.   double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} };
  173.   double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} };
  174.   double norm_org = 0.0;
  175.   double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  176.   double numer = {0.0};
  177.   double denom[MAX_REFERENCE_PICTURES] = {0.0};
  178.   int k;
  179.   int default_weight[3];
  180.   int list_offset   = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
  181.   int weight[6][MAX_REFERENCE_PICTURES][3];
  182.   int offset[6][MAX_REFERENCE_PICTURES][3];
  183.   int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3];
  184.   int clist;
  185.   int wf_weight, wf_offset;
  186.   imgpel **tmpPtr;
  187.   if (active_pps->weighted_bipred_idc == 2) //! implicit mode. Values are fixed and it is important to show it here
  188.   {
  189.     luma_log_weight_denom = 5;
  190.     chroma_log_weight_denom = 5;
  191.   }
  192.   else                                     //! explicit mode. Values can be changed for higher precision.
  193.   {
  194.     luma_log_weight_denom = 5;
  195.     chroma_log_weight_denom = 5;
  196.   }
  197.   wp_luma_round     = 1 << (luma_log_weight_denom - 1);
  198.   wp_chroma_round   = 1 << (chroma_log_weight_denom - 1);
  199.   default_weight[0] = 1 << luma_log_weight_denom;
  200.   default_weight[1] = 1 << chroma_log_weight_denom;
  201.   default_weight[2] = 1 << chroma_log_weight_denom;
  202.   if (active_pps->weighted_bipred_idc == 2) //! implicit mode
  203.   {
  204.     for (i = 0; i < listXsize[LIST_0]; i++)
  205.     {
  206.       for (j = 0; j < listXsize[LIST_1]; j++)
  207.       {
  208.         int td, tb;
  209.         td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc));
  210.         tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc));
  211.         for (comp = 0; comp < 3; comp++)
  212.         {
  213.           // implicit weights
  214.           if (td == 0)
  215.           {
  216.             im_weight[0][i][j][comp] = default_weight[comp];
  217.             im_weight[1][i][j][comp] = default_weight[comp];
  218.           }
  219.           else
  220.           {
  221.             tx = (16384 + iabs(td/2))/td;
  222.             DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
  223.             im_weight[1][i][j][comp] = DistScaleFactor>>2;
  224.             if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128)
  225.               im_weight[1][i][j][comp] = default_weight[comp];
  226.             im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp];
  227.           }
  228.         }
  229. #if DEBUG_WP
  230.         printf ("%d imp weight[%d][%d] = %d  , %d (%d %d %d) (%d %d) (%d %d)n",enc_picture->poc, i, j,  im_weight[0][i][j][0], im_weight[1][i][j][0],
  231.         enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc,
  232.         DistScaleFactor ,tx,td,tb);
  233. #endif
  234.       }
  235.     }
  236.     for (k = 0; k < 2; k++)
  237.     {
  238.       for (i = 0; i < listXsize[LIST_0]; i++)
  239.       {
  240.         for (j = 0; j < listXsize[LIST_1]; j++)
  241.         {
  242.           for (comp = 0; comp < 3; comp++)
  243.           {
  244.             wbp_weight[k][i][j][comp] = im_weight[k][i][j][comp];
  245.           }
  246.         }
  247.       }
  248.     }
  249.     for (clist=0; clist<2 + list_offset; clist++)
  250.     {
  251.       for (index = 0; index < listXsize[clist]; index++)
  252.       {
  253.         for (comp = 0; comp < 3; comp++)
  254.         {
  255.           wp_weight[clist][index][comp] = default_weight[comp];
  256.           wp_offset[clist][index][comp] = 0;
  257.         }
  258.       }
  259.     }
  260.   }
  261.   else // explicit WP mode (or no WP at all)
  262.   {
  263.     dc_org = ComputeImgSum(pCurImg, img->height, img->width);
  264.     if (params->EnhancedBWeightSupport)
  265.     {
  266.       norm_org = dc_org / ((double) img->size);
  267.       numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width);
  268.     }
  269.     if (params->ChromaWeightSupport == 1)
  270.     {
  271.       for (k = 0; k < 2; k++)
  272.       {
  273.         dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr);
  274.       } 
  275.     }
  276.     for (clist=0; clist<2 + list_offset; clist++)
  277.     {
  278.       for (n = 0; n < listXsize[clist]; n++)
  279.       {
  280.         if ( wpxDetermineWP( params, img, clist, n ) )
  281.         {
  282.           /* set all values to defaults */
  283.           for (i = 0; i < 3; i++)
  284.           {
  285.             wp_weight[clist][n][i] = default_weight[i];
  286.             wp_offset[clist][n][i] = 0;
  287.             offset   [clist][n][i] = 0;
  288.             weight   [clist][n][i] = default_weight[i];
  289.           }
  290.           // To simplify these computations we may wish to perform these after a reference is 
  291.           // stored in the reference buffer and attach them to the storedimage structure!!!
  292.           // Y
  293.           tmpPtr = listX[clist][n]->p_curr_img;
  294.           dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width);
  295.           if (params->EnhancedBWeightSupport)
  296.           {
  297.             norm_ref[n] = dc_ref[clist][n] / ((double) img->size);
  298.             denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width);
  299.           }
  300.           if (params->EnhancedBWeightSupport)
  301.           {
  302.             if (denom[n] != 0)
  303.               wf_weight = (int) (default_weight[0] * numer / denom[n] + 0.5);
  304.             else
  305.               wf_weight = default_weight[0];  // only used when reference picture is black
  306.             wf_weight = iClip3(-128, 127, wf_weight);
  307.             wf_offset = (int) (norm_org - ((double) wf_weight * norm_ref[n] / (double) default_weight[0]) + 0.5);
  308.             wf_offset = (wf_offset + ((img->bitdepth_luma - 8)>>1))>>(img->bitdepth_luma-8);
  309.             wf_offset = iClip3( -128, 127, wf_offset);
  310.             wf_offset = wf_offset <<(img->bitdepth_luma - 8);
  311.           }
  312.           else
  313.           {
  314.             if (dc_ref[clist][n] != 0.0)
  315.               wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5);
  316.             else
  317.               wf_weight = default_weight[0];  // only used when reference picture is black
  318.             wf_weight = iClip3(-128, 127, wf_weight);
  319.             wf_offset = 0;
  320.           }
  321.           //    printf("dc_org = %d, dc_ref = %d, weight[%d] = %dn",dc_org, dc_ref[n],n,weight[n][0]);
  322.           weight[clist][n][0] = wf_weight;
  323.           offset[clist][n][0] = wf_offset;
  324.           // UV
  325.           if (params->ChromaWeightSupport == 1)
  326.           {          
  327.             for (k = 0; k < 2; k++)
  328.             {        
  329.               tmpPtr = listX[clist][n]->imgUV[k];
  330.               dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr);
  331.               if (dc_ref_UV[clist][n][k] != 0.0)
  332.                 wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5);
  333.               else
  334.                 wf_weight = default_weight[k + 1];  // only used when reference picture is black
  335.               wf_weight = iClip3(-128, 127, wf_weight);
  336.               wf_offset = 0;
  337.               weight[clist][n][k + 1] = wf_weight;
  338.               offset[clist][n][k + 1] = wf_offset;
  339.             }
  340.           }
  341.           else
  342.           {
  343.             weight[clist][n][1] = default_weight[1];
  344.             weight[clist][n][2] = default_weight[2];        
  345.             offset[clist][n][1] = 0;
  346.             offset[clist][n][2] = 0;
  347.           }
  348.           for (i = 0; i < 3; i++)
  349.           {
  350.             wp_weight[clist][n][i] = weight[clist][n][i];
  351.             wp_offset[clist][n][i] = offset[clist][n][i];
  352. #if DEBUG_WP
  353.             printf("%d %dn",wp_weight[clist][index][comp],wp_offset[clist][index][comp]);
  354. #endif
  355.           }
  356.         }
  357.       }
  358.     }
  359.     if (active_pps->weighted_bipred_idc != 1)
  360.     {
  361.       for (clist=0; clist<2 + list_offset; clist++)
  362.       {
  363.         for (index = 0; index < listXsize[clist]; index++)
  364.         {
  365.           memcpy(wp_weight[clist][index], default_weight, 3 * sizeof(int));
  366.           memset(wp_offset[clist][index], 0, 3 * sizeof(int));
  367.         }
  368.       }
  369.     }
  370.     for (i = 0; i < listXsize[LIST_0]; i++)
  371.     {
  372.       for (j = 0; j < listXsize[LIST_1]; j++)
  373.       {
  374.         for (comp = 0; comp < 3; comp++)
  375.         {
  376.           wbp_weight[0][i][j][comp] = wp_weight[0][i][comp];
  377.           wbp_weight[1][i][j][comp] = wp_weight[1][j][comp];
  378.         }
  379. #if DEBUG_WP
  380.         printf ("bpw weight[%d][%d] = %d  , %d (%d %d %d) (%d %d) (%d %d)n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0],
  381.         enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc,
  382.         DistScaleFactor ,tx,tx,tx);
  383. #endif
  384.       }
  385.     }
  386.   }
  387. }
  388. /*!
  389. ************************************************************************
  390. * brief
  391. *    Tests P slice weighting factors to perform or not WP RD decision
  392. ************************************************************************
  393. */
  394. int TestWPPSliceAlg1(ImageParameters *img, InputParameters *params, int select_offset)
  395. {
  396.   int i, j, k, n;
  397.   int index;
  398.   int comp;
  399.   double dc_org = 0.0;
  400.   double dc_org_UV[2] = {0.0};  
  401.   double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  402.   double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}};
  403.   double norm_org = 0.0;
  404.   double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  405.   double numer = {0.0};
  406.   double denom[MAX_REFERENCE_PICTURES] = {0.0};
  407.   int default_weight[3];
  408.   int list_offset   = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
  409.   int weight[2][MAX_REFERENCE_PICTURES][3];
  410.   int offset[2][MAX_REFERENCE_PICTURES][3];
  411.   int clist;
  412.   int perform_wp = 0;
  413.   imgpel **tmpPtr;
  414.   luma_log_weight_denom =   5;
  415.   chroma_log_weight_denom = 5;
  416.   wp_luma_round     = 1 << (luma_log_weight_denom - 1);
  417.   wp_chroma_round   = 1 << (chroma_log_weight_denom - 1);
  418.   default_weight[0] = 1 << luma_log_weight_denom;
  419.   default_weight[1] = default_weight[2] = 1 << chroma_log_weight_denom;
  420.   /* set all values to defaults */
  421.   for (i = 0; i < 2 + list_offset; i++)
  422.   {
  423.     for (j = 0; j < listXsize[i]; j++)
  424.     {
  425.       for (n = 0; n < 3; n++)
  426.       {
  427.         weight[i][j][n] = default_weight[n];
  428.         wp_weight[i][j][n] = default_weight[n];
  429.         wp_offset[i][j][n] = 0;
  430.         offset[i][j][n] = 0;
  431.       }
  432.     }
  433.   }
  434.   dc_org = ComputeImgSum(pCurImg, img->height, img->width);
  435.   norm_org = dc_org / ((double) img->size);
  436.   numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width);
  437.   if (params->ChromaWeightSupport == 1)
  438.   {
  439.     for (k = 0; k < 2; k++)
  440.     {
  441.       dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr);
  442.     } 
  443.   }
  444.   for (clist = 0; clist < 2 + list_offset; clist++)
  445.   {
  446.     for (n = 0; n < listXsize[clist]; n++)
  447.     {
  448.       tmpPtr = listX[clist][n]->p_curr_img;
  449.       dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width);
  450.       norm_ref[n] = dc_ref[n] / ((double) img->size);
  451.       denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width);
  452.       if (params->ChromaWeightSupport == 1)
  453.       {
  454.         for (k = 0; k < 2; k++)
  455.         {
  456.           tmpPtr = listX[clist][n]->imgUV[k];
  457.           dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr);
  458.         }        
  459.       }
  460.       if (select_offset == 0)
  461.       {
  462.         if (denom[n] != 0)
  463.           weight[clist][n][0] = (int) (default_weight[0] * numer / denom[n] + 0.5);
  464.         else
  465.           weight[clist][n][0] = default_weight[0];  // only used when reference picture is black
  466.         weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]);
  467.         offset[clist][n][0] = (int) (norm_org - ((double) weight[clist][n][0] * norm_ref[n] / (double) default_weight[0]) + 0.5);
  468.         offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8);
  469.         offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]);
  470.         offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8);       
  471.         if (params->ChromaWeightSupport == 1)
  472.         {
  473.           if (dc_ref_UV[n][0] != 0)
  474.             weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5);
  475.           else
  476.             weight[clist][n][1] = default_weight[1];  // only used when reference picture is black
  477.           weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]);
  478.           if (dc_ref_UV[n][1] != 0)
  479.             weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5);
  480.           else
  481.             weight[clist][n][2] = default_weight[2];  // only used when reference picture is black
  482.           weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]);
  483.         }
  484.       }
  485.       else
  486.       {
  487.         offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5);
  488.         offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8);
  489.         offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]);
  490.         offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8);
  491.         weight[clist][n][0] = default_weight[0];
  492.         if (params->ChromaWeightSupport == 1)
  493.         {
  494.             offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5);
  495.             offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8);
  496.             offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]);
  497.             offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8);
  498.             
  499.             weight[clist][n][1] = default_weight[1];
  500.             offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5);
  501.             offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8);
  502.             offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]);
  503.             offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8);
  504.             weight[clist][n][2] = default_weight[2];
  505.         }
  506.       }
  507.     }
  508.   }
  509.   for (clist=0; clist<2 + list_offset; clist++)
  510.   {
  511.     for (index = 0; index < listXsize[clist]; index++)
  512.     {
  513.       for (comp=0; comp < 3; comp ++)
  514.       {
  515.         int offset_test = params->RDPSliceBTest && active_sps->profile_idc != 66
  516.           ? iabs(offset[clist][index][comp]) > 2
  517.           : offset[clist][index][comp] != 0;
  518.         if (weight[clist][index][comp] != default_weight[0] || offset_test)
  519.         {
  520.           perform_wp = 1;
  521.           break;
  522.         }
  523.       }
  524.       if (perform_wp == 1) break;
  525.     }
  526.     if (perform_wp == 1) break;
  527.   }
  528.   return perform_wp;
  529. }
  530. /*!
  531. ************************************************************************
  532. * brief
  533. *    TestWPBSliceAlg1:
  534. *    Tests B slice weighting prediction
  535. ************************************************************************
  536. */
  537. int TestWPBSliceAlg1(ImageParameters *img, InputParameters *params, int select_method)
  538. {
  539.   int i, j, k, n;
  540.   int tx,DistScaleFactor;
  541.   int index;
  542.   int comp;
  543.   double dc_org = 0.0;
  544.   double dc_org_UV[2] = { 0.0 };    
  545.   double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} };  
  546.   double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} };
  547.   double norm_org = 0.0;
  548.   double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 };
  549.   double numer = {0.0};
  550.   double denom[MAX_REFERENCE_PICTURES] = {0.0};
  551.   int default_weight[3];
  552.   // this needs to be fixed.
  553.   int list_offset   = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
  554.   int weight[6][MAX_REFERENCE_PICTURES][3];
  555.   int offset[6][MAX_REFERENCE_PICTURES][3];
  556.   int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3];
  557.   int clist;
  558.   int wf_weight, wf_offset;
  559.   int perform_wp = 0;
  560.   imgpel **tmpPtr;
  561.   if (select_method == 1) //! implicit mode
  562.   {
  563.     luma_log_weight_denom = 5;
  564.     chroma_log_weight_denom = 5;
  565.   }
  566.   else
  567.   {
  568.     luma_log_weight_denom = 5;
  569.     chroma_log_weight_denom = 5;
  570.   }
  571.   wp_luma_round     = 1 << (luma_log_weight_denom - 1);
  572.   wp_chroma_round   = 1 << (chroma_log_weight_denom - 1);
  573.   default_weight[0] = 1 << luma_log_weight_denom;
  574.   default_weight[1] = 1 << chroma_log_weight_denom;
  575.   default_weight[2] = 1 << chroma_log_weight_denom;
  576.   /* set all values to defaults */
  577.   for (i = 0; i < 2 + list_offset; i++)
  578.   {
  579.     for (j = 0; j < listXsize[i]; j++)
  580.     {
  581.       for (n = 0; n < 3; n++)
  582.       {
  583.         wp_weight[i][j][n] = default_weight[n];
  584.         wp_offset[i][j][n] = 0;
  585.         offset   [i][j][n] = 0;
  586.         weight   [i][j][n] = default_weight[n];
  587.       }
  588.     }
  589.   }
  590.   for (i = 0; i < listXsize[LIST_0]; i++)
  591.   {
  592.     for (j = 0; j < listXsize[LIST_1]; j++)
  593.     {
  594.       int td, tb;
  595.       td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc));
  596.       tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc));
  597.       for (comp = 0; comp < 3; comp++)
  598.       {
  599.         // implicit weights
  600.         if (td == 0)
  601.         {
  602.           im_weight[0][i][j][comp] = default_weight[comp];
  603.           im_weight[1][i][j][comp] = default_weight[comp];
  604.         }
  605.         else
  606.         {
  607.           tx = (16384 + iabs(td/2))/td;
  608.           DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
  609.           im_weight[1][i][j][comp] = DistScaleFactor >> 2;
  610.           if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128)
  611.             im_weight[1][i][j][comp] = default_weight[comp];
  612.           im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp];
  613.         }
  614.       }
  615.     }
  616.   }
  617.   if (select_method == 1) //! implicit mode
  618.   {
  619.     for (i = 0; i < listXsize[LIST_0]; i++)
  620.     {
  621.       for (j = 0; j < listXsize[LIST_1]; j++)
  622.       {
  623.         for (comp = 0; comp < 3; comp++)
  624.         {
  625.           wbp_weight[1][i][j][comp] = im_weight[1][i][j][comp] ;
  626.           wbp_weight[0][i][j][comp] = im_weight[0][i][j][comp];
  627.         }
  628.       }
  629.     }
  630.     for (clist=0; clist<2 + list_offset; clist++)
  631.     {
  632.       for (index = 0; index < listXsize[clist]; index++)
  633.       {
  634.         for (comp = 0; comp < 3; comp++)
  635.         {
  636.           wp_weight[clist][index][comp] = default_weight[comp];
  637.           wp_offset[clist][index][comp] = 0;
  638.         }
  639.       }
  640.     }
  641.   }
  642.   else
  643.   {
  644.     dc_org = ComputeImgSum(pCurImg, img->height, img->width);
  645.     if (params->EnhancedBWeightSupport)
  646.     {
  647.       norm_org = dc_org / ((double) img->size);
  648.       numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width);
  649.     }
  650.     if (params->ChromaWeightSupport == 1)
  651.     {
  652.       for (k = 0; k < 2; k++)
  653.       {
  654.         dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr);
  655.       } 
  656.     }
  657.     for (clist=0; clist<2 + list_offset; clist++)
  658.     {
  659.       for (n = 0; n < listXsize[clist]; n++)
  660.       {
  661.         // To simplify these computations we may wish to perform these after a reference is 
  662.         // stored in the reference buffer and attach them to the storedimage structure!!!
  663.         // Y
  664.         tmpPtr = listX[clist][n]->p_curr_img;
  665.         dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width);
  666.         if (params->EnhancedBWeightSupport)
  667.         {
  668.           norm_ref[n] = dc_ref[clist][n] / ((double) img->size);
  669.           denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width);
  670.           if (denom[n] != 0)
  671.             wf_weight = (int) (default_weight[0] * numer / denom[n] + 0.5);
  672.           else
  673.             wf_weight = default_weight[0];  // only used when reference picture is black
  674.           wf_weight = iClip3(-128, 127, wf_weight);
  675.           wf_offset = (int) (norm_org - ((double) wf_weight * norm_ref[n] / (double) default_weight[0]) + 0.5);
  676.           wf_offset = (wf_offset  + ((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8);
  677.           wf_offset = iClip3( -128, 127, wf_offset);
  678.           wf_offset = wf_offset <<(img->bitdepth_luma - 8);
  679.         }
  680.         else
  681.         {
  682.           if (dc_ref[clist][n] != 0.0)
  683.             wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5);
  684.           else
  685.             wf_weight = default_weight[0];  // only used when reference picture is black
  686.           wf_weight = iClip3(-128, 127, wf_weight);
  687.           wf_offset = 0;
  688.         }
  689.         weight[clist][n][0] = wf_weight;
  690.         offset[clist][n][0] = wf_offset;
  691.         // UV
  692.         if (params->ChromaWeightSupport == 1)
  693.         {          
  694.           for (k = 0; k < 2; k++)
  695.           {
  696.             tmpPtr = listX[clist][n]->imgUV[k];
  697.             dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr);
  698.             if (dc_ref_UV[clist][n][k] != 0.0)
  699.               wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5);
  700.             else
  701.               wf_weight = default_weight[k + 1];  // only used when reference picture is black
  702.             wf_weight = iClip3(-128, 127, wf_weight);
  703.             wf_offset = 0;
  704.             weight[clist][n][k + 1] = wf_weight;
  705.             offset[clist][n][k + 1] = wf_offset;
  706.           }
  707.         }
  708.         else
  709.         {
  710.           weight[clist][n][1] = default_weight[1];
  711.           weight[clist][n][2] = default_weight[2];        
  712.           offset[clist][n][1] = 0;
  713.           offset[clist][n][2] = 0;
  714.         }
  715.       }
  716.     }
  717.     if (select_method == 0) //! explicit mode
  718.     {
  719.       for (clist=0; clist<2 + list_offset; clist++)
  720.       {
  721.         for (index = 0; index < listXsize[clist]; index++)
  722.         {
  723.           memcpy(wp_weight[clist][index], weight[clist][index], 3 * sizeof(int));
  724.           memcpy(wp_offset[clist][index], offset[clist][index], 3 * sizeof(int));
  725.         }
  726.       }
  727.     }
  728.     else
  729.     {
  730.       for (clist=0; clist<2 + list_offset; clist++)
  731.       {
  732.         for (index = 0; index < listXsize[clist]; index++)
  733.         {
  734.           memcpy(wp_weight[clist][index], default_weight, 3 * sizeof(int));
  735.           memset(wp_offset[clist][index], 0, 3 * sizeof(int));
  736.         }
  737.       }
  738.     }
  739.     for (i = 0; i < listXsize[LIST_0]; i++)
  740.     {
  741.       for (j = 0; j < listXsize[LIST_1]; j++)
  742.       {
  743.         for (comp = 0; comp < 3; comp++)
  744.         {
  745.           wbp_weight[0][i][j][comp] = wp_weight[0][i][comp];
  746.           wbp_weight[1][i][j][comp] = wp_weight[1][j][comp];
  747.         }
  748. #if DEBUG_WP
  749.         printf ("bpw weight[%d][%d] = %d  , %d (%d %d %d) (%d %d) (%d %d)n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0],
  750.         enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc,
  751.         DistScaleFactor ,tx,tx,tx);
  752. #endif
  753.       }
  754.     }
  755.   }
  756.   if (select_method == 0) //! implicit mode
  757.   {
  758.     int active_refs[2];
  759.     active_refs[0] = (params->B_List0_refs == 0 ? listXsize[0] : imin(params->B_List0_refs, listXsize[0]));
  760.     active_refs[1] = (params->B_List1_refs == 0 ? listXsize[1] : imin(params->B_List1_refs, listXsize[1]));
  761.     for (clist=0; clist<2 + list_offset; clist++)
  762.     {
  763.       for (index = 0; index < active_refs[clist]; index++)
  764.       {
  765.         for (comp=0; comp < 3; comp ++)
  766.         {
  767.           if (wp_weight[clist][index][comp] != default_weight[comp])
  768.           {
  769.             perform_wp = 1;
  770.             break;
  771.           }
  772.         }
  773.         if (perform_wp == 1) break;
  774.       }
  775.       if (perform_wp == 1) break;
  776.     }
  777.   }
  778.   return perform_wp;
  779. }