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*/
SetEncodeParam(AVCHandle * avcHandle,AVCEncParams * encParam,void * extSPS,void * extPPS)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 */
VerifyProfile(AVCEncObject * encvid,AVCSeqParamSet * seqParam,AVCPicParamSet * picParam)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 */
VerifyLevel(AVCEncObject * encvid,AVCSeqParamSet * seqParam,AVCPicParamSet * picParam)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 */
InitFrame(AVCEncObject * encvid)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 */
InitSlice(AVCEncObject * encvid)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