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