1 /*
2 * Copyright 2021 Rockchip Electronics Co. LTD
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 express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "avs2d_parse"
18
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include "mpp_mem.h"
23 #include "mpp_log.h"
24 #include "mpp_packet_impl.h"
25 #include "hal_task.h"
26
27 #include "avs2d_api.h"
28 #include "avs2d_dpb.h"
29 #include "avs2d_parse.h"
30 #include "avs2d_ps.h"
31 #include "avs2d_global.h"
32
33 #define AVS2_ISPIC(x) ((x) == 0xB3 || (x) == 0xB6)
34 #define AVS2_ISUNIT(x) ((x) == 0xB0 || (x) == 0xB1 || (x) == 0xB2 || AVS2_ISPIC(x))
35 #define AVS2_IS_START_CODE(x) (((x) & 0xffffff00) == 0x100)
36
37 #define AVS2_IS_SLICE_START_CODE(x) ((x) >= AVS2_SLICE_MIN_START_CODE && (x) <= AVS2_SLICE_MAX_START_CODE)
38 #define AVS2_IS_HEADER(x) ((x) >= AVS2_VIDEO_SEQUENCE_START_CODE && (x) <= AVS2_VIDEO_EDIT_CODE)
39 #define AVS2_IS_PIC_START_CODE(x) ((x) == AVS2_I_PICTURE_START_CODE || (x) == AVS2_PB_PICTURE_START_CODE)
40
41 /**
42 * @brief Find start code 00 00 01 xx
43 *
44 * Search 01 first and check the previous 2 bytes and the following 1 bytes.
45 * If it is start code, return the value of start code at U32 as 0x000001xx.
46 *
47 * @param buf_start the start of input buffer
48 * @param buf_end the end of input buffer
49 * @param pos output value, the position of start code
50 * @return RK_U32
51 */
avs2_find_start_code(RK_U8 * buf_start,RK_U8 * buf_end,RK_U8 ** pos)52 static RK_U32 avs2_find_start_code(RK_U8 *buf_start, RK_U8* buf_end, RK_U8 **pos)
53 {
54 RK_U8 *buf_ptr = NULL;
55 RK_U8 *ptr = buf_start;
56 RK_U32 remain_size = buf_end - buf_start + 1;
57
58 while (ptr < buf_end) {
59 buf_ptr = memchr(ptr, 0x01, remain_size);
60
61 if (!buf_ptr) {
62 return 0;
63 }
64
65 //check the position of "01"
66 if ((buf_ptr < buf_end) && (buf_ptr - buf_start > 1) &&
67 (*(buf_ptr - 1) == 0) && (*(buf_ptr - 2) == 0)) {
68 //found 00 00 01 xx
69 *pos = buf_ptr + 1;
70 return (AVS2_START_CODE | *(buf_ptr + 1));
71 } else {
72 // keep search at remaining buffer
73 remain_size = remain_size - (buf_ptr - ptr + 1);
74 ptr = buf_ptr + 1;
75 }
76 }
77
78 return 0;
79 }
80
avs2_add_nalu_header(Avs2dCtx_t * p_dec,RK_U32 header)81 static MPP_RET avs2_add_nalu_header(Avs2dCtx_t *p_dec, RK_U32 header)
82 {
83 MPP_RET ret = MPP_OK;
84 Avs2dNalu_t *p_nal = NULL;
85
86 if (p_dec->nal_cnt + 1 > p_dec->nal_allocated) {
87 Avs2dNalu_t *new_buffer = mpp_realloc(p_dec->p_nals, Avs2dNalu_t, p_dec->nal_allocated + MAX_NALU_NUM);
88
89 if (!new_buffer) {
90 mpp_err_f("Realloc NALU buffer failed, could not add more NALU!");
91 ret = MPP_ERR_NOMEM;
92 } else {
93 p_dec->p_nals = new_buffer;
94 memset(&p_dec->p_nals[p_dec->nal_allocated], 0, MAX_NALU_NUM * sizeof(Avs2dNalu_t));
95 p_dec->nal_allocated += MAX_NALU_NUM;
96 AVS2D_PARSE_TRACE("Realloc NALU buffer, current allocated %d", p_dec->nal_allocated);
97 }
98 }
99
100 p_nal = p_dec->p_nals + p_dec->nal_cnt;
101 p_nal->header = header;
102 p_nal->length = 0;
103 p_nal->data_pos = 0;
104 p_nal->eof = 0;
105
106 p_dec->nal_cnt++;
107 AVS2D_PARSE_TRACE("add header 0x%x, nal_cnt %d", header, p_dec->nal_cnt);
108
109 return ret;
110 }
111
112 /**
113 * @brief store nalu startcode and data
114 * TODO If nalu data isn't appear right after startcode, it may go wrong
115 *
116 * @param p_dec
117 * @param p_start
118 * @param len
119 * @param start_code
120 * @return MPP_RET
121 */
store_nalu(Avs2dCtx_t * p_dec,RK_U8 * p_start,RK_U32 len,RK_U32 start_code)122 static MPP_RET store_nalu(Avs2dCtx_t *p_dec, RK_U8 *p_start, RK_U32 len, RK_U32 start_code)
123 {
124 MPP_RET ret = MPP_OK;
125 Avs2dNalu_t *p_nalu = &p_dec->p_nals[p_dec->nal_cnt - 1];
126 Avs2dStreamBuf_t *p_header = NULL;;
127 RK_U32 add_size = SZ_1K;
128 RK_U8 *data_ptr = NULL;
129
130 if (AVS2_IS_SLICE_START_CODE(start_code)) {
131 p_header = p_dec->p_stream;
132 add_size = SZ_512K;
133 } else if (AVS2_IS_HEADER(start_code)) {
134 p_header = p_dec->p_header;
135 add_size = SZ_1K;
136 }
137
138 if ((p_header->len + len) > p_header->size) {
139 mpp_log_f("realloc %p p_header->pbuf, size %d, len %d %d", p_header->pbuf, p_header->size, p_header->len, len);
140 RK_U32 new_size = p_header->size + add_size + len;
141 RK_U8 * new_buffer = mpp_realloc(p_header->pbuf, RK_U8, new_size);
142 mpp_log_f("realloc %p, size %d", p_header->pbuf, new_size);
143 if (!new_buffer) {
144 mpp_err_f("Realloc header buffer with size %d failed", new_size);
145 return MPP_ERR_NOMEM;
146 } else {
147 p_header->pbuf = new_buffer;
148 memset(p_header->pbuf + p_header->size, 0, new_size - p_header->size);
149 p_header->size = new_size;
150 }
151 }
152
153 data_ptr = p_header->pbuf + p_header->len;
154
155 if (p_nalu->length == 0) {
156 p_nalu->data_pos = p_header->len;
157 }
158
159 if (len > 0) {
160 memcpy(data_ptr, p_start, len);
161 p_nalu->length += len;
162 p_header->len += len;
163 }
164
165 return ret;
166 }
167
168 /**
169 * @brief Once got a new frame, reset previous stored nalu data an buffer
170 *
171 * @param p_dec
172 * @return MPP_RET
173 */
reset_nalu_buf(Avs2dCtx_t * p_dec)174 static MPP_RET reset_nalu_buf(Avs2dCtx_t *p_dec)
175 {
176 MPP_RET ret = MPP_OK;
177
178 AVS2D_PARSE_TRACE("In.");
179 p_dec->prev_start_code = 0;
180 p_dec->new_frame_flag = 0;
181
182 memset(p_dec->prev_tail_data, 0xff, AVS2D_PACKET_SPLIT_CHECKER_BUFFER_SIZE);
183
184 if (p_dec->p_stream) {
185 memset(p_dec->p_stream->pbuf, 0, p_dec->p_stream->size);
186 p_dec->p_stream->len = 0;
187 }
188
189 if (p_dec->p_header) {
190 memset(p_dec->p_header->pbuf, 0, p_dec->p_header->size);
191 p_dec->p_header->len = 0;
192 }
193
194 if (p_dec->p_nals) {
195 memset(p_dec->p_nals, 0, sizeof(Avs2dNalu_t) * p_dec->nal_allocated);
196 p_dec->nal_cnt = 0;
197 }
198
199 AVS2D_PARSE_TRACE("Out.");
200 return ret;
201 }
202
parse_seq_dispay_ext_header(BitReadCtx_t * bitctx,Avs2dSeqExtHeader_t * exh)203 static MPP_RET parse_seq_dispay_ext_header(BitReadCtx_t *bitctx, Avs2dSeqExtHeader_t *exh)
204 {
205 MPP_RET ret = MPP_OK;
206
207 READ_BITS(bitctx, 3, &exh->video_format);
208 READ_ONEBIT(bitctx, &exh->sample_range);
209 READ_ONEBIT(bitctx, &exh->color_description);
210
211 if (exh->color_description) {
212 READ_BITS(bitctx, 8, &exh->color_primaries);
213 READ_BITS(bitctx, 8, &exh->transfer_characteristics);
214 READ_BITS(bitctx, 8, &exh->matrix_coefficients);
215 }
216 READ_BITS(bitctx, 14, &exh->display_horizontal_size);
217 READ_MARKER_BIT(bitctx);
218 READ_BITS(bitctx, 14, &exh->display_vertical_size);
219
220 READ_ONEBIT(bitctx, &exh->td_mode_flag);
221 if (exh->td_mode_flag) {
222 READ_BITS(bitctx, 8, &exh->td_packing_mode);
223 READ_ONEBIT(bitctx, &exh->view_reverse_flag);
224 }
225
226 return ret;
227 __BITREAD_ERR:
228 return ret = bitctx->ret;
229 }
230
parse_mastering_display_and_content_meta(BitReadCtx_t * bitctx,MppFrameMasteringDisplayMetadata * display_meta,MppFrameContentLightMetadata * content_light)231 static MPP_RET parse_mastering_display_and_content_meta(BitReadCtx_t *bitctx,
232 MppFrameMasteringDisplayMetadata *display_meta,
233 MppFrameContentLightMetadata *content_light)
234 {
235 MPP_RET ret = MPP_OK;
236 RK_U32 i = 0;
237 RK_U16 value;
238
239 /* display metadata */
240 for (i = 0; i < 3; i++) {
241 READ_BITS(bitctx, 16, &value);
242 READ_MARKER_BIT(bitctx);
243 display_meta->display_primaries[i][0] = value;
244 READ_BITS(bitctx, 16, &value);
245 READ_MARKER_BIT(bitctx);
246 display_meta->display_primaries[i][1] = value;
247 }
248 READ_BITS(bitctx, 16, &value);
249 READ_MARKER_BIT(bitctx);
250 display_meta->white_point[0] = value;
251 READ_BITS(bitctx, 16, &value);
252 READ_MARKER_BIT(bitctx);
253 display_meta->white_point[1] = value;
254 READ_BITS(bitctx, 16, &value);
255 READ_MARKER_BIT(bitctx);
256 display_meta->max_luminance = value;
257 READ_BITS(bitctx, 16, &value);
258 READ_MARKER_BIT(bitctx);
259 display_meta->min_luminance = value;
260
261 /* content light */
262 READ_BITS(bitctx, 16, &value);
263 READ_MARKER_BIT(bitctx);
264 content_light->MaxCLL = value;
265 READ_BITS(bitctx, 16, &value);
266 READ_MARKER_BIT(bitctx);
267 content_light->MaxFALL = value;
268
269 SKIP_BITS(bitctx, 16);
270
271 return ret;
272 __BITREAD_ERR:
273 return ret = bitctx->ret;
274 }
275
parse_hdr_dynamic_meta_extension(BitReadCtx_t * bitctx,MppFrameHdrDynamicMeta * hdr_meta)276 static MPP_RET parse_hdr_dynamic_meta_extension(BitReadCtx_t *bitctx, MppFrameHdrDynamicMeta *hdr_meta)
277 {
278 MPP_RET ret = MPP_OK;
279 RK_S32 country_code, provider_code;
280 RK_U16 terminal_provide_oriented_code;
281 (void)hdr_meta;
282 /* hdr_dynamic_metadata_type */
283 SKIP_BITS(bitctx, 4);
284 READ_BITS(bitctx, 8, &country_code);
285 READ_BITS(bitctx, 16, &provider_code);
286 READ_BITS(bitctx, 16, &terminal_provide_oriented_code);
287 AVS2D_PARSE_TRACE("country_code=%d provider_code=%d terminal_provider_code %d\n",
288 country_code, provider_code, terminal_provide_oriented_code);
289
290 //TODO: copy dynamic data
291
292 return ret;
293 __BITREAD_ERR:
294 return ret = bitctx->ret;
295 }
296
parse_extension_header(Avs2dCtx_t * p_dec,BitReadCtx_t * bitctx)297 static MPP_RET parse_extension_header(Avs2dCtx_t *p_dec, BitReadCtx_t *bitctx)
298 {
299 MPP_RET ret = MPP_OK;
300 RK_U32 val_temp = 0;
301
302 READ_BITS(bitctx, 4, &val_temp); //!< extension_start_code
303 switch (val_temp) {
304 case AVS2_SEQUENCE_DISPLAY_EXT_ID:
305 FUN_CHECK(ret = parse_seq_dispay_ext_header(bitctx, &p_dec->exh));
306 p_dec->got_exh = 1;
307 if (p_dec->exh.transfer_characteristics == MPP_FRAME_TRC_BT2020_10 ||
308 p_dec->exh.transfer_characteristics == MPP_FRAME_TRC_BT1361_ECG)
309 p_dec->is_hdr = 1;
310 break;
311 case AVS2_MASTERING_DISPLAY_AND_CONTENT_METADATA_EXT_ID:
312 FUN_CHECK(ret = parse_mastering_display_and_content_meta(bitctx,
313 &p_dec->display_meta,
314 &p_dec->content_light));
315 p_dec->is_hdr = 1;
316 break;
317 case AVS2_HDR_DYNAMIC_METADATA_EXT_ID:
318 FUN_CHECK(ret = parse_hdr_dynamic_meta_extension(bitctx, p_dec->hdr_dynamic_meta));
319 break;
320 default:
321 break;
322 }
323
324 return ret;
325 __BITREAD_ERR:
326 return ret = bitctx->ret;
327 __FAILED:
328 return ret;
329 }
330
avs2d_reset_parser(Avs2dCtx_t * p_dec)331 MPP_RET avs2d_reset_parser(Avs2dCtx_t *p_dec)
332 {
333 AVS2D_PARSE_TRACE("In.");
334 p_dec->got_vsh = 0;
335 p_dec->got_exh = 0;
336 p_dec->got_keyframe = 0;
337 p_dec->enable_wq = 0;
338 p_dec->new_frame_flag = 0;
339 p_dec->new_seq_flag = 0;
340 reset_nalu_buf(p_dec);
341 AVS2D_PARSE_TRACE("Out.");
342
343 return MPP_OK;
344 }
345
346 /*!
347 ***********************************************************************
348 * \brief
349 * commit buffer to hal
350 ***********************************************************************
351 */
avs2d_commit_syntaxs(Avs2dSyntax_t * syntax,HalDecTask * task)352 MPP_RET avs2d_commit_syntaxs(Avs2dSyntax_t *syntax, HalDecTask *task)
353 {
354 task->syntax.number = 1;
355 task->syntax.data = syntax;
356
357 return MPP_OK;
358 }
359
avs2d_fill_parameters(Avs2dCtx_t * p_dec,Avs2dSyntax_t * syntax)360 MPP_RET avs2d_fill_parameters(Avs2dCtx_t *p_dec, Avs2dSyntax_t *syntax)
361 {
362 RK_S32 i = 0;
363 Avs2dSeqHeader_t *vsh = &p_dec->vsh;
364 Avs2dPicHeader_t *ph = &p_dec->ph;
365 Avs2dFrameMgr_t *mgr = &p_dec->frm_mgr;
366 PicParams_Avs2d *pp = &syntax->pp;
367 RefParams_Avs2d *refp = &syntax->refp;
368 AlfParams_Avs2d *alfp = &syntax->alfp;
369 WqmParams_Avs2d *wqmp = &syntax->wqmp;
370
371 //!< sequence header
372 pp->chroma_format_idc = vsh->chroma_format;
373 pp->pic_width_in_luma_samples = MPP_ALIGN(vsh->horizontal_size, 8);
374 pp->pic_height_in_luma_samples = MPP_ALIGN(vsh->vertical_size, 8);
375 pp->bit_depth_luma_minus8 = vsh->bit_depth - 8;
376 pp->bit_depth_chroma_minus8 = vsh->bit_depth - 8;
377 pp->lcu_size = vsh->lcu_size;
378 pp->progressive_sequence = vsh->progressive_sequence;
379 pp->field_coded_sequence = vsh->field_coded_sequence;
380 pp->multi_hypothesis_skip_enable_flag = vsh->enable_mhp_skip;
381 pp->dual_hypothesis_prediction_enable_flag = vsh->enable_dhp;
382 pp->weighted_skip_enable_flag = vsh->enable_wsm;
383 pp->asymmetrc_motion_partitions_enable_flag = vsh->enable_amp;
384 pp->nonsquare_quadtree_transform_enable_flag = vsh->enable_nsqt;
385 pp->nonsquare_intra_prediction_enable_flag = vsh->enable_nsip;
386 pp->secondary_transform_enable_flag = vsh->enable_2nd_transform;
387 pp->sample_adaptive_offset_enable_flag = vsh->enable_sao;
388 pp->adaptive_loop_filter_enable_flag = vsh->enable_alf;
389 pp->pmvr_enable_flag = vsh->enable_pmvr;
390 pp->cross_slice_loopfilter_enable_flag = vsh->enable_clf;
391
392 //!< picture header
393 pp->picture_type = ph->picture_type;
394 pp->scene_reference_enable_flag = ph->background_reference_flag;
395 pp->bottom_field_picture_flag = (vsh->field_coded_sequence) && (!ph->is_top_field);
396 // pp->bottom_field_picture_flag = !ph->is_top_field;
397 pp->fixed_picture_qp = ph->fixed_picture_qp;
398 pp->picture_qp = ph->picture_qp;
399 pp->loop_filter_disable_flag = !ph->enable_loop_filter;
400 pp->alpha_c_offset = ph->alpha_c_offset;
401 pp->beta_offset = ph->beta_offset;
402
403 //!< current poc
404 pp->cur_poc = ph->poi;
405
406 //!< picture reference params
407 refp->ref_pic_num = mgr->num_of_ref;
408 memset(refp->ref_poc_list, -1, sizeof(refp->ref_poc_list));
409 for (i = 0; i < mgr->num_of_ref; i++) {
410 refp->ref_poc_list[i] = mgr->refs[i] ? mgr->refs[i]->poi : -1;
411 }
412
413 //!< picture alf params
414 alfp->enable_pic_alf_y = ph->enable_pic_alf_y;
415 alfp->enable_pic_alf_cb = ph->enable_pic_alf_cb;
416 alfp->enable_pic_alf_cr = ph->enable_pic_alf_cr;
417 alfp->alf_filter_num_minus1 = (ph->alf_filter_num > 0) ? (ph->alf_filter_num - 1) : 0;
418 memcpy(alfp->alf_coeff_idx_tab, ph->alf_coeff_idx_tab, sizeof(ph->alf_coeff_idx_tab));
419 memcpy(alfp->alf_coeff_y, ph->alf_coeff_y, sizeof(ph->alf_coeff_y));
420 memcpy(alfp->alf_coeff_cb, ph->alf_coeff_cb, sizeof(ph->alf_coeff_cb));
421 memcpy(alfp->alf_coeff_cr, ph->alf_coeff_cr, sizeof(ph->alf_coeff_cr));
422
423 //!< picture wqm params
424 wqmp->pic_weight_quant_enable_flag = p_dec->enable_wq;
425 wqmp->chroma_quant_param_delta_cb = ph->chroma_quant_param_delta_cb;
426 wqmp->chroma_quant_param_delta_cr = ph->chroma_quant_param_delta_cr;
427 memcpy(wqmp->wq_matrix, p_dec->cur_wq_matrix, sizeof(p_dec->cur_wq_matrix));
428
429 return MPP_OK;
430 }
431
avs2_split_nalu(Avs2dCtx_t * p_dec,RK_U8 * buf_start,RK_U32 buf_length,RK_U32 over_read,RK_U32 * remain)432 MPP_RET avs2_split_nalu(Avs2dCtx_t *p_dec, RK_U8 *buf_start, RK_U32 buf_length, RK_U32 over_read, RK_U32 *remain)
433 {
434 MPP_RET ret = MPP_OK;
435
436 RK_U8 *start_code_ptr = NULL;
437 RK_U32 start_code = 0;
438 RK_U32 nalu_len = 0;
439
440 RK_U8 *buf_end;
441
442 buf_end = buf_start + buf_length - 1;
443
444 start_code = avs2_find_start_code(buf_start, buf_end, &start_code_ptr);
445
446 if (start_code_ptr) {
447 AVS2D_PARSE_TRACE("Found start_code 0x%08x at offset 0x%08x, prev_starcode 0x%08x\n",
448 start_code, start_code_ptr - buf_start, p_dec->prev_start_code);
449 if (!p_dec->new_seq_flag) {
450 if (start_code == AVS2_VIDEO_SEQUENCE_START_CODE) {
451 AVS2D_PARSE_TRACE("Found the first video_sequence_start_code");
452 p_dec->nal_cnt = 0;
453 avs2_add_nalu_header(p_dec, AVS2_VIDEO_SEQUENCE_START_CODE);
454 p_dec->new_seq_flag = 1;
455 p_dec->prev_start_code = AVS2_VIDEO_SEQUENCE_START_CODE;
456 } else {
457 AVS2D_PARSE_TRACE("Skip start code before first video_sequence_start_code");
458 }
459
460 *remain = buf_end - start_code_ptr;
461 } else {
462 if (start_code == AVS2_VIDEO_SEQUENCE_START_CODE) {
463 AVS2D_PARSE_TRACE("Found repeated video_sequence_start_code");
464 }
465
466 if (AVS2_IS_START_CODE(p_dec->prev_start_code) && p_dec->prev_start_code != AVS2_USER_DATA_START_CODE) {
467 nalu_len = start_code_ptr - buf_start - 3;
468 if (nalu_len > over_read) {
469 store_nalu(p_dec, buf_start + over_read, nalu_len - over_read, p_dec->prev_start_code);
470 }
471 }
472
473 if (AVS2_IS_SLICE_START_CODE(p_dec->prev_start_code) && !AVS2_IS_SLICE_START_CODE(start_code)) {
474 p_dec->new_frame_flag = 1;
475 p_dec->p_nals[p_dec->nal_cnt - 1].eof = 1;
476 *remain = buf_end - start_code_ptr + 4;
477 } else {
478 if (start_code != AVS2_USER_DATA_START_CODE)
479 avs2_add_nalu_header(p_dec, start_code);
480
481 // need to put slice start code to stream buffer
482 if (AVS2_IS_SLICE_START_CODE(start_code)) {
483 store_nalu(p_dec, start_code_ptr - 3, 4, start_code);
484 } else if (start_code == AVS2_VIDEO_SEQUENCE_END_CODE) {
485 p_dec->p_nals[p_dec->nal_cnt - 1].eof = 1;
486 }
487
488 *remain = buf_end - start_code_ptr;
489 }
490
491 p_dec->prev_start_code = start_code;
492 }
493 } else {
494 if (!p_dec->new_seq_flag) {
495 AVS2D_PARSE_TRACE("Skip data code before first video_sequence_start_code");
496 } else {
497 if (AVS2_IS_START_CODE(p_dec->prev_start_code)) {
498 nalu_len = buf_length;
499 if (nalu_len > over_read) {
500 store_nalu(p_dec, buf_start + over_read, nalu_len - over_read, p_dec->prev_start_code);
501 }
502 }
503 }
504
505 *remain = 0;
506 }
507
508 return ret;
509 }
510
avs2d_parse_prepare_split(Avs2dCtx_t * p_dec,MppPacket * pkt,HalDecTask * task)511 MPP_RET avs2d_parse_prepare_split(Avs2dCtx_t *p_dec, MppPacket *pkt, HalDecTask *task)
512 {
513 MPP_RET ret = MPP_OK;
514 RK_U8 *p_curdata = NULL;
515 RK_U8 *p_start = NULL;
516 RK_U8 *p_end = NULL;
517 RK_U32 pkt_length = 0;
518 RK_U32 first_read_length = 0;
519
520 AVS2D_PARSE_TRACE("In.");
521
522 pkt_length = (RK_U32) mpp_packet_get_length(pkt);
523
524 p_curdata = p_start = (RK_U8 *) mpp_packet_get_pos(pkt);
525 p_end = p_start + pkt_length - 1;
526
527 // Combine last packet data
528 first_read_length = (pkt_length >= 4) ? 4 : pkt_length;
529 memcpy(p_dec->prev_tail_data + 3, p_curdata, first_read_length);
530
531 RK_U32 remain = 0;
532
533 AVS2D_PARSE_TRACE("previous data[0~3]=%02x %02x %02x, first_read_length %d\n",
534 p_dec->prev_tail_data[0], p_dec->prev_tail_data[1],
535 p_dec->prev_tail_data[2], first_read_length);
536 ret = avs2_split_nalu(p_dec, p_dec->prev_tail_data,
537 AVS2D_PACKET_SPLIT_CHECKER_BUFFER_SIZE,
538 AVS2D_PACKET_SPLIT_LAST_KEPT_LENGTH,
539 &remain);
540 p_curdata = p_start + first_read_length - remain;
541 AVS2D_PARSE_TRACE("remian length %d\n", remain);
542
543 remain = 0;
544
545 while (p_curdata < p_end) {
546 ret = avs2_split_nalu(p_dec, p_curdata, p_end - p_curdata + 1, 0, &remain);
547
548 if (ret) {
549 break;
550 } else {
551 p_curdata = p_end - remain + 1;
552 }
553
554 if (p_dec->new_frame_flag || (p_dec->nal_cnt > 1 && p_dec->p_nals[p_dec->nal_cnt - 1].eof == 1)) {
555 task->valid = 1;
556 break;
557 }
558 }
559
560 mpp_packet_set_pos(pkt, p_curdata);
561
562 if (remain == 0) {
563 memset(p_dec->prev_tail_data, 0xff, 3);
564
565 if (pkt_length >= 3) {
566 p_dec->prev_tail_data[0] = p_end[0];
567 p_dec->prev_tail_data[1] = p_end[-1];
568 p_dec->prev_tail_data[2] = p_end[-2];
569 }
570 }
571
572 AVS2D_PARSE_TRACE("Out.");
573 return ret;
574 }
575
576 /**
577 * @brief Every packet is a complete frame.
578 * So we don't have to do combine data from different packet.
579 *
580 * @param p_dec
581 * @param pkt
582 * @param task
583 * @return MPP_RET
584 */
avs2d_parse_prepare_fast(Avs2dCtx_t * p_dec,MppPacket * pkt,HalDecTask * task)585 MPP_RET avs2d_parse_prepare_fast(Avs2dCtx_t *p_dec, MppPacket *pkt, HalDecTask *task)
586 {
587 MPP_RET ret = MPP_OK;
588 RK_U8 *p_curdata = NULL;
589 RK_U8 *p_start = NULL;
590 RK_U8 *p_end = NULL;
591 RK_U32 pkt_length = 0;
592 RK_U32 remain = 0;
593
594 AVS2D_PARSE_TRACE("In.");
595
596 pkt_length = (RK_U32) mpp_packet_get_length(pkt);
597
598 p_curdata = p_start = (RK_U8 *) mpp_packet_get_pos(pkt);
599 p_end = p_start + pkt_length - 1;
600
601 while (p_curdata < p_end) {
602 ret = avs2_split_nalu(p_dec, p_curdata, p_end - p_curdata + 1, 0, &remain);
603
604 if (ret) {
605 break;
606 } else {
607 p_curdata = p_end - remain + 1;
608 }
609
610 if (p_dec->new_frame_flag || (p_dec->nal_cnt && (p_dec->p_nals[p_dec->nal_cnt - 1].eof == 1))
611 || p_curdata >= p_end) {
612 task->valid = 1;
613 break;
614 }
615 }
616
617 // sequence_end_code and video_edit_code at the end of a packet will be ignored.
618 mpp_packet_set_pos(pkt, p_end + 1);
619 AVS2D_PARSE_TRACE("after split, remain %d, task->valid %d\n", remain, task->valid);
620
621 AVS2D_PARSE_TRACE("Out.");
622 return ret;
623 }
624
avs2d_parse_stream(Avs2dCtx_t * p_dec,HalDecTask * task)625 MPP_RET avs2d_parse_stream(Avs2dCtx_t *p_dec, HalDecTask *task)
626 {
627 MPP_RET ret = MPP_OK;
628 Avs2dNalu_t *p_nalu = p_dec->p_nals;
629 AVS2D_PARSE_TRACE("In.");
630 RK_U32 i = 0;
631 for (i = 0 ; i < p_dec->nal_cnt; i++) {
632 RK_U32 startcode = p_nalu->header;
633
634 AVS2D_PARSE_TRACE("start code[%d] 0x%08x\n", i, startcode);
635 if (!AVS2_IS_SLICE_START_CODE(startcode)) {
636 RK_U8 *data_ptr = p_dec->p_header->pbuf + p_nalu->data_pos;
637 memset(&p_dec->bitctx, 0, sizeof(BitReadCtx_t));
638 AVS2D_PARSE_TRACE("bitread ctx, pos %d, length %d\n", p_nalu->data_pos, p_nalu->length);
639 mpp_set_bitread_ctx(&p_dec->bitctx, data_ptr, p_nalu->length);
640 mpp_set_bitread_pseudo_code_type(&p_dec->bitctx, PSEUDO_CODE_AVS2);
641 }
642
643 switch (startcode) {
644 case AVS2_VIDEO_SEQUENCE_START_CODE:
645 ret = avs2d_parse_sequence_header(p_dec);
646 if (ret == MPP_OK) {
647 p_dec->got_vsh = 1;
648
649 if (p_dec->new_seq_flag && !p_dec->frm_mgr.initial_flag) {
650 avs2d_dpb_create(p_dec);
651 }
652 }
653 p_dec->got_exh = 0;
654 break;
655 case AVS2_I_PICTURE_START_CODE:
656 case AVS2_PB_PICTURE_START_CODE:
657 ret = avs2d_parse_picture_header(p_dec, startcode);
658 break;
659 case AVS2_EXTENSION_START_CODE:
660 ret = parse_extension_header(p_dec, &p_dec->bitctx);
661 break;
662 case AVS2_USER_DATA_START_CODE:
663 case AVS2_VIDEO_SEQUENCE_END_CODE:
664 case AVS2_VIDEO_EDIT_CODE:
665 break;
666 default:
667 if (AVS2_IS_SLICE_START_CODE(startcode)) {
668 task->valid = 1;
669 }
670
671 break;
672 }
673
674 p_nalu++;
675 }
676
677 reset_nalu_buf(p_dec);
678
679 AVS2D_PARSE_TRACE("Out. task->valid = %d", task->valid);
680 return ret;
681 }
682