xref: /rockchip-linux_mpp/mpp/codec/dec/av1/av1d_api.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "av1d_api"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <stdlib.h>
21*437bfbebSnyanmisaka #include <string.h>
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_debug.h"
25*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #include "av1d_codec.h"
28*437bfbebSnyanmisaka #include "av1d_parser.h"
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #include "av1d_api.h"
31*437bfbebSnyanmisaka 
32*437bfbebSnyanmisaka /*!
33*437bfbebSnyanmisaka  ***********************************************************************
34*437bfbebSnyanmisaka  * \brief
35*437bfbebSnyanmisaka  *   alloc all buffer
36*437bfbebSnyanmisaka  ***********************************************************************
37*437bfbebSnyanmisaka  */
38*437bfbebSnyanmisaka 
av1d_init(void * ctx,ParserCfg * init)39*437bfbebSnyanmisaka MPP_RET av1d_init(void *ctx, ParserCfg *init)
40*437bfbebSnyanmisaka {
41*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
42*437bfbebSnyanmisaka     RK_U8 *buf = NULL;
43*437bfbebSnyanmisaka     RK_S32 size = SZ_512K;
44*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     if (!av1_ctx || !init) {
47*437bfbebSnyanmisaka         mpp_err("av1d init fail");
48*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
49*437bfbebSnyanmisaka     }
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka     av1_ctx->pix_fmt = MPP_FMT_BUTT;
52*437bfbebSnyanmisaka     av1_ctx->usr_set_fmt = MPP_FMT_BUTT;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     if ((ret = av1d_parser_init(av1_ctx, init)) != MPP_OK)
55*437bfbebSnyanmisaka         goto _err_exit;
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka     if ((ret = av1d_split_init(av1_ctx)) != MPP_OK)
58*437bfbebSnyanmisaka         goto _err_exit;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     buf = mpp_malloc(RK_U8, size);
61*437bfbebSnyanmisaka     if (!buf) {
62*437bfbebSnyanmisaka         mpp_err("av1d init malloc stream buffer fail");
63*437bfbebSnyanmisaka         ret = MPP_ERR_NOMEM;
64*437bfbebSnyanmisaka         goto _err_exit;
65*437bfbebSnyanmisaka     }
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka     if ((ret = mpp_packet_init(&av1_ctx->pkt, (void *)buf, size)) != MPP_OK)
68*437bfbebSnyanmisaka         goto _err_exit;
69*437bfbebSnyanmisaka 
70*437bfbebSnyanmisaka     av1_ctx->stream = buf;
71*437bfbebSnyanmisaka     av1_ctx->stream_size = size;
72*437bfbebSnyanmisaka     mpp_packet_set_size(av1_ctx->pkt, size);
73*437bfbebSnyanmisaka     mpp_packet_set_length(av1_ctx->pkt, 0);
74*437bfbebSnyanmisaka 
75*437bfbebSnyanmisaka     return ret;
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka _err_exit:
78*437bfbebSnyanmisaka     av1d_deinit(av1_ctx);
79*437bfbebSnyanmisaka     return ret;
80*437bfbebSnyanmisaka }
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka /*!
83*437bfbebSnyanmisaka  ***********************************************************************
84*437bfbebSnyanmisaka  * \brief
85*437bfbebSnyanmisaka  *   free all buffer
86*437bfbebSnyanmisaka  ***********************************************************************
87*437bfbebSnyanmisaka  */
av1d_deinit(void * ctx)88*437bfbebSnyanmisaka MPP_RET av1d_deinit(void *ctx)
89*437bfbebSnyanmisaka {
90*437bfbebSnyanmisaka     RK_U8 *buf = NULL;
91*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
92*437bfbebSnyanmisaka 
93*437bfbebSnyanmisaka     if (av1_ctx) {
94*437bfbebSnyanmisaka         av1d_parser_deinit(av1_ctx);
95*437bfbebSnyanmisaka         if (av1_ctx->pkt) {
96*437bfbebSnyanmisaka             buf = mpp_packet_get_data(av1_ctx->pkt);
97*437bfbebSnyanmisaka             MPP_FREE(buf);
98*437bfbebSnyanmisaka             mpp_packet_deinit(&av1_ctx->pkt);
99*437bfbebSnyanmisaka         }
100*437bfbebSnyanmisaka     }
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka     return MPP_OK;
103*437bfbebSnyanmisaka }
104*437bfbebSnyanmisaka 
105*437bfbebSnyanmisaka /*!
106*437bfbebSnyanmisaka  ***********************************************************************
107*437bfbebSnyanmisaka  * \brief
108*437bfbebSnyanmisaka  *   reset
109*437bfbebSnyanmisaka  ***********************************************************************
110*437bfbebSnyanmisaka  */
av1d_reset(void * ctx)111*437bfbebSnyanmisaka MPP_RET  av1d_reset(void *ctx)
112*437bfbebSnyanmisaka {
113*437bfbebSnyanmisaka     MPP_RET ret = MPP_ERR_UNKNOW;
114*437bfbebSnyanmisaka 
115*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
116*437bfbebSnyanmisaka     av1d_paser_reset(av1_ctx);
117*437bfbebSnyanmisaka     return ret = MPP_OK;
118*437bfbebSnyanmisaka }
119*437bfbebSnyanmisaka 
120*437bfbebSnyanmisaka /*!
121*437bfbebSnyanmisaka  ***********************************************************************
122*437bfbebSnyanmisaka  * \brief
123*437bfbebSnyanmisaka  *   flush
124*437bfbebSnyanmisaka  ***********************************************************************
125*437bfbebSnyanmisaka  */
av1d_flush(void * ctx)126*437bfbebSnyanmisaka MPP_RET  av1d_flush(void *ctx)
127*437bfbebSnyanmisaka {
128*437bfbebSnyanmisaka     MPP_RET ret = MPP_ERR_UNKNOW;
129*437bfbebSnyanmisaka 
130*437bfbebSnyanmisaka     (void)ctx;
131*437bfbebSnyanmisaka     return ret = MPP_OK;
132*437bfbebSnyanmisaka }
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka /*!
135*437bfbebSnyanmisaka  ***********************************************************************
136*437bfbebSnyanmisaka  * \brief
137*437bfbebSnyanmisaka  *   prepare
138*437bfbebSnyanmisaka  ***********************************************************************
139*437bfbebSnyanmisaka  */
av1d_prepare(void * ctx,MppPacket pkt,HalDecTask * task)140*437bfbebSnyanmisaka MPP_RET av1d_prepare(void *ctx, MppPacket pkt, HalDecTask *task)
141*437bfbebSnyanmisaka {
142*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
143*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
144*437bfbebSnyanmisaka     AV1Context *s = (AV1Context *)av1_ctx->priv_data;
145*437bfbebSnyanmisaka     RK_S64 pts = -1;
146*437bfbebSnyanmisaka     RK_S64 dts = -1;
147*437bfbebSnyanmisaka     RK_U8 *buf = NULL;
148*437bfbebSnyanmisaka     RK_S32 length = 0;
149*437bfbebSnyanmisaka     RK_U8 *out_data = NULL;
150*437bfbebSnyanmisaka     RK_S32 out_size = -1;
151*437bfbebSnyanmisaka     RK_S32 consumed = 0;
152*437bfbebSnyanmisaka     RK_U8 *pos = NULL;
153*437bfbebSnyanmisaka     RK_U32 need_split = s->cfg->base.split_parse;
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka     need_split = 1;
156*437bfbebSnyanmisaka     task->valid = 0;
157*437bfbebSnyanmisaka     av1_ctx->new_frame = 0;
158*437bfbebSnyanmisaka 
159*437bfbebSnyanmisaka     pts = mpp_packet_get_pts(pkt);
160*437bfbebSnyanmisaka     dts = mpp_packet_get_dts(pkt);
161*437bfbebSnyanmisaka     buf = pos = mpp_packet_get_pos(pkt);
162*437bfbebSnyanmisaka     length = (RK_S32)mpp_packet_get_length(pkt);
163*437bfbebSnyanmisaka     if (mpp_packet_get_flag(pkt)& MPP_PACKET_FLAG_EXTRA_DATA) {
164*437bfbebSnyanmisaka         s->extra_has_frame = 0;
165*437bfbebSnyanmisaka         task = NULL;
166*437bfbebSnyanmisaka         s->current_obu.data = buf;
167*437bfbebSnyanmisaka         s->current_obu.data_size = length;
168*437bfbebSnyanmisaka         ret = mpp_av1_split_fragment(s, &s->current_obu, 1);
169*437bfbebSnyanmisaka         if (ret < 0) {
170*437bfbebSnyanmisaka             return ret;
171*437bfbebSnyanmisaka         }
172*437bfbebSnyanmisaka         ret = mpp_av1_read_fragment_content(s, &s->current_obu);
173*437bfbebSnyanmisaka         if (ret < 0) {
174*437bfbebSnyanmisaka             return ret;
175*437bfbebSnyanmisaka         }
176*437bfbebSnyanmisaka         if (!s->sequence_header) {
177*437bfbebSnyanmisaka             goto end;
178*437bfbebSnyanmisaka         }
179*437bfbebSnyanmisaka         ret = mpp_av1_set_context_with_sequence(av1_ctx, s->sequence_header);
180*437bfbebSnyanmisaka     end:
181*437bfbebSnyanmisaka         pos = buf + length;
182*437bfbebSnyanmisaka         mpp_packet_set_pos(pkt, pos);
183*437bfbebSnyanmisaka         mpp_av1_fragment_reset(&s->current_obu);
184*437bfbebSnyanmisaka         return ret;
185*437bfbebSnyanmisaka     }
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka     if (need_split) {
188*437bfbebSnyanmisaka         consumed = av1d_split_frame(av1_ctx, &out_data, &out_size, buf, length);
189*437bfbebSnyanmisaka     } else {
190*437bfbebSnyanmisaka         out_size = consumed = length;
191*437bfbebSnyanmisaka         av1_ctx->new_frame = 1;
192*437bfbebSnyanmisaka     }
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka     pos += (consumed >= 0) ? consumed : length;
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka     mpp_packet_set_pos(pkt, pos);
197*437bfbebSnyanmisaka     mpp_packet_set_length(pkt, length - consumed);
198*437bfbebSnyanmisaka     if (!mpp_packet_get_length(pkt))
199*437bfbebSnyanmisaka         av1_ctx->eos = mpp_packet_get_eos(pkt);
200*437bfbebSnyanmisaka     av1d_dbg(AV1D_DBG_STRMIN, "pkt_len=%d, pts=%lld , out_size %d consumed %d new frame %d eos %d\n",
201*437bfbebSnyanmisaka              length, pts, out_size, consumed, av1_ctx->new_frame, av1_ctx->eos);
202*437bfbebSnyanmisaka     if (out_size > 0) {
203*437bfbebSnyanmisaka         av1d_get_frame_stream(av1_ctx, buf, consumed);
204*437bfbebSnyanmisaka         task->input_packet = av1_ctx->pkt;
205*437bfbebSnyanmisaka         mpp_packet_set_pts(av1_ctx->pkt, pts);
206*437bfbebSnyanmisaka         mpp_packet_set_dts(av1_ctx->pkt, dts);
207*437bfbebSnyanmisaka     } else {
208*437bfbebSnyanmisaka         task->valid = 0;
209*437bfbebSnyanmisaka         if (av1_ctx->eos)
210*437bfbebSnyanmisaka             task->input_packet = av1_ctx->pkt;
211*437bfbebSnyanmisaka     }
212*437bfbebSnyanmisaka     if (av1_ctx->eos && !mpp_packet_get_length(pkt))
213*437bfbebSnyanmisaka         task->flags.eos = av1_ctx->eos;
214*437bfbebSnyanmisaka 
215*437bfbebSnyanmisaka     if (av1_ctx->new_frame || (task->flags.eos)) {
216*437bfbebSnyanmisaka         if (av1_ctx->stream_offset > 0)
217*437bfbebSnyanmisaka             task->valid = 1;
218*437bfbebSnyanmisaka         av1_ctx->stream_offset = 0;
219*437bfbebSnyanmisaka     }
220*437bfbebSnyanmisaka 
221*437bfbebSnyanmisaka     (void)pts;
222*437bfbebSnyanmisaka     (void)dts;
223*437bfbebSnyanmisaka     (void)task;
224*437bfbebSnyanmisaka     return ret = MPP_OK;
225*437bfbebSnyanmisaka }
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka /*!
228*437bfbebSnyanmisaka  ***********************************************************************
229*437bfbebSnyanmisaka  * \brief
230*437bfbebSnyanmisaka  *   parser
231*437bfbebSnyanmisaka  ***********************************************************************
232*437bfbebSnyanmisaka  */
av1d_parser(void * ctx,HalDecTask * in_task)233*437bfbebSnyanmisaka MPP_RET av1d_parser(void *ctx, HalDecTask *in_task)
234*437bfbebSnyanmisaka {
235*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
236*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
237*437bfbebSnyanmisaka     av1d_parser_frame(av1_ctx, in_task);
238*437bfbebSnyanmisaka     return ret;
239*437bfbebSnyanmisaka }
240*437bfbebSnyanmisaka 
241*437bfbebSnyanmisaka /*!
242*437bfbebSnyanmisaka  ***********************************************************************
243*437bfbebSnyanmisaka  * \brief
244*437bfbebSnyanmisaka  *   control
245*437bfbebSnyanmisaka  ***********************************************************************
246*437bfbebSnyanmisaka  */
av1d_control(void * ctx,MpiCmd cmd,void * param)247*437bfbebSnyanmisaka MPP_RET av1d_control(void *ctx, MpiCmd cmd, void *param)
248*437bfbebSnyanmisaka {
249*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)ctx;
250*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
251*437bfbebSnyanmisaka 
252*437bfbebSnyanmisaka     if (!ctx)
253*437bfbebSnyanmisaka         return MPP_ERR_VALUE;
254*437bfbebSnyanmisaka 
255*437bfbebSnyanmisaka     switch (cmd) {
256*437bfbebSnyanmisaka     case MPP_DEC_SET_OUTPUT_FORMAT : {
257*437bfbebSnyanmisaka         av1_ctx->usr_set_fmt = param ? *((MppFrameFormat *)param) : MPP_FMT_YUV420SP;
258*437bfbebSnyanmisaka     } break;
259*437bfbebSnyanmisaka     default:
260*437bfbebSnyanmisaka         break;
261*437bfbebSnyanmisaka     }
262*437bfbebSnyanmisaka 
263*437bfbebSnyanmisaka     return ret;
264*437bfbebSnyanmisaka }
265*437bfbebSnyanmisaka 
266*437bfbebSnyanmisaka /*!
267*437bfbebSnyanmisaka  ***********************************************************************
268*437bfbebSnyanmisaka  * \brief
269*437bfbebSnyanmisaka  *   callback
270*437bfbebSnyanmisaka  ***********************************************************************
271*437bfbebSnyanmisaka  */
av1d_callback(void * decoder,void * info)272*437bfbebSnyanmisaka MPP_RET av1d_callback(void *decoder, void *info)
273*437bfbebSnyanmisaka {
274*437bfbebSnyanmisaka     MPP_RET ret = MPP_ERR_UNKNOW;
275*437bfbebSnyanmisaka     Av1CodecContext *av1_ctx = (Av1CodecContext *)decoder;
276*437bfbebSnyanmisaka     av1d_parser_update(av1_ctx, info);
277*437bfbebSnyanmisaka 
278*437bfbebSnyanmisaka     return ret = MPP_OK;
279*437bfbebSnyanmisaka }
280*437bfbebSnyanmisaka 
281*437bfbebSnyanmisaka /*!
282*437bfbebSnyanmisaka  ***********************************************************************
283*437bfbebSnyanmisaka  * \brief
284*437bfbebSnyanmisaka  *   api struct interface
285*437bfbebSnyanmisaka  ***********************************************************************
286*437bfbebSnyanmisaka  */
287*437bfbebSnyanmisaka 
288*437bfbebSnyanmisaka const ParserApi api_av1d_parser = {
289*437bfbebSnyanmisaka     .name = "av1d_parse",
290*437bfbebSnyanmisaka     .coding = MPP_VIDEO_CodingAV1,
291*437bfbebSnyanmisaka     .ctx_size = sizeof(Av1CodecContext),
292*437bfbebSnyanmisaka     .flag = 0,
293*437bfbebSnyanmisaka     .init = av1d_init,
294*437bfbebSnyanmisaka     .deinit = av1d_deinit,
295*437bfbebSnyanmisaka     .prepare = av1d_prepare,
296*437bfbebSnyanmisaka     .parse = av1d_parser,
297*437bfbebSnyanmisaka     .reset = av1d_reset,
298*437bfbebSnyanmisaka     .flush = av1d_flush,
299*437bfbebSnyanmisaka     .control = av1d_control,
300*437bfbebSnyanmisaka     .callback = av1d_callback,
301*437bfbebSnyanmisaka };
302