1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define MODULE_TAG "vp9d_api"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "mpp_mem.h"
25 #include "mpp_packet_impl.h"
26
27 #include "vp9d_codec.h"
28 #include "vp9d_parser.h"
29 #include "vp9d_api.h"
30
31 /*!
32 ***********************************************************************
33 * \brief
34 * alloc all buffer
35 ***********************************************************************
36 */
37
vp9d_init(void * ctx,ParserCfg * init)38 MPP_RET vp9d_init(void *ctx, ParserCfg *init)
39 {
40 MPP_RET ret = MPP_OK;
41 RK_U8 *buf = NULL;
42 RK_S32 size = SZ_512K;
43 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx;
44
45 if (!vp9_ctx || !init) {
46 mpp_err("vp9d init fail");
47 return MPP_ERR_NULL_PTR;
48 }
49
50 if ((ret = vp9d_parser_init(vp9_ctx, init)) != MPP_OK)
51 goto _err_exit;
52
53 if ((ret = vp9d_split_init(vp9_ctx)) != MPP_OK)
54 goto _err_exit;
55
56 buf = mpp_malloc(RK_U8, size);
57 if (!buf) {
58 mpp_err("vp9 init malloc stream buffer fail");
59 ret = MPP_ERR_NOMEM;
60 goto _err_exit;
61 }
62
63 if ((ret = mpp_packet_init(&vp9_ctx->pkt, (void *)buf, size)) != MPP_OK)
64 goto _err_exit;
65
66 return ret;
67
68 _err_exit:
69 vp9d_deinit(vp9_ctx);
70 return ret;
71 }
72
73 /*!
74 ***********************************************************************
75 * \brief
76 * free all buffer
77 ***********************************************************************
78 */
vp9d_deinit(void * ctx)79 MPP_RET vp9d_deinit(void *ctx)
80 {
81 RK_U8 *buf = NULL;
82 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx;
83
84 if (vp9_ctx) {
85 vp9d_parser_deinit(vp9_ctx);
86 vp9d_split_deinit(vp9_ctx);
87 if (vp9_ctx->pkt) {
88 buf = mpp_packet_get_data(vp9_ctx->pkt);
89 MPP_FREE(buf);
90 mpp_packet_deinit(&vp9_ctx->pkt);
91 }
92 }
93
94 return MPP_OK;
95 }
96
97 /*!
98 ***********************************************************************
99 * \brief
100 * reset
101 ***********************************************************************
102 */
vp9d_reset(void * ctx)103 MPP_RET vp9d_reset(void *ctx)
104 {
105 MPP_RET ret = MPP_ERR_UNKNOW;
106
107 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx;
108 vp9d_paser_reset(vp9_ctx);
109 return ret = MPP_OK;
110 }
111
112 /*!
113 ***********************************************************************
114 * \brief
115 * flush
116 ***********************************************************************
117 */
vp9d_flush(void * ctx)118 MPP_RET vp9d_flush(void *ctx)
119 {
120 MPP_RET ret = MPP_ERR_UNKNOW;
121
122 (void)ctx;
123 return ret = MPP_OK;
124 }
125
126 /*!
127 ***********************************************************************
128 * \brief
129 * prepare
130 ***********************************************************************
131 */
vp9d_prepare(void * ctx,MppPacket pkt,HalDecTask * task)132 MPP_RET vp9d_prepare(void *ctx, MppPacket pkt, HalDecTask *task)
133 {
134 MPP_RET ret = MPP_OK;
135 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx;
136 SplitContext_t *ps = (SplitContext_t *)vp9_ctx->priv_data2;
137 RK_S64 pts = -1;
138 RK_S64 dts = -1;
139 RK_U8 *buf = NULL;
140 RK_S32 length = 0;
141 RK_U8 *out_data = NULL;
142 RK_S32 out_size = -1;
143 RK_S32 consumed = 0;
144 RK_U8 *pos = NULL;
145 task->valid = -1;
146
147 pts = mpp_packet_get_pts(pkt);
148 dts = mpp_packet_get_dts(pkt);
149 vp9_ctx->eos = mpp_packet_get_eos(pkt);
150 buf = pos = mpp_packet_get_pos(pkt);
151 length = (RK_S32)mpp_packet_get_length(pkt);
152
153 consumed = vp9d_split_frame(ps, &out_data, &out_size, buf, length);
154 pos += (consumed >= 0) ? consumed : length;
155
156 mpp_packet_set_pos(pkt, pos);
157 vp9d_dbg(VP9D_DBG_STRMIN, "pkt_len=%d, pts=%lld\n", length, pts);
158 if (out_size > 0) {
159 vp9d_get_frame_stream(vp9_ctx, out_data, out_size);
160 task->input_packet = vp9_ctx->pkt;
161 task->valid = 1;
162 mpp_packet_set_pts(vp9_ctx->pkt, pts);
163 mpp_packet_set_dts(vp9_ctx->pkt, dts);
164 task->flags.eos = vp9_ctx->eos;
165 } else {
166 task->valid = 0;
167 task->flags.eos = vp9_ctx->eos;
168 }
169
170 (void)pts;
171 (void)dts;
172 (void)task;
173 return ret = MPP_OK;
174 }
175
176
177 /*!
178 ***********************************************************************
179 * \brief
180 * parser
181 ***********************************************************************
182 */
vp9d_parse(void * ctx,HalDecTask * in_task)183 MPP_RET vp9d_parse(void *ctx, HalDecTask *in_task)
184 {
185 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx;
186 MPP_RET ret = MPP_OK;
187 vp9_parser_frame(vp9_ctx, in_task);
188
189 return ret;
190 }
191 /*!
192 ***********************************************************************
193 * \brief
194 * callback
195 ***********************************************************************
196 */
vp9d_callback(void * decoder,void * info)197 MPP_RET vp9d_callback(void *decoder, void *info)
198 {
199 MPP_RET ret = MPP_ERR_UNKNOW;
200 Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)decoder;
201 vp9_parser_update(vp9_ctx, info);
202
203 return ret = MPP_OK;
204 }
205
206 /*!
207 ***********************************************************************
208 * \brief
209 * api struct interface
210 ***********************************************************************
211 */
212
213 const ParserApi api_vp9d_parser = {
214 .name = "vp9d_parse",
215 .coding = MPP_VIDEO_CodingVP9,
216 .ctx_size = sizeof(Vp9CodecContext),
217 .flag = 0,
218 .init = vp9d_init,
219 .deinit = vp9d_deinit,
220 .prepare = vp9d_prepare,
221 .parse = vp9d_parse,
222 .reset = vp9d_reset,
223 .flush = vp9d_flush,
224 .control = NULL,
225 .callback = vp9d_callback,
226 };
227
228