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