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