00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "contributors.h"
00015
00016 #include <ctype.h>
00017 #include <limits.h>
00018 #include "global.h"
00019
00020 #include "explicit_gop.h"
00021 #include "image.h"
00022 #include "nalucommon.h"
00023 #include "report.h"
00024
00025
00026
00027
00028
00029
00030
00031 void create_hierarchy(InputParameters *pparams)
00032 {
00033 int i, j;
00034 int centerB = pparams->NumberBFrames/2;
00035 GOP_DATA tmp;
00036
00037 if (pparams->HierarchicalCoding == 1)
00038 {
00039 for (i=0;i<pparams->NumberBFrames;i++)
00040 {
00041 if (i < centerB)
00042 {
00043 gop_structure[i].slice_type = ( pparams->PReplaceBSlice ) ? P_SLICE : B_SLICE;
00044 gop_structure[i].display_no = i * 2 + 1;
00045 gop_structure[i].hierarchy_layer = 1;
00046 gop_structure[i].reference_idc = NALU_PRIORITY_LOW;
00047 gop_structure[i].slice_qp = imax(0, (pparams->qp[0][B_SLICE] + (pparams->HierarchyLevelQPEnable ? -1: pparams->qpBRSOffset[0])));
00048
00049 }
00050 else
00051 {
00052 gop_structure[i].slice_type = ( pparams->PReplaceBSlice ) ? P_SLICE : B_SLICE;
00053 gop_structure[i].display_no = (i - centerB) * 2;
00054 gop_structure[i].hierarchy_layer = 0;
00055 gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
00056 gop_structure[i].slice_qp = pparams->qp[0][B_SLICE];
00057 }
00058 }
00059 img->GopLevels = 2;
00060 }
00061 else
00062 {
00063 int GOPlevels = 1;
00064 int Bframes = pparams->NumberBFrames;
00065 int *curGOPLevelfrm,*curGOPLeveldist ;
00066 int curlevel = GOPlevels ;
00067 int i;
00068
00069 while (((Bframes + 1 ) >> GOPlevels) > 1)
00070 {
00071 GOPlevels ++;
00072 }
00073
00074 curlevel = GOPlevels;
00075 img->GopLevels = GOPlevels;
00076 if (NULL == (curGOPLevelfrm = (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_hierarchy:curGOPLevelfrm");
00077 if (NULL == (curGOPLeveldist= (int*)malloc(GOPlevels * sizeof(int)))) no_mem_exit("create_hierarchy:curGOPLeveldist");
00078
00079 for (i=0; i <pparams->NumberBFrames; i++)
00080 {
00081 gop_structure[i].display_no = i;
00082 gop_structure[i].slice_type = ( pparams->PReplaceBSlice ) ? P_SLICE : B_SLICE;
00083 gop_structure[i].hierarchy_layer = 0;
00084 gop_structure[i].reference_idc = NALU_PRIORITY_DISPOSABLE;
00085 gop_structure[i].slice_qp = pparams->qp[0][B_SLICE];
00086 }
00087
00088 for (j = 1; j < GOPlevels; j++)
00089 {
00090 for (i = (1 << j) - 1; i < Bframes + 1 - (1 << j); i += (1 << j))
00091 {
00092 gop_structure[i].hierarchy_layer = j;
00093 gop_structure[i].reference_idc = NALU_PRIORITY_LOW;
00094 gop_structure[i].slice_qp = imax(0, pparams->qp[0][B_SLICE] + (pparams->HierarchyLevelQPEnable ? -j: pparams->qpBRSOffset[0]));
00095
00096
00097
00098
00099
00100 }
00101 }
00102
00103 for (i = 1; i < Bframes; i++)
00104 {
00105 j = i;
00106
00107 while (j > 0 && gop_structure[j].hierarchy_layer > gop_structure[j-1].hierarchy_layer)
00108 {
00109 tmp = gop_structure[j-1];
00110 gop_structure[j-1] = gop_structure[j];
00111 gop_structure[j] = tmp;
00112 j--;
00113 }
00114 }
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 void init_gop_structure(InputParameters *pparams)
00127 {
00128 int max_gopsize = pparams->NumberBFrames;
00129
00130 gop_structure = calloc(imax(10,max_gopsize), sizeof (GOP_DATA));
00131 if (NULL==gop_structure)
00132 no_mem_exit("init_gop_structure: gop_structure");
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142 void clear_gop_structure(void)
00143 {
00144 if (gop_structure)
00145 free(gop_structure);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 void interpret_gop_structure()
00156 {
00157 int nLength = strlen(params->ExplicitHierarchyFormat);
00158 int i =0, k, dqp, display_no;
00159 int slice_read =0, order_read = 0, stored_read = 0, qp_read =0;
00160 int coded_frame = 0;
00161
00162 if (nLength > 0)
00163 {
00164
00165 for (i = 0; i < nLength ; i++)
00166 {
00167
00168 if (slice_read == 0)
00169 {
00170 switch (params->ExplicitHierarchyFormat[i])
00171 {
00172 case 'P':
00173 case 'p':
00174 gop_structure[coded_frame].slice_type=P_SLICE;
00175 break;
00176 case 'B':
00177 case 'b':
00178 gop_structure[coded_frame].slice_type=B_SLICE;
00179 break;
00180 case 'I':
00181 case 'i':
00182 gop_structure[coded_frame].slice_type=I_SLICE;
00183 break;
00184 default:
00185 snprintf(errortext, ET_SIZE, "Slice Type invalid in ExplicitHierarchyFormat param. Please check configuration file.");
00186 error (errortext, 400);
00187 break;
00188 }
00189 slice_read = 1;
00190 }
00191 else
00192 {
00193
00194 if (order_read == 0)
00195 {
00196 if (isdigit((int)(*(params->ExplicitHierarchyFormat+i))))
00197 {
00198 sscanf(params->ExplicitHierarchyFormat+i,"%d",&display_no);
00199 gop_structure[coded_frame].display_no = display_no;
00200 order_read = 1;
00201 if (display_no < 0 || display_no >= params->NumberBFrames)
00202 {
00203 snprintf(errortext, ET_SIZE, "Invalid Frame Order value. Frame position needs to be in [0,%d] range.",params->NumberBFrames - 1);
00204 error (errortext, 400);
00205 }
00206 for (k=0;k<coded_frame;k++)
00207 {
00208 if (gop_structure[k].display_no == display_no)
00209 {
00210 snprintf(errortext, ET_SIZE, "Frame Order value %d in frame %d already used for enhancement frame %d.",display_no,coded_frame,k);
00211 error (errortext, 400);
00212 }
00213 }
00214 }
00215 else
00216 {
00217 snprintf(errortext, ET_SIZE, "Slice Type needs to be followed by Display Order. Please check configuration file.");
00218 error (errortext, 400);
00219 }
00220 }
00221 else if (order_read == 1)
00222 {
00223 if (stored_read == 0 && !(isdigit((int)(*(params->ExplicitHierarchyFormat+i)))))
00224 {
00225 switch (params->ExplicitHierarchyFormat[i])
00226 {
00227 case 'E':
00228 case 'e':
00229 gop_structure[coded_frame].reference_idc = NALU_PRIORITY_DISPOSABLE;
00230 gop_structure[coded_frame].hierarchy_layer = 0;
00231 break;
00232 case 'R':
00233 case 'r':
00234 gop_structure[coded_frame].reference_idc= NALU_PRIORITY_LOW;
00235 gop_structure[coded_frame].hierarchy_layer = 1;
00236 img->GopLevels = 2;
00237 break;
00238 default:
00239 snprintf(errortext, ET_SIZE, "Reference_IDC invalid in ExplicitHierarchyFormat param. Please check configuration file.");
00240 error (errortext, 400);
00241 break;
00242 }
00243 stored_read = 1;
00244 }
00245 else if (stored_read == 1 && qp_read == 0)
00246 {
00247 if (isdigit((int)(*(params->ExplicitHierarchyFormat+i))))
00248 {
00249 sscanf(params->ExplicitHierarchyFormat+i,"%d",&dqp);
00250
00251 gop_structure[coded_frame].slice_qp = params->qp[0][ gop_structure[coded_frame].slice_type ];
00252 gop_structure[coded_frame].slice_qp = iClip3(-img->bitdepth_luma_qp_scale, 51,gop_structure[coded_frame].slice_qp + dqp);
00253 qp_read = 1;
00254 }
00255 else
00256 {
00257 snprintf(errortext, ET_SIZE, "Reference_IDC needs to be followed by QP. Please check configuration file.");
00258 error (errortext, 400);
00259 }
00260 }
00261 else if (stored_read == 1 && qp_read == 1 && !(isdigit((int)(*(params->ExplicitHierarchyFormat+i)))) && (i < nLength - 2))
00262 {
00263 stored_read =0;
00264 qp_read=0;
00265 order_read=0;
00266 slice_read=0;
00267 i--;
00268 coded_frame ++;
00269 if (coded_frame >= params->NumberBFrames )
00270 {
00271 snprintf(errortext, ET_SIZE, "Total number of frames in Enhancement GOP need to be fewer or equal to NumberBFrames parameter.");
00272 error (errortext, 400);
00273 }
00274 }
00275 }
00276 }
00277 }
00278 }
00279 else
00280 {
00281 snprintf(errortext, ET_SIZE, "ExplicitHierarchyFormat is empty. Please check configuration file.");
00282 error (errortext, 400);
00283 }
00284
00285 params->NumberBFrames = coded_frame + 1;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 void poc_based_ref_management_frame_pic(int current_pic_num)
00296 {
00297 unsigned i, pic_num = 0;
00298
00299 int min_poc=INT_MAX;
00300 DecRefPicMarking_t *tmp_drpm,*tmp_drpm2;
00301
00302 if (img->dec_ref_pic_marking_buffer!=NULL)
00303 return;
00304
00305 if ((dpb.ref_frames_in_buffer + dpb.ltref_frames_in_buffer)==0)
00306 return;
00307
00308 for (i = 0; i < dpb.used_size; i++)
00309 {
00310 if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)) && dpb.fs[i]->poc < min_poc)
00311 {
00312 min_poc = dpb.fs[i]->frame->poc ;
00313 pic_num = dpb.fs[i]->frame->pic_num;
00314 }
00315 }
00316
00317 if (NULL==(tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t))))
00318 no_mem_exit("poc_based_ref_management: tmp_drpm");
00319 tmp_drpm->Next=NULL;
00320
00321 tmp_drpm->memory_management_control_operation = 0;
00322
00323 if (NULL==(tmp_drpm2=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t))))
00324 no_mem_exit("poc_based_ref_management: tmp_drpm2");
00325 tmp_drpm2->Next=tmp_drpm;
00326
00327 tmp_drpm2->memory_management_control_operation = 1;
00328 tmp_drpm2->difference_of_pic_nums_minus1 = current_pic_num - pic_num - 1;
00329 img->dec_ref_pic_marking_buffer = tmp_drpm2;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 void poc_based_ref_management_field_pic(int current_pic_num)
00340 {
00341 unsigned int i, pic_num1 = 0, pic_num2 = 0;
00342
00343 int min_poc=INT_MAX;
00344 DecRefPicMarking_t *tmp_drpm,*tmp_drpm2, *tmp_drpm3;
00345
00346 if (img->dec_ref_pic_marking_buffer!=NULL)
00347 return;
00348
00349 if ((dpb.ref_frames_in_buffer+dpb.ltref_frames_in_buffer)==0)
00350 return;
00351
00352 if ( img->structure == TOP_FIELD )
00353 {
00354 for (i=0; i<dpb.used_size;i++)
00355 {
00356 if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)) && dpb.fs[i]->poc < min_poc)
00357 {
00358 min_poc = dpb.fs[i]->poc;
00359 pic_num1 = dpb.fs[i]->top_field->pic_num;
00360 pic_num2 = dpb.fs[i]->bottom_field->pic_num;
00361 }
00362 }
00363 }
00364
00365 if (NULL==(tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm");
00366 tmp_drpm->Next=NULL;
00367 tmp_drpm->memory_management_control_operation = 0;
00368
00369 if ( img->structure == BOTTOM_FIELD )
00370 {
00371 img->dec_ref_pic_marking_buffer = tmp_drpm;
00372 return;
00373 }
00374
00375 if (NULL==(tmp_drpm2=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm2");
00376 tmp_drpm2->Next=tmp_drpm;
00377 tmp_drpm2->memory_management_control_operation = 1;
00378 tmp_drpm2->difference_of_pic_nums_minus1 = current_pic_num - pic_num1 - 1;
00379
00380 if (NULL==(tmp_drpm3=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm3");
00381 tmp_drpm3->Next=tmp_drpm2;
00382 tmp_drpm3->memory_management_control_operation = 1;
00383 tmp_drpm3->difference_of_pic_nums_minus1 = current_pic_num - pic_num2 - 1;
00384
00385 img->dec_ref_pic_marking_buffer = tmp_drpm3;
00386 }
00387