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