00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "contributors.h"
00018
00019 #include <math.h>
00020 #include <float.h>
00021
00022 #include "global.h"
00023 #include "image.h"
00024 #include "wp.h"
00025 #include "list_reorder.h"
00026
00027
00028
00029
00030
00031
00032
00033 void init_ref_pic_list_reordering(Slice* currSlice)
00034 {
00035 currSlice->ref_pic_list_reordering_flag[LIST_0] = 0;
00036 currSlice->ref_pic_list_reordering_flag[LIST_1] = 0;
00037
00038 currSlice->poc_ref_pic_reorder_frame = poc_ref_pic_reorder_frame_default;
00039
00040 }
00041
00042
00043
00044
00045
00046
00047
00048 void poc_ref_pic_reorder_frame_default(Slice *currSlice, StorablePicture **list,
00049 unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
00050 {
00051 ImageParameters *p_Img = currSlice->p_Img;
00052 InputParameters *p_Inp = currSlice->p_Inp;
00053 StorablePicture *p_Enc_Pic = p_Img->enc_picture;
00054
00055 unsigned int i,j,k;
00056
00057 int currPicNum, picNumLXPred;
00058
00059 int default_order[32];
00060 int re_order[32];
00061 int tmp_reorder[32];
00062 int list_sign[32];
00063 int reorder_stop, no_reorder;
00064 int poc_diff[32];
00065 int tmp_value, diff;
00066
00067 int abs_poc_dist;
00068 int maxPicNum;
00069 unsigned int num_refs;
00070
00071 maxPicNum = p_Img->max_frame_num;
00072 currPicNum = p_Img->frame_num;
00073
00074 picNumLXPred = currPicNum;
00075
00076
00077 for (i=0; i<num_ref_idx_lX_active; i++)
00078 {
00079 default_order[i] = list[i]->pic_num;
00080 }
00081
00082
00083
00084
00085
00086 num_refs = p_Img->p_Dpb->ref_frames_in_buffer;
00087 for (i=0; i<p_Img->p_Dpb->ref_frames_in_buffer; i++)
00088 {
00089 poc_diff[i] = 0xFFFF;
00090 re_order[i] = p_Img->p_Dpb->fs_ref[i]->frame->pic_num;
00091
00092 if (p_Img->p_Dpb->fs_ref[i]->is_used==3 && (p_Img->p_Dpb->fs_ref[i]->frame->used_for_reference)&&(!p_Img->p_Dpb->fs_ref[i]->frame->is_long_term))
00093 {
00094 abs_poc_dist = iabs(p_Img->p_Dpb->fs_ref[i]->frame->poc - p_Enc_Pic->poc) ;
00095 poc_diff[i] = abs_poc_dist;
00096 if (list_no == LIST_0)
00097 {
00098 list_sign[i] = (p_Enc_Pic->poc < p_Img->p_Dpb->fs_ref[i]->frame->poc) ? +1 : -1;
00099 }
00100 else
00101 {
00102 list_sign[i] = (p_Enc_Pic->poc > p_Img->p_Dpb->fs_ref[i]->frame->poc) ? +1 : -1;
00103 }
00104 }
00105 }
00106
00107
00108 for (i = 0; i < (num_refs - 1); i++)
00109 {
00110 for (j = i + 1; j < num_refs; j++)
00111 {
00112 if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
00113 {
00114
00115 tmp_value = poc_diff[i];
00116 poc_diff[i] = poc_diff[j];
00117 poc_diff[j] = tmp_value;
00118 tmp_value = re_order[i];
00119 re_order[i] = re_order[j];
00120 re_order[j] = tmp_value ;
00121 tmp_value = list_sign[i];
00122 list_sign[i] = list_sign[j];
00123 list_sign[j] = tmp_value;
00124 }
00125 }
00126 }
00127
00128
00129 if ( p_Inp->WPMCPrecision
00130 && p_Img->pWPX->curr_wp_rd_pass->algorithm != WP_REGULAR
00131 && p_Img->pWPX->num_wp_ref_list[list_no] )
00132 {
00133 for (i=0; i<num_ref_idx_lX_active; i++)
00134 {
00135 re_order[i] = p_Img->pWPX->wp_ref_list[list_no][i].PicNum;
00136 }
00137 }
00138
00139
00140
00141 no_reorder = 1;
00142 for (i=0; i<num_ref_idx_lX_active; i++)
00143 {
00144 if (default_order[i] != re_order[i])
00145 {
00146 no_reorder = 0;
00147 }
00148 }
00149
00150
00151 if (no_reorder==0)
00152 {
00153 for (i=0; i<num_ref_idx_lX_active; i++)
00154 {
00155 diff = re_order[i]-picNumLXPred;
00156 if (diff <= 0)
00157 {
00158 reordering_of_pic_nums_idc[i] = 0;
00159 abs_diff_pic_num_minus1[i] = iabs(diff)-1;
00160 if (abs_diff_pic_num_minus1[i] < 0)
00161 abs_diff_pic_num_minus1[i] = maxPicNum -1;
00162 }
00163 else
00164 {
00165 reordering_of_pic_nums_idc[i] = 1;
00166 abs_diff_pic_num_minus1[i] = iabs(diff)-1;
00167 }
00168 picNumLXPred = re_order[i];
00169
00170 tmp_reorder[i] = re_order[i];
00171
00172 k = i;
00173 for (j=i; j<num_ref_idx_lX_active; j++)
00174 {
00175 if (default_order[j] != re_order[i])
00176 {
00177 ++k;
00178 tmp_reorder[k] = default_order[j];
00179 }
00180 }
00181 reorder_stop = 1;
00182 for(j=i+1; j<num_ref_idx_lX_active; j++)
00183 {
00184 if (tmp_reorder[j] != re_order[j])
00185 {
00186 reorder_stop = 0;
00187 break;
00188 }
00189 }
00190
00191 if (reorder_stop==1)
00192 {
00193 ++i;
00194 break;
00195 }
00196 memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
00197
00198 }
00199 reordering_of_pic_nums_idc[i] = 3;
00200
00201 memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
00202
00203 if (list_no==0)
00204 {
00205 currSlice->ref_pic_list_reordering_flag[LIST_0] = 1;
00206 }
00207 else
00208 {
00209 currSlice->ref_pic_list_reordering_flag[LIST_1] = 1;
00210 }
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 void poc_ref_pic_reorder_field(Slice *currSlice, StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no)
00221 {
00222 ImageParameters *p_Img = currSlice->p_Img;
00223
00224 StorablePicture *p_Enc_Pic = p_Img->enc_picture;
00225
00226 unsigned int i,j,k;
00227
00228 int currPicNum, picNumLXPred;
00229
00230 int default_order[32];
00231 int re_order[32];
00232 int tmp_reorder[32];
00233 int list_sign[32];
00234 int poc_diff[32];
00235 int fld_type[32];
00236
00237 int reorder_stop, no_reorder;
00238 int tmp_value, diff;
00239
00240 int abs_poc_dist;
00241 int maxPicNum;
00242 unsigned int num_refs;
00243
00244 int field_used[2] = {1, 2};
00245 int fld, idx, num_flds;
00246
00247 unsigned int top_idx = 0;
00248 unsigned int bot_idx = 0;
00249 unsigned int list_size = 0;
00250
00251 StorablePicture *pField[2];
00252 FrameStore *pFrameStore;
00253
00254 maxPicNum = 2 * p_Img->max_frame_num;
00255 currPicNum = 2 * p_Img->frame_num + 1;
00256
00257 picNumLXPred = currPicNum;
00258
00259
00260 for (i=0; i<num_ref_idx_lX_active; i++)
00261 {
00262 default_order[i] = list[i]->pic_num;
00263 }
00264
00265
00266
00267
00268
00269
00270 idx = 0;
00271
00272 for (i=0; i<p_Img->p_Dpb->ref_frames_in_buffer; i++)
00273 {
00274 pFrameStore = p_Img->p_Dpb->fs_ref[i];
00275 pField[0] = pFrameStore->top_field;
00276 pField[1] = pFrameStore->bottom_field;
00277 num_flds = (currSlice->structure == BOTTOM_FIELD && (p_Enc_Pic->poc == (pField[0]->poc + 1) ) ) ? 1 : 2;
00278
00279 poc_diff[2*i ] = 0xFFFF;
00280 poc_diff[2*i + 1] = 0xFFFF;
00281
00282 for ( fld = 0; fld < num_flds; fld++ )
00283 {
00284 if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term) )
00285 {
00286 abs_poc_dist = iabs(pField[fld]->poc - p_Enc_Pic->poc) ;
00287 poc_diff[idx] = abs_poc_dist;
00288 re_order[idx] = pField[fld]->pic_num;
00289 fld_type[idx] = fld + 1;
00290
00291 if (list_no == LIST_0)
00292 {
00293 list_sign[idx] = (p_Enc_Pic->poc < pField[fld]->poc) ? +1 : -1;
00294 }
00295 else
00296 {
00297 list_sign[idx] = (p_Enc_Pic->poc > pField[fld]->poc) ? +1 : -1;
00298 }
00299 idx++;
00300 }
00301 }
00302 }
00303 num_refs = idx;
00304
00305
00306 for (i=0; i < num_refs-1; i++)
00307 {
00308 for (j = (i + 1); j < num_refs; j++)
00309 {
00310 if (poc_diff[i] > poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i]))
00311 {
00312
00313 tmp_value = poc_diff[i];
00314 poc_diff[i] = poc_diff[j];
00315 poc_diff[j] = tmp_value;
00316
00317 tmp_value = re_order[i];
00318 re_order[i] = re_order[j];
00319 re_order[j] = tmp_value;
00320
00321 tmp_value = list_sign[i];
00322 list_sign[i] = list_sign[j];
00323 list_sign[j] = tmp_value;
00324
00325 tmp_value = fld_type[i];
00326 fld_type[i] = fld_type[j];
00327 fld_type[j] = tmp_value ;
00328 }
00329 }
00330 }
00331
00332 if (currSlice->structure == TOP_FIELD)
00333 {
00334 while ((top_idx < num_refs)||(bot_idx < num_refs))
00335 {
00336 for ( ; top_idx < num_refs; top_idx++)
00337 {
00338 if ( fld_type[top_idx] == TOP_FIELD )
00339 {
00340 tmp_reorder[list_size] = re_order[top_idx];
00341 list_size++;
00342 top_idx++;
00343 break;
00344 }
00345 }
00346 for ( ; bot_idx < num_refs; bot_idx++)
00347 {
00348 if ( fld_type[bot_idx] == BOTTOM_FIELD )
00349 {
00350 tmp_reorder[list_size] = re_order[bot_idx];
00351 list_size++;
00352 bot_idx++;
00353 break;
00354 }
00355 }
00356 }
00357 }
00358 if (currSlice->structure == BOTTOM_FIELD)
00359 {
00360 while ((top_idx < num_refs)||(bot_idx < num_refs))
00361 {
00362 for ( ; bot_idx < num_refs; bot_idx++)
00363 {
00364 if ( fld_type[bot_idx] == BOTTOM_FIELD )
00365 {
00366 tmp_reorder[list_size] = re_order[bot_idx];
00367 list_size++;
00368 bot_idx++;
00369 break;
00370 }
00371 }
00372 for ( ; top_idx < num_refs; top_idx++)
00373 {
00374 if ( fld_type[top_idx] == TOP_FIELD )
00375 {
00376 tmp_reorder[list_size] = re_order[top_idx];
00377 list_size++;
00378 top_idx++;
00379 break;
00380 }
00381 }
00382 }
00383 }
00384
00385
00386 list_size = imin( list_size, 32 );
00387 for ( i = 0; i < list_size; i++ )
00388 {
00389 re_order[i] = tmp_reorder[i];
00390 }
00391
00392
00393
00394 no_reorder = 1;
00395 for (i=0; i<num_ref_idx_lX_active; i++)
00396 {
00397 if (default_order[i] != re_order[i])
00398 {
00399 no_reorder = 0;
00400 }
00401 }
00402
00403
00404 if (no_reorder == 0)
00405 {
00406 for (i=0; i<num_ref_idx_lX_active; i++)
00407 {
00408 diff = re_order[i] - picNumLXPred;
00409 if (diff <= 0)
00410 {
00411 reordering_of_pic_nums_idc[i] = 0;
00412 abs_diff_pic_num_minus1[i] = iabs(diff)-1;
00413 if (abs_diff_pic_num_minus1[i] < 0)
00414 abs_diff_pic_num_minus1[i] = maxPicNum -1;
00415 }
00416 else
00417 {
00418 reordering_of_pic_nums_idc[i] = 1;
00419 abs_diff_pic_num_minus1[i] = iabs(diff)-1;
00420 }
00421 picNumLXPred = re_order[i];
00422
00423 tmp_reorder[i] = re_order[i];
00424
00425 k = i;
00426 for (j = i; j < num_ref_idx_lX_active; j++)
00427 {
00428 if (default_order[j] != re_order[i])
00429 {
00430 ++k;
00431 tmp_reorder[k] = default_order[j];
00432 }
00433 }
00434 reorder_stop = 1;
00435 for(j=i+1; j<num_ref_idx_lX_active; j++)
00436 {
00437 if (tmp_reorder[j] != re_order[j])
00438 {
00439 reorder_stop = 0;
00440 break;
00441 }
00442 }
00443
00444 if (reorder_stop==1)
00445 {
00446 ++i;
00447 break;
00448 }
00449
00450 memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
00451 }
00452 reordering_of_pic_nums_idc[i] = 3;
00453
00454 memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int));
00455
00456 if (list_no==0)
00457 {
00458 currSlice->ref_pic_list_reordering_flag[LIST_0] = 1;
00459 }
00460 else
00461 {
00462 currSlice->ref_pic_list_reordering_flag[LIST_1] = 1;
00463 }
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 void reorder_lists( Slice *currSlice )
00475 {
00476 ImageParameters *p_Img = currSlice->p_Img;
00477 InputParameters *p_Inp = currSlice->p_Inp;
00478
00479
00480 if ( currSlice->slice_type == P_SLICE && p_Inp->ReferenceReorder)
00481 {
00482 int i, num_ref;
00483
00484 alloc_ref_pic_list_reordering_buffer(currSlice);
00485
00486 for (i = 0; i < currSlice->num_ref_idx_active[LIST_0] + 1; i++)
00487 {
00488 currSlice->reordering_of_pic_nums_idc[LIST_0][i] = 3;
00489 currSlice->abs_diff_pic_num_minus1[LIST_0][i] = 0;
00490 currSlice->long_term_pic_idx[LIST_0][i] = 0;
00491 }
00492
00493 num_ref = currSlice->num_ref_idx_active[LIST_0];
00494 if ( currSlice->structure == FRAME )
00495 currSlice->poc_ref_pic_reorder_frame(currSlice, p_Img->listX[LIST_0], num_ref,
00496 currSlice->reordering_of_pic_nums_idc[LIST_0],
00497 currSlice->abs_diff_pic_num_minus1[LIST_0],
00498 currSlice->long_term_pic_idx[LIST_0], LIST_0);
00499 else
00500 {
00501 poc_ref_pic_reorder_field(currSlice, p_Img->listX[LIST_0], num_ref,
00502 currSlice->reordering_of_pic_nums_idc[LIST_0],
00503 currSlice->abs_diff_pic_num_minus1[LIST_0],
00504 currSlice->long_term_pic_idx[LIST_0], LIST_0);
00505 }
00506
00507 reorder_ref_pic_list ( currSlice, p_Img->listX, p_Img->listXsize, LIST_0);
00508 }
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518 void wp_mcprec_reorder_lists( Slice *currSlice )
00519 {
00520
00521 ImageParameters *p_Img = currSlice->p_Img;
00522 int i, num_ref;
00523
00524 wpxModifyRefPicList( currSlice );
00525
00526 alloc_ref_pic_list_reordering_buffer(currSlice);
00527
00528 for (i = 0; i < currSlice->num_ref_idx_active[LIST_0] + 1; i++)
00529 {
00530 currSlice->reordering_of_pic_nums_idc[LIST_0][i] = 3;
00531 currSlice->abs_diff_pic_num_minus1[LIST_0][i] = 0;
00532 currSlice->long_term_pic_idx[LIST_0][i] = 0;
00533 }
00534
00535 if (currSlice->slice_type == B_SLICE)
00536 {
00537 for (i = 0; i < currSlice->num_ref_idx_active[LIST_1] + 1; i++)
00538 {
00539 currSlice->reordering_of_pic_nums_idc[LIST_1][i] = 3;
00540 currSlice->abs_diff_pic_num_minus1[LIST_1][i] = 0;
00541 currSlice->long_term_pic_idx[LIST_1][i] = 0;
00542 }
00543 }
00544
00545
00546 num_ref = currSlice->num_ref_idx_active[LIST_0];
00547
00548 currSlice->poc_ref_pic_reorder_frame(currSlice, p_Img->listX[LIST_0], num_ref,
00549 currSlice->reordering_of_pic_nums_idc[LIST_0],
00550 currSlice->abs_diff_pic_num_minus1[LIST_0],
00551 currSlice->long_term_pic_idx[LIST_0], LIST_0);
00552
00553 reorder_ref_pic_list ( currSlice, p_Img->listX, p_Img->listXsize, LIST_0);
00554
00555 if ( currSlice->slice_type == B_SLICE )
00556 {
00557
00558 num_ref = currSlice->num_ref_idx_active[LIST_1];
00559
00560 currSlice->poc_ref_pic_reorder_frame(currSlice, p_Img->listX[LIST_1], num_ref,
00561 currSlice->reordering_of_pic_nums_idc[LIST_1],
00562 currSlice->abs_diff_pic_num_minus1[LIST_1],
00563 currSlice->long_term_pic_idx[LIST_1], LIST_1);
00564
00565 reorder_ref_pic_list ( currSlice, p_Img->listX, p_Img->listXsize, LIST_1);
00566 }
00567 }
00568