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 "hal_avsd_api"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "rk_mpi_cmd.h"
24 #include "mpp_debug.h"
25 #include "mpp_mem.h"
26 #include "mpp_env.h"
27 #include "mpp_common.h"
28 #include "mpp_platform.h"
29 #include "mpp_device.h"
30
31 #include "mpp_dec_cb_param.h"
32 #include "hal_avsd_api.h"
33 #include "hal_avsd_base.h"
34 #include "hal_avsd_vdpu1.h"
35 #include "hal_avsd_vdpu2.h"
36 #include "hal_avsd_plus.h"
37
init_hard_platform(AvsdHalCtx_t * p_hal,MppCodingType coding)38 static MPP_RET init_hard_platform(AvsdHalCtx_t *p_hal, MppCodingType coding)
39 {
40 MppHalApi *p_api = &p_hal->hal_api;
41 RK_U32 vcodec_type = mpp_get_vcodec_type();
42 MppClientType client_type = VPU_CLIENT_BUTT;
43 MPP_RET ret = MPP_ERR_UNKNOW;
44
45 if (coding == MPP_VIDEO_CodingAVSPLUS) {
46 if (!(vcodec_type & HAVE_AVSDEC))
47 mpp_err("coding %x vcodec_type %x do not found avs hw %x\n",
48 coding, vcodec_type, HAVE_AVSDEC);
49 } else {
50 RK_U32 hw_flag = HAVE_VDPU1 | HAVE_VDPU2 | HAVE_VDPU1_PP | HAVE_VDPU2_PP;
51
52 if (!(vcodec_type & hw_flag ))
53 mpp_err("coding %x vcodec_type %x do not found avs hw %x\n",
54 coding, vcodec_type, hw_flag);
55 }
56
57 if ((coding == MPP_VIDEO_CodingAVSPLUS) &&
58 (vcodec_type & HAVE_AVSDEC)) {
59 p_api->init = hal_avsd_plus_init;
60 p_api->deinit = hal_avsd_plus_deinit;
61 p_api->reg_gen = hal_avsd_plus_gen_regs;
62 p_api->start = hal_avsd_plus_start;
63 p_api->wait = hal_avsd_plus_wait;
64 p_api->reset = hal_avsd_plus_reset;
65 p_api->flush = hal_avsd_plus_flush;
66 p_api->control = hal_avsd_plus_control;
67 client_type = VPU_CLIENT_AVSPLUS_DEC;
68 } else if ((coding == MPP_VIDEO_CodingAVS) &&
69 (vcodec_type & (HAVE_VDPU1 | HAVE_VDPU1_PP))) {
70 p_api->init = hal_avsd_vdpu1_init;
71 p_api->deinit = hal_avsd_vdpu1_deinit;
72 p_api->reg_gen = hal_avsd_vdpu1_gen_regs;
73 p_api->start = hal_avsd_vdpu1_start;
74 p_api->wait = hal_avsd_vdpu1_wait;
75 p_api->reset = hal_avsd_vdpu1_reset;
76 p_api->flush = hal_avsd_vdpu1_flush;
77 p_api->control = hal_avsd_vdpu1_control;
78 client_type = VPU_CLIENT_VDPU1;
79 } else if ((coding == MPP_VIDEO_CodingAVS) &&
80 (vcodec_type & (HAVE_VDPU2 | HAVE_VDPU2_PP))) {
81 p_api->init = hal_avsd_vdpu2_init;
82 p_api->deinit = hal_avsd_vdpu2_deinit;
83 p_api->reg_gen = hal_avsd_vdpu2_gen_regs;
84 p_api->start = hal_avsd_vdpu2_start;
85 p_api->wait = hal_avsd_vdpu2_wait;
86 p_api->reset = hal_avsd_vdpu2_reset;
87 p_api->flush = hal_avsd_vdpu2_flush;
88 p_api->control = hal_avsd_vdpu2_control;
89 client_type = VPU_CLIENT_VDPU2;
90 } else {
91 ret = MPP_NOK;
92 goto __FAILED;
93 }
94 p_hal->coding = coding;
95 AVSD_HAL_DBG(AVSD_DBG_HARD_MODE, "hw_spt %08x, coding %d\n", vcodec_type, coding);
96
97 ret = mpp_dev_init(&p_hal->dev, client_type);
98 if (ret) {
99 mpp_err("mpp_device_init failed. ret: %d\n", ret);
100 return ret;
101
102 }
103 return ret = MPP_OK;
104 __FAILED:
105 return ret;
106 }
107
108 /*!
109 ***********************************************************************
110 * \brief
111 * deinit
112 ***********************************************************************
113 */
114 //extern "C"
hal_avsd_deinit(void * decoder)115 MPP_RET hal_avsd_deinit(void *decoder)
116 {
117 MPP_RET ret = MPP_ERR_UNKNOW;
118 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
119
120 AVSD_HAL_TRACE("In.");
121 INP_CHECK(ret, NULL == decoder);
122
123 FUN_CHECK(ret = p_hal->hal_api.deinit(decoder));
124 //!< mpp_dev_init
125 if (p_hal->dev) {
126 ret = mpp_dev_deinit(p_hal->dev);
127 if (ret)
128 mpp_err("mpp_dev_deinit failed. ret: %d\n", ret);
129 }
130
131 if (p_hal->buf_group) {
132 FUN_CHECK(ret = mpp_buffer_group_put(p_hal->buf_group));
133 }
134 __RETURN:
135 AVSD_HAL_TRACE("Out.");
136
137 return ret = MPP_OK;
138 __FAILED:
139 return ret;
140 }
141
142 /*!
143 ***********************************************************************
144 * \brief
145 * init
146 ***********************************************************************
147 */
148 //extern "C"
hal_avsd_init(void * decoder,MppHalCfg * cfg)149 MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg)
150 {
151 MPP_RET ret = MPP_ERR_UNKNOW;
152 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
153
154 AVSD_HAL_TRACE("In.");
155 INP_CHECK(ret, NULL == decoder);
156
157 memset(p_hal, 0, sizeof(AvsdHalCtx_t));
158 p_hal->frame_slots = cfg->frame_slots;
159 p_hal->packet_slots = cfg->packet_slots;
160
161 //!< callback function to parser module
162 p_hal->dec_cb = cfg->dec_cb;
163 mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0);
164 //< get buffer group
165 FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_ION));
166
167 FUN_CHECK(ret = init_hard_platform(p_hal, cfg->coding));
168
169 //!< run init funtion
170 FUN_CHECK(ret = p_hal->hal_api.init(decoder, cfg));
171
172 __RETURN:
173 AVSD_HAL_TRACE("Out.");
174
175 return ret = MPP_OK;
176 __FAILED:
177 hal_avsd_deinit(decoder);
178 return ret;
179 }
180
181 /*!
182 ***********************************************************************
183 * \brief
184 * generate register
185 ***********************************************************************
186 */
187 //extern "C"
hal_avsd_gen_regs(void * decoder,HalTaskInfo * task)188 MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task)
189 {
190 MPP_RET ret = MPP_ERR_UNKNOW;
191 MppCodingType coding = MPP_VIDEO_CodingUnused;
192 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
193
194 memcpy(&p_hal->syn, task->dec.syntax.data, sizeof(AvsdSyntax_t));
195 // check coding
196 coding = (p_hal->syn.pp.profileId == 0x48) ? MPP_VIDEO_CodingAVSPLUS : MPP_VIDEO_CodingAVS;
197 if (coding != p_hal->coding) {
198 if (p_hal->dev) {
199 ret = mpp_dev_deinit(p_hal->dev);
200 if (ret)
201 mpp_err("mpp_dev_deinit failed. ret: %d\n", ret);
202
203 p_hal->dev = NULL;
204 }
205
206 ret = p_hal->hal_api.deinit(decoder);
207 if (ret) {
208 mpp_err_f("deinit decoder failed, ret %d\n", ret);
209 return ret;
210 }
211
212 ret = init_hard_platform(p_hal, coding);
213 if (ret) {
214 mpp_err_f("change paltform %x -> %x error\n", p_hal->coding, coding);
215 return ret;
216 }
217
218 ret = p_hal->hal_api.init(decoder, p_hal->cfg);
219 if (ret) {
220 mpp_err_f("init decoder failed, ret %d\n", ret);
221 return ret;
222 }
223 }
224
225 p_hal->frame_no++;
226
227 return p_hal->hal_api.reg_gen(decoder, task);
228 }
229 /*!
230 ***********************************************************************
231 * \brief h
232 * start hard
233 ***********************************************************************
234 */
235 //extern "C"
hal_avsd_start(void * decoder,HalTaskInfo * task)236 MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task)
237 {
238 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
239
240 return p_hal->hal_api.start(decoder, task);
241 }
242 /*!
243 ***********************************************************************
244 * \brief
245 * wait hard
246 ***********************************************************************
247 */
248 //extern "C"
hal_avsd_wait(void * decoder,HalTaskInfo * task)249 MPP_RET hal_avsd_wait(void *decoder, HalTaskInfo *task)
250 {
251 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
252
253 return p_hal->hal_api.wait(decoder, task);
254 }
255 /*!
256 ***********************************************************************
257 * \brief
258 * reset
259 ***********************************************************************
260 */
261 //extern "C"
hal_avsd_reset(void * decoder)262 MPP_RET hal_avsd_reset(void *decoder)
263 {
264 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
265
266 return p_hal->hal_api.reset(p_hal);
267 }
268 /*!
269 ***********************************************************************
270 * \brief
271 * flush
272 ***********************************************************************
273 */
274 //extern "C"
hal_avsd_flush(void * decoder)275 MPP_RET hal_avsd_flush(void *decoder)
276 {
277 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
278
279 return p_hal->hal_api.flush(p_hal);
280 }
281 /*!
282 ***********************************************************************
283 * \brief
284 * control
285 ***********************************************************************
286 */
287 //extern "C"
hal_avsd_control(void * decoder,MpiCmd cmd_type,void * param)288 MPP_RET hal_avsd_control(void *decoder, MpiCmd cmd_type, void *param)
289 {
290 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
291
292 return p_hal->hal_api.control(decoder, cmd_type, param);
293 }
294
295 const MppHalApi hal_api_avsd = {
296 .name = "avsd_vdpu",
297 .type = MPP_CTX_DEC,
298 .coding = MPP_VIDEO_CodingAVS,
299 .ctx_size = sizeof(AvsdHalCtx_t),
300 .flag = 0,
301 .init = hal_avsd_init,
302 .deinit = hal_avsd_deinit,
303 .reg_gen = hal_avsd_gen_regs,
304 .start = hal_avsd_start,
305 .wait = hal_avsd_wait,
306 .reset = hal_avsd_reset,
307 .flush = hal_avsd_flush,
308 .control = hal_avsd_control,
309 };
310
311 const MppHalApi hal_api_avsd_plus = {
312 .name = "avsd_plus",
313 .type = MPP_CTX_DEC,
314 .coding = MPP_VIDEO_CodingAVSPLUS,
315 .ctx_size = sizeof(AvsdHalCtx_t),
316 .flag = 0,
317 .init = hal_avsd_init,
318 .deinit = hal_avsd_deinit,
319 .reg_gen = hal_avsd_gen_regs,
320 .start = hal_avsd_start,
321 .wait = hal_avsd_wait,
322 .reset = hal_avsd_reset,
323 .flush = hal_avsd_flush,
324 .control = hal_avsd_control,
325 };
326