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

Audio

开发平台:

Visual C++

  1. /*!
  2. *************************************************************************************
  3. * file wp_mcprec.c
  4. *
  5. * brief
  6. *    Improved Motion Compensation Precision Scheme using Weighted Prediction
  7. *
  8. * author
  9. *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10. *     - Athanasios Leontaris            <aleon@dolby.com>
  11. *     - Alexis Michael Tourapis         <alexismt@ieee.org>
  12. *************************************************************************************
  13. */
  14. #include "contributors.h"
  15. #include "global.h"
  16. #include "image.h"
  17. #include "slice.h"
  18. #include "wp_mcprec.h"
  19. /*!
  20. ************************************************************************
  21. * brief
  22. *    Initialize WPR object structure
  23. ************************************************************************
  24. */
  25. void wpxInitWPXObject( void )
  26. {
  27.   pWPX = (WPXObject *)malloc( sizeof( WPXObject ) );
  28.   if ( pWPX == NULL )
  29.   {
  30.     fprintf( stderr, "n Error initializing memory for WPXObject. Exiting...n" );
  31.     exit(1);
  32.   }
  33.   // wp_ref_l0
  34.   if ((pWPX->wp_ref_list[LIST_0] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL)
  35.     no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[0]");
  36.   // wp_ref_l1
  37.   if ((pWPX->wp_ref_list[LIST_1] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL)
  38.     no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[1]");
  39. }
  40. /*!
  41. ************************************************************************
  42. * brief
  43. *    Free WPR object structure
  44. ************************************************************************
  45. */
  46. void wpxFreeWPXObject( void )
  47. {
  48.   if ( pWPX != NULL )
  49.   {
  50.     free( pWPX );
  51.   }
  52.   // wp_ref_l0
  53.   if (pWPX->wp_ref_list[LIST_0])
  54.     free(pWPX->wp_ref_list[LIST_0]);
  55.   pWPX->wp_ref_list[LIST_0] = NULL;
  56.   // wp_ref_l1
  57.   if (pWPX->wp_ref_list[LIST_1])
  58.     free(pWPX->wp_ref_list[LIST_1]);
  59.   pWPX->wp_ref_list[LIST_1] = NULL;
  60. }
  61. /*!
  62. ************************************************************************
  63. * brief
  64. *    Initialize WPR coding passes
  65. ************************************************************************
  66. */
  67. void wpxInitWPXPasses( InputParameters *params )
  68. {
  69.   // initialize number of wp reference frames in each list
  70.   pWPX->num_wp_ref_list[LIST_0] = 0;
  71.   pWPX->num_wp_ref_list[LIST_1] = 0;
  72.   switch( params->WPMCPrecision )
  73.   {
  74.   default:
  75.   case 0:
  76.     break;
  77.   case 1:
  78.     pWPX->wp_rd_passes[0].algorithm = WP_REGULAR;
  79.     pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0;      
  80.     break;
  81.   case 2:
  82.     pWPX->wp_rd_passes[0].algorithm = WP_REGULAR;
  83.     pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0;
  84.     pWPX->wp_rd_passes[2].algorithm = WP_MCPREC_MINUS1;      
  85.     break;
  86.   }
  87. }
  88. /*!
  89. ************************************************************************
  90. * brief
  91. *    Modifies ref_pic_list for all lists
  92. ************************************************************************
  93. */
  94. void wpxModifyRefPicList( ImageParameters *img )
  95. {
  96.   unsigned int i, j, cloned_refs;
  97.   static int   default_order_list0[32];
  98.   static int   default_order_list1[32];
  99.   static int   re_order[32], *list_order;  
  100.   int          pred_list;
  101.   StorablePicture **list;
  102.   // set memory
  103.   memset( (void *)default_order_list0, 1<<20, 32 * sizeof( int ) );
  104.   memset( (void *)default_order_list1, 1<<20, 32 * sizeof( int ) );
  105.   memset( (void *)re_order,            1<<20, 32 * sizeof( int ) );
  106.   // First assign default list orders
  107.   list = listX[LIST_0];
  108.   for (i=0; i<(unsigned int)(img->num_ref_idx_l0_active); i++)
  109.   {
  110.     default_order_list0[i] = list[i]->pic_num;
  111.   }
  112.   if ( img->type == B_SLICE )
  113.   {
  114.     list = listX[LIST_1];
  115.     for (i=0; i<(unsigned int)(img->num_ref_idx_l1_active); i++)
  116.     {
  117.       default_order_list1[i] = list[i]->pic_num;
  118.     }
  119.   }
  120.   // obtain the ref_pic_list using POC-based reordering if img->type != B_SLICE
  121.   if ( img->type == P_SLICE )
  122.   {
  123.     int  list_sign[32];
  124.     int  poc_diff[32];
  125.     int  tmp_value;
  126.     int  abs_poc_dist;
  127.     
  128.     for (i=0; i<dpb.ref_frames_in_buffer; i++)
  129.     {
  130.       re_order[i] = dpb.fs_ref[i]->frame->pic_num;
  131.       if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
  132.       {
  133.         abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ;
  134.         poc_diff[i]  = abs_poc_dist;
  135.         list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1;
  136.       }
  137.     }
  138.     // sort these references based on poc (temporal) distance
  139.     for (i=0; i< dpb.ref_frames_in_buffer-1; i++)
  140.     {
  141.       for (j=i+1; j< dpb.ref_frames_in_buffer; j++)
  142.       {
  143.         if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
  144.         {
  145.           tmp_value = poc_diff[i];
  146.           poc_diff[i] = poc_diff[j];
  147.           poc_diff[j] = tmp_value;
  148.           tmp_value  = re_order[i];
  149.           re_order[i] = re_order[j];
  150.           re_order[j] = tmp_value ;
  151.           tmp_value  = list_sign[i];
  152.           list_sign[i] = list_sign[j];
  153.           list_sign[j] = tmp_value ;
  154.         }
  155.       }
  156.     }
  157.   }
  158.   // end of POC-based reordering of P_SLICE
  159.   // loop over two lists
  160.   for ( pred_list = 0; pred_list < (1 + ( img->type == B_SLICE ? 1 : 0 )); pred_list++ )
  161.   {
  162.     if ( pred_list == LIST_0 )
  163.     {
  164.       list_order = (img->type == P_SLICE) ? re_order : default_order_list0;
  165.     }
  166.     else
  167.     {
  168.       list_order = default_order_list1;
  169.     }
  170.     // check algorithms (more flexibility for the future...)
  171.     switch( pWPX->curr_wp_rd_pass->algorithm )
  172.     {
  173.     default:
  174.     case WP_MCPREC_PLUS0:
  175.     case WP_MCPREC_PLUS1:
  176.     case WP_MCPREC_MINUS0:
  177.     case WP_MCPREC_MINUS1:
  178.       // ref 0 and 1 point to to the same reference
  179.       cloned_refs = pWPX->num_wp_ref_list[pred_list] = 2;
  180.       for ( j = 0; j < cloned_refs; j++ )
  181.       {
  182.         pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0];
  183.       }
  184.       // shift the rest
  185.       for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ )
  186.       {
  187.         pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)];
  188.         pWPX->num_wp_ref_list[pred_list]++;
  189.       }
  190.       break;
  191.     case WP_MCPREC_MINUS_PLUS0:
  192.       // ref 0 and 1 point to to the same reference
  193.       cloned_refs = pWPX->num_wp_ref_list[pred_list] = 3;
  194.       for ( j = 0; j < cloned_refs; j++ )
  195.       {
  196.         pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0];
  197.       }
  198.       // shift the rest
  199.       for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ )
  200.       {
  201.         pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)];
  202.         pWPX->num_wp_ref_list[pred_list]++;
  203.       }      
  204.       break;
  205.     }
  206.     // constrain list length
  207.     pWPX->num_wp_ref_list[pred_list] = imin( pWPX->num_wp_ref_list[pred_list],
  208.       ( pred_list == LIST_0 ) ? img->num_ref_idx_l0_active : img->num_ref_idx_l1_active );
  209.   }
  210. }
  211. /*!
  212. ************************************************************************
  213. * brief
  214. *    Determine whether it is fine to determine WP parameters
  215. ************************************************************************
  216. */
  217. int wpxDetermineWP( InputParameters *params, ImageParameters *img, int clist, int n )
  218. {
  219.   int i, j, determine_wp = 0;
  220.   int default_weight[3];
  221.   // we assume it's the same as in the WP functions
  222.   int luma_log_weight_denom   = 5;
  223.   int chroma_log_weight_denom = 5;
  224.   int cur_list = LIST_0;
  225.   default_weight[0] = 1 << luma_log_weight_denom;
  226.   default_weight[1] = 1 << chroma_log_weight_denom;
  227.   default_weight[2] = 1 << chroma_log_weight_denom;
  228.   if ( !params->WPMCPrecision )
  229.   {
  230.     determine_wp = 1;
  231.   }
  232.   else
  233.   {
  234.     determine_wp = 0;
  235.     // check slice type
  236.     if ( img->type == P_SLICE )
  237.     {
  238.       for (i = 0; i < 3; i++)
  239.       {
  240.         wp_weight[clist][n][i] = default_weight[i];
  241.       }      
  242.     }
  243.     else if ( img->type == B_SLICE )
  244.     {
  245.       cur_list = ((clist % 2) ==  LIST_1) ? LIST_0 : LIST_1;
  246.       // single-list prediction
  247.       for (i = 0; i < 3; i++)
  248.       {
  249.         wp_weight[clist][n][i] = default_weight[i];
  250.       }
  251.       // bi-pred
  252.       for (j = 0; j < listXsize[cur_list]; j++)
  253.       {
  254.         for (i = 0; i < 3; i++)
  255.           wbp_weight[clist][n][j][i] = default_weight[i];
  256.       }      
  257.     }
  258.     // algorithm consideration
  259.     switch( pWPX->curr_wp_rd_pass->algorithm )
  260.     {
  261.     case WP_MCPREC_PLUS0:
  262.       for (i = 0; i < 3; i++)
  263.         wp_offset[clist][n][i] = (n == 1) ? 1 : 0;
  264.       break;
  265.     case WP_MCPREC_MINUS0:
  266.       for (i = 0; i < 3; i++)
  267.         wp_offset[clist][n][i] = (n == 1) ? -1 : 0;
  268.       break;
  269.     case WP_MCPREC_PLUS1:
  270.       for (i = 0; i < 3; i++)
  271.         wp_offset[clist][n][i] = (n == 0) ? 1 : 0;
  272.       break;
  273.     case WP_MCPREC_MINUS1:
  274.       for (i = 0; i < 3; i++)
  275.         wp_offset[clist][n][i] = (n == 0) ? -1 : 0;
  276.       break;
  277.     case WP_MCPREC_MINUS_PLUS0:
  278.       for (i = 0; i < 3; i++)
  279.         wp_offset[clist][n][i] = (n == 1) ? -1 : ((n == 2) ? 1 : 0);
  280.       break;
  281.     default:
  282.     case WP_REGULAR:
  283.       determine_wp = 1;
  284.       break;
  285.     }    
  286.     // check list (play with the WP factors)
  287.     if ( img->type == B_SLICE && cur_list == LIST_0 )
  288.     {
  289.       for (i = 0; i < 3; i++)
  290.         wp_offset[clist][n][i] *= 2;
  291.     }
  292.     // zero out chroma offsets
  293.     for (i = 1; i < 3; i++)
  294.     {
  295.       wp_offset[clist][n][i] = 0;
  296.     }
  297.   }
  298.   return determine_wp;
  299. }
  300. /*!
  301. ************************************************************************
  302. * brief
  303. *    Modify number of references
  304. ************************************************************************
  305. */
  306. void wpxAdaptRefNum( ImageParameters *img )
  307. {
  308.   if ( pWPX->curr_wp_rd_pass->algorithm == WP_REGULAR )
  309.   {
  310.     switch( img->type )
  311.     {
  312.     default:
  313.     case I_SLICE:
  314.       break;
  315.     case P_SLICE:
  316.       if ( img->num_ref_idx_l0_active == ( params->P_List0_refs * ((img->structure !=0) + 1) ) )
  317.       {
  318.         listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) );
  319.       }
  320.       break;
  321.     case B_SLICE:
  322.       if ( img->num_ref_idx_l0_active == ( params->B_List0_refs * ((img->structure !=0) + 1) ) )
  323.       {
  324.         listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) );
  325.       }
  326.       if ( img->num_ref_idx_l1_active == ( params->B_List1_refs * ((img->structure !=0) + 1) ) )
  327.       {
  328.         listXsize[LIST_1] = img->num_ref_idx_l1_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l1_active - ((img->structure !=0) + 1) );
  329.       }
  330.       break;
  331.     }    
  332.   }
  333. }
  334. /*!
  335. ************************************************************************
  336. * brief
  337. *    Reorder lists
  338. ************************************************************************
  339. */
  340. void wpxReorderLists( ImageParameters *img, Slice *currSlice )
  341. {
  342.   int i, num_ref;
  343.   wpxModifyRefPicList( img );
  344.   alloc_ref_pic_list_reordering_buffer(currSlice);
  345.   for (i = 0; i < img->num_ref_idx_l0_active + 1; i++)
  346.   {
  347.     currSlice->reordering_of_pic_nums_idc_l0[i] = 3;
  348.     currSlice->abs_diff_pic_num_minus1_l0[i] = 0;
  349.     currSlice->long_term_pic_idx_l0[i] = 0;
  350.   }
  351.   if (img->type == B_SLICE) // type should be part of currSlice not img
  352.   {
  353.     for (i = 0; i < img->num_ref_idx_l1_active + 1; i++)
  354.     {
  355.       currSlice->reordering_of_pic_nums_idc_l1[i] = 3;
  356.       currSlice->abs_diff_pic_num_minus1_l1[i] = 0;
  357.       currSlice->long_term_pic_idx_l1[i] = 0;
  358.     }
  359.   }
  360.   // LIST_0
  361.   num_ref = img->num_ref_idx_l0_active;
  362.   poc_ref_pic_reorder_frame(listX[LIST_0], num_ref,
  363.     currSlice->reordering_of_pic_nums_idc_l0,
  364.     currSlice->abs_diff_pic_num_minus1_l0,
  365.     currSlice->long_term_pic_idx_l0, LIST_0);
  366.   // reference picture reordering
  367.   reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0],
  368.     img->num_ref_idx_l0_active - 1,
  369.     currSlice->reordering_of_pic_nums_idc_l0,
  370.     currSlice->abs_diff_pic_num_minus1_l0,
  371.     currSlice->long_term_pic_idx_l0);
  372.   if ( img->type == B_SLICE )
  373.   {
  374.     // LIST_1
  375.     num_ref = img->num_ref_idx_l1_active;
  376.     poc_ref_pic_reorder_frame(listX[LIST_1], num_ref,
  377.       currSlice->reordering_of_pic_nums_idc_l1,
  378.       currSlice->abs_diff_pic_num_minus1_l1,
  379.       currSlice->long_term_pic_idx_l1, LIST_1);
  380.     // reference picture reordering
  381.     reorder_ref_pic_list(listX[LIST_1], &listXsize[LIST_1],
  382.       img->num_ref_idx_l1_active - 1,
  383.       currSlice->reordering_of_pic_nums_idc_l1,
  384.       currSlice->abs_diff_pic_num_minus1_l1,
  385.       currSlice->long_term_pic_idx_l1);
  386.   }
  387. }