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
19 #define MODULE_TAG "hal_h264d_api"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <dlfcn.h>
25 #include <unistd.h>
26
27 #include "mpp_mem.h"
28 #include "mpp_env.h"
29 #include "mpp_platform.h"
30 #include "mpp_common.h"
31 #include "osal_2str.h"
32
33 #include "dxva_syntax.h"
34 #include "h264d_syntax.h"
35
36 #include "hal_h264d_global.h"
37 #include "hal_h264d_api.h"
38
39 #include "hal_h264d_rkv_reg.h"
40 #include "hal_h264d_vdpu34x.h"
41 #include "hal_h264d_vdpu382.h"
42 #include "hal_h264d_vdpu2.h"
43 #include "hal_h264d_vdpu1.h"
44
45 RK_U32 hal_h264d_debug = 0;
46
explain_input_buffer(void * hal,HalDecTask * task)47 static void explain_input_buffer(void *hal, HalDecTask *task)
48 {
49 RK_U32 i = 0;
50 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
51 DXVA2_DecodeBufferDesc *pdes = (DXVA2_DecodeBufferDesc *)task->syntax.data;
52 for (i = 0; i < task->syntax.number; i++) {
53 switch (pdes[i].CompressedBufferType) {
54 case DXVA2_PictureParametersBufferType:
55 p_hal->pp = (DXVA_PicParams_H264_MVC *)pdes[i].pvPVPState;
56 break;
57 case DXVA2_InverseQuantizationMatrixBufferType:
58 p_hal->qm = (DXVA_Qmatrix_H264 *)pdes[i].pvPVPState;
59 break;
60 case DXVA2_SliceControlBufferType:
61 p_hal->slice_num = pdes[i].DataSize / sizeof(DXVA_Slice_H264_Long);
62 p_hal->slice_long = (DXVA_Slice_H264_Long *)pdes[i].pvPVPState;
63 break;
64 case DXVA2_BitStreamDateBufferType:
65 p_hal->bitstream = (RK_U8 *)pdes[i].pvPVPState;
66 p_hal->strm_len = pdes[i].DataSize;
67 break;
68 default:
69 break;
70 }
71 }
72 }
73
74 /*!
75 ***********************************************************************
76 * \brief
77 * init
78 ***********************************************************************
79 */
80 //extern "C"
hal_h264d_init(void * hal,MppHalCfg * cfg)81 MPP_RET hal_h264d_init(void *hal, MppHalCfg *cfg)
82 {
83 MppHalApi *p_api = NULL;
84 MPP_RET ret = MPP_ERR_UNKNOW;
85 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
86 MppClientType client_type = VPU_CLIENT_BUTT;
87
88 INP_CHECK(ret, NULL == p_hal);
89 memset(p_hal, 0, sizeof(H264dHalCtx_t));
90
91
92 //!< choose hard mode
93 {
94 RK_S32 hw_type = -1;
95 RK_U32 mode = MODE_NULL;
96 RK_U32 vcodec_type = mpp_get_vcodec_type();
97
98 // check codec_type
99 if (!(vcodec_type & (HAVE_RKVDEC | HAVE_VDPU1 | HAVE_VDPU2))) {
100 mpp_err_f("can not found H.264 decoder hardware on platform %x\n", vcodec_type);
101 return ret;
102 }
103 mpp_env_get_u32("use_mpp_mode", &mode, MODE_NULL);
104 if (MODE_NULL == mode) {
105 MppDecBaseCfg *base = &cfg->cfg->base;
106
107 if (mpp_check_soc_cap(base->type, base->coding))
108 hw_type = base->hw_type;
109
110 if (hw_type > 0) {
111 if (vcodec_type & (1 << hw_type)) {
112 mpp_log("init with %s hw\n", strof_client_type(hw_type));
113 client_type = hw_type;
114 } else
115 mpp_err_f("invalid hw_type %d with vcodec_type %08x\n",
116 hw_type, vcodec_type);
117 }
118 }
119
120 if (client_type == VPU_CLIENT_BUTT) {
121 if ((mode <= RKVDEC_MODE) && (vcodec_type & HAVE_RKVDEC)) {
122 client_type = VPU_CLIENT_RKVDEC;
123 } else if (vcodec_type & HAVE_VDPU1) {
124 client_type = VPU_CLIENT_VDPU1;
125 } else if (vcodec_type & HAVE_VDPU2) {
126 client_type = VPU_CLIENT_VDPU2;
127 }
128 }
129 H264D_DBG(H264D_DBG_HARD_MODE, "client_type %d\n", client_type);
130 }
131
132 p_api = &p_hal->hal_api;
133 switch (client_type) {
134 case VPU_CLIENT_RKVDEC : {
135 RK_U32 hw_id = mpp_get_client_hw_id(client_type);
136
137 if (hw_id == HWID_VDPU382_RK3528 || hw_id == HWID_VDPU382_RK3562) {
138 p_api->init = vdpu382_h264d_init;
139 p_api->deinit = vdpu382_h264d_deinit;
140 p_api->reg_gen = vdpu382_h264d_gen_regs;
141 p_api->start = vdpu382_h264d_start;
142 p_api->wait = vdpu382_h264d_wait;
143 p_api->reset = vdpu382_h264d_reset;
144 p_api->flush = vdpu382_h264d_flush;
145 p_api->control = vdpu382_h264d_control;
146 } else if (hw_id == HWID_VDPU34X || hw_id == HWID_VDPU38X) {
147 p_api->init = vdpu34x_h264d_init;
148 p_api->deinit = vdpu34x_h264d_deinit;
149 p_api->reg_gen = vdpu34x_h264d_gen_regs;
150 p_api->start = vdpu34x_h264d_start;
151 p_api->wait = vdpu34x_h264d_wait;
152 p_api->reset = vdpu34x_h264d_reset;
153 p_api->flush = vdpu34x_h264d_flush;
154 p_api->control = vdpu34x_h264d_control;
155 } else {
156 p_api->init = rkv_h264d_init;
157 p_api->deinit = rkv_h264d_deinit;
158 p_api->reg_gen = rkv_h264d_gen_regs;
159 p_api->start = rkv_h264d_start;
160 p_api->wait = rkv_h264d_wait;
161 p_api->reset = rkv_h264d_reset;
162 p_api->flush = rkv_h264d_flush;
163 p_api->control = rkv_h264d_control;
164 }
165
166 cfg->support_fast_mode = 1;
167 } break;
168 case VPU_CLIENT_VDPU1 : {
169 p_api->init = vdpu1_h264d_init;
170 p_api->deinit = vdpu1_h264d_deinit;
171 p_api->reg_gen = vdpu1_h264d_gen_regs;
172 p_api->start = vdpu1_h264d_start;
173 p_api->wait = vdpu1_h264d_wait;
174 p_api->reset = vdpu1_h264d_reset;
175 p_api->flush = vdpu1_h264d_flush;
176 p_api->control = vdpu1_h264d_control;
177 } break;
178 case VPU_CLIENT_VDPU2 : {
179 p_api->init = vdpu2_h264d_init;
180 p_api->deinit = vdpu2_h264d_deinit;
181 p_api->reg_gen = vdpu2_h264d_gen_regs;
182 p_api->start = vdpu2_h264d_start;
183 p_api->wait = vdpu2_h264d_wait;
184 p_api->reset = vdpu2_h264d_reset;
185 p_api->flush = vdpu2_h264d_flush;
186 p_api->control = vdpu2_h264d_control;
187 } break;
188 default : {
189 mpp_err_f("client_type error, value=%d\n", client_type);
190 mpp_assert(0);
191 } break;
192 }
193
194 mpp_env_get_u32("hal_h264d_debug", &hal_h264d_debug, 0);
195
196 ret = mpp_dev_init(&cfg->dev, client_type);
197 if (ret) {
198 mpp_err("mpp_dev_init failed ret: %d\n", ret);
199 goto __FAILED;
200 }
201
202 //!< callback function to parser module
203 p_hal->dec_cb = cfg->dec_cb;
204 p_hal->cfg = cfg->cfg;
205 p_hal->dev = cfg->dev;
206 p_hal->frame_slots = cfg->frame_slots;
207 p_hal->packet_slots = cfg->packet_slots;
208 p_hal->fast_mode = cfg->cfg->base.fast_parse;
209
210 //< get buffer group
211 if (p_hal->buf_group == NULL) {
212 FUN_CHECK(ret = mpp_buffer_group_get_internal
213 (&p_hal->buf_group, MPP_BUFFER_TYPE_ION));
214 }
215
216 //!< run init funtion
217 FUN_CHECK(ret = p_api->init(hal, cfg));
218 __RETURN:
219 return MPP_OK;
220 __FAILED:
221 return ret;
222 }
223
224 /*!
225 ***********************************************************************
226 * \brief
227 * deinit
228 ***********************************************************************
229 */
230 //extern "C"
hal_h264d_deinit(void * hal)231 MPP_RET hal_h264d_deinit(void *hal)
232 {
233 MPP_RET ret = MPP_ERR_UNKNOW;
234 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
235
236 FUN_CHECK(ret = p_hal->hal_api.deinit(hal));
237
238 if (p_hal->dev) {
239 mpp_dev_deinit(p_hal->dev);
240 p_hal->dev = NULL;
241 }
242
243 if (p_hal->buf_group) {
244 FUN_CHECK(ret = mpp_buffer_group_put(p_hal->buf_group));
245 }
246
247 return MPP_OK;
248 __FAILED:
249 return ret;
250 }
251
252 /*!
253 ***********************************************************************
254 * \brief
255 * generate register
256 ***********************************************************************
257 */
258 //extern "C"
hal_h264d_gen_regs(void * hal,HalTaskInfo * task)259 MPP_RET hal_h264d_gen_regs(void *hal, HalTaskInfo *task)
260 {
261 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
262
263 explain_input_buffer(hal, &task->dec);
264 return p_hal->hal_api.reg_gen(hal, task);
265 }
266
267 /*!
268 ***********************************************************************
269 * \brief h
270 * start hard
271 ***********************************************************************
272 */
273 //extern "C"
hal_h264d_start(void * hal,HalTaskInfo * task)274 MPP_RET hal_h264d_start(void *hal, HalTaskInfo *task)
275 {
276 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
277
278 return p_hal->hal_api.start(hal, task);
279 }
280
281 /*!
282 ***********************************************************************
283 * \brief
284 * wait hard
285 ***********************************************************************
286 */
287 //extern "C"
hal_h264d_wait(void * hal,HalTaskInfo * task)288 MPP_RET hal_h264d_wait(void *hal, HalTaskInfo *task)
289 {
290 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
291
292 return p_hal->hal_api.wait(hal, task);
293 }
294
295 /*!
296 ***********************************************************************
297 * \brief
298 * reset
299 ***********************************************************************
300 */
301 //extern "C"
hal_h264d_reset(void * hal)302 MPP_RET hal_h264d_reset(void *hal)
303 {
304 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
305
306 return p_hal->hal_api.reset(hal);
307 }
308
309 /*!
310 ***********************************************************************
311 * \brief
312 * flush
313 ***********************************************************************
314 */
315 //extern "C"
hal_h264d_flush(void * hal)316 MPP_RET hal_h264d_flush(void *hal)
317 {
318 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
319
320 return p_hal->hal_api.flush(hal);
321 }
322
323 /*!
324 ***********************************************************************
325 * \brief
326 * control
327 ***********************************************************************
328 */
329 //extern "C"
hal_h264d_control(void * hal,MpiCmd cmd_type,void * param)330 MPP_RET hal_h264d_control(void *hal, MpiCmd cmd_type, void *param)
331 {
332 H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
333
334 return p_hal->hal_api.control(hal, cmd_type, param);
335 }
336
337
338 const MppHalApi hal_api_h264d = {
339 .name = "h264d_rkdec",
340 .type = MPP_CTX_DEC,
341 .coding = MPP_VIDEO_CodingAVC,
342 .ctx_size = sizeof(H264dHalCtx_t),
343 .flag = 0,
344 .init = hal_h264d_init,
345 .deinit = hal_h264d_deinit,
346 .reg_gen = hal_h264d_gen_regs,
347 .start = hal_h264d_start,
348 .wait = hal_h264d_wait,
349 .reset = hal_h264d_reset,
350 .flush = hal_h264d_flush,
351 .control = hal_h264d_control,
352 };
353
354