xref: /rockchip-linux_mpp/mpp/codec/dec/avs2/avs2d_api.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_api"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "mpp_mem.h"
24 #include "mpp_log.h"
25 #include "mpp_debug.h"
26 #include "mpp_env.h"
27 #include "mpp_packet_impl.h"
28 #include "mpp_buffer_impl.h"
29 
30 #include "avs2d_syntax.h"
31 #include "avs2d_api.h"
32 #include "avs2d_parse.h"
33 #include "avs2d_dpb.h"
34 #include "mpp_dec_cb_param.h"
35 
36 // for avs2d max ctu size 64
rkv_ctu_64_align(RK_U32 val)37 static RK_U32 rkv_ctu_64_align(RK_U32 val)
38 {
39     return MPP_ALIGN(val, 64);
40 }
41 
42 RK_U32 avs2d_parse_debug = 0;
43 
avs2d_deinit(void * decoder)44 MPP_RET avs2d_deinit(void *decoder)
45 {
46     MPP_RET ret = MPP_OK;
47     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
48 
49     INP_CHECK(ret, !decoder);
50     AVS2D_PARSE_TRACE("In.");
51 
52     MPP_FREE(p_dec->p_stream->pbuf);
53     MPP_FREE(p_dec->p_header->pbuf);
54     MPP_FREE(p_dec->mem);
55     MPP_FREE(p_dec->p_nals);
56     mpp_packet_deinit(&p_dec->task_pkt);
57     avs2d_dpb_destroy(p_dec);
58 
59 __RETURN:
60     AVS2D_PARSE_TRACE("Out.");
61     return ret;
62 }
63 
avs2d_init(void * decoder,ParserCfg * init)64 MPP_RET avs2d_init(void *decoder, ParserCfg *init)
65 {
66     MPP_RET ret = MPP_OK;
67     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
68 
69     AVS2D_PARSE_TRACE("In.");
70     INP_CHECK(ret, !p_dec);
71 
72     memset(p_dec, 0, sizeof(Avs2dCtx_t));
73     mpp_env_get_u32("avs2d_debug", &avs2d_parse_debug, 0);
74     //!< restore init parameters
75     p_dec->init = *init;
76     // p_dec->init.cfg->base.split_parse = 1;
77     p_dec->frame_slots = init->frame_slots;
78     p_dec->packet_slots = init->packet_slots;
79     //!< decoder parameters
80     mpp_buf_slot_setup(p_dec->frame_slots, AVS2_MAX_BUF_NUM);
81 
82     p_dec->mem = mpp_calloc(Avs2dMemory_t, 1);
83     MEM_CHECK(ret, p_dec->mem);
84     p_dec->p_header = &p_dec->mem->headerbuf;
85     p_dec->p_header->size = MAX_HEADER_SIZE;
86     p_dec->p_header->pbuf = mpp_calloc(RK_U8, p_dec->p_header->size);
87     MEM_CHECK(ret, p_dec->p_header->pbuf);
88 
89     p_dec->p_stream = &p_dec->mem->streambuf;
90     p_dec->p_stream->size = MAX_STREAM_SIZE;
91     p_dec->p_stream->pbuf = mpp_calloc(RK_U8, p_dec->p_stream->size);
92     MEM_CHECK(ret, p_dec->p_stream->pbuf);
93 
94     p_dec->p_nals = mpp_calloc(Avs2dNalu_t, MAX_NALU_NUM);
95     MEM_CHECK(ret, p_dec->p_nals);
96     p_dec->nal_allocated = MAX_NALU_NUM;
97     p_dec->nal_cnt = 0;
98 
99     mpp_packet_init(&p_dec->task_pkt, p_dec->p_stream->pbuf, p_dec->p_stream->size);
100     mpp_packet_set_length(p_dec->task_pkt, 0);
101     MEM_CHECK(ret, p_dec->task_pkt);
102 
103     mpp_slots_set_prop(p_dec->frame_slots, SLOTS_WIDTH_ALIGN, rkv_ctu_64_align);
104 
105 __RETURN:
106     AVS2D_PARSE_TRACE("Out.");
107     return ret;
108 __FAILED:
109     avs2d_deinit(decoder);
110 
111     return ret;
112 }
113 
avs2d_reset(void * decoder)114 MPP_RET avs2d_reset(void *decoder)
115 {
116     MPP_RET ret = MPP_OK;
117     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
118 
119     AVS2D_PARSE_TRACE("In.");
120 
121     //!< flush dpb
122     avs2d_dpb_flush(p_dec);
123 
124     //!< reset parser parameters
125     avs2d_reset_parser(p_dec);
126 
127     //!< reset decoder parameters
128     p_dec->pkt_no      = 0;
129     p_dec->frame_no    = 0;
130     p_dec->has_get_eos = 0;
131 
132     AVS2D_PARSE_TRACE("Out.");
133     return ret;
134 }
135 
avs2d_flush(void * decoder)136 MPP_RET avs2d_flush(void *decoder)
137 {
138     MPP_RET ret = MPP_OK;
139     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
140     AVS2D_PARSE_TRACE("In.");
141 
142     dpb_remove_unused_frame(p_dec);
143 
144     AVS2D_PARSE_TRACE("Out.");
145     return ret;
146 }
147 
avs2d_control(void * decoder,MpiCmd cmd_type,void * param)148 MPP_RET avs2d_control(void *decoder, MpiCmd cmd_type, void *param)
149 {
150     MPP_RET ret = MPP_OK;
151 
152     AVS2D_PARSE_TRACE("In.");
153     (void)decoder;
154     (void)cmd_type;
155     (void)param;
156     AVS2D_PARSE_TRACE("Out.");
157     return ret;
158 }
159 
160 
avs2d_prepare(void * decoder,MppPacket pkt,HalDecTask * task)161 MPP_RET avs2d_prepare(void *decoder, MppPacket pkt, HalDecTask *task)
162 {
163     MPP_RET ret = MPP_OK;
164     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
165     RK_S64 pts = -1;
166     RK_S64 dts = -1;
167     RK_U32 length = 0;
168     RK_U32 pkt_eos = 0;
169 
170     AVS2D_PARSE_TRACE("In.");
171     INP_CHECK(ret, !decoder && !pkt && !task);
172 
173     task->valid = 0;
174 
175     pkt_eos = mpp_packet_get_eos(pkt);
176 
177     pts = mpp_packet_get_pts(pkt);
178     dts = mpp_packet_get_dts(pkt);
179     length = (RK_U32)mpp_packet_get_length(pkt);
180 
181     AVS2D_DBG(AVS2D_DBG_INPUT, "[pkt_in_timeUs] in_pts=%lld, dts=%lld, len=%d, eos=%d, pkt_no=%lld\n",
182               pts, dts, length, pkt_eos, p_dec->pkt_no);
183     p_dec->pkt_no++;
184 
185     AVS2D_DBG(AVS2D_DBG_INPUT, "packet length %d, eos %d\n", length, pkt_eos);
186 
187     if (pkt_eos) {
188         p_dec->has_get_eos = 1;
189         task->flags.eos = 1;
190     }
191 
192     if (!length) {
193         AVS2D_PARSE_TRACE("Input have no stream.");
194         task->valid = 0;
195 
196         if (pkt_eos)
197             avs2d_dpb_flush(p_dec);
198 
199         goto __RETURN;
200     }
201 
202     if (!p_dec->init.cfg->base.split_parse) {
203         ret = avs2d_parse_prepare_fast(p_dec, pkt, task);
204     } else {
205         ret = avs2d_parse_prepare_split(p_dec, pkt, task);
206     }
207 
208     if (task->valid) {
209         //!< bit stream
210         RK_U32 align_len = MPP_ALIGN(p_dec->p_stream->len + 32, 16);
211 
212         mpp_assert(p_dec->p_stream->size > align_len);
213         memset(p_dec->p_stream->pbuf + p_dec->p_stream->len,
214                0, align_len - p_dec->p_stream->len);
215 
216         p_dec->syntax.bitstream_size = align_len;
217         p_dec->syntax.bitstream = p_dec->p_stream->pbuf;
218 
219         mpp_packet_set_data(p_dec->task_pkt, p_dec->syntax.bitstream);
220         mpp_packet_set_length(p_dec->task_pkt, p_dec->syntax.bitstream_size);
221         mpp_packet_set_size(p_dec->task_pkt, p_dec->p_stream->size);
222 
223         mpp_packet_set_pts(p_dec->task_pkt, mpp_packet_get_pts(pkt));
224         mpp_packet_set_dts(p_dec->task_pkt, mpp_packet_get_dts(pkt));
225         task->input_packet = p_dec->task_pkt;
226 
227         p_dec->p_stream->len = 0;
228         p_dec->p_header->len = 0;
229     } else {
230         task->input_packet = NULL;
231     }
232 
233 __RETURN:
234     AVS2D_PARSE_TRACE("Out.");
235     return ret;
236 }
237 
avs2d_parse(void * decoder,HalDecTask * task)238 MPP_RET avs2d_parse(void *decoder, HalDecTask *task)
239 {
240     MPP_RET ret = MPP_OK;
241     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
242     AVS2D_PARSE_TRACE("In.");
243 
244     task->valid = 0;
245 
246     ret = avs2d_parse_stream(p_dec, task);
247     if (ret) {
248         mpp_err_f("Parse stream failed!");
249     }
250     if (task->valid) {
251         AVS2D_PARSE_TRACE("-------- Frame %lld--------", p_dec->frame_no);
252         avs2d_dpb_insert(p_dec, task);
253         avs2d_fill_parameters(p_dec, &p_dec->syntax);
254         avs2d_commit_syntaxs(&p_dec->syntax, task);
255         AVS2D_PARSE_TRACE("--------------------------");
256     } else {
257         task->flags.parse_err = 1;
258     }
259 
260     if (p_dec->has_get_eos)
261         avs2d_dpb_flush(p_dec);
262 
263     AVS2D_PARSE_TRACE("Out.");
264 
265     return ret;
266 }
267 
avs2d_callback(void * decoder,void * info)268 MPP_RET avs2d_callback(void *decoder, void *info)
269 {
270     MPP_RET ret = MPP_ERR_UNKNOW;
271     Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
272     DecCbHalDone *ctx = (DecCbHalDone *)info;
273     HalDecTask *task_dec = (HalDecTask *)ctx->task;
274     MppFrame mframe = NULL;
275     MppFrame ref_frm = NULL;
276     RK_U32 i = 0;
277     RK_U32 error = 0;
278     RK_U32 discard = 0;
279     RK_U32 ref_used = task_dec->flags.ref_info_valid ? task_dec->flags.ref_used : 0xff;
280     RK_U32 ref_used_flag = 0;
281 
282     AVS2D_PARSE_TRACE("In.");
283     mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe);
284 
285     if (!mframe) {
286         ret = MPP_ERR_UNKNOW;
287         AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: failed to get frame\n");
288         goto __FAILED;
289     }
290 
291     if (ctx->hard_err || task_dec->flags.ref_err) {
292         if (task_dec->flags.used_for_ref) {
293             error = 1;
294         } else {
295             discard = 1;
296         }
297     } else {
298         if (task_dec->flags.ref_miss & ref_used) {
299             discard = 1;
300             AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: fake ref used, miss 0x%x used 0x%x\n",
301                       task_dec->flags.ref_miss, ref_used);
302         }
303     }
304 
305     for (i = 0; i < AVS2_MAX_REFS; i++) {
306         if (task_dec->refer[i] < 0)
307             continue;
308 
309         mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->refer[i], SLOT_FRAME_PTR, &ref_frm);
310         if (!ref_frm)
311             continue;
312 
313         ref_used_flag = (ref_used >> i) & 1;
314         //TODO: In fast mode, ref list isn't kept sync with task flag.ref_used
315         AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: ref_frm poc %d, err %d, dis %d, ref_used %d\n",
316                   mpp_frame_get_poc(ref_frm), mpp_frame_get_errinfo(ref_frm),
317                   mpp_frame_get_discard(ref_frm), ref_used_flag);
318 
319         if (ref_used_flag) {
320             discard |= mpp_frame_get_discard(ref_frm);
321             error |= mpp_frame_get_errinfo(ref_frm);
322         }
323     }
324 
325     mpp_frame_set_errinfo(mframe, error);
326     mpp_frame_set_discard(mframe, discard);
327 
328     AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: frame poc %d, ref=%d, dpberr=%d, harderr=%d, err:dis=%d:%d\n",
329               mpp_frame_get_poc(mframe), task_dec->flags.used_for_ref, task_dec->flags.ref_err,
330               ctx->hard_err, error, discard);
331 
332 __FAILED:
333     AVS2D_PARSE_TRACE("Out.");
334     return ret;
335 }
336 
337 const ParserApi api_avs2d_parser = {
338     .name = "avs2d_parse",
339     .coding = MPP_VIDEO_CodingAVS2,
340     .ctx_size = sizeof(Avs2dCtx_t),
341     .flag = 0,
342     .init = avs2d_init,
343     .deinit = avs2d_deinit,
344     .prepare = avs2d_prepare,
345     .parse = avs2d_parse,
346     .reset = avs2d_reset,
347     .flush = avs2d_flush,
348     .control = avs2d_control,
349     .callback = avs2d_callback,
350 };
351