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