1 /*
2 * Copyright (c) 2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_avc_header_packer.cpp
24 //! \brief Defines header packing logic for avc encode
25 //!
26
27 #include "encode_avc_header_packer.h"
28 #include "encode_utils.h"
29
30 namespace encode
31 {
32
33 #define ENCODE_AVC_EXTENDED_SAR 255
34
SetNalUnit(uint8_t ** bsbuffer,uint8_t refIDC,CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType)35 static void SetNalUnit(uint8_t **bsbuffer, uint8_t refIDC, CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType)
36 {
37 uint8_t *byte = *bsbuffer;
38
39 // for SPS and PPS NAL units zero_byte should exist
40 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_SPS || nalType == CODECHAL_ENCODE_AVC_NAL_UT_PPS || nalType == CODECHAL_ENCODE_AVC_NAL_UT_AUD)
41 {
42 *byte++ = 0;
43 }
44
45 *byte++ = 0;
46 *byte++ = 0;
47 *byte++ = 1;
48 *byte++ = (uint8_t)((refIDC << 5) | nalType);
49 *byte = 0; // Clear the next byte
50 *bsbuffer = byte;
51 }
52
PutBit(BSBuffer * bsbuffer,uint32_t code)53 static void PutBit(BSBuffer *bsbuffer, uint32_t code)
54 {
55 if (code & 1)
56 {
57 *(bsbuffer->pCurrent) = (*(bsbuffer->pCurrent) | (uint8_t)(0x01 << (7 - bsbuffer->BitOffset)));
58 }
59
60 bsbuffer->BitOffset++;
61 if (bsbuffer->BitOffset == 8)
62 {
63 bsbuffer->BitOffset = 0;
64 bsbuffer->pCurrent++;
65 *(bsbuffer->pCurrent) = 0;
66 }
67 }
68
PutBitsSub(BSBuffer * bsbuffer,uint32_t code,uint32_t length)69 static void PutBitsSub(BSBuffer *bsbuffer, uint32_t code, uint32_t length)
70 {
71 uint8_t *byte = bsbuffer->pCurrent;
72
73 // make sure that the number of bits given is <= 24
74 ENCODE_ASSERT(length <= 24);
75
76 code <<= (32 - length);
77
78 // shift field so that the given code begins at the current bit
79 // offset in the most significant byte of the 32-bit word
80 length += bsbuffer->BitOffset;
81 code >>= bsbuffer->BitOffset;
82
83 // write bytes back into memory, big-endian
84 byte[0] = (uint8_t)((code >> 24) | byte[0]);
85 byte[1] = (uint8_t)(code >> 16);
86 if (length > 16)
87 {
88 byte[2] = (uint8_t)(code >> 8);
89 byte[3] = (uint8_t)code;
90 }
91 else
92 {
93 byte[2] = 0;
94 }
95
96 // update bitstream pointer and bit offset
97 bsbuffer->pCurrent += (length >> 3);
98 bsbuffer->BitOffset = (length & 7);
99 }
100
PutBits(BSBuffer * bsbuffer,uint32_t code,uint32_t length)101 static void PutBits(BSBuffer *bsbuffer, uint32_t code, uint32_t length)
102 {
103 uint32_t code1, code2;
104
105 // temp solution, only support up to 32 bits based on current usage
106 ENCODE_ASSERT(length <= 32);
107
108 if (length >= 24)
109 {
110 code1 = code & 0xFFFF;
111 code2 = code >> 16;
112
113 // high bits go first
114 PutBitsSub(bsbuffer, code2, length - 16);
115 PutBitsSub(bsbuffer, code1, 16);
116 }
117 else
118 {
119 PutBitsSub(bsbuffer, code, length);
120 }
121 }
122
PutVLCCode(BSBuffer * bsbuffer,uint32_t code)123 static void PutVLCCode(BSBuffer *bsbuffer, uint32_t code)
124 {
125 uint8_t leadingZeroBits, bitcount;
126 uint32_t code1, bits;
127
128 code1 = code + 1;
129 bitcount = 0;
130 while (code1)
131 {
132 code1 >>= 1;
133 bitcount++;
134 }
135
136 if (bitcount == 1)
137 {
138 PutBit(bsbuffer, 1);
139 }
140 else
141 {
142 leadingZeroBits = bitcount - 1;
143 bits = code + 1 - (1 << leadingZeroBits);
144 PutBits(bsbuffer, 1, leadingZeroBits + 1);
145 PutBits(bsbuffer, bits, leadingZeroBits);
146 }
147 }
148
SetTrailingBits(BSBuffer * bsbuffer)149 static void SetTrailingBits(BSBuffer *bsbuffer)
150 {
151 // Write Stop Bit
152 PutBits(bsbuffer, 1, 1);
153 // Make byte aligned
154 while (bsbuffer->BitOffset)
155 {
156 PutBit(bsbuffer, 0);
157 }
158 }
159
PackScalingList(BSBuffer * bsbuffer,uint8_t * scalingList,uint8_t sizeOfScalingList)160 static void PackScalingList(BSBuffer *bsbuffer, uint8_t *scalingList, uint8_t sizeOfScalingList)
161 {
162 uint8_t lastScale, nextScale, j;
163 char delta_scale;
164
165 lastScale = nextScale = 8;
166
167 for (j = 0; j < sizeOfScalingList; j++)
168 {
169 if (nextScale != 0)
170 {
171 delta_scale = (char)(scalingList[j] - lastScale);
172
173 PutVLCCode(bsbuffer, SIGNED(delta_scale));
174
175 nextScale = scalingList[j];
176 }
177 lastScale = (nextScale == 0) ? lastScale : nextScale;
178 }
179 }
180
PackAUDParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)181 MOS_STATUS AvcEncodeHeaderPacker::PackAUDParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
182 {
183 uint32_t picType;
184 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
185
186 ENCODE_CHK_NULL_RETURN(params);
187 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
188
189 // refer table 7-5 in H.264 spec on primary_pic_type
190 // Here I,P,B types are included
191 // According BD Spec 9.5.1.1, 0 - I; 1 - P; 2 - B
192
193 picType = (uint32_t)(params->wPictureCodingType) - 1;
194 PutBits(params->pBsBuffer, picType, 3);
195
196 return eStatus;
197 }
198
PackHrdParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)199 MOS_STATUS AvcEncodeHeaderPacker::PackHrdParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
200 {
201 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams;
202 PBSBuffer bsbuffer;
203 int schedSelIdx;
204 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
205
206 ENCODE_CHK_NULL_RETURN(params);
207
208 vuiParams = params->pAvcVuiParams;
209 bsbuffer = params->pBsBuffer;
210
211 PutVLCCode(bsbuffer, vuiParams->cpb_cnt_minus1);
212 PutBits(bsbuffer, vuiParams->bit_rate_scale, 4);
213 PutBits(bsbuffer, vuiParams->cpb_size_scale, 4);
214
215 for (schedSelIdx = 0; schedSelIdx <= vuiParams->cpb_cnt_minus1; schedSelIdx++)
216 {
217 PutVLCCode(bsbuffer, vuiParams->bit_rate_value_minus1[schedSelIdx]);
218 PutVLCCode(bsbuffer, vuiParams->cpb_size_value_minus1[schedSelIdx]);
219 PutBit(bsbuffer, ((vuiParams->cbr_flag >> schedSelIdx) & 1));
220 }
221
222 PutBits(bsbuffer, vuiParams->initial_cpb_removal_delay_length_minus1, 5);
223 PutBits(bsbuffer, vuiParams->cpb_removal_delay_length_minus1, 5);
224 PutBits(bsbuffer, vuiParams->dpb_output_delay_length_minus1, 5);
225 PutBits(bsbuffer, vuiParams->time_offset_length, 5);
226
227 return eStatus;
228 }
229
PackVuiParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)230 MOS_STATUS AvcEncodeHeaderPacker::PackVuiParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
231 {
232 PCODECHAL_ENCODE_AVC_VUI_PARAMS vuiParams;
233 PBSBuffer bsbuffer;
234 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
235
236 ENCODE_CHK_NULL_RETURN(params);
237 ENCODE_CHK_NULL_RETURN(params->pAvcVuiParams);
238
239 vuiParams = params->pAvcVuiParams;
240 bsbuffer = params->pBsBuffer;
241
242 PutBit(bsbuffer, vuiParams->aspect_ratio_info_present_flag);
243 if (vuiParams->aspect_ratio_info_present_flag)
244 {
245 PutBits(bsbuffer, vuiParams->aspect_ratio_idc, 8);
246 if (vuiParams->aspect_ratio_idc == ENCODE_AVC_EXTENDED_SAR)
247 {
248 PutBits(bsbuffer, vuiParams->sar_width, 16);
249 PutBits(bsbuffer, vuiParams->sar_height, 16);
250 }
251 }
252
253 PutBit(bsbuffer, vuiParams->overscan_info_present_flag);
254 if (vuiParams->overscan_info_present_flag)
255 {
256 PutBit(bsbuffer, vuiParams->overscan_appropriate_flag);
257 }
258
259 PutBit(bsbuffer, vuiParams->video_signal_type_present_flag);
260 if (vuiParams->video_signal_type_present_flag)
261 {
262 PutBits(bsbuffer, vuiParams->video_format, 3);
263 PutBit(bsbuffer, vuiParams->video_full_range_flag);
264 PutBit(bsbuffer, vuiParams->colour_description_present_flag);
265 if (vuiParams->colour_description_present_flag)
266 {
267 PutBits(bsbuffer, vuiParams->colour_primaries, 8);
268 PutBits(bsbuffer, vuiParams->transfer_characteristics, 8);
269 PutBits(bsbuffer, vuiParams->matrix_coefficients, 8);
270 }
271 }
272
273 PutBit(bsbuffer, vuiParams->chroma_loc_info_present_flag);
274 if (vuiParams->chroma_loc_info_present_flag)
275 {
276 PutVLCCode(bsbuffer, vuiParams->chroma_sample_loc_type_top_field);
277 PutVLCCode(bsbuffer, vuiParams->chroma_sample_loc_type_bottom_field);
278 }
279
280 PutBit(bsbuffer, vuiParams->timing_info_present_flag);
281 if (vuiParams->timing_info_present_flag)
282 {
283 PutBits(bsbuffer, vuiParams->num_units_in_tick, 32);
284 PutBits(bsbuffer, vuiParams->time_scale, 32);
285 PutBit(bsbuffer, vuiParams->fixed_frame_rate_flag);
286 }
287
288 PutBit(bsbuffer, vuiParams->nal_hrd_parameters_present_flag);
289 if (vuiParams->nal_hrd_parameters_present_flag)
290 {
291 ENCODE_CHK_STATUS_RETURN(PackHrdParams(params));
292 }
293
294 PutBit(bsbuffer, vuiParams->vcl_hrd_parameters_present_flag);
295 if (vuiParams->vcl_hrd_parameters_present_flag)
296 {
297 ENCODE_CHK_STATUS_RETURN(PackHrdParams(params));
298 }
299
300 if (vuiParams->nal_hrd_parameters_present_flag || vuiParams->vcl_hrd_parameters_present_flag)
301 {
302 PutBit(bsbuffer, vuiParams->low_delay_hrd_flag);
303 }
304
305 PutBit(bsbuffer, vuiParams->pic_struct_present_flag);
306 PutBit(bsbuffer, vuiParams->bitstream_restriction_flag);
307 if (vuiParams->bitstream_restriction_flag)
308 {
309 PutBit(bsbuffer, vuiParams->motion_vectors_over_pic_boundaries_flag);
310 PutVLCCode(bsbuffer, vuiParams->max_bytes_per_pic_denom);
311 PutVLCCode(bsbuffer, vuiParams->max_bits_per_mb_denom);
312 PutVLCCode(bsbuffer, vuiParams->log2_max_mv_length_horizontal);
313 PutVLCCode(bsbuffer, vuiParams->log2_max_mv_length_vertical);
314 PutVLCCode(bsbuffer, vuiParams->num_reorder_frames);
315 PutVLCCode(bsbuffer, vuiParams->max_dec_frame_buffering);
316 }
317
318 return eStatus;
319 }
320
PackSeqParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)321 MOS_STATUS AvcEncodeHeaderPacker::PackSeqParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
322 {
323 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
324 BSBuffer * bsbuffer;
325 uint8_t i;
326 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
327
328 ENCODE_CHK_NULL_RETURN(params);
329 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
330 ENCODE_CHK_NULL_RETURN(params->pSeqParams);
331
332 seqParams = params->pSeqParams;
333 bsbuffer = params->pBsBuffer;
334
335 PutBits(bsbuffer, seqParams->Profile, 8);
336
337 PutBit(bsbuffer, seqParams->constraint_set0_flag);
338 PutBit(bsbuffer, seqParams->constraint_set1_flag);
339 PutBit(bsbuffer, seqParams->constraint_set2_flag);
340 PutBit(bsbuffer, seqParams->constraint_set3_flag);
341
342 PutBits(bsbuffer, 0, 4);
343 PutBits(bsbuffer, seqParams->Level, 8);
344 PutVLCCode(bsbuffer, seqParams->seq_parameter_set_id);
345
346 if (seqParams->Profile == CODEC_AVC_HIGH_PROFILE ||
347 seqParams->Profile == CODEC_AVC_HIGH10_PROFILE ||
348 seqParams->Profile == CODEC_AVC_HIGH422_PROFILE ||
349 seqParams->Profile == CODEC_AVC_HIGH444_PROFILE ||
350 seqParams->Profile == CODEC_AVC_CAVLC444_INTRA_PROFILE ||
351 seqParams->Profile == CODEC_AVC_SCALABLE_BASE_PROFILE ||
352 seqParams->Profile == CODEC_AVC_SCALABLE_HIGH_PROFILE)
353 {
354 PutVLCCode(bsbuffer, seqParams->chroma_format_idc);
355 if (seqParams->chroma_format_idc == 3)
356 {
357 PutBit(bsbuffer, seqParams->separate_colour_plane_flag);
358 }
359 PutVLCCode(bsbuffer, seqParams->bit_depth_luma_minus8);
360 PutVLCCode(bsbuffer, seqParams->bit_depth_chroma_minus8);
361 PutBit(bsbuffer, seqParams->qpprime_y_zero_transform_bypass_flag);
362 PutBit(bsbuffer, seqParams->seq_scaling_matrix_present_flag);
363 if (seqParams->seq_scaling_matrix_present_flag)
364 {
365 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.1
366 for (i = 0; i < 8; i++)
367 {
368 // scaling list present flag
369 PutBit(bsbuffer, seqParams->seq_scaling_list_present_flag[i]);
370 if (seqParams->seq_scaling_list_present_flag[i])
371 {
372 if (i < 6)
373 {
374 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
375 }
376 else
377 {
378 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
379 }
380 }
381 }
382 }
383 }
384
385 PutVLCCode(bsbuffer, seqParams->log2_max_frame_num_minus4);
386 PutVLCCode(bsbuffer, seqParams->pic_order_cnt_type);
387 if (seqParams->pic_order_cnt_type == 0)
388 {
389 PutVLCCode(bsbuffer, seqParams->log2_max_pic_order_cnt_lsb_minus4);
390 }
391 else if (seqParams->pic_order_cnt_type == 1)
392 {
393 PutBit(bsbuffer, seqParams->delta_pic_order_always_zero_flag);
394 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_non_ref_pic));
395 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_top_to_bottom_field));
396 PutVLCCode(bsbuffer, seqParams->num_ref_frames_in_pic_order_cnt_cycle);
397 for (i = 0; i < seqParams->num_ref_frames_in_pic_order_cnt_cycle; i++)
398 {
399 PutVLCCode(bsbuffer, SIGNED(seqParams->offset_for_ref_frame[i]));
400 }
401 }
402
403 PutVLCCode(bsbuffer, seqParams->NumRefFrames);
404 PutBit(bsbuffer, seqParams->gaps_in_frame_num_value_allowed_flag);
405 PutVLCCode(bsbuffer, seqParams->pic_width_in_mbs_minus1);
406 PutVLCCode(bsbuffer, seqParams->pic_height_in_map_units_minus1);
407 PutBit(bsbuffer, seqParams->frame_mbs_only_flag);
408
409 if (!seqParams->frame_mbs_only_flag)
410 {
411 PutBit(bsbuffer, seqParams->mb_adaptive_frame_field_flag);
412 }
413
414 PutBit(bsbuffer, seqParams->direct_8x8_inference_flag);
415
416 if ((!seqParams->frame_cropping_flag) &&
417 (params->dwFrameHeight != params->dwOriFrameHeight))
418 {
419 seqParams->frame_cropping_flag = 1;
420 seqParams->frame_crop_bottom_offset =
421 (int16_t)((params->dwFrameHeight - params->dwOriFrameHeight) >>
422 (2 - seqParams->frame_mbs_only_flag)); // 4:2:0
423 }
424
425 PutBit(bsbuffer, seqParams->frame_cropping_flag);
426
427 if (seqParams->frame_cropping_flag)
428 {
429 PutVLCCode(bsbuffer, seqParams->frame_crop_left_offset);
430 PutVLCCode(bsbuffer, seqParams->frame_crop_right_offset);
431 PutVLCCode(bsbuffer, seqParams->frame_crop_top_offset);
432 PutVLCCode(bsbuffer, seqParams->frame_crop_bottom_offset);
433 }
434
435 PutBit(bsbuffer, seqParams->vui_parameters_present_flag);
436
437 if (seqParams->vui_parameters_present_flag)
438 {
439 ENCODE_CHK_STATUS_RETURN(PackVuiParams(params));
440 }
441
442 *params->pbNewSeqHeader = 1;
443
444 return eStatus;
445 }
446
PackPicParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)447 MOS_STATUS AvcEncodeHeaderPacker::PackPicParams(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
448 {
449 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
450 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
451 PBSBuffer bsbuffer;
452 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
453
454 ENCODE_CHK_NULL_RETURN(params);
455 ENCODE_CHK_NULL_RETURN(params->pSeqParams);
456 ENCODE_CHK_NULL_RETURN(params->pPicParams);
457 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
458
459 seqParams = params->pSeqParams;
460 picParams = params->pPicParams;
461 bsbuffer = params->pBsBuffer;
462
463 PutVLCCode(bsbuffer, picParams->pic_parameter_set_id);
464 PutVLCCode(bsbuffer, picParams->seq_parameter_set_id);
465
466 PutBit(bsbuffer, picParams->entropy_coding_mode_flag);
467 PutBit(bsbuffer, picParams->pic_order_present_flag);
468
469 PutVLCCode(bsbuffer, picParams->num_slice_groups_minus1);
470
471 PutVLCCode(bsbuffer, picParams->num_ref_idx_l0_active_minus1);
472 PutVLCCode(bsbuffer, picParams->num_ref_idx_l1_active_minus1);
473
474 PutBit(bsbuffer, picParams->weighted_pred_flag);
475 PutBits(bsbuffer, picParams->weighted_bipred_idc, 2);
476
477 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qp_minus26));
478 PutVLCCode(bsbuffer, SIGNED(picParams->pic_init_qs_minus26));
479 PutVLCCode(bsbuffer, SIGNED(picParams->chroma_qp_index_offset));
480
481 PutBit(bsbuffer, picParams->deblocking_filter_control_present_flag);
482 PutBit(bsbuffer, picParams->constrained_intra_pred_flag);
483 PutBit(bsbuffer, picParams->redundant_pic_cnt_present_flag);
484
485 // The syntax elements transform_8x8_mode_flag, pic_scaling_matrix_present_flag, and second_chroma_qp_index_offset
486 // shall not be present for main profile
487 if (seqParams->Profile == CODEC_AVC_MAIN_PROFILE || seqParams->Profile == CODEC_AVC_BASE_PROFILE)
488 {
489 return eStatus;
490 }
491
492 PutBit(bsbuffer, picParams->transform_8x8_mode_flag);
493 PutBit(bsbuffer, picParams->pic_scaling_matrix_present_flag);
494 if (picParams->pic_scaling_matrix_present_flag)
495 {
496 uint8_t i;
497
498 //Iterate thro' the scaling lists. Refer to ITU-T H.264 std. section 7.3.2.2
499 for (i = 0; i < 6 + 2 * picParams->transform_8x8_mode_flag; i++)
500 {
501 //Put scaling list present flag
502 PutBit(bsbuffer, picParams->pic_scaling_list_present_flag[i]);
503 if (picParams->pic_scaling_list_present_flag[i])
504 {
505 if (i < 6)
506 {
507 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList4x4[i][0], 16);
508 }
509 else
510 {
511 PackScalingList(bsbuffer, ¶ms->pAvcIQMatrixParams->ScalingList8x8[i - 6][0], 64);
512 }
513 }
514 }
515 }
516
517 PutVLCCode(bsbuffer, SIGNED(picParams->second_chroma_qp_index_offset));
518
519 *params->pbNewPPSHeader = 1;
520
521 return eStatus;
522 }
523
PackPictureHeader(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)524 MOS_STATUS AvcEncodeHeaderPacker::PackPictureHeader(PCODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS params)
525 {
526 ENCODE_FUNC_CALL();
527
528 PBSBuffer bsbuffer;
529 uint32_t indexNALUnit;
530 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
531
532 ENCODE_CHK_NULL_RETURN(params);
533 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
534 ENCODE_CHK_NULL_RETURN(params->pSeqParams);
535 ENCODE_CHK_NULL_RETURN(params->ppNALUnitParams);
536
537 bsbuffer = params->pBsBuffer;
538 *(bsbuffer->pBase) = 0; // init first byte to 0
539 bsbuffer->pCurrent = bsbuffer->pBase;
540 bsbuffer->SliceOffset = 0;
541 bsbuffer->BitOffset = 0;
542 bsbuffer->BitSize = 0;
543
544 MOS_ZeroMemory(params->ppNALUnitParams[0], sizeof(CODECHAL_NAL_UNIT_PARAMS) * CODECHAL_ENCODE_AVC_MAX_NAL_TYPE);
545 indexNALUnit = 0;
546
547 // AU_Delimiter
548 // nal_ref_idc to be 0 for all nal_unit_type equal to 6, 9, 10, 11 or12
549 params->ppNALUnitParams[indexNALUnit]->uiOffset = 0;
550 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_AUD;
551 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
552 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
553 SetNalUnit(&bsbuffer->pCurrent, 0, CODECHAL_ENCODE_AVC_NAL_UT_AUD);
554 ENCODE_CHK_STATUS_RETURN(PackAUDParams(params));
555 SetTrailingBits(bsbuffer);
556 //NAL unit are byte aligned, bsbuffer->BitOffset should be 0
557 params->ppNALUnitParams[indexNALUnit]->uiSize =
558 (uint32_t)(bsbuffer->pCurrent -
559 bsbuffer->pBase -
560 params->ppNALUnitParams[indexNALUnit]->uiOffset);
561 indexNALUnit++;
562
563 // If this is a new sequence, write the seq set
564 if (params->bNewSeq && !params->pSeqParams->bNoAcceleratorSPSInsertion)
565 {
566 // Pack SPS
567 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
568 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SPS;
569 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
570 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
571 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_SPS);
572 ENCODE_CHK_STATUS_RETURN(PackSeqParams(params));
573 SetTrailingBits(bsbuffer);
574 params->ppNALUnitParams[indexNALUnit]->uiSize =
575 (uint32_t)(bsbuffer->pCurrent -
576 bsbuffer->pBase -
577 params->ppNALUnitParams[indexNALUnit]->uiOffset);
578 indexNALUnit++;
579 }
580
581 // Pack PPS
582 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
583 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_PPS;
584 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = true;
585 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
586 SetNalUnit(&bsbuffer->pCurrent, 1, CODECHAL_ENCODE_AVC_NAL_UT_PPS);
587 ENCODE_CHK_STATUS_RETURN(PackPicParams(params));
588 SetTrailingBits(bsbuffer);
589 params->ppNALUnitParams[indexNALUnit]->uiSize =
590 (uint32_t)(bsbuffer->pCurrent -
591 bsbuffer->pBase -
592 params->ppNALUnitParams[indexNALUnit]->uiOffset);
593 indexNALUnit++;
594
595 // Pack SEI
596 if (params->pSeiData->newSEIData)
597 {
598 params->ppNALUnitParams[indexNALUnit]->uiOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
599 params->ppNALUnitParams[indexNALUnit]->uiNalUnitType = CODECHAL_ENCODE_AVC_NAL_UT_SEI;
600 params->ppNALUnitParams[indexNALUnit]->bInsertEmulationBytes = false;
601 params->ppNALUnitParams[indexNALUnit]->uiSkipEmulationCheckCount = 4;
602 eStatus = MOS_SecureMemcpy(bsbuffer->pCurrent,
603 params->pSeiData->dwSEIBufSize,
604 params->pSeiData->pSEIBuffer,
605 params->pSeiData->dwSEIBufSize);
606 if (eStatus != MOS_STATUS_SUCCESS)
607 {
608 ENCODE_ASSERTMESSAGE("Failed to copy memory.");
609 return eStatus;
610 }
611 bsbuffer->pCurrent += params->pSeiData->dwSEIDataSize;
612 params->pSeiData->newSEIData = false;
613 params->ppNALUnitParams[indexNALUnit]->uiSize =
614 (uint32_t)(bsbuffer->pCurrent -
615 bsbuffer->pBase -
616 params->ppNALUnitParams[indexNALUnit]->uiOffset);
617 indexNALUnit++;
618 }
619
620 bsbuffer->SliceOffset = (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase);
621
622 return eStatus;
623 }
624
PackSliceHeader(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)625 MOS_STATUS AvcEncodeHeaderPacker::PackSliceHeader(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
626 {
627 PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams;
628 PCODEC_AVC_ENCODE_PIC_PARAMS picParams;
629 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
630 PBSBuffer bsbuffer;
631 uint8_t sliceType;
632 CODECHAL_ENCODE_AVC_NAL_UNIT_TYPE nalType;
633 bool ref;
634 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
635
636 ENCODE_CHK_NULL_RETURN(params);
637 ENCODE_CHK_NULL_RETURN(params->pSeqParams);
638 ENCODE_CHK_NULL_RETURN(params->pPicParams);
639 ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
640 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
641
642 slcParams = params->pAvcSliceParams;
643 picParams = params->pPicParams;
644 seqParams = params->pSeqParams;
645 bsbuffer = params->pBsBuffer;
646 sliceType = Slice_Type[slcParams->slice_type];
647 nalType = params->NalUnitType;
648 ref = params->ppRefList[params->CurrReconPic.FrameIdx]->bUsedAsRef;
649
650 // Make slice header uint8_t aligned
651 while (bsbuffer->BitOffset)
652 {
653 PutBit(bsbuffer, 0);
654 }
655
656 // zero byte shall exist when the byte stream NAL unit syntax structure contains the first
657 // NAL unit of an access unit in decoding order, as specified by subclause 7.4.1.2.3.
658 // VDEnc Slice header packing handled by PAK does not need the 0 byte inserted
659 if (params->UserFlags.bDisableAcceleratorHeaderPacking && (!params->bVdencEnabled))
660 {
661 *bsbuffer->pCurrent = 0;
662 bsbuffer->pCurrent++;
663 }
664
665 SetNalUnit(&bsbuffer->pCurrent, (uint8_t)ref, nalType);
666
667 // In the VDEnc mode, PAK only gets this command at the beginning of the frame for slice position X=0, Y=0
668 PutVLCCode(bsbuffer, params->bVdencEnabled ? 0 : slcParams->first_mb_in_slice);
669 PutVLCCode(bsbuffer, slcParams->slice_type);
670 PutVLCCode(bsbuffer, slcParams->pic_parameter_set_id);
671
672 if (seqParams->separate_colour_plane_flag)
673 {
674 PutBits(bsbuffer, slcParams->colour_plane_id, 2);
675 }
676
677 PutBits(bsbuffer, slcParams->frame_num, seqParams->log2_max_frame_num_minus4 + 4);
678
679 if (!seqParams->frame_mbs_only_flag)
680 {
681 PutBit(bsbuffer, slcParams->field_pic_flag);
682 if (slcParams->field_pic_flag)
683 {
684 PutBit(bsbuffer, slcParams->bottom_field_flag);
685 }
686 }
687
688 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
689 {
690 PutVLCCode(bsbuffer, slcParams->idr_pic_id);
691 }
692
693 if (seqParams->pic_order_cnt_type == 0)
694 {
695 PutBits(bsbuffer, slcParams->pic_order_cnt_lsb, seqParams->log2_max_pic_order_cnt_lsb_minus4 + 4);
696 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
697 {
698 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt_bottom));
699 }
700 }
701
702 if (seqParams->pic_order_cnt_type == 1 && !seqParams->delta_pic_order_always_zero_flag)
703 {
704 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[0]));
705 if (picParams->pic_order_present_flag && !slcParams->field_pic_flag)
706 {
707 PutVLCCode(bsbuffer, SIGNED(slcParams->delta_pic_order_cnt[1]));
708 }
709 }
710
711 if (picParams->redundant_pic_cnt_present_flag)
712 {
713 PutVLCCode(bsbuffer, slcParams->redundant_pic_cnt);
714 }
715
716 if (sliceType == SLICE_B)
717 {
718 PutBit(bsbuffer, slcParams->direct_spatial_mv_pred_flag);
719 }
720
721 if (sliceType == SLICE_P || sliceType == SLICE_SP || sliceType == SLICE_B)
722 {
723 PutBit(bsbuffer, slcParams->num_ref_idx_active_override_flag);
724 if (slcParams->num_ref_idx_active_override_flag)
725 {
726 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l0_active_minus1);
727 if (sliceType == SLICE_B)
728 {
729 PutVLCCode(bsbuffer, slcParams->num_ref_idx_l1_active_minus1);
730 }
731 }
732 }
733
734 // ref_pic_list_reordering()
735 ENCODE_CHK_STATUS_RETURN(RefPicListReordering(params));
736
737 if ((picParams->weighted_pred_flag &&
738 (sliceType == SLICE_P || sliceType == SLICE_SP)) ||
739 (picParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE &&
740 sliceType == SLICE_B))
741 {
742 ENCODE_CHK_STATUS_RETURN(PredWeightTable(params));
743 }
744
745 if (ref)
746 {
747 // dec_ref_pic_marking()
748 if (nalType == CODECHAL_ENCODE_AVC_NAL_UT_IDR_SLICE)
749 {
750 PutBit(bsbuffer, slcParams->no_output_of_prior_pics_flag);
751 PutBit(bsbuffer, slcParams->long_term_reference_flag);
752 }
753 else
754 {
755 PutBit(bsbuffer, slcParams->adaptive_ref_pic_marking_mode_flag);
756 if (slcParams->adaptive_ref_pic_marking_mode_flag)
757 {
758 ENCODE_CHK_STATUS_RETURN(MMCO(params));
759 }
760 }
761 }
762
763 if (picParams->entropy_coding_mode_flag && sliceType != SLICE_I && sliceType != SLICE_SI)
764 {
765 PutVLCCode(bsbuffer, slcParams->cabac_init_idc);
766 }
767
768 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qp_delta));
769
770 if (sliceType == SLICE_SP || sliceType == SLICE_SI)
771 {
772 if (sliceType == SLICE_SP)
773 {
774 PutBit(bsbuffer, slcParams->sp_for_switch_flag);
775 }
776 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_qs_delta));
777 }
778
779 if (picParams->deblocking_filter_control_present_flag)
780 {
781 PutVLCCode(bsbuffer, slcParams->disable_deblocking_filter_idc);
782 if (slcParams->disable_deblocking_filter_idc != 1)
783 {
784 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_alpha_c0_offset_div2));
785 PutVLCCode(bsbuffer, SIGNED(slcParams->slice_beta_offset_div2));
786 }
787 }
788
789 bsbuffer->BitSize =
790 (uint32_t)((bsbuffer->pCurrent - bsbuffer->SliceOffset - bsbuffer->pBase) * 8 + bsbuffer->BitOffset);
791 bsbuffer->SliceOffset =
792 (uint32_t)(bsbuffer->pCurrent - bsbuffer->pBase + (bsbuffer->BitOffset != 0));
793
794 return eStatus;
795 }
796
RefPicListReordering(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)797 MOS_STATUS AvcEncodeHeaderPacker::RefPicListReordering(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
798 {
799 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
800 PBSBuffer bsbuffer;
801 CODEC_PIC_REORDER * picOrder;
802 uint8_t sliceType;
803 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
804
805 ENCODE_CHK_NULL_RETURN(params);
806 ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
807
808 slcParams = params->pAvcSliceParams;
809 bsbuffer = params->pBsBuffer;
810 sliceType = Slice_Type[slcParams->slice_type];
811
812 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
813 {
814 // Generate the initial reference list (PicOrder)
815 SetInitialRefPicList(params);
816 }
817
818 if (sliceType != SLICE_I && sliceType != SLICE_SI)
819 {
820 if (slcParams->ref_pic_list_reordering_flag_l0)
821 {
822 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
823 {
824 ENCODE_CHK_STATUS_RETURN(SetRefPicListParam(params, 0));
825 }
826
827 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
828
829 if (slcParams->ref_pic_list_reordering_flag_l0)
830 {
831 picOrder = &slcParams->PicOrder[0][0];
832 do
833 {
834 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
835 if (picOrder->ReorderPicNumIDC == 0 ||
836 picOrder->ReorderPicNumIDC == 1)
837 {
838 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
839 } else
840 if (picOrder->ReorderPicNumIDC == 2)
841 {
842 PutVLCCode(bsbuffer, picOrder->LongTermPicNum);
843 }
844 } while ((picOrder++)->ReorderPicNumIDC != 3);
845 }
846 }
847 else
848 {
849 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l0);
850 }
851 }
852 if (sliceType == SLICE_B)
853 {
854 if (slcParams->ref_pic_list_reordering_flag_l1)
855 {
856 if (!params->UserFlags.bDisableAcceleratorRefPicListReordering)
857 {
858 SetRefPicListParam(params, 1);
859 }
860
861 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
862
863 if (slcParams->ref_pic_list_reordering_flag_l1)
864 {
865 picOrder = &slcParams->PicOrder[1][0];
866 do
867 {
868 PutVLCCode(bsbuffer, picOrder->ReorderPicNumIDC);
869 if (picOrder->ReorderPicNumIDC == 0 ||
870 picOrder->ReorderPicNumIDC == 1)
871 {
872 PutVLCCode(bsbuffer, picOrder->DiffPicNumMinus1);
873 } else
874 if (picOrder->ReorderPicNumIDC == 2)
875 {
876 PutVLCCode(bsbuffer, picOrder->PicNum);
877 }
878 } while ((picOrder++)->ReorderPicNumIDC != 3);
879 }
880 }
881 else
882 {
883 PutBit(bsbuffer, slcParams->ref_pic_list_reordering_flag_l1);
884 }
885 }
886
887 return eStatus;
888 }
889
PredWeightTable(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)890 MOS_STATUS AvcEncodeHeaderPacker::PredWeightTable(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
891 {
892 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
893 PBSBuffer bsbuffer;
894 int16_t weight, offset, weight2, offset2;
895 uint8_t i, weight_flag, chromaIDC;
896 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
897
898 ENCODE_CHK_NULL_RETURN(params);
899 ENCODE_CHK_NULL_RETURN(params->pSeqParams);
900 ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
901 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
902
903 bsbuffer = params->pBsBuffer;
904 slcParams = params->pAvcSliceParams;
905 chromaIDC = params->pSeqParams->chroma_format_idc;
906
907 PutVLCCode(bsbuffer, slcParams->luma_log2_weight_denom);
908
909 if (chromaIDC)
910 {
911 PutVLCCode(bsbuffer, slcParams->chroma_log2_weight_denom);
912 }
913
914 for (i = 0; i <= slcParams->num_ref_idx_l0_active_minus1; i++)
915 {
916 // Luma
917 weight = slcParams->Weights[0][i][0][0];
918 offset = slcParams->Weights[0][i][0][1];
919 weight_flag = (weight != (1 << slcParams->luma_log2_weight_denom)) || (offset != 0);
920 PutBit(bsbuffer, weight_flag);
921 if (weight_flag)
922 {
923 PutVLCCode(bsbuffer, SIGNED(weight));
924 PutVLCCode(bsbuffer, SIGNED(offset));
925 }
926
927 // Chroma
928 if (chromaIDC)
929 {
930 weight = slcParams->Weights[0][i][1][0];
931 offset = slcParams->Weights[0][i][1][1];
932 weight2 = slcParams->Weights[0][i][2][0];
933 offset2 = slcParams->Weights[0][i][2][1];
934 weight_flag = (weight != (1 << slcParams->chroma_log2_weight_denom)) ||
935 (weight2 != (1 << slcParams->chroma_log2_weight_denom)) ||
936 (offset != 0) || (offset2 != 0);
937 PutBit(bsbuffer, weight_flag);
938 if (weight_flag)
939 {
940 PutVLCCode(bsbuffer, SIGNED(weight));
941 PutVLCCode(bsbuffer, SIGNED(offset));
942 PutVLCCode(bsbuffer, SIGNED(weight2));
943 PutVLCCode(bsbuffer, SIGNED(offset2));
944 }
945 }
946 }
947
948 if (Slice_Type[slcParams->slice_type] == SLICE_B)
949 {
950 for (i = 0; i <= slcParams->num_ref_idx_l1_active_minus1; i++)
951 {
952 // Luma
953 weight = slcParams->Weights[1][i][0][0];
954 offset = slcParams->Weights[1][i][0][1];
955 weight_flag = (weight != (1 << slcParams->luma_log2_weight_denom)) || (offset != 0);
956 PutBit(bsbuffer, weight_flag);
957 if (weight_flag)
958 {
959 PutVLCCode(bsbuffer, SIGNED(weight));
960 PutVLCCode(bsbuffer, SIGNED(offset));
961 }
962
963 // Chroma
964 if (chromaIDC)
965 {
966 weight = slcParams->Weights[1][i][1][0];
967 offset = slcParams->Weights[1][i][1][1];
968 weight2 = slcParams->Weights[1][i][2][0];
969 offset2 = slcParams->Weights[1][i][2][1];
970 weight_flag = (weight != (1 << slcParams->chroma_log2_weight_denom)) ||
971 (weight2 != (1 << slcParams->chroma_log2_weight_denom)) ||
972 (offset != 0) || (offset2 != 0);
973 PutBit(bsbuffer, weight_flag);
974 if (weight_flag)
975 {
976 PutVLCCode(bsbuffer, SIGNED(weight));
977 PutVLCCode(bsbuffer, SIGNED(offset));
978 PutVLCCode(bsbuffer, SIGNED(weight2));
979 PutVLCCode(bsbuffer, SIGNED(offset2));
980 }
981 }
982 }
983 }
984
985 return eStatus;
986 }
987
MMCO(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)988 MOS_STATUS AvcEncodeHeaderPacker::MMCO(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
989 {
990 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
991 PBSBuffer bsbuffer;
992 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
993
994 ENCODE_CHK_NULL_RETURN(params);
995 ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
996 ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
997
998 bsbuffer = params->pBsBuffer;
999 slcParams = params->pAvcSliceParams;
1000
1001 PCODEC_SLICE_MMCO mmco = &slcParams->MMCO[0];
1002 do
1003 {
1004 PutVLCCode(bsbuffer, mmco->MmcoIDC);
1005 if (mmco->MmcoIDC == 1 ||
1006 mmco->MmcoIDC == 3)
1007 PutVLCCode(bsbuffer, mmco->DiffPicNumMinus1);
1008 if (mmco->MmcoIDC == 2)
1009 PutVLCCode(bsbuffer, mmco->LongTermPicNum);
1010 if (mmco->MmcoIDC == 3 ||
1011 mmco->MmcoIDC == 6)
1012 PutVLCCode(bsbuffer, mmco->LongTermFrameIdx);
1013 if (mmco->MmcoIDC == 4)
1014 PutVLCCode(bsbuffer, mmco->MaxLongTermFrameIdxPlus1);
1015 } while ((mmco++)->MmcoIDC != 0);
1016
1017 return eStatus;
1018 }
1019
SetInitialRefPicList(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)1020 void AvcEncodeHeaderPacker::SetInitialRefPicList(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params)
1021 {
1022 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1023 PCODEC_REF_LIST * refList;
1024 CODEC_PIC_REORDER * picOrder, pTempPicOrder[32];
1025 CODEC_PICTURE picture;
1026 uint8_t i, j, botField;
1027 uint32_t picNum, picOC;
1028 uint8_t topIdx, botIdx, listSize;
1029 uint32_t defaultPicNumOrder[32];
1030 bool reorder;
1031
1032 ENCODE_CHK_NULL_NO_STATUS_RETURN(params);
1033 ENCODE_CHK_NULL_NO_STATUS_RETURN(params->pAvcSliceParams);
1034 ENCODE_CHK_NULL_NO_STATUS_RETURN(params->ppRefList);
1035
1036 slcParams = params->pAvcSliceParams;
1037 refList = params->ppRefList;
1038 reorder = false;
1039 topIdx = 0;
1040 botIdx = 0;
1041 listSize = 0;
1042
1043 if (params->wPictureCodingType == P_TYPE)
1044 {
1045 GetPicNum(params, 0); // list 0
1046 picOrder = &slcParams->PicOrder[0][0];
1047 // Save the default pic order.
1048 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
1049 {
1050 defaultPicNumOrder[i] = picOrder[i].PicNum;
1051 }
1052 for (i = 1; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
1053 {
1054 picNum = picOrder[i].PicNum;
1055 picture = picOrder[i].Picture;
1056 picOC = picOrder[i].POC;
1057 j = i;
1058 while ((j > 0) && (picOrder[j - 1].PicNum < picNum))
1059 {
1060 picOrder[j].PicNum = picOrder[j - 1].PicNum;
1061 picOrder[j].Picture = picOrder[j - 1].Picture;
1062 picOrder[j].POC = picOrder[j - 1].POC;
1063 j--;
1064 reorder = true;
1065 }
1066 picOrder[j].PicNum = picNum;
1067 picOrder[j].Picture = picture;
1068 picOrder[j].POC = picOC;
1069 }
1070
1071 // Sort picOrder[] based on polarity in field case
1072 if (CodecHal_PictureIsTopField(params->CurrPic))
1073 {
1074 while ((topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)) ||
1075 (botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)))
1076 {
1077 for (; topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); topIdx++)
1078 {
1079 if (CodecHal_PictureIsTopField(picOrder[topIdx].Picture)) //TOP_FIELD
1080 {
1081 pTempPicOrder[listSize].PicNum = picOrder[topIdx].PicNum;
1082 pTempPicOrder[listSize].Picture = picOrder[topIdx].Picture;
1083 pTempPicOrder[listSize].POC = picOrder[topIdx].POC;
1084 listSize++;
1085 topIdx++;
1086 break;
1087 }
1088 }
1089 for (; botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); botIdx++)
1090 {
1091 if (CodecHal_PictureIsBottomField(picOrder[botIdx].Picture)) //BOTTOM_FIELD
1092 {
1093 pTempPicOrder[listSize].PicNum = picOrder[botIdx].PicNum;
1094 pTempPicOrder[listSize].Picture = picOrder[botIdx].Picture;
1095 pTempPicOrder[listSize].POC = picOrder[botIdx].POC;
1096 listSize++;
1097 botIdx++;
1098 break;
1099 }
1100 }
1101 }
1102 }
1103 if (CodecHal_PictureIsBottomField(params->CurrPic))
1104 {
1105 while ((topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)) ||
1106 (botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1)))
1107 {
1108 for (; botIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); botIdx++)
1109 {
1110 if (CodecHal_PictureIsBottomField(picOrder[botIdx].Picture)) //BOTTOM_FIELD
1111 {
1112 pTempPicOrder[listSize].PicNum = picOrder[botIdx].PicNum;
1113 pTempPicOrder[listSize].Picture = picOrder[botIdx].Picture;
1114 pTempPicOrder[listSize].POC = picOrder[botIdx].POC;
1115 listSize++;
1116 botIdx++;
1117 break;
1118 }
1119 }
1120 for (; topIdx < (slcParams->num_ref_idx_l0_active_minus1 + 1); topIdx++)
1121 {
1122 if (CodecHal_PictureIsTopField(picOrder[topIdx].Picture)) //TOP_FIELD
1123 {
1124 pTempPicOrder[listSize].PicNum = picOrder[topIdx].PicNum;
1125 pTempPicOrder[listSize].Picture = picOrder[topIdx].Picture;
1126 pTempPicOrder[listSize].POC = picOrder[topIdx].POC;
1127 listSize++;
1128 topIdx++;
1129 break;
1130 }
1131 }
1132 }
1133 }
1134
1135 if (!CodecHal_PictureIsFrame(params->CurrPic))
1136 {
1137 listSize = MOS_MIN(listSize, 32);
1138 // Copy temp array back to picOrder[]
1139 for (i = 0; i < listSize; i++)
1140 {
1141 picOrder[i].PicNum = pTempPicOrder[i].PicNum;
1142 picOrder[i].Picture = pTempPicOrder[i].Picture;
1143 picOrder[i].POC = pTempPicOrder[i].POC;
1144 }
1145
1146 // Check if picOrder[] has been shuffled compared to the original list
1147 reorder = false;
1148 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
1149 {
1150 if (defaultPicNumOrder[i] != picOrder[i].PicNum)
1151 {
1152 reorder = true;
1153 break;
1154 }
1155 }
1156 }
1157
1158 if (reorder)
1159 {
1160 slcParams->ref_pic_list_reordering_flag_l0 = 1;
1161 }
1162 else
1163 {
1164 slcParams->ref_pic_list_reordering_flag_l0 = 0;
1165 }
1166 for (i = 0; i < (slcParams->num_ref_idx_l0_active_minus1 + 1); i++)
1167 {
1168 botField = (CodecHal_PictureIsBottomField(picOrder[i].Picture)) ? 1 : 0;
1169 refList[picOrder[i].Picture.FrameIdx]->ucInitialIdx[0][botField] = i;
1170 }
1171 }
1172 if (params->wPictureCodingType == B_TYPE)
1173 {
1174 }
1175
1176 return;
1177 }
1178
SetRefPicListParam(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,uint8_t list)1179 MOS_STATUS AvcEncodeHeaderPacker::SetRefPicListParam(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params, uint8_t list)
1180 {
1181 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1182 PCODEC_REF_LIST * refList;
1183 PCODEC_PIC_REORDER picOrder;
1184 uint8_t i, j, idx, picIdx, numReorder, numActiveMinus1, refPolarity;
1185 uint32_t picNumPred, currPicNum, picNumNoWrap, maxPicNum;
1186 int16_t frameNum;
1187 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1188
1189 ENCODE_CHK_NULL_RETURN(params);
1190 ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
1191 ENCODE_CHK_NULL_RETURN(params->ppRefList);
1192
1193 slcParams = params->pAvcSliceParams;
1194 refList = params->ppRefList;
1195 frameNum = refList[params->CurrReconPic.FrameIdx]->sFrameNumber;
1196
1197 currPicNum = (CodecHal_PictureIsFrame(params->CurrPic)) ? frameNum : 2 * frameNum + 1;
1198 picNumPred = currPicNum;
1199 maxPicNum = (CodecHal_PictureIsFrame(params->CurrPic)) ? slcParams->MaxFrameNum : (2 * slcParams->MaxFrameNum);
1200
1201 numActiveMinus1 = list ? slcParams->num_ref_idx_l1_active_minus1 : slcParams->num_ref_idx_l0_active_minus1;
1202
1203 picOrder = &slcParams->PicOrder[list][0];
1204
1205 idx = 0;
1206 picIdx = picOrder[idx].Picture.FrameIdx;
1207 refPolarity = (CodecHal_PictureIsBottomField(picOrder[idx].Picture)) ? 1 : 0;
1208 if (refList[picIdx]->ucFinalIdx[list][refPolarity] ==
1209 refList[picIdx]->ucInitialIdx[list][refPolarity])
1210 {
1211 // Should never happen, something must be wrong in CodecHal_PackSliceHeader_SetInitialRefPicList()
1212 ENCODE_ASSERT(false);
1213 if (list) // L1
1214 {
1215 slcParams->ref_pic_list_reordering_flag_l1 = 0;
1216 }
1217 else // L0
1218 {
1219 slcParams->ref_pic_list_reordering_flag_l0 = 0;
1220 }
1221 eStatus = MOS_STATUS_UNKNOWN;
1222 return eStatus;
1223 }
1224
1225 numReorder = refList[picIdx]->ucFinalIdx[list][refPolarity] - refList[picIdx]->ucInitialIdx[list][refPolarity];
1226 if (numReorder > numActiveMinus1)
1227 {
1228 numReorder = numActiveMinus1;
1229 }
1230 slcParams->NumReorder = numReorder;
1231 do
1232 {
1233 for (i = (idx + 1); i <= numActiveMinus1; i++)
1234 {
1235 picIdx = picOrder[i].Picture.FrameIdx;
1236 refPolarity = (CodecHal_PictureIsBottomField(picOrder[i].Picture)) ? 1 : 0;
1237 if (refList[picIdx]->ucFinalIdx[list][refPolarity] == idx)
1238 {
1239 break;
1240 }
1241 }
1242 if (i == (numActiveMinus1 + 1))
1243 {
1244 // Should never happen, something must be wrong
1245 ENCODE_ASSERT(false);
1246 if (list) // L1
1247 {
1248 slcParams->ref_pic_list_reordering_flag_l1 = 0;
1249 }
1250 else // L0
1251 {
1252 slcParams->ref_pic_list_reordering_flag_l0 = 0;
1253 }
1254 eStatus = MOS_STATUS_UNKNOWN;
1255 return eStatus;
1256 }
1257
1258 if (picOrder[i].PicNum > picNumPred)
1259 {
1260 picOrder[idx].ReorderPicNumIDC = 1;
1261 }
1262 else
1263 {
1264 picOrder[idx].ReorderPicNumIDC = 0;
1265 }
1266
1267 if (picOrder[i].PicNum > currPicNum)
1268 {
1269 picNumNoWrap = picOrder[i].PicNum + maxPicNum;
1270 }
1271 else
1272 {
1273 picNumNoWrap = picOrder[i].PicNum;
1274 }
1275
1276 if (picOrder[idx].ReorderPicNumIDC == 0)
1277 {
1278 if (picNumPred > picNumNoWrap)
1279 {
1280 picOrder[idx].DiffPicNumMinus1 = picNumPred - picNumNoWrap - 1;
1281 }
1282 else
1283 {
1284 picOrder[idx].DiffPicNumMinus1 = picNumPred + maxPicNum - picNumNoWrap - 1;
1285 }
1286 }
1287 else
1288 {
1289 if (picNumNoWrap > picNumPred)
1290 {
1291 picOrder[idx].DiffPicNumMinus1 = picNumNoWrap - picNumPred - 1;
1292 }
1293 else
1294 {
1295 picOrder[idx].DiffPicNumMinus1 = picNumNoWrap + maxPicNum - picNumPred - 1;
1296 }
1297 }
1298 picNumPred = picNumNoWrap;
1299
1300 for (j = i; j > idx; j--)
1301 {
1302 picOrder[j].Picture = picOrder[j - 1].Picture;
1303 picOrder[j].PicNum = picOrder[j - 1].PicNum;
1304 picOrder[j].POC = picOrder[j - 1].POC;
1305 }
1306
1307 idx++;
1308 } while (--numReorder);
1309 picOrder[idx].ReorderPicNumIDC = 3;
1310
1311 return eStatus;
1312 }
1313
GetPicNum(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,uint8_t list)1314 void AvcEncodeHeaderPacker::GetPicNum(PCODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS params,uint8_t list)
1315 {
1316 PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams;
1317 PCODEC_REF_LIST * refList;
1318 uint32_t frameNum, frameNumWrap, picNum;
1319 uint8_t i, botField, size;
1320 CODEC_PICTURE picture;
1321
1322 ENCODE_CHK_NULL_NO_STATUS_RETURN(params);
1323 ENCODE_CHK_NULL_NO_STATUS_RETURN(params->pAvcSliceParams);
1324 ENCODE_CHK_NULL_NO_STATUS_RETURN(params->ppRefList);
1325
1326 slcParams = params->pAvcSliceParams;
1327 refList = params->ppRefList;
1328
1329 size = list ? (slcParams->num_ref_idx_l1_active_minus1 + 1) : (slcParams->num_ref_idx_l0_active_minus1 + 1);
1330
1331 for (i = 0; i < size; i++)
1332 {
1333 picture = slcParams->PicOrder[list][i].Picture;
1334 botField = (CodecHal_PictureIsBottomField(picture)) ? 1 : 0;
1335 refList[picture.FrameIdx]->ucFinalIdx[list][botField] = i;
1336 frameNum = refList[picture.FrameIdx]->sFrameNumber;
1337 if (frameNum > (uint32_t)refList[params->CurrReconPic.FrameIdx]->sFrameNumber)
1338 {
1339 frameNumWrap = frameNum - slcParams->MaxFrameNum;
1340 }
1341 else
1342 {
1343 frameNumWrap = frameNum;
1344 }
1345
1346 if (CodecHal_PictureIsFrame(params->CurrPic))
1347 {
1348 picNum = frameNumWrap;
1349 }
1350 else if ((CodecHal_PictureIsTopField(params->CurrPic) &&
1351 CodecHal_PictureIsTopField(picture)) ||
1352 (CodecHal_PictureIsBottomField(params->CurrPic) &&
1353 CodecHal_PictureIsBottomField(picture)))
1354 {
1355 // Same polarity
1356 picNum = (frameNumWrap << 1) + 1;
1357 }
1358 else
1359 {
1360 picNum = frameNumWrap << 1;
1361 }
1362 slcParams->PicOrder[list][i].PicNum = picNum;
1363 slcParams->PicOrder[list][i].POC =
1364 refList[picture.FrameIdx]->iFieldOrderCnt[botField];
1365 }
1366
1367 return;
1368 }
1369
1370 } // namespace encode
1371