1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #include "avcenc_lib.h" 19 #include "avcenc_api.h" 20 21 #define LOG2_MAX_FRAME_NUM_MINUS4 12 /* 12 default */ 22 #define SLICE_GROUP_CHANGE_CYCLE 1 /* default */ 23 24 /* initialized variables to be used in SPS*/ 25 AVCEnc_Status SetEncodeParam(AVCHandle* avcHandle, AVCEncParams* encParam, 26 void* extSPS, void* extPPS) 27 { 28 AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 29 AVCCommonObj *video = encvid->common; 30 AVCSeqParamSet *seqParam = video->currSeqParams; 31 AVCPicParamSet *picParam = video->currPicParams; 32 AVCSliceHeader *sliceHdr = video->sliceHdr; 33 AVCRateControl *rateCtrl = encvid->rateCtrl; 34 AVCEnc_Status status; 35 void *userData = avcHandle->userData; 36 int ii, maxFrameNum; 37 38 AVCSeqParamSet* extS = NULL; 39 AVCPicParamSet* extP = NULL; 40 41 if (extSPS) extS = (AVCSeqParamSet*) extSPS; 42 if (extPPS) extP = (AVCPicParamSet*) extPPS; 43 44 /* This part sets the default values of the encoding options this 45 library supports in seqParam, picParam and sliceHdr structures and 46 also copy the values from the encParam into the above 3 structures. 47 48 Some parameters will be assigned later when we encode SPS or PPS such as 49 the seq_parameter_id or pic_parameter_id. Also some of the slice parameters 50 have to be re-assigned per slice basis such as frame_num, slice_type, 51 first_mb_in_slice, pic_order_cnt_lsb, slice_qp_delta, slice_group_change_cycle */ 52 53 /* profile_idc, constrained_setx_flag and level_idc is set by VerifyProfile(), 54 and VerifyLevel() functions later. */ 55 56 encvid->fullsearch_enable = encParam->fullsearch; 57 58 encvid->outOfBandParamSet = ((encParam->out_of_band_param_set == AVC_ON) ? TRUE : FALSE); 59 60 /* parameters derived from the the encParam that are used in SPS */ 61 if (extS) 62 { 63 video->MaxPicOrderCntLsb = 1 << (extS->log2_max_pic_order_cnt_lsb_minus4 + 4); 64 video->PicWidthInMbs = extS->pic_width_in_mbs_minus1 + 1; 65 video->PicHeightInMapUnits = extS->pic_height_in_map_units_minus1 + 1 ; 66 video->FrameHeightInMbs = (2 - extS->frame_mbs_only_flag) * video->PicHeightInMapUnits ; 67 } 68 else 69 { 70 video->MaxPicOrderCntLsb = 1 << (encParam->log2_max_poc_lsb_minus_4 + 4); 71 video->PicWidthInMbs = (encParam->width + 15) >> 4; /* round it to multiple of 16 */ 72 video->FrameHeightInMbs = (encParam->height + 15) >> 4; /* round it to multiple of 16 */ 73 video->PicHeightInMapUnits = video->FrameHeightInMbs; 74 } 75 76 video->PicWidthInSamplesL = video->PicWidthInMbs * 16 ; 77 if (video->PicWidthInSamplesL + 32 > 0xFFFF) 78 { 79 return AVCENC_NOT_SUPPORTED; // we use 2-bytes for pitch 80 } 81 82 video->PicWidthInSamplesC = video->PicWidthInMbs * 8 ; 83 video->PicHeightInMbs = video->FrameHeightInMbs; 84 video->PicSizeInMapUnits = video->PicWidthInMbs * video->PicHeightInMapUnits ; 85 video->PicHeightInSamplesL = video->PicHeightInMbs * 16; 86 video->PicHeightInSamplesC = video->PicHeightInMbs * 8; 87 video->PicSizeInMbs = video->PicWidthInMbs * video->PicHeightInMbs; 88 89 if (!extS && !extP) 90 { 91 maxFrameNum = (encParam->idr_period == -1) ? (1 << 16) : encParam->idr_period; 92 ii = 0; 93 while (maxFrameNum > 0) 94 { 95 ii++; 96 maxFrameNum >>= 1; 97 } 98 if (ii < 4) ii = 4; 99 else if (ii > 16) ii = 16; 100 101 seqParam->log2_max_frame_num_minus4 = ii - 4;//LOG2_MAX_FRAME_NUM_MINUS4; /* default */ 102 103 video->MaxFrameNum = 1 << ii; //(LOG2_MAX_FRAME_NUM_MINUS4 + 4); /* default */ 104 video->MaxPicNum = video->MaxFrameNum; 105 106 /************* set the SPS *******************/ 107 seqParam->seq_parameter_set_id = 0; /* start with zero */ 108 /* POC */ 109 seqParam->pic_order_cnt_type = encParam->poc_type; /* POC type */ 110 if (encParam->poc_type == 0) 111 { 112 if (/*encParam->log2_max_poc_lsb_minus_4<0 || (no need, it's unsigned)*/ 113 encParam->log2_max_poc_lsb_minus_4 > 12) 114 { 115 return AVCENC_INVALID_POC_LSB; 116 } 117 seqParam->log2_max_pic_order_cnt_lsb_minus4 = encParam->log2_max_poc_lsb_minus_4; 118 } 119 else if (encParam->poc_type == 1) 120 { 121 seqParam->delta_pic_order_always_zero_flag = encParam->delta_poc_zero_flag; 122 seqParam->offset_for_non_ref_pic = encParam->offset_poc_non_ref; 123 seqParam->offset_for_top_to_bottom_field = encParam->offset_top_bottom; 124 seqParam->num_ref_frames_in_pic_order_cnt_cycle = encParam->num_ref_in_cycle; 125 if (encParam->offset_poc_ref == NULL) 126 { 127 return AVCENC_ENCPARAM_MEM_FAIL; 128 } 129 for (ii = 0; ii < encParam->num_ref_frame; ii++) 130 { 131 seqParam->offset_for_ref_frame[ii] = encParam->offset_poc_ref[ii]; 132 } 133 } 134 /* number of reference frame */ 135 if (encParam->num_ref_frame > 16 || encParam->num_ref_frame < 0) 136 { 137 return AVCENC_INVALID_NUM_REF; 138 } 139 seqParam->num_ref_frames = encParam->num_ref_frame; /* num reference frame range 0...16*/ 140 seqParam->gaps_in_frame_num_value_allowed_flag = FALSE; 141 seqParam->pic_width_in_mbs_minus1 = video->PicWidthInMbs - 1; 142 seqParam->pic_height_in_map_units_minus1 = video->PicHeightInMapUnits - 1; 143 seqParam->frame_mbs_only_flag = TRUE; 144 seqParam->mb_adaptive_frame_field_flag = FALSE; 145 seqParam->direct_8x8_inference_flag = FALSE; /* default */ 146 seqParam->frame_cropping_flag = FALSE; 147 seqParam->frame_crop_bottom_offset = 0; 148 seqParam->frame_crop_left_offset = 0; 149 seqParam->frame_crop_right_offset = 0; 150 seqParam->frame_crop_top_offset = 0; 151 seqParam->vui_parameters_present_flag = FALSE; /* default */ 152 } 153 else if (extS) // use external SPS and PPS 154 { 155 seqParam->seq_parameter_set_id = extS->seq_parameter_set_id; 156 seqParam->log2_max_frame_num_minus4 = extS->log2_max_frame_num_minus4; 157 video->MaxFrameNum = 1 << (extS->log2_max_frame_num_minus4 + 4); 158 video->MaxPicNum = video->MaxFrameNum; 159 if (encParam->idr_period > (int)(video->MaxFrameNum) || (encParam->idr_period == -1)) 160 { 161 encParam->idr_period = (int)video->MaxFrameNum; 162 } 163 164 seqParam->pic_order_cnt_type = extS->pic_order_cnt_type; 165 if (seqParam->pic_order_cnt_type == 0) 166 { 167 if (/*extS->log2_max_pic_order_cnt_lsb_minus4<0 || (no need it's unsigned)*/ 168 extS->log2_max_pic_order_cnt_lsb_minus4 > 12) 169 { 170 return AVCENC_INVALID_POC_LSB; 171 } 172 seqParam->log2_max_pic_order_cnt_lsb_minus4 = extS->log2_max_pic_order_cnt_lsb_minus4; 173 } 174 else if (seqParam->pic_order_cnt_type == 1) 175 { 176 seqParam->delta_pic_order_always_zero_flag = extS->delta_pic_order_always_zero_flag; 177 seqParam->offset_for_non_ref_pic = extS->offset_for_non_ref_pic; 178 seqParam->offset_for_top_to_bottom_field = extS->offset_for_top_to_bottom_field; 179 seqParam->num_ref_frames_in_pic_order_cnt_cycle = extS->num_ref_frames_in_pic_order_cnt_cycle; 180 for (ii = 0; ii < (int) extS->num_ref_frames; ii++) 181 { 182 seqParam->offset_for_ref_frame[ii] = extS->offset_for_ref_frame[ii]; 183 } 184 } 185 /* number of reference frame */ 186 if (extS->num_ref_frames > 16 /*|| extS->num_ref_frames<0 (no need, it's unsigned)*/) 187 { 188 return AVCENC_INVALID_NUM_REF; 189 } 190 seqParam->num_ref_frames = extS->num_ref_frames; /* num reference frame range 0...16*/ 191 seqParam->gaps_in_frame_num_value_allowed_flag = extS->gaps_in_frame_num_value_allowed_flag; 192 seqParam->pic_width_in_mbs_minus1 = extS->pic_width_in_mbs_minus1; 193 seqParam->pic_height_in_map_units_minus1 = extS->pic_height_in_map_units_minus1; 194 seqParam->frame_mbs_only_flag = extS->frame_mbs_only_flag; 195 if (extS->frame_mbs_only_flag != TRUE) 196 { 197 return AVCENC_NOT_SUPPORTED; 198 } 199 seqParam->mb_adaptive_frame_field_flag = extS->mb_adaptive_frame_field_flag; 200 if (extS->mb_adaptive_frame_field_flag != FALSE) 201 { 202 return AVCENC_NOT_SUPPORTED; 203 } 204 205 seqParam->direct_8x8_inference_flag = extS->direct_8x8_inference_flag; 206 seqParam->frame_cropping_flag = extS->frame_cropping_flag ; 207 if (extS->frame_cropping_flag != FALSE) 208 { 209 return AVCENC_NOT_SUPPORTED; 210 } 211 212 seqParam->frame_crop_bottom_offset = 0; 213 seqParam->frame_crop_left_offset = 0; 214 seqParam->frame_crop_right_offset = 0; 215 seqParam->frame_crop_top_offset = 0; 216 seqParam->vui_parameters_present_flag = extS->vui_parameters_present_flag; 217 if (extS->vui_parameters_present_flag) 218 { 219 memcpy(&(seqParam->vui_parameters), &(extS->vui_parameters), sizeof(AVCVUIParams)); 220 } 221 } 222 else 223 { 224 return AVCENC_NOT_SUPPORTED; 225 } 226 227 /***************** now PPS ******************************/ 228 if (!extP && !extS) 229 { 230 picParam->pic_parameter_set_id = (uint)(-1); /* start with zero */ 231 picParam->seq_parameter_set_id = (uint)(-1); /* start with zero */ 232 picParam->entropy_coding_mode_flag = 0; /* default to CAVLC */ 233 picParam->pic_order_present_flag = 0; /* default for now, will need it for B-slice */ 234 /* FMO */ 235 if (encParam->num_slice_group < 1 || encParam->num_slice_group > MAX_NUM_SLICE_GROUP) 236 { 237 return AVCENC_INVALID_NUM_SLICEGROUP; 238 } 239 picParam->num_slice_groups_minus1 = encParam->num_slice_group - 1; 240 241 if (picParam->num_slice_groups_minus1 > 0) 242 { 243 picParam->slice_group_map_type = encParam->fmo_type; 244 switch (encParam->fmo_type) 245 { 246 case 0: 247 for (ii = 0; ii <= (int)picParam->num_slice_groups_minus1; ii++) 248 { 249 picParam->run_length_minus1[ii] = encParam->run_length_minus1[ii]; 250 } 251 break; 252 case 2: 253 for (ii = 0; ii < (int)picParam->num_slice_groups_minus1; ii++) 254 { 255 picParam->top_left[ii] = encParam->top_left[ii]; 256 picParam->bottom_right[ii] = encParam->bottom_right[ii]; 257 } 258 break; 259 case 3: 260 case 4: 261 case 5: 262 if (encParam->change_dir_flag == AVC_ON) 263 { 264 picParam->slice_group_change_direction_flag = TRUE; 265 } 266 else 267 { 268 picParam->slice_group_change_direction_flag = FALSE; 269 } 270 if (/*encParam->change_rate_minus1 < 0 || (no need it's unsigned) */ 271 encParam->change_rate_minus1 > video->PicSizeInMapUnits - 1) 272 { 273 return AVCENC_INVALID_CHANGE_RATE; 274 } 275 picParam->slice_group_change_rate_minus1 = encParam->change_rate_minus1; 276 video->SliceGroupChangeRate = picParam->slice_group_change_rate_minus1 + 1; 277 break; 278 case 6: 279 picParam->pic_size_in_map_units_minus1 = video->PicSizeInMapUnits - 1; 280 281 /* allocate picParam->slice_group_id */ 282 picParam->slice_group_id = (uint*)avcHandle->CBAVC_Malloc(userData, sizeof(uint) * video->PicSizeInMapUnits, DEFAULT_ATTR); 283 if (picParam->slice_group_id == NULL) 284 { 285 return AVCENC_MEMORY_FAIL; 286 } 287 288 if (encParam->slice_group == NULL) 289 { 290 return AVCENC_ENCPARAM_MEM_FAIL; 291 } 292 for (ii = 0; ii < (int)video->PicSizeInMapUnits; ii++) 293 { 294 picParam->slice_group_id[ii] = encParam->slice_group[ii]; 295 } 296 break; 297 default: 298 return AVCENC_INVALID_FMO_TYPE; 299 } 300 } 301 picParam->num_ref_idx_l0_active_minus1 = encParam->num_ref_frame - 1; /* assume frame only */ 302 picParam->num_ref_idx_l1_active_minus1 = 0; /* default value */ 303 picParam->weighted_pred_flag = 0; /* no weighted prediction supported */ 304 picParam->weighted_bipred_idc = 0; /* range 0,1,2 */ 305 if (/*picParam->weighted_bipred_idc < 0 || (no need, it's unsigned) */ 306 picParam->weighted_bipred_idc > 2) 307 { 308 return AVCENC_WEIGHTED_BIPRED_FAIL; 309 } 310 picParam->pic_init_qp_minus26 = 0; /* default, will be changed at slice level anyway */ 311 if (picParam->pic_init_qp_minus26 < -26 || picParam->pic_init_qp_minus26 > 25) 312 { 313 return AVCENC_INIT_QP_FAIL; /* out of range */ 314 } 315 picParam->pic_init_qs_minus26 = 0; 316 if (picParam->pic_init_qs_minus26 < -26 || picParam->pic_init_qs_minus26 > 25) 317 { 318 return AVCENC_INIT_QS_FAIL; /* out of range */ 319 } 320 321 picParam->chroma_qp_index_offset = 0; /* default to zero for now */ 322 if (picParam->chroma_qp_index_offset < -12 || picParam->chroma_qp_index_offset > 12) 323 { 324 return AVCENC_CHROMA_QP_FAIL; /* out of range */ 325 } 326 /* deblocking */ 327 picParam->deblocking_filter_control_present_flag = (encParam->db_filter == AVC_ON) ? TRUE : FALSE ; 328 /* constrained intra prediction */ 329 picParam->constrained_intra_pred_flag = (encParam->constrained_intra_pred == AVC_ON) ? TRUE : FALSE; 330 picParam->redundant_pic_cnt_present_flag = 0; /* default */ 331 } 332 else if (extP)// external PPS 333 { 334 picParam->pic_parameter_set_id = extP->pic_parameter_set_id - 1; /* to be increased by one */ 335 picParam->seq_parameter_set_id = extP->seq_parameter_set_id; 336 picParam->entropy_coding_mode_flag = extP->entropy_coding_mode_flag; 337 if (extP->entropy_coding_mode_flag != 0) /* default to CAVLC */ 338 { 339 return AVCENC_NOT_SUPPORTED; 340 } 341 picParam->pic_order_present_flag = extP->pic_order_present_flag; /* default for now, will need it for B-slice */ 342 if (extP->pic_order_present_flag != 0) 343 { 344 return AVCENC_NOT_SUPPORTED; 345 } 346 /* FMO */ 347 if (/*(extP->num_slice_groups_minus1<0) || (no need it's unsigned) */ 348 (extP->num_slice_groups_minus1 > MAX_NUM_SLICE_GROUP - 1)) 349 { 350 return AVCENC_INVALID_NUM_SLICEGROUP; 351 } 352 picParam->num_slice_groups_minus1 = extP->num_slice_groups_minus1; 353 354 if (picParam->num_slice_groups_minus1 > 0) 355 { 356 picParam->slice_group_map_type = extP->slice_group_map_type; 357 switch (extP->slice_group_map_type) 358 { 359 case 0: 360 for (ii = 0; ii <= (int)extP->num_slice_groups_minus1; ii++) 361 { 362 picParam->run_length_minus1[ii] = extP->run_length_minus1[ii]; 363 } 364 break; 365 case 2: 366 for (ii = 0; ii < (int)picParam->num_slice_groups_minus1; ii++) 367 { 368 picParam->top_left[ii] = extP->top_left[ii]; 369 picParam->bottom_right[ii] = extP->bottom_right[ii]; 370 } 371 break; 372 case 3: 373 case 4: 374 case 5: 375 picParam->slice_group_change_direction_flag = extP->slice_group_change_direction_flag; 376 if (/*extP->slice_group_change_rate_minus1 < 0 || (no need, it's unsigned) */ 377 extP->slice_group_change_rate_minus1 > video->PicSizeInMapUnits - 1) 378 { 379 return AVCENC_INVALID_CHANGE_RATE; 380 } 381 picParam->slice_group_change_rate_minus1 = extP->slice_group_change_rate_minus1; 382 video->SliceGroupChangeRate = picParam->slice_group_change_rate_minus1 + 1; 383 break; 384 case 6: 385 if (extP->pic_size_in_map_units_minus1 != video->PicSizeInMapUnits - 1) 386 { 387 return AVCENC_NOT_SUPPORTED; 388 } 389 390 picParam->pic_size_in_map_units_minus1 = extP->pic_size_in_map_units_minus1; 391 392 /* allocate picParam->slice_group_id */ 393 picParam->slice_group_id = (uint*)avcHandle->CBAVC_Malloc(userData, sizeof(uint) * video->PicSizeInMapUnits, DEFAULT_ATTR); 394 if (picParam->slice_group_id == NULL) 395 { 396 return AVCENC_MEMORY_FAIL; 397 } 398 399 if (extP->slice_group_id == NULL) 400 { 401 return AVCENC_ENCPARAM_MEM_FAIL; 402 } 403 for (ii = 0; ii < (int)video->PicSizeInMapUnits; ii++) 404 { 405 picParam->slice_group_id[ii] = extP->slice_group_id[ii]; 406 } 407 break; 408 default: 409 return AVCENC_INVALID_FMO_TYPE; 410 } 411 } 412 picParam->num_ref_idx_l0_active_minus1 = extP->num_ref_idx_l0_active_minus1; 413 picParam->num_ref_idx_l1_active_minus1 = extP->num_ref_idx_l1_active_minus1; /* default value */ 414 if (picParam->num_ref_idx_l1_active_minus1 != 0) 415 { 416 return AVCENC_NOT_SUPPORTED; 417 } 418 419 if (extP->weighted_pred_flag) 420 { 421 return AVCENC_NOT_SUPPORTED; 422 } 423 424 picParam->weighted_pred_flag = 0; /* no weighted prediction supported */ 425 picParam->weighted_bipred_idc = extP->weighted_bipred_idc; /* range 0,1,2 */ 426 if (/*picParam->weighted_bipred_idc < 0 || (no need, it's unsigned) */ 427 picParam->weighted_bipred_idc > 2) 428 { 429 return AVCENC_WEIGHTED_BIPRED_FAIL; 430 } 431 picParam->pic_init_qp_minus26 = extP->pic_init_qp_minus26; /* default, will be changed at slice level anyway */ 432 if (picParam->pic_init_qp_minus26 < -26 || picParam->pic_init_qp_minus26 > 25) 433 { 434 return AVCENC_INIT_QP_FAIL; /* out of range */ 435 } 436 picParam->pic_init_qs_minus26 = extP->pic_init_qs_minus26; 437 if (picParam->pic_init_qs_minus26 < -26 || picParam->pic_init_qs_minus26 > 25) 438 { 439 return AVCENC_INIT_QS_FAIL; /* out of range */ 440 } 441 442 picParam->chroma_qp_index_offset = extP->chroma_qp_index_offset; /* default to zero for now */ 443 if (picParam->chroma_qp_index_offset < -12 || picParam->chroma_qp_index_offset > 12) 444 { 445 return AVCENC_CHROMA_QP_FAIL; /* out of range */ 446 } 447 /* deblocking */ 448 picParam->deblocking_filter_control_present_flag = extP->deblocking_filter_control_present_flag; 449 /* constrained intra prediction */ 450 picParam->constrained_intra_pred_flag = extP->constrained_intra_pred_flag; 451 if (extP->redundant_pic_cnt_present_flag != 0) 452 { 453 return AVCENC_NOT_SUPPORTED; 454 } 455 picParam->redundant_pic_cnt_present_flag = extP->redundant_pic_cnt_present_flag; /* default */ 456 } 457 else 458 { 459 return AVCENC_NOT_SUPPORTED; 460 } 461 462 /****************** now set up some SliceHeader parameters ***********/ 463 if (picParam->deblocking_filter_control_present_flag == TRUE) 464 { 465 /* these values only present when db_filter is ON */ 466 if (encParam->disable_db_idc > 2) 467 { 468 return AVCENC_INVALID_DEBLOCK_IDC; /* out of range */ 469 } 470 sliceHdr->disable_deblocking_filter_idc = encParam->disable_db_idc; 471 472 if (encParam->alpha_offset < -6 || encParam->alpha_offset > 6) 473 { 474 return AVCENC_INVALID_ALPHA_OFFSET; 475 } 476 sliceHdr->slice_alpha_c0_offset_div2 = encParam->alpha_offset; 477 478 if (encParam->beta_offset < -6 || encParam->beta_offset > 6) 479 { 480 return AVCENC_INVALID_BETA_OFFSET; 481 } 482 sliceHdr->slice_beta_offset_div_2 = encParam->beta_offset; 483 } 484 if (encvid->outOfBandParamSet == TRUE) 485 { 486 sliceHdr->idr_pic_id = 0; 487 } 488 else 489 { 490 sliceHdr->idr_pic_id = (uint)(-1); /* start with zero */ 491 } 492 sliceHdr->field_pic_flag = FALSE; 493 sliceHdr->bottom_field_flag = FALSE; /* won't be used anyway */ 494 video->MbaffFrameFlag = (seqParam->mb_adaptive_frame_field_flag && !sliceHdr->field_pic_flag); 495 496 /* the rest will be set in InitSlice() */ 497 498 /* now the rate control and performance related parameters */ 499 rateCtrl->scdEnable = (encParam->auto_scd == AVC_ON) ? TRUE : FALSE; 500 rateCtrl->idrPeriod = encParam->idr_period + 1; 501 rateCtrl->intraMBRate = encParam->intramb_refresh; 502 rateCtrl->dpEnable = (encParam->data_par == AVC_ON) ? TRUE : FALSE; 503 504 rateCtrl->subPelEnable = (encParam->sub_pel == AVC_ON) ? TRUE : FALSE; 505 rateCtrl->mvRange = encParam->search_range; 506 507 rateCtrl->subMBEnable = (encParam->submb_pred == AVC_ON) ? TRUE : FALSE; 508 rateCtrl->rdOptEnable = (encParam->rdopt_mode == AVC_ON) ? TRUE : FALSE; 509 rateCtrl->bidirPred = (encParam->bidir_pred == AVC_ON) ? TRUE : FALSE; 510 511 rateCtrl->rcEnable = (encParam->rate_control == AVC_ON) ? TRUE : FALSE; 512 rateCtrl->initQP = encParam->initQP; 513 rateCtrl->initQP = AVC_CLIP3(0, 51, rateCtrl->initQP); 514 515 rateCtrl->bitRate = encParam->bitrate; 516 rateCtrl->cpbSize = encParam->CPB_size; 517 rateCtrl->initDelayOffset = (rateCtrl->bitRate * encParam->init_CBP_removal_delay / 1000); 518 519 if (encParam->frame_rate == 0) 520 { 521 return AVCENC_INVALID_FRAMERATE; 522 } 523 524 rateCtrl->frame_rate = (OsclFloat)(encParam->frame_rate * 1.0 / 1000); 525 // rateCtrl->srcInterval = encParam->src_interval; 526 rateCtrl->first_frame = 1; /* set this flag for the first time */ 527 528 /* contrained_setx_flag will be set inside the VerifyProfile called below.*/ 529 if (!extS && !extP) 530 { 531 seqParam->profile_idc = encParam->profile; 532 seqParam->constrained_set0_flag = FALSE; 533 seqParam->constrained_set1_flag = FALSE; 534 seqParam->constrained_set2_flag = FALSE; 535 seqParam->constrained_set3_flag = FALSE; 536 seqParam->level_idc = encParam->level; 537 } 538 else 539 { 540 seqParam->profile_idc = extS->profile_idc; 541 seqParam->constrained_set0_flag = extS->constrained_set0_flag; 542 seqParam->constrained_set1_flag = extS->constrained_set1_flag; 543 seqParam->constrained_set2_flag = extS->constrained_set2_flag; 544 seqParam->constrained_set3_flag = extS->constrained_set3_flag; 545 seqParam->level_idc = extS->level_idc; 546 } 547 548 549 status = VerifyProfile(encvid, seqParam, picParam); 550 if (status != AVCENC_SUCCESS) 551 { 552 return status; 553 } 554 555 status = VerifyLevel(encvid, seqParam, picParam); 556 if (status != AVCENC_SUCCESS) 557 { 558 return status; 559 } 560 561 return AVCENC_SUCCESS; 562 } 563 564 /* verify the profile setting */ 565 AVCEnc_Status VerifyProfile(AVCEncObject *encvid, AVCSeqParamSet *seqParam, AVCPicParamSet *picParam) 566 { 567 AVCRateControl *rateCtrl = encvid->rateCtrl; 568 AVCEnc_Status status = AVCENC_SUCCESS; 569 570 if (seqParam->profile_idc == 0) /* find profile for this setting */ 571 { 572 /* find the right profile for it */ 573 if (seqParam->direct_8x8_inference_flag == TRUE && 574 picParam->entropy_coding_mode_flag == FALSE && 575 picParam->num_slice_groups_minus1 <= 7 /*&& 576 picParam->num_slice_groups_minus1>=0 (no need, it's unsigned) */) 577 { 578 seqParam->profile_idc = AVC_EXTENDED; 579 seqParam->constrained_set2_flag = TRUE; 580 } 581 582 if (rateCtrl->dpEnable == FALSE && 583 picParam->num_slice_groups_minus1 == 0 && 584 picParam->redundant_pic_cnt_present_flag == FALSE) 585 { 586 seqParam->profile_idc = AVC_MAIN; 587 seqParam->constrained_set1_flag = TRUE; 588 } 589 590 if (rateCtrl->bidirPred == FALSE && 591 rateCtrl->dpEnable == FALSE && 592 seqParam->frame_mbs_only_flag == TRUE && 593 picParam->weighted_pred_flag == FALSE && 594 picParam->weighted_bipred_idc == 0 && 595 picParam->entropy_coding_mode_flag == FALSE && 596 picParam->num_slice_groups_minus1 <= 7 /*&& 597 picParam->num_slice_groups_minus1>=0 (no need, it's unsigned)*/) 598 { 599 seqParam->profile_idc = AVC_BASELINE; 600 seqParam->constrained_set0_flag = TRUE; 601 } 602 603 if (seqParam->profile_idc == 0) /* still zero */ 604 { 605 return AVCENC_PROFILE_NOT_SUPPORTED; 606 } 607 } 608 609 /* check the list of supported profile by this library */ 610 switch (seqParam->profile_idc) 611 { 612 case AVC_BASELINE: 613 if (rateCtrl->bidirPred == TRUE || 614 rateCtrl->dpEnable == TRUE || 615 seqParam->frame_mbs_only_flag != TRUE || 616 picParam->weighted_pred_flag == TRUE || 617 picParam->weighted_bipred_idc != 0 || 618 picParam->entropy_coding_mode_flag == TRUE || 619 picParam->num_slice_groups_minus1 > 7 /*|| 620 picParam->num_slice_groups_minus1<0 (no need, it's unsigned) */) 621 { 622 status = AVCENC_TOOLS_NOT_SUPPORTED; 623 } 624 break; 625 626 case AVC_MAIN: 627 case AVC_EXTENDED: 628 status = AVCENC_PROFILE_NOT_SUPPORTED; 629 } 630 631 return status; 632 } 633 634 /* verify the level setting */ 635 AVCEnc_Status VerifyLevel(AVCEncObject *encvid, AVCSeqParamSet *seqParam, AVCPicParamSet *picParam) 636 { 637 (void)(picParam); 638 639 AVCRateControl *rateCtrl = encvid->rateCtrl; 640 AVCCommonObj *video = encvid->common; 641 int mb_per_sec, ii; 642 int lev_idx; 643 int dpb_size; 644 645 mb_per_sec = (int)(video->PicSizeInMbs * rateCtrl->frame_rate + 0.5); 646 dpb_size = (seqParam->num_ref_frames * video->PicSizeInMbs * 3) >> 6; 647 648 if (seqParam->level_idc == 0) /* find level for this setting */ 649 { 650 for (ii = 0; ii < MAX_LEVEL_IDX; ii++) 651 { 652 if (mb_per_sec <= MaxMBPS[ii] && 653 video->PicSizeInMbs <= (uint)MaxFS[ii] && 654 rateCtrl->bitRate <= (int32)MaxBR[ii]*1000 && 655 rateCtrl->cpbSize <= (int32)MaxCPB[ii]*1000 && 656 rateCtrl->mvRange <= MaxVmvR[ii] && 657 dpb_size <= MaxDPBX2[ii]*512) 658 { 659 seqParam->level_idc = mapIdx2Lev[ii]; 660 break; 661 } 662 } 663 if (seqParam->level_idc == 0) 664 { 665 return AVCENC_LEVEL_NOT_SUPPORTED; 666 } 667 } 668 669 /* check if this level is supported by this library */ 670 lev_idx = mapLev2Idx[seqParam->level_idc]; 671 if (seqParam->level_idc == AVC_LEVEL1_B) 672 { 673 seqParam->constrained_set3_flag = 1; 674 } 675 676 677 if (lev_idx == 255) /* not defined */ 678 { 679 return AVCENC_LEVEL_NOT_SUPPORTED; 680 } 681 682 /* check if the encoding setting complies with the level */ 683 if (mb_per_sec > MaxMBPS[lev_idx] || 684 video->PicSizeInMbs > (uint)MaxFS[lev_idx] || 685 rateCtrl->bitRate > (int32)MaxBR[lev_idx]*1000 || 686 rateCtrl->cpbSize > (int32)MaxCPB[lev_idx]*1000 || 687 rateCtrl->mvRange > MaxVmvR[lev_idx]) 688 { 689 return AVCENC_LEVEL_FAIL; 690 } 691 692 return AVCENC_SUCCESS; 693 } 694 695 /* initialize variables at the beginning of each frame */ 696 /* determine the picture type */ 697 /* encode POC */ 698 /* maybe we should do more stuff here. MotionEstimation+SCD and generate a new SPS and PPS */ 699 AVCEnc_Status InitFrame(AVCEncObject *encvid) 700 { 701 AVCStatus ret; 702 AVCEnc_Status status; 703 AVCCommonObj *video = encvid->common; 704 AVCSliceHeader *sliceHdr = video->sliceHdr; 705 706 /* look for the next frame in coding_order and look for available picture 707 in the DPB. Note, video->currFS->PicOrderCnt, currFS->FrameNum and currPic->PicNum 708 are set to wrong number in this function (right for decoder). */ 709 if (video->nal_unit_type == AVC_NALTYPE_IDR) 710 { 711 // call init DPB in here. 712 ret = AVCConfigureSequence(encvid->avcHandle, video, TRUE); 713 if (ret != AVC_SUCCESS) 714 { 715 return AVCENC_FAIL; 716 } 717 } 718 719 /* flexible macroblock ordering (every frame)*/ 720 /* populate video->mapUnitToSliceGroupMap and video->MbToSliceGroupMap */ 721 /* It changes once per each PPS. */ 722 FMOInit(video); 723 724 ret = DPBInitBuffer(encvid->avcHandle, video); // get new buffer 725 726 if (ret != AVC_SUCCESS) 727 { 728 return (AVCEnc_Status)ret; // AVCENC_PICTURE_READY, FAIL 729 } 730 731 DPBInitPic(video, 0); /* 0 is dummy */ 732 733 /************* determine picture type IDR or non-IDR ***********/ 734 video->currPicType = AVC_FRAME; 735 video->slice_data_partitioning = FALSE; 736 encvid->currInput->is_reference = 1; /* default to all frames */ 737 video->nal_ref_idc = 1; /* need to set this for InitPOC */ 738 video->currPic->isReference = TRUE; 739 740 /************* set frame_num ********************/ 741 if (video->nal_unit_type == AVC_NALTYPE_IDR) 742 { 743 video->prevFrameNum = video->MaxFrameNum; 744 video->PrevRefFrameNum = 0; 745 sliceHdr->frame_num = 0; 746 } 747 /* otherwise, it's set to previous reference frame access unit's frame_num in decoding order, 748 see the end of PVAVCDecodeSlice()*/ 749 /* There's also restriction on the frame_num, see page 59 of JVT-I1010.doc. */ 750 /* Basically, frame_num can't be repeated unless it's opposite fields or non reference fields */ 751 else 752 { 753 sliceHdr->frame_num = (video->PrevRefFrameNum + 1) % video->MaxFrameNum; 754 } 755 video->CurrPicNum = sliceHdr->frame_num; /* for field_pic_flag = 0 */ 756 //video->CurrPicNum = 2*sliceHdr->frame_num + 1; /* for field_pic_flag = 1 */ 757 758 /* assign pic_order_cnt, video->PicOrderCnt */ 759 status = InitPOC(encvid); 760 if (status != AVCENC_SUCCESS) /* incorrigable fail */ 761 { 762 return status; 763 } 764 765 /* Initialize refListIdx for this picture */ 766 RefListInit(video); 767 768 /************* motion estimation and scene analysis ************/ 769 // , to move this to MB-based MV search for comparison 770 // use sub-optimal QP for mv search 771 AVCMotionEstimation(encvid); /* AVCENC_SUCCESS or AVCENC_NEW_IDR */ 772 773 /* after this point, the picture type will be fixed to either IDR or non-IDR */ 774 video->currFS->PicOrderCnt = video->PicOrderCnt; 775 video->currFS->FrameNum = video->sliceHdr->frame_num; 776 video->currPic->PicNum = video->CurrPicNum; 777 video->mbNum = 0; /* start from zero MB */ 778 encvid->currSliceGroup = 0; /* start from slice group #0 */ 779 encvid->numIntraMB = 0; /* reset this counter */ 780 781 if (video->nal_unit_type == AVC_NALTYPE_IDR) 782 { 783 RCInitGOP(encvid); 784 785 /* calculate picture QP */ 786 RCInitFrameQP(encvid); 787 788 return AVCENC_NEW_IDR; 789 } 790 791 /* calculate picture QP */ 792 RCInitFrameQP(encvid); /* get QP after MV search */ 793 794 return AVCENC_SUCCESS; 795 } 796 797 /* initialize variables for this slice */ 798 AVCEnc_Status InitSlice(AVCEncObject *encvid) 799 { 800 AVCCommonObj *video = encvid->common; 801 AVCSliceHeader *sliceHdr = video->sliceHdr; 802 AVCPicParamSet *currPPS = video->currPicParams; 803 AVCSeqParamSet *currSPS = video->currSeqParams; 804 int slice_type = video->slice_type; 805 806 sliceHdr->first_mb_in_slice = video->mbNum; 807 if (video->mbNum) // not first slice of a frame 808 { 809 video->sliceHdr->slice_type = (AVCSliceType)slice_type; 810 } 811 812 /* sliceHdr->slice_type already set in InitFrame */ 813 814 sliceHdr->pic_parameter_set_id = video->currPicParams->pic_parameter_set_id; 815 816 /* sliceHdr->frame_num already set in InitFrame */ 817 818 if (!currSPS->frame_mbs_only_flag) /* we shouldn't need this check */ 819 { 820 sliceHdr->field_pic_flag = sliceHdr->bottom_field_flag = FALSE; 821 return AVCENC_TOOLS_NOT_SUPPORTED; 822 } 823 824 /* sliceHdr->idr_pic_id already set in PVAVCEncodeNAL 825 826 sliceHdr->pic_order_cnt_lsb already set in InitFrame..InitPOC 827 sliceHdr->delta_pic_order_cnt_bottom already set in InitPOC 828 829 sliceHdr->delta_pic_order_cnt[0] already set in InitPOC 830 sliceHdr->delta_pic_order_cnt[1] already set in InitPOC 831 */ 832 833 sliceHdr->redundant_pic_cnt = 0; /* default if(currPPS->redundant_pic_cnt_present_flag), range 0..127 */ 834 sliceHdr->direct_spatial_mv_pred_flag = 0; // default if(slice_type == AVC_B_SLICE) 835 836 sliceHdr->num_ref_idx_active_override_flag = FALSE; /* default, if(slice_type== P,SP or B)*/ 837 sliceHdr->num_ref_idx_l0_active_minus1 = 0; /* default, if (num_ref_idx_active_override_flag) */ 838 sliceHdr->num_ref_idx_l1_active_minus1 = 0; /* default, if above and B_slice */ 839 /* the above 2 values range from 0..15 for frame picture and 0..31 for field picture */ 840 841 /* ref_pic_list_reordering(), currently we don't do anything */ 842 sliceHdr->ref_pic_list_reordering_flag_l0 = FALSE; /* default */ 843 sliceHdr->ref_pic_list_reordering_flag_l1 = FALSE; /* default */ 844 /* if the above are TRUE, some other params must be set */ 845 846 if ((currPPS->weighted_pred_flag && (slice_type == AVC_P_SLICE || slice_type == AVC_SP_SLICE)) || 847 (currPPS->weighted_bipred_idc == 1 && slice_type == AVC_B_SLICE)) 848 { 849 // pred_weight_table(); // not supported !! 850 return AVCENC_TOOLS_NOT_SUPPORTED; 851 } 852 853 /* dec_ref_pic_marking(), this will be done later*/ 854 sliceHdr->no_output_of_prior_pics_flag = FALSE; /* default */ 855 sliceHdr->long_term_reference_flag = FALSE; /* for IDR frame, do not make it long term */ 856 sliceHdr->adaptive_ref_pic_marking_mode_flag = FALSE; /* default */ 857 /* other params are not set here because they are not used */ 858 859 sliceHdr->cabac_init_idc = 0; /* default, if entropy_coding_mode_flag && slice_type==I or SI, range 0..2 */ 860 sliceHdr->slice_qp_delta = 0; /* default for now */ 861 sliceHdr->sp_for_switch_flag = FALSE; /* default, if slice_type == SP */ 862 sliceHdr->slice_qs_delta = 0; /* default, if slice_type == SP or SI */ 863 864 /* derived variables from encParam */ 865 /* deblocking filter */ 866 video->FilterOffsetA = video->FilterOffsetB = 0; 867 if (currPPS->deblocking_filter_control_present_flag == TRUE) 868 { 869 video->FilterOffsetA = sliceHdr->slice_alpha_c0_offset_div2 << 1; 870 video->FilterOffsetB = sliceHdr->slice_beta_offset_div_2 << 1; 871 } 872 873 /* flexible macroblock ordering */ 874 /* populate video->mapUnitToSliceGroupMap and video->MbToSliceGroupMap */ 875 /* We already call it at the end of PVAVCEncInitialize(). It changes once per each PPS. */ 876 if (video->currPicParams->num_slice_groups_minus1 > 0 && video->currPicParams->slice_group_map_type >= 3 877 && video->currPicParams->slice_group_map_type <= 5) 878 { 879 sliceHdr->slice_group_change_cycle = SLICE_GROUP_CHANGE_CYCLE; /* default, don't understand how to set it!!!*/ 880 881 video->MapUnitsInSliceGroup0 = 882 AVC_MIN(sliceHdr->slice_group_change_cycle * video->SliceGroupChangeRate, video->PicSizeInMapUnits); 883 884 FMOInit(video); 885 } 886 887 /* calculate SliceQPy first */ 888 /* calculate QSy first */ 889 890 sliceHdr->slice_qp_delta = video->QPy - 26 - currPPS->pic_init_qp_minus26; 891 //sliceHdr->slice_qs_delta = video->QSy - 26 - currPPS->pic_init_qs_minus26; 892 893 return AVCENC_SUCCESS; 894 } 895 896