xref: /rockchip-linux_mpp/mpp/codec/dec/avs2/avs2d_parse.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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