1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define MODULE_TAG "h264d_fill"
19
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "mpp_mem.h"
24 #include "mpp_common.h"
25
26 #include "h264d_fill.h"
27
realloc_slice_list(H264dDxvaCtx_t * dxva_ctx)28 static MPP_RET realloc_slice_list(H264dDxvaCtx_t *dxva_ctx)
29 {
30 MPP_RET ret = MPP_ERR_UNKNOW;
31
32 dxva_ctx->max_slice_size += ADD_SLICE_SIZE;
33 dxva_ctx->slice_long = mpp_realloc(dxva_ctx->slice_long,
34 DXVA_Slice_H264_Long,
35 dxva_ctx->max_slice_size);
36 MEM_CHECK(ret, dxva_ctx->slice_long);
37
38 return ret = MPP_OK;
39 __FAILED:
40 return ret;
41 }
42
fill_slice_stream(H264dDxvaCtx_t * dxva_ctx,H264_Nalu_t * p_nal)43 static MPP_RET fill_slice_stream(H264dDxvaCtx_t *dxva_ctx, H264_Nalu_t *p_nal)
44 {
45 MPP_RET ret = MPP_ERR_UNKNOW;
46 DXVA_Slice_H264_Long *p_long = NULL;
47
48 if (dxva_ctx->slice_count >= dxva_ctx->max_slice_size) {
49 FUN_CHECK(ret = realloc_slice_list(dxva_ctx));
50 }
51 p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count];
52 memset(p_long, 0, sizeof(DXVA_Slice_H264_Long));
53 p_long->BSNALunitDataLocation = dxva_ctx->strm_offset;
54 p_long->wBadSliceChopping = 0; //!< set to 0 in Rock-Chip RKVDEC IP
55
56 (void)p_nal;
57 return ret = MPP_OK;
58 __FAILED:
59 return ret;
60 }
61
fill_picture_entry(DXVA_PicEntry_H264 * pic,RK_U32 index,RK_U32 flag)62 static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag)
63 {
64 ASSERT((index & 0x7f) == index && (flag & 0x01) == flag);
65 pic->bPicEntry = index | (flag << 7);
66 }
67
68
69 /*!
70 ***********************************************************************
71 * \brief
72 * fill picture parameters
73 ***********************************************************************
74 */
75 //extern "C"
fill_scanlist(H264dVideoCtx_t * p_Vid,DXVA_Qmatrix_H264 * qm)76 void fill_scanlist(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm)
77 {
78 RK_S32 i = 0, j = 0;
79
80 memset(qm, 0, sizeof(DXVA_Qmatrix_H264));
81 for (i = 0; i < 6; ++i) { //!< 4x4, 6 lists
82 for (j = 0; j < H264ScalingList4x4Length; j++) {
83 qm->bScalingLists4x4[i][j] = p_Vid->qmatrix[i][j];
84 }
85 }
86 for (i = 6; i < ((p_Vid->active_sps->chroma_format_idc != H264_CHROMA_444) ? 8 : 12); ++i) {
87 for (j = 0; j < H264ScalingList8x8Length; j++) {
88 qm->bScalingLists8x8[i - 6][j] = p_Vid->qmatrix[i][j];
89 }
90 }
91 }
92 /*!
93 ***********************************************************************
94 * \brief
95 * fill picture parameters
96 ***********************************************************************
97 */
98 //extern "C"
fill_picparams(H264dVideoCtx_t * p_Vid,DXVA_PicParams_H264_MVC * pp)99 void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp)
100 {
101 RK_U32 i = 0, j = 0;
102 H264_StorePic_t *dec_pic = p_Vid->dec_pic;
103 H264_DpbInfo_t *dpb_info = p_Vid->p_Dec->dpb_info;
104
105 // memset(pp, 0, sizeof(DXVA_PicParams_H264_MVC));
106 //!< Configure current picture
107 fill_picture_entry(&pp->CurrPic, dec_pic->mem_mark->slot_idx, dec_pic->structure == BOTTOM_FIELD);
108 //!< Configure the set of references
109 pp->UsedForReferenceFlags = 0;
110 pp->NonExistingFrameFlags = 0;
111 for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) {
112 if (dpb_info[i].refpic) {
113 fill_picture_entry(&pp->RefFrameList[i], dpb_info[i].slot_index, dpb_info[i].is_long_term);
114 pp->FieldOrderCntList[i][0] = dpb_info[i].TOP_POC;
115 pp->FieldOrderCntList[i][1] = dpb_info[i].BOT_POC;
116 pp->FrameNumList[i] = dpb_info[i].is_long_term ? dpb_info[i].long_term_frame_idx : dpb_info[i].frame_num;
117 pp->LongTermPicNumList[i] = dpb_info[i].long_term_pic_num;
118 if (dpb_info[i].is_used & 0x01) { //!< top_field
119 pp->UsedForReferenceFlags |= 1 << (2 * i + 0);
120 }
121 if (dpb_info[i].is_used & 0x02) { //!< bot_field
122 pp->UsedForReferenceFlags |= 1 << (2 * i + 1);
123 }
124 } else {
125 pp->RefFrameList[i].bPicEntry = 0xff;
126 pp->FieldOrderCntList[i][0] = 0;
127 pp->FieldOrderCntList[i][1] = 0;
128 pp->FrameNumList[i] = 0;
129 }
130 }
131
132 pp->spspps_update = p_Vid->spspps_update;
133 if (pp->spspps_update) {
134 pp->wFrameWidthInMbsMinus1 = p_Vid->active_sps->pic_width_in_mbs_minus1;
135 pp->wFrameHeightInMbsMinus1 = p_Vid->active_sps->pic_height_in_map_units_minus1;
136 pp->num_ref_frames = p_Vid->active_sps->max_num_ref_frames;
137
138 pp->residual_colour_transform_flag = 0;
139 pp->sp_for_switch_flag = 0;
140 pp->chroma_format_idc = p_Vid->active_sps->chroma_format_idc;
141 pp->constrained_intra_pred_flag = p_Vid->active_pps->constrained_intra_pred_flag;
142 pp->weighted_pred_flag = p_Vid->active_pps->weighted_pred_flag;
143 pp->weighted_bipred_idc = p_Vid->active_pps->weighted_bipred_idc;
144 pp->MbsConsecutiveFlag = 1;
145 pp->frame_mbs_only_flag = p_Vid->active_sps->frame_mbs_only_flag;
146 pp->transform_8x8_mode_flag = p_Vid->active_pps->transform_8x8_mode_flag;
147 pp->MinLumaBipredSize8x8Flag = (p_Vid->active_sps->level_idc >= 31);
148 pp->IntraPicFlag = 1; //(Modified if we detect a non-intra slice in dxva2_h264_decode_slice)
149
150 pp->bit_depth_luma_minus8 = p_Vid->active_sps->bit_depth_luma_minus8;
151 pp->bit_depth_chroma_minus8 = p_Vid->active_sps->bit_depth_chroma_minus8;
152 pp->Reserved16Bits = 3; //!< FIXME is there a way to detect the right mode
153
154 pp->StatusReportFeedbackNumber = 1 /*+ ctx->report_id++*/;
155 }
156 pp->MbaffFrameFlag = dec_pic->mb_aff_frame_flag;
157 pp->field_pic_flag = (dec_pic->iCodingType == FIELD_CODING);
158 pp->RefPicFlag = dec_pic->used_for_reference;
159 //!< for current poc
160 pp->CurrFieldOrderCnt[0] = 0;
161 if (dec_pic->structure == TOP_FIELD || dec_pic->structure == FRAME) {
162 pp->CurrFieldOrderCnt[0] = dec_pic->top_poc;
163 }
164 pp->CurrFieldOrderCnt[1] = 0;
165 if (dec_pic->structure == BOTTOM_FIELD || dec_pic->structure == FRAME) {
166 pp->CurrFieldOrderCnt[1] = dec_pic->bottom_poc;
167 }
168 pp->frame_num = dec_pic->frame_num;
169
170 if (pp->spspps_update) {
171 pp->pic_init_qs_minus26 = p_Vid->active_pps->pic_init_qs_minus26;
172 pp->chroma_qp_index_offset = p_Vid->active_pps->chroma_qp_index_offset;
173 pp->second_chroma_qp_index_offset = p_Vid->active_pps->second_chroma_qp_index_offset;
174 pp->ContinuationFlag = 1;
175 pp->pic_init_qp_minus26 = p_Vid->active_pps->pic_init_qp_minus26;
176 pp->num_ref_idx_l0_active_minus1 = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1;
177 pp->num_ref_idx_l1_active_minus1 = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1;
178 pp->Reserved8BitsA = 0;
179
180 pp->log2_max_frame_num_minus4 = p_Vid->active_sps->log2_max_frame_num_minus4;
181 pp->pic_order_cnt_type = p_Vid->active_sps->pic_order_cnt_type;
182 if (pp->pic_order_cnt_type == 0) {
183 pp->log2_max_pic_order_cnt_lsb_minus4 = p_Vid->active_sps->log2_max_pic_order_cnt_lsb_minus4;
184 } else if (pp->pic_order_cnt_type == 1) {
185 pp->delta_pic_order_always_zero_flag = p_Vid->active_sps->delta_pic_order_always_zero_flag;
186 }
187 pp->direct_8x8_inference_flag = p_Vid->active_sps->direct_8x8_inference_flag;
188 pp->entropy_coding_mode_flag = p_Vid->active_pps->entropy_coding_mode_flag;
189 pp->pic_order_present_flag = p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag;
190 pp->num_slice_groups_minus1 = p_Vid->active_pps->num_slice_groups_minus1;
191 pp->slice_group_map_type = p_Vid->active_pps->slice_group_map_type;
192 pp->deblocking_filter_control_present_flag = p_Vid->active_pps->deblocking_filter_control_present_flag;
193 pp->redundant_pic_cnt_present_flag = p_Vid->active_pps->redundant_pic_cnt_present_flag;
194 pp->Reserved8BitsB = 0;
195 /* FMO is not implemented and is not implemented by FF neither */
196 pp->slice_group_change_rate_minus1 = 0;
197 }
198
199 //!< scaleing list flag
200 if (p_Vid->active_pps->pic_scaling_matrix_present_flag
201 || p_Vid->active_sps->seq_scaling_matrix_present_flag) {
202 pp->scaleing_list_enable_flag = 1;
203 } else {
204 pp->scaleing_list_enable_flag = 0;
205 }
206
207 //!< add in Rock-chip RKVDEC IP
208 pp->RefPicFiledFlags = 0;
209 pp->RefPicColmvUsedFlags = 0;
210 for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) {
211 if (dpb_info[i].refpic) {
212 if (dpb_info[i].colmv_is_used) {
213 pp->RefPicColmvUsedFlags |= 1 << i;
214 }
215 if (dpb_info[i].field_flag) {
216 pp->RefPicFiledFlags |= 1 << i;
217 }
218 }
219 }
220
221 //!< Following are H.264 MVC Specific parameters
222 if (p_Vid->active_subsps) {
223 RK_S32 num_views = 0;
224 pp->num_views_minus1 = p_Vid->active_subsps->num_views_minus1;
225 num_views = 1 + pp->num_views_minus1;
226 ASSERT(num_views <= 16);
227 ASSERT(num_views >= 0);
228
229 for (i = 0; i < (RK_U32)num_views; i++) {
230 pp->view_id[i] = p_Vid->active_subsps->view_id[i];
231 pp->num_anchor_refs_l0[i] = p_Vid->active_subsps->num_anchor_refs_l0[i];
232 for (j = 0; j < pp->num_anchor_refs_l0[i]; j++) {
233 pp->anchor_ref_l0[i][j] = p_Vid->active_subsps->anchor_ref_l0[i][j];
234 }
235 pp->num_anchor_refs_l1[i] = p_Vid->active_subsps->num_anchor_refs_l1[i];
236 for (j = 0; j < pp->num_anchor_refs_l1[i]; j++) {
237 pp->anchor_ref_l1[i][j] = p_Vid->active_subsps->anchor_ref_l1[i][j];
238 }
239 pp->num_non_anchor_refs_l0[i] = p_Vid->active_subsps->num_non_anchor_refs_l0[i];
240 for (j = 0; j < pp->num_non_anchor_refs_l0[i]; j++) {
241 pp->non_anchor_ref_l0[i][j] = p_Vid->active_subsps->non_anchor_ref_l0[i][j];
242 }
243 pp->num_non_anchor_refs_l1[i] = p_Vid->active_subsps->num_non_anchor_refs_l1[i];
244 for (j = 0; j < pp->num_non_anchor_refs_l1[i]; j++) {
245 pp->non_anchor_ref_l1[i][j] = p_Vid->active_subsps->non_anchor_ref_l1[i][j];
246 }
247 }
248
249 for (i = num_views; i < 16; i++)
250 pp->view_id[i] = 0xffff;
251
252 pp->curr_view_id = dec_pic->view_id;
253 pp->anchor_pic_flag = dec_pic->anchor_pic_flag;
254 pp->inter_view_flag = dec_pic->inter_view_flag;
255 for (i = 0; i < 16; i++) {
256 pp->ViewIDList[i] = dpb_info[i].view_id;
257 }
258 //!< add in Rock-chip RKVDEC IP
259 pp->curr_layer_id = dec_pic->layer_id;
260 pp->UsedForInTerviewflags = 0;
261 for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) {
262 if (dpb_info[i].is_ilt_flag) {
263 pp->UsedForInTerviewflags |= 1 << i;
264 }
265 pp->RefPicLayerIdList[i] = dpb_info[i].voidx;
266 }
267 } else {
268 pp->num_views_minus1 = 0;
269 pp->curr_layer_id = dec_pic->layer_id;
270 memset(pp->view_id, 0, sizeof(pp->view_id));
271 memset(pp->ViewIDList, 0, sizeof(pp->ViewIDList));
272 memset(pp->RefPicLayerIdList, 0, sizeof(pp->RefPicLayerIdList));
273 }
274
275 p_Vid->spspps_update = 0;
276
277 //!< for fpga test
278 pp->seq_parameter_set_id = p_Vid->active_sps->seq_parameter_set_id;
279 pp->pps_seq_parameter_set_id = p_Vid->active_pps->seq_parameter_set_id;
280 pp->pps_pic_parameter_set_id = p_Vid->active_pps->pic_parameter_set_id;
281 pp->profile_idc = p_Vid->active_sps->profile_idc;
282 pp->constraint_set3_flag = p_Vid->active_sps->constrained_set3_flag;
283 pp->qpprime_y_zero_transform_bypass_flag = p_Vid->active_sps->qpprime_y_zero_transform_bypass_flag;;
284 pp->mvc_extension_enable = p_Vid->active_subsps ? 1 : 0;
285 }
286
287 /*!
288 ***********************************************************************
289 * \brief
290 * fill slice short struct
291 ***********************************************************************
292 */
293 //extern "C"
fill_slice_syntax(H264_SLICE_t * currSlice,H264dDxvaCtx_t * dxva_ctx)294 MPP_RET fill_slice_syntax(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx)
295 {
296 RK_U32 list = 0, i = 0;
297 MPP_RET ret = MPP_ERR_UNKNOW;
298 DXVA_Slice_H264_Long *p_long = NULL;
299 RK_S32 dpb_idx = 0, dpb_valid = 0, bottom_flag = 0;
300
301 FUN_CHECK(ret = fill_slice_stream(dxva_ctx, &currSlice->p_Cur->nalu));
302 p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count];
303 //!< fill slice long contents
304 p_long->first_mb_in_slice = currSlice->start_mb_nr;
305 p_long->NumMbsForSlice = 0; //!< XXX it is set once we have all slices
306 p_long->slice_type = currSlice->slice_type;
307 p_long->num_ref_idx_l0_active_minus1 = currSlice->active_pps->num_ref_idx_l0_default_active_minus1;
308 p_long->num_ref_idx_l1_active_minus1 = currSlice->active_pps->num_ref_idx_l1_default_active_minus1;
309 p_long->redundant_pic_cnt = currSlice->redundant_pic_cnt;
310 p_long->direct_spatial_mv_pred_flag = currSlice->direct_spatial_mv_pred_flag;
311 p_long->slice_id = dxva_ctx->slice_count;
312 //!< add parameters
313 p_long->active_sps_id = currSlice->active_sps->seq_parameter_set_id;
314 p_long->active_pps_id = currSlice->active_pps->pic_parameter_set_id;
315 p_long->idr_pic_id = currSlice->idr_pic_id;
316 p_long->idr_flag = currSlice->idr_flag;
317 p_long->drpm_used_bitlen = currSlice->drpm_used_bitlen;
318 p_long->poc_used_bitlen = currSlice->poc_used_bitlen;
319 p_long->nal_ref_idc = currSlice->nal_reference_idc;
320 p_long->profileIdc = currSlice->active_sps->profile_idc;
321
322 for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[0]); i++) {
323 dpb_idx = currSlice->p_Dec->refpic_info_p[i].dpb_idx;
324 dpb_valid = currSlice->p_Dec->refpic_info_p[i].valid;
325 //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0);
326 if (dpb_valid) {
327 bottom_flag = currSlice->p_Dec->refpic_info_p[i].bottom_flag;
328 fill_picture_entry(&p_long->RefPicList[0][i], dpb_idx, bottom_flag);
329 } else {
330 p_long->RefPicList[0][i].bPicEntry = 0xff;
331 }
332 }
333
334 for (list = 0; list < 2; list++) {
335 for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[list + 1]); i++) {
336 dpb_idx = currSlice->p_Dec->refpic_info_b[list][i].dpb_idx;
337 dpb_valid = currSlice->p_Dec->refpic_info_b[list][i].valid;
338 //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0);
339 if (dpb_valid) {
340 bottom_flag = currSlice->p_Dec->refpic_info_b[list][i].bottom_flag;
341 fill_picture_entry(&p_long->RefPicList[list + 1][i], dpb_idx, bottom_flag);
342 } else {
343 p_long->RefPicList[list + 1][i].bPicEntry = 0xff;
344 }
345 }
346 }
347 dxva_ctx->slice_count++;
348
349 return ret = MPP_OK;
350 __FAILED:
351 return ret;
352 }
353
354
355 /*!
356 ***********************************************************************
357 * \brief
358 * check parser is end and then configure register
359 ***********************************************************************
360 */
361 //extern "C"
commit_buffer(H264dDxvaCtx_t * dxva_ctx)362 void commit_buffer(H264dDxvaCtx_t *dxva_ctx)
363 {
364 H264dSyntax_t *p_syn = &dxva_ctx->syn;
365 DXVA2_DecodeBufferDesc *p_dec = NULL;
366
367 p_syn->num = 0;
368 //!< commit picture paramters
369 p_dec = &p_syn->buf[p_syn->num++];
370 memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
371 p_dec->CompressedBufferType = DXVA2_PictureParametersBufferType;
372 p_dec->pvPVPState = (void *)&dxva_ctx->pp;
373 p_dec->DataSize = sizeof(DXVA_PicParams_H264_MVC);
374 p_dec->NumMBsInBuffer = 0;
375 //!< commit scanlist Qmatrix
376 p_dec = &p_syn->buf[p_syn->num++];
377 memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
378 p_dec->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType;
379 p_dec->pvPVPState = (void *)&dxva_ctx->qm;
380 p_dec->DataSize = sizeof(DXVA_Qmatrix_H264);
381 p_dec->NumMBsInBuffer = 0;
382 //!< commit bitstream
383 p_dec = &p_syn->buf[p_syn->num++];
384 memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
385 p_dec->CompressedBufferType = DXVA2_BitStreamDateBufferType;
386 p_dec->DataSize = MPP_ALIGN(dxva_ctx->strm_offset, 16);
387 memset(dxva_ctx->bitstream + dxva_ctx->strm_offset, 0, p_dec->DataSize - dxva_ctx->strm_offset);
388 p_dec->pvPVPState = (void *)dxva_ctx->bitstream;
389 //!< commit slice control, DXVA_Slice_H264_Long
390 p_dec = &p_syn->buf[p_syn->num++];
391 memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc));
392 p_dec->CompressedBufferType = DXVA2_SliceControlBufferType;
393 p_dec->NumMBsInBuffer = (dxva_ctx->pp.wFrameHeightInMbsMinus1 + 1)
394 * (dxva_ctx->pp.wFrameWidthInMbsMinus1 + 1);
395 p_dec->pvPVPState = dxva_ctx->slice_long;
396 p_dec->DataSize = dxva_ctx->slice_count * sizeof(DXVA_Slice_H264_Long);
397
398 //!< reset dxva parameters
399 dxva_ctx->slice_count = 0;
400 dxva_ctx->strm_offset = 0;
401 }
402