00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "contributors.h"
00016
00017 #include "global.h"
00018 #include "image.h"
00019 #include "slice.h"
00020 #include "wp_mcprec.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029 void wpxInitWPXObject( void )
00030 {
00031 pWPX = (WPXObject *)malloc( sizeof( WPXObject ) );
00032 if ( pWPX == NULL )
00033 {
00034 fprintf( stderr, "\n Error initializing memory for WPXObject. Exiting...\n" );
00035 exit(1);
00036 }
00037
00038
00039 if ((pWPX->wp_ref_list[LIST_0] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL)
00040 no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[0]");
00041
00042 if ((pWPX->wp_ref_list[LIST_1] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL)
00043 no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[1]");
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053 void wpxFreeWPXObject( void )
00054 {
00055 if ( pWPX != NULL )
00056 {
00057 free( pWPX );
00058 }
00059
00060
00061 if (pWPX->wp_ref_list[LIST_0])
00062 free(pWPX->wp_ref_list[LIST_0]);
00063 pWPX->wp_ref_list[LIST_0] = NULL;
00064
00065 if (pWPX->wp_ref_list[LIST_1])
00066 free(pWPX->wp_ref_list[LIST_1]);
00067 pWPX->wp_ref_list[LIST_1] = NULL;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 void wpxInitWPXPasses( InputParameters *params )
00078 {
00079
00080 pWPX->num_wp_ref_list[LIST_0] = 0;
00081 pWPX->num_wp_ref_list[LIST_1] = 0;
00082
00083 switch( params->WPMCPrecision )
00084 {
00085 default:
00086 case 0:
00087 break;
00088 case 1:
00089 pWPX->wp_rd_passes[0].algorithm = WP_REGULAR;
00090 pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0;
00091 break;
00092 case 2:
00093 pWPX->wp_rd_passes[0].algorithm = WP_REGULAR;
00094 pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0;
00095 pWPX->wp_rd_passes[2].algorithm = WP_MCPREC_MINUS1;
00096 break;
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 void wpxModifyRefPicList( ImageParameters *img )
00108 {
00109 unsigned int i, j, cloned_refs;
00110 static int default_order_list0[32];
00111 static int default_order_list1[32];
00112 static int re_order[32], *list_order;
00113 int pred_list;
00114
00115 StorablePicture **list;
00116
00117
00118 memset( (void *)default_order_list0, 1<<20, 32 * sizeof( int ) );
00119 memset( (void *)default_order_list1, 1<<20, 32 * sizeof( int ) );
00120 memset( (void *)re_order, 1<<20, 32 * sizeof( int ) );
00121
00122
00123 list = listX[LIST_0];
00124 for (i=0; i<(unsigned int)(img->num_ref_idx_l0_active); i++)
00125 {
00126 default_order_list0[i] = list[i]->pic_num;
00127 }
00128 if ( img->type == B_SLICE )
00129 {
00130 list = listX[LIST_1];
00131 for (i=0; i<(unsigned int)(img->num_ref_idx_l1_active); i++)
00132 {
00133 default_order_list1[i] = list[i]->pic_num;
00134 }
00135 }
00136
00137
00138 if ( img->type == P_SLICE )
00139 {
00140 int list_sign[32];
00141 int poc_diff[32];
00142 int tmp_value;
00143 int abs_poc_dist;
00144
00145 for (i=0; i<dpb.ref_frames_in_buffer; i++)
00146 {
00147 re_order[i] = dpb.fs_ref[i]->frame->pic_num;
00148 if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
00149 {
00150 abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ;
00151 poc_diff[i] = abs_poc_dist;
00152 list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1;
00153 }
00154 }
00155
00156
00157 for (i=0; i< dpb.ref_frames_in_buffer-1; i++)
00158 {
00159 for (j=i+1; j< dpb.ref_frames_in_buffer; j++)
00160 {
00161 if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
00162 {
00163 tmp_value = poc_diff[i];
00164 poc_diff[i] = poc_diff[j];
00165 poc_diff[j] = tmp_value;
00166 tmp_value = re_order[i];
00167 re_order[i] = re_order[j];
00168 re_order[j] = tmp_value ;
00169 tmp_value = list_sign[i];
00170 list_sign[i] = list_sign[j];
00171 list_sign[j] = tmp_value ;
00172 }
00173 }
00174 }
00175 }
00176
00177
00178
00179 for ( pred_list = 0; pred_list < (1 + ( img->type == B_SLICE ? 1 : 0 )); pred_list++ )
00180 {
00181 if ( pred_list == LIST_0 )
00182 {
00183 list_order = (img->type == P_SLICE) ? re_order : default_order_list0;
00184 }
00185 else
00186 {
00187 list_order = default_order_list1;
00188 }
00189
00190
00191 switch( pWPX->curr_wp_rd_pass->algorithm )
00192 {
00193 default:
00194 case WP_MCPREC_PLUS0:
00195 case WP_MCPREC_PLUS1:
00196 case WP_MCPREC_MINUS0:
00197 case WP_MCPREC_MINUS1:
00198
00199 cloned_refs = pWPX->num_wp_ref_list[pred_list] = 2;
00200 for ( j = 0; j < cloned_refs; j++ )
00201 {
00202 pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0];
00203 }
00204
00205 for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ )
00206 {
00207 pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)];
00208 pWPX->num_wp_ref_list[pred_list]++;
00209 }
00210 break;
00211 case WP_MCPREC_MINUS_PLUS0:
00212
00213 cloned_refs = pWPX->num_wp_ref_list[pred_list] = 3;
00214 for ( j = 0; j < cloned_refs; j++ )
00215 {
00216 pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0];
00217 }
00218
00219 for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ )
00220 {
00221 pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)];
00222 pWPX->num_wp_ref_list[pred_list]++;
00223 }
00224 break;
00225 }
00226
00227 pWPX->num_wp_ref_list[pred_list] = imin( pWPX->num_wp_ref_list[pred_list],
00228 ( pred_list == LIST_0 ) ? img->num_ref_idx_l0_active : img->num_ref_idx_l1_active );
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 int wpxDetermineWP( InputParameters *params, ImageParameters *img, int clist, int n )
00240 {
00241 int i, j, determine_wp = 0;
00242 int default_weight[3];
00243
00244 int luma_log_weight_denom = 5;
00245 int chroma_log_weight_denom = 5;
00246 int cur_list = LIST_0;
00247
00248 default_weight[0] = 1 << luma_log_weight_denom;
00249 default_weight[1] = 1 << chroma_log_weight_denom;
00250 default_weight[2] = 1 << chroma_log_weight_denom;
00251
00252 if ( !params->WPMCPrecision )
00253 {
00254 determine_wp = 1;
00255 }
00256 else
00257 {
00258 determine_wp = 0;
00259
00260 if ( img->type == P_SLICE )
00261 {
00262 for (i = 0; i < 3; i++)
00263 {
00264 wp_weight[clist][n][i] = default_weight[i];
00265 }
00266 }
00267 else if ( img->type == B_SLICE )
00268 {
00269 cur_list = ((clist % 2) == LIST_1) ? LIST_0 : LIST_1;
00270
00271
00272 for (i = 0; i < 3; i++)
00273 {
00274 wp_weight[clist][n][i] = default_weight[i];
00275 }
00276
00277 for (j = 0; j < listXsize[cur_list]; j++)
00278 {
00279 for (i = 0; i < 3; i++)
00280 wbp_weight[clist][n][j][i] = default_weight[i];
00281 }
00282 }
00283
00284 switch( pWPX->curr_wp_rd_pass->algorithm )
00285 {
00286 case WP_MCPREC_PLUS0:
00287 for (i = 0; i < 3; i++)
00288 wp_offset[clist][n][i] = (n == 1) ? 1 : 0;
00289 break;
00290 case WP_MCPREC_MINUS0:
00291 for (i = 0; i < 3; i++)
00292 wp_offset[clist][n][i] = (n == 1) ? -1 : 0;
00293 break;
00294 case WP_MCPREC_PLUS1:
00295 for (i = 0; i < 3; i++)
00296 wp_offset[clist][n][i] = (n == 0) ? 1 : 0;
00297 break;
00298 case WP_MCPREC_MINUS1:
00299 for (i = 0; i < 3; i++)
00300 wp_offset[clist][n][i] = (n == 0) ? -1 : 0;
00301 break;
00302 case WP_MCPREC_MINUS_PLUS0:
00303 for (i = 0; i < 3; i++)
00304 wp_offset[clist][n][i] = (n == 1) ? -1 : ((n == 2) ? 1 : 0);
00305 break;
00306 default:
00307 case WP_REGULAR:
00308 determine_wp = 1;
00309 break;
00310 }
00311
00312 if ( img->type == B_SLICE && cur_list == LIST_0 )
00313 {
00314 for (i = 0; i < 3; i++)
00315 wp_offset[clist][n][i] *= 2;
00316 }
00317
00318 for (i = 1; i < 3; i++)
00319 {
00320 wp_offset[clist][n][i] = 0;
00321 }
00322 }
00323
00324 return determine_wp;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334 void wpxAdaptRefNum( ImageParameters *img )
00335 {
00336 if ( pWPX->curr_wp_rd_pass->algorithm == WP_REGULAR )
00337 {
00338 switch( img->type )
00339 {
00340 default:
00341 case I_SLICE:
00342 break;
00343 case P_SLICE:
00344 if ( img->num_ref_idx_l0_active == ( params->P_List0_refs * ((img->structure !=0) + 1) ) )
00345 {
00346 listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) );
00347 }
00348 break;
00349 case B_SLICE:
00350 if ( img->num_ref_idx_l0_active == ( params->B_List0_refs * ((img->structure !=0) + 1) ) )
00351 {
00352 listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) );
00353 }
00354 if ( img->num_ref_idx_l1_active == ( params->B_List1_refs * ((img->structure !=0) + 1) ) )
00355 {
00356 listXsize[LIST_1] = img->num_ref_idx_l1_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l1_active - ((img->structure !=0) + 1) );
00357 }
00358 break;
00359 }
00360 }
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370 void wpxReorderLists( ImageParameters *img, Slice *currSlice )
00371 {
00372 int i, num_ref;
00373
00374 wpxModifyRefPicList( img );
00375
00376 alloc_ref_pic_list_reordering_buffer(currSlice);
00377
00378 for (i = 0; i < img->num_ref_idx_l0_active + 1; i++)
00379 {
00380 currSlice->reordering_of_pic_nums_idc_l0[i] = 3;
00381 currSlice->abs_diff_pic_num_minus1_l0[i] = 0;
00382 currSlice->long_term_pic_idx_l0[i] = 0;
00383 }
00384
00385 if (img->type == B_SLICE)
00386 {
00387 for (i = 0; i < img->num_ref_idx_l1_active + 1; i++)
00388 {
00389 currSlice->reordering_of_pic_nums_idc_l1[i] = 3;
00390 currSlice->abs_diff_pic_num_minus1_l1[i] = 0;
00391 currSlice->long_term_pic_idx_l1[i] = 0;
00392 }
00393 }
00394
00395
00396 num_ref = img->num_ref_idx_l0_active;
00397
00398 poc_ref_pic_reorder_frame(currSlice, listX[LIST_0], num_ref,
00399 currSlice->reordering_of_pic_nums_idc_l0,
00400 currSlice->abs_diff_pic_num_minus1_l0,
00401 currSlice->long_term_pic_idx_l0, LIST_0);
00402
00403 reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0],
00404 img->num_ref_idx_l0_active - 1,
00405 currSlice->reordering_of_pic_nums_idc_l0,
00406 currSlice->abs_diff_pic_num_minus1_l0,
00407 currSlice->long_term_pic_idx_l0);
00408
00409 if ( img->type == B_SLICE )
00410 {
00411
00412 num_ref = img->num_ref_idx_l1_active;
00413
00414 poc_ref_pic_reorder_frame(currSlice, listX[LIST_1], num_ref,
00415 currSlice->reordering_of_pic_nums_idc_l1,
00416 currSlice->abs_diff_pic_num_minus1_l1,
00417 currSlice->long_term_pic_idx_l1, LIST_1);
00418
00419 reorder_ref_pic_list(listX[LIST_1], &listXsize[LIST_1],
00420 img->num_ref_idx_l1_active - 1,
00421 currSlice->reordering_of_pic_nums_idc_l1,
00422 currSlice->abs_diff_pic_num_minus1_l1,
00423 currSlice->long_term_pic_idx_l1);
00424 }
00425 }