xref: /OK3568_Linux_fs/external/mpp/mpp/codec/dec/avs2/avs2d_parse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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         break;
308     case AVS2_MASTERING_DISPLAY_AND_CONTENT_METADATA_EXT_ID:
309         FUN_CHECK(ret = parse_mastering_display_and_content_meta(bitctx,
310                                                                  &p_dec->display_meta,
311                                                                  &p_dec->content_light));
312         p_dec->is_hdr = 1;
313         break;
314     case AVS2_HDR_DYNAMIC_METADATA_EXT_ID:
315         FUN_CHECK(ret = parse_hdr_dynamic_meta_extension(bitctx, p_dec->hdr_dynamic_meta));
316         break;
317     default:
318         break;
319     }
320 
321     return ret;
322 __BITREAD_ERR:
323     return ret = bitctx->ret;
324 __FAILED:
325     return ret;
326 }
327 
avs2d_reset_parser(Avs2dCtx_t * p_dec)328 MPP_RET avs2d_reset_parser(Avs2dCtx_t *p_dec)
329 {
330     AVS2D_PARSE_TRACE("In.");
331     p_dec->got_vsh      = 0;
332     p_dec->got_exh      = 0;
333     p_dec->got_keyframe = 0;
334     p_dec->vec_flag     = 0;
335     p_dec->enable_wq    = 0;
336     p_dec->new_frame_flag = 0;
337     p_dec->new_seq_flag = 0;
338     reset_nalu_buf(p_dec);
339     AVS2D_PARSE_TRACE("Out.");
340 
341     return MPP_OK;
342 }
343 
344 /*!
345 ***********************************************************************
346 * \brief
347 *    commit buffer to hal
348 ***********************************************************************
349 */
avs2d_commit_syntaxs(Avs2dSyntax_t * syntax,HalDecTask * task)350 MPP_RET avs2d_commit_syntaxs(Avs2dSyntax_t *syntax, HalDecTask *task)
351 {
352     task->syntax.number = 1;
353     task->syntax.data = syntax;
354 
355     return MPP_OK;
356 }
357 
avs2d_fill_parameters(Avs2dCtx_t * p_dec,Avs2dSyntax_t * syntax)358 MPP_RET avs2d_fill_parameters(Avs2dCtx_t *p_dec, Avs2dSyntax_t *syntax)
359 {
360     RK_S32 i = 0;
361     Avs2dSeqHeader_t *vsh = &p_dec->vsh;
362     Avs2dPicHeader_t *ph  = &p_dec->ph;
363     Avs2dFrameMgr_t *mgr  = &p_dec->frm_mgr;
364     PicParams_Avs2d *pp   = &syntax->pp;
365     RefParams_Avs2d *refp = &syntax->refp;
366     AlfParams_Avs2d *alfp = &syntax->alfp;
367     WqmParams_Avs2d *wqmp = &syntax->wqmp;
368 
369     //!< sequence header
370     pp->chroma_format_idc          = vsh->chroma_format;
371     pp->pic_width_in_luma_samples  = MPP_ALIGN(vsh->horizontal_size, 8);
372     pp->pic_height_in_luma_samples = MPP_ALIGN(vsh->vertical_size, 8);
373     pp->bit_depth_luma_minus8      = vsh->bit_depth - 8;
374     pp->bit_depth_chroma_minus8    = vsh->bit_depth - 8;
375     pp->lcu_size                   = vsh->lcu_size;
376     pp->progressive_sequence       = vsh->progressive_sequence;
377     pp->field_coded_sequence       = vsh->field_coded_sequence;
378     pp->multi_hypothesis_skip_enable_flag        = vsh->enable_mhp_skip;
379     pp->dual_hypothesis_prediction_enable_flag   = vsh->enable_dhp;
380     pp->weighted_skip_enable_flag                = vsh->enable_wsm;
381     pp->asymmetrc_motion_partitions_enable_flag  = vsh->enable_amp;
382     pp->nonsquare_quadtree_transform_enable_flag = vsh->enable_nsqt;
383     pp->nonsquare_intra_prediction_enable_flag   = vsh->enable_nsip;
384     pp->secondary_transform_enable_flag          = vsh->enable_2nd_transform;
385     pp->sample_adaptive_offset_enable_flag       = vsh->enable_sao;
386     pp->adaptive_loop_filter_enable_flag         = vsh->enable_alf;
387     pp->pmvr_enable_flag                         = vsh->enable_pmvr;
388     pp->cross_slice_loopfilter_enable_flag       = vsh->enable_clf;
389 
390     //!< picture header
391     pp->picture_type                = ph->picture_type;
392     pp->scene_reference_enable_flag = ph->background_reference_flag;
393     pp->bottom_field_picture_flag   = (vsh->field_coded_sequence) && (!ph->is_top_field);
394     // pp->bottom_field_picture_flag   = !ph->is_top_field;
395     pp->fixed_picture_qp            = ph->fixed_picture_qp;
396     pp->picture_qp                  = ph->picture_qp;
397     pp->loop_filter_disable_flag    = !ph->enable_loop_filter;
398     pp->alpha_c_offset              = ph->alpha_c_offset;
399     pp->beta_offset                 = ph->beta_offset;
400 
401     //!< picture reference params
402     refp->ref_pic_num = mgr->num_of_ref;
403     memset(refp->ref_poc_list, -1, sizeof(refp->ref_poc_list));
404     for (i = 0; i < mgr->num_of_ref; i++) {
405         refp->ref_poc_list[i] = mgr->refs[i] ? mgr->refs[i]->poi : -1;
406     }
407 
408     //!< picture alf params
409     alfp->enable_pic_alf_y  = ph->enable_pic_alf_y;
410     alfp->enable_pic_alf_cb = ph->enable_pic_alf_cb;
411     alfp->enable_pic_alf_cr = ph->enable_pic_alf_cr;
412     alfp->alf_filter_num_minus1 = ph->alf_filter_num - 1;
413     memcpy(alfp->alf_coeff_idx_tab, ph->alf_coeff_idx_tab, sizeof(ph->alf_coeff_idx_tab));
414     memcpy(alfp->alf_coeff_y, ph->alf_coeff_y, sizeof(ph->alf_coeff_y));
415     memcpy(alfp->alf_coeff_cb, ph->alf_coeff_cb, sizeof(ph->alf_coeff_cb));
416     memcpy(alfp->alf_coeff_cr, ph->alf_coeff_cr, sizeof(ph->alf_coeff_cr));
417 
418     //!< picture wqm params
419     wqmp->pic_weight_quant_enable_flag = p_dec->enable_wq;
420     wqmp->chroma_quant_param_delta_cb = ph->chroma_quant_param_delta_cb;
421     wqmp->chroma_quant_param_delta_cr = ph->chroma_quant_param_delta_cr;
422     memcpy(wqmp->wq_matrix, p_dec->cur_wq_matrix, sizeof(p_dec->cur_wq_matrix));
423 
424     return MPP_OK;
425 }
426 
avs2_split_nalu(Avs2dCtx_t * p_dec,RK_U8 * buf_start,RK_U32 buf_length,RK_U32 over_read,RK_U32 * remain)427 MPP_RET avs2_split_nalu(Avs2dCtx_t *p_dec, RK_U8 *buf_start, RK_U32 buf_length, RK_U32 over_read, RK_U32 *remain)
428 {
429     MPP_RET ret = MPP_OK;
430 
431     RK_U8 *start_code_ptr = NULL;
432     RK_U32 start_code = 0;
433     RK_U32 nalu_len = 0;
434 
435     RK_U8 *buf_end;
436 
437     buf_end = buf_start + buf_length - 1;
438 
439     start_code = avs2_find_start_code(buf_start, buf_end, &start_code_ptr);
440 
441     if (start_code_ptr) {
442         AVS2D_PARSE_TRACE("Found start_code 0x%08x at offset 0x%08x, prev_starcode 0x%08x\n",
443                           start_code, start_code_ptr - buf_start, p_dec->prev_start_code);
444         if (!p_dec->new_seq_flag) {
445             if (start_code == AVS2_VIDEO_SEQUENCE_START_CODE) {
446                 AVS2D_PARSE_TRACE("Found the first video_sequence_start_code");
447                 p_dec->nal_cnt = 0;
448                 avs2_add_nalu_header(p_dec, AVS2_VIDEO_SEQUENCE_START_CODE);
449                 p_dec->new_seq_flag = 1;
450                 p_dec->prev_start_code = AVS2_VIDEO_SEQUENCE_START_CODE;
451             } else {
452                 AVS2D_PARSE_TRACE("Skip start code before first video_sequence_start_code");
453             }
454 
455             *remain = buf_end - start_code_ptr;
456         } else {
457             if (start_code == AVS2_VIDEO_SEQUENCE_START_CODE) {
458                 AVS2D_PARSE_TRACE("Found repeated video_sequence_start_code");
459             }
460 
461             if (AVS2_IS_START_CODE(p_dec->prev_start_code) && p_dec->prev_start_code != AVS2_USER_DATA_START_CODE) {
462                 nalu_len = start_code_ptr - buf_start - 3;
463                 if (nalu_len > over_read) {
464                     store_nalu(p_dec, buf_start + over_read, nalu_len - over_read, p_dec->prev_start_code);
465                 }
466             }
467 
468             if (AVS2_IS_SLICE_START_CODE(p_dec->prev_start_code) && !AVS2_IS_SLICE_START_CODE(start_code)) {
469                 p_dec->new_frame_flag = 1;
470                 p_dec->p_nals[p_dec->nal_cnt - 1].eof = 1;
471                 *remain = buf_end - start_code_ptr + 4;
472             } else {
473                 if (start_code != AVS2_USER_DATA_START_CODE)
474                     avs2_add_nalu_header(p_dec, start_code);
475 
476                 // need to put slice start code to stream buffer
477                 if (AVS2_IS_SLICE_START_CODE(start_code)) {
478                     store_nalu(p_dec, start_code_ptr - 3, 4, start_code);
479                 } else if (start_code == AVS2_VIDEO_SEQUENCE_END_CODE) {
480                     p_dec->p_nals[p_dec->nal_cnt - 1].eof = 1;
481                 }
482 
483                 *remain = buf_end - start_code_ptr;
484             }
485 
486             p_dec->prev_start_code = start_code;
487         }
488     } else {
489         if (!p_dec->new_seq_flag) {
490             AVS2D_PARSE_TRACE("Skip data code before first video_sequence_start_code");
491         } else {
492             if (AVS2_IS_START_CODE(p_dec->prev_start_code)) {
493                 nalu_len = buf_length;
494                 if (nalu_len > over_read) {
495                     store_nalu(p_dec, buf_start + over_read, nalu_len - over_read, p_dec->prev_start_code);
496                 }
497             }
498         }
499 
500         *remain = 0;
501     }
502 
503     return ret;
504 }
505 
avs2d_parse_prepare_split(Avs2dCtx_t * p_dec,MppPacket * pkt,HalDecTask * task)506 MPP_RET avs2d_parse_prepare_split(Avs2dCtx_t *p_dec, MppPacket *pkt, HalDecTask *task)
507 {
508     MPP_RET ret = MPP_OK;
509     RK_U8 *p_curdata = NULL;
510     RK_U8 *p_start = NULL;
511     RK_U8 *p_end = NULL;
512     RK_U32 pkt_length = 0;
513     RK_U32 first_read_length = 0;
514 
515     AVS2D_PARSE_TRACE("In.");
516 
517     pkt_length = (RK_U32) mpp_packet_get_length(pkt);
518 
519     p_curdata = p_start = (RK_U8 *) mpp_packet_get_pos(pkt);
520     p_end = p_start + pkt_length - 1;
521 
522     // Combine last packet data
523     first_read_length = (pkt_length >= 4) ? 4 : pkt_length;
524     memcpy(p_dec->prev_tail_data + 3, p_curdata, first_read_length);
525 
526     RK_U32 remain = 0;
527 
528     AVS2D_PARSE_TRACE("previous data[0~3]=%02x %02x %02x, first_read_length %d\n",
529                       p_dec->prev_tail_data[0], p_dec->prev_tail_data[1],
530                       p_dec->prev_tail_data[2], first_read_length);
531     ret = avs2_split_nalu(p_dec, p_dec->prev_tail_data,
532                           AVS2D_PACKET_SPLIT_CHECKER_BUFFER_SIZE,
533                           AVS2D_PACKET_SPLIT_LAST_KEPT_LENGTH,
534                           &remain);
535     p_curdata = p_start + first_read_length - remain;
536     AVS2D_PARSE_TRACE("remian length %d\n", remain);
537 
538     remain = 0;
539 
540     while (p_curdata < p_end) {
541         ret = avs2_split_nalu(p_dec, p_curdata, p_end - p_curdata + 1, 0, &remain);
542 
543         if (ret) {
544             break;
545         } else {
546             p_curdata = p_end - remain + 1;
547         }
548 
549         if (p_dec->new_frame_flag || (p_dec->p_nals[p_dec->nal_cnt - 1].eof == 1)) {
550             task->valid = 1;
551             break;
552         }
553     }
554 
555     mpp_packet_set_pos(pkt, p_curdata);
556 
557     if (remain == 0) {
558         memset(p_dec->prev_tail_data, 0xff, 3);
559 
560         if (pkt_length >= 3) {
561             p_dec->prev_tail_data[0] = p_end[0];
562             p_dec->prev_tail_data[1] = p_end[-1];
563             p_dec->prev_tail_data[2] = p_end[-2];
564         }
565     }
566 
567     AVS2D_PARSE_TRACE("Out.");
568     return ret;
569 }
570 
571 /**
572  * @brief Every packet is a complete frame.
573  * So we don't have to do combine data from different packet.
574  *
575  * @param p_dec
576  * @param pkt
577  * @param task
578  * @return MPP_RET
579  */
avs2d_parse_prepare_fast(Avs2dCtx_t * p_dec,MppPacket * pkt,HalDecTask * task)580 MPP_RET avs2d_parse_prepare_fast(Avs2dCtx_t *p_dec, MppPacket *pkt, HalDecTask *task)
581 {
582     MPP_RET ret = MPP_OK;
583     RK_U8 *p_curdata = NULL;
584     RK_U8 *p_start = NULL;
585     RK_U8 *p_end = NULL;
586     RK_U32 pkt_length = 0;
587     RK_U32 remain = 0;
588 
589     AVS2D_PARSE_TRACE("In.");
590 
591     pkt_length = (RK_U32) mpp_packet_get_length(pkt);
592 
593     p_curdata = p_start = (RK_U8 *) mpp_packet_get_pos(pkt);
594     p_end = p_start + pkt_length - 1;
595 
596     while (p_curdata < p_end) {
597         ret = avs2_split_nalu(p_dec, p_curdata, p_end - p_curdata + 1, 0, &remain);
598 
599         if (ret) {
600             break;
601         } else {
602             p_curdata = p_end - remain + 1;
603         }
604 
605         if (p_dec->new_frame_flag || (p_dec->p_nals[p_dec->nal_cnt - 1].eof == 1)
606             || p_curdata >= p_end) {
607             task->valid = 1;
608             break;
609         }
610     }
611 
612     mpp_packet_set_pos(pkt, p_curdata);
613 
614     AVS2D_PARSE_TRACE("Out.");
615     return ret;
616 }
617 
avs2d_parse_stream(Avs2dCtx_t * p_dec,HalDecTask * task)618 MPP_RET avs2d_parse_stream(Avs2dCtx_t *p_dec, HalDecTask *task)
619 {
620     MPP_RET ret = MPP_OK;
621     Avs2dNalu_t *p_nalu = p_dec->p_nals;
622     AVS2D_PARSE_TRACE("In.");
623     RK_U32 i = 0;
624     for (i = 0 ; i < p_dec->nal_cnt; i++) {
625         RK_U32 startcode = p_nalu->header;
626 
627         AVS2D_PARSE_TRACE("start code 0x%08x\n", startcode);
628         if (!AVS2_IS_SLICE_START_CODE(startcode)) {
629             RK_U8 *data_ptr = p_dec->p_header->pbuf + p_nalu->data_pos;
630             memset(&p_dec->bitctx, 0, sizeof(BitReadCtx_t));
631             AVS2D_PARSE_TRACE("bitread ctx, pos %d, length %d\n", p_nalu->data_pos, p_nalu->length);
632             mpp_set_bitread_ctx(&p_dec->bitctx, data_ptr, p_nalu->length);
633             mpp_set_bitread_pseudo_code_type(&p_dec->bitctx, PSEUDO_CODE_AVS2);
634         }
635 
636         switch (startcode) {
637         case AVS2_VIDEO_SEQUENCE_START_CODE:
638             ret = avs2d_parse_sequence_header(p_dec);
639             if (ret == MPP_OK) {
640                 p_dec->got_vsh = 1;
641 
642                 if (p_dec->new_seq_flag && !p_dec->frm_mgr.initial_flag) {
643                     avs2d_dpb_create(p_dec);
644                 }
645             }
646             p_dec->got_exh = 0;
647             break;
648         case AVS2_I_PICTURE_START_CODE:
649         case AVS2_PB_PICTURE_START_CODE:
650             ret = avs2d_parse_picture_header(p_dec, startcode);
651             break;
652         case AVS2_EXTENSION_START_CODE:
653             ret = parse_extension_header(p_dec, &p_dec->bitctx);
654             break;
655         case AVS2_USER_DATA_START_CODE:
656             break;
657         case AVS2_VIDEO_SEQUENCE_END_CODE:
658             p_dec->new_seq_flag = 0;
659             avs2d_dpb_flush(p_dec);
660             break;
661         case AVS2_VIDEO_EDIT_CODE:
662             p_dec->vec_flag = 0;
663             avs2d_dpb_flush(p_dec);
664             break;
665         default:
666             if (AVS2_IS_SLICE_START_CODE(startcode)) {
667                 task->valid = 1;
668             }
669 
670             break;
671         }
672 
673         p_nalu++;
674     }
675 
676     reset_nalu_buf(p_dec);
677 
678     AVS2D_PARSE_TRACE("Out. task->valid = %d", task->valid);
679     return ret;
680 }
681