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_vdpu1"
18
19 #include <string.h>
20
21 #include "mpp_debug.h"
22 #include "mpp_common.h"
23 #include "mpp_mem.h"
24 #include "mpp_device.h"
25 #include "mpp_dec_cb_param.h"
26
27 #include "hal_avsd_base.h"
28 #include "hal_avsd_vdpu1.h"
29 #include "hal_avsd_vdpu1_reg.h"
30
set_defalut_parameters(AvsdHalCtx_t * p_hal)31 static MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal)
32 {
33 AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
34
35 p_regs->sw02.dec_out_endian = 1;
36 p_regs->sw02.dec_in_endian = 0;
37 p_regs->sw02.dec_strendian_e = 1;
38 p_regs->sw02.dec_max_burst = 16;
39 p_regs->sw02.dec_scmd_dis = 0;
40
41 p_regs->sw02.dec_adv_pre_dis = 0;
42 p_regs->sw55.apf_threshold = 8;
43 p_regs->sw02.dec_latency = 0;
44
45 p_regs->sw02.dec_data_disc_e = 0;
46 p_regs->sw02.dec_outswap32_e = 1;
47 p_regs->sw02.dec_inswap32_e = 1;
48 p_regs->sw02.dec_strswap32_e = 1;
49
50 p_regs->sw02.dec_timeout_e = 0;
51 p_regs->sw02.dec_clk_gate_e = 1;
52 p_regs->sw01.dec_irq_dis = 0;
53
54 p_regs->sw02.dec_axi_rd_id = 0xFF;
55 p_regs->sw03.dec_axi_wr_id = 0;
56
57 p_regs->sw49.pred_bc_tap_0_0 = 0x3FF;
58 p_regs->sw49.pred_bc_tap_0_1 = 5;
59 p_regs->sw49.pred_bc_tap_0_2 = 5;
60 p_regs->sw34.pred_bc_tap_0_3 = 0x3FF;
61 p_regs->sw34.pred_bc_tap_1_0 = 1;
62 p_regs->sw34.pred_bc_tap_1_1 = 7;
63 p_regs->sw35.pred_bc_tap_1_2 = 7;
64 p_regs->sw35.pred_bc_tap_1_3 = 1;
65
66 p_regs->sw02.tiled_mode_lsb = 0;
67
68 return MPP_OK;
69 }
70
set_regs_parameters(AvsdHalCtx_t * p_hal,HalDecTask * task)71 static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task)
72 {
73 MPP_RET ret = MPP_ERR_UNKNOW;
74
75 AvsdSyntax_t *p_syn = &p_hal->syn;
76 AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
77
78 set_defalut_parameters(p_hal);
79
80 p_regs->sw02.dec_timeout_e = 1;
81 p_regs->sw02.dec_clk_gate_e = 1;
82 p_regs->sw01.dec_irq_dis = 0;
83 p_regs->sw03.rlc_mode_e = 0;
84
85 //!< set wrok_out pic info
86 if (p_hal->work_out < 0) {
87 p_hal->work_out = get_queue_pic(p_hal);
88 if (p_hal->work_out < 0) {
89 ret = MPP_NOK;
90 mpp_err_f("cannot get a pic_info buffer.\n");
91 goto __FAILED;
92 }
93 }
94 {
95 AvsdHalPic_t *p_work_out = &p_hal->pic[p_hal->work_out];
96
97 p_work_out->slot_idx = task->output;
98 p_work_out->pic_code_type = p_syn->pp.picCodingType;
99 p_work_out->picture_distance = p_syn->pp.pictureDistance;
100 }
101 //!< set register
102 p_regs->sw04.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4;
103 p_regs->sw03.dec_mode = 11; //!< DEC_MODE_AVS
104
105 if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
106 p_regs->sw03.pic_interlace_e = 0;
107 p_regs->sw03.pic_fieldmode_e = 0;
108 p_regs->sw03.pic_topfiled_e = 0;
109 } else {
110 p_regs->sw03.pic_interlace_e = 1;
111 p_regs->sw03.pic_fieldmode_e = 1;
112 p_regs->sw03.pic_topfiled_e = p_hal->first_field;
113 }
114
115 p_regs->sw04.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4;
116 //p_regs->sw07.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12;
117
118 if (p_syn->pp.picCodingType == BFRAME) {
119 p_regs->sw03.pic_b_e = 1;
120 } else {
121 p_regs->sw03.pic_b_e = 0;
122 }
123 p_regs->sw03.pic_inter_e = (p_syn->pp.picCodingType != IFRAME) ? 1 : 0;
124
125 mpp_log("data_offset %x\n", p_hal->data_offset);
126 p_regs->sw05.strm_start_bit = 8 * (p_hal->data_offset & 0x7);
127 p_hal->data_offset = (p_hal->data_offset & ~0x7);
128 p_regs->sw12.rlc_vlc_base = get_packet_fd(p_hal, task->input);
129 mpp_dev_set_reg_offset(p_hal->dev, 12, p_hal->data_offset);
130 p_regs->sw06.stream_len = p_syn->bitstream_size - p_hal->data_offset;
131 p_regs->sw03.pic_fixed_quant = p_syn->pp.fixedPictureQp;
132 p_regs->sw06.init_qp = p_syn->pp.pictureQp;
133
134 p_regs->sw13.dec_out_base = get_frame_fd(p_hal, task->output);
135 if (p_syn->pp.pictureStructure == FIELDPICTURE && !p_hal->first_field) {
136 //!< start of bottom field line
137 mpp_dev_set_reg_offset(p_hal->dev, 13, p_syn->pp.horizontalSize);
138 }
139 {
140 RK_S32 tmp_fwd = -1;
141 RK_S32 refer0 = -1;
142 RK_S32 refer1 = -1;
143
144 tmp_fwd = (p_hal->work1 < 0) ? p_hal->work0 : p_hal->work1;
145 tmp_fwd = (tmp_fwd < 0) ? p_hal->work_out : tmp_fwd;
146
147 refer0 = (task->refer[0] < 0) ? task->output : task->refer[0];
148 refer1 = (task->refer[1] < 0) ? refer0 : task->refer[1];
149 if (!p_hal->first_field
150 && p_syn->pp.pictureStructure == FIELDPICTURE
151 && p_syn->pp.picCodingType != BFRAME) {
152 p_regs->sw14.refer0_base = get_frame_fd(p_hal, task->output);
153 p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0);
154 p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer0);
155 p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1);
156 } else {
157 p_regs->sw14.refer0_base = get_frame_fd(p_hal, refer0);
158 p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0);
159 p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer1);
160 p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1);
161 }
162 }
163 //!< block distances
164 if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
165 if (p_syn->pp.picCodingType == BFRAME) {
166 RK_S32 tmp = 0;
167 //!< current to future anchor
168 if (p_hal->work0 >= 0) {
169 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
170 2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
171 }
172 //!< prevent division by zero
173 if (!tmp) tmp = 2;
174 p_regs->sw31.ref_dist_cur_2 = tmp;
175 p_regs->sw31.ref_dist_cur_3 = tmp;
176 p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
177 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
178
179 //!< current to past anchor
180 if (p_hal->work1 >= 0) {
181 tmp = (2 * p_syn->pp.pictureDistance -
182 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
183 if (!tmp) tmp = 2;
184 }
185 p_regs->sw30.ref_dist_cur_0 = tmp;
186 p_regs->sw30.ref_dist_cur_1 = tmp;
187 p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
188 p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
189 //!< future anchor to past anchor
190 if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
191 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
192 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
193 if (!tmp) tmp = 2;
194 }
195 tmp = 16384 / tmp;
196 p_regs->sw32.ref_invd_col_0 = tmp;
197 p_regs->sw32.ref_invd_col_1 = tmp;
198 //!< future anchor to previous past anchor
199 tmp = p_hal->future2prev_past_dist;
200 tmp = 16384 / tmp;
201 p_regs->sw33.ref_invd_col_2 = tmp;
202 p_regs->sw33.ref_invd_col_3 = tmp;
203 } else {
204 RK_S32 tmp = 0;
205 //!< current to past anchor
206 if (p_hal->work0 >= 0) {
207 tmp = (2 * p_syn->pp.pictureDistance -
208 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
209 }
210 if (!tmp) tmp = 2;
211 p_regs->sw30.ref_dist_cur_0 = tmp;
212 p_regs->sw30.ref_dist_cur_1 = tmp;
213 p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
214 p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
215 //!< current to previous past anchor
216 if (p_hal->work1 >= 0) {
217 tmp = (2 * p_syn->pp.pictureDistance -
218 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
219 if (!tmp) tmp = 2;
220 }
221 //!< this will become "future to previous past" for next B
222 p_hal->future2prev_past_dist = tmp;
223
224 p_regs->sw31.ref_dist_cur_2 = tmp;
225 p_regs->sw31.ref_dist_cur_3 = tmp;
226 p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
227 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
228
229 p_regs->sw32.ref_invd_col_0 = 0;
230 p_regs->sw32.ref_invd_col_1 = 0;
231 p_regs->sw33.ref_invd_col_2 = 0;
232 p_regs->sw33.ref_invd_col_3 = 0;
233 }
234 } else {
235 //!< field interlaced
236 if (p_syn->pp.picCodingType == BFRAME) {
237 RK_S32 tmp = 0;
238 //!< block distances
239 if (p_hal->work0 >= 0) {
240 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
241 2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
242 }
243 //!< prevent division by zero
244 if (!tmp) tmp = 2;
245
246 if (p_hal->first_field) {
247 p_regs->sw31.ref_dist_cur_2 = tmp;
248 p_regs->sw31.ref_dist_cur_3 = tmp + 1;
249 p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
250 p_regs->sw29.ref_invd_cur_3 = 512 / (tmp + 1);
251 } else {
252 p_regs->sw31.ref_dist_cur_2 = tmp - 1;
253 p_regs->sw31.ref_dist_cur_3 = tmp;
254 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1);
255 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
256 }
257
258 if (p_hal->work1 >= 0) {
259 tmp = (2 * p_syn->pp.pictureDistance -
260 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
261 if (!tmp) tmp = 2;
262 }
263 if (p_hal->first_field) {
264 p_regs->sw30.ref_dist_cur_0 = (tmp - 1);
265 p_regs->sw30.ref_dist_cur_1 = tmp;
266 p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1);
267 p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
268 } else {
269 p_regs->sw30.ref_dist_cur_0 = tmp;
270 p_regs->sw30.ref_dist_cur_1 = tmp + 1;
271 p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
272 p_regs->sw28.ref_invd_cur_1 = 512 / (tmp + 1);
273 }
274
275 if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
276 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
277 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
278 if (!tmp) tmp = 2;
279 }
280
281 if (p_syn->pp.pbFieldEnhancedFlag && !p_hal->first_field) {
282 //!< in this case, BlockDistanceRef is different with before, the mvRef points to top field
283 p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1);
284 p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
285
286 //!< future anchor to previous past anchor
287 tmp = p_hal->future2prev_past_dist;
288
289 p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1);
290 p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
291 } else {
292 if (p_hal->first_field) {
293 p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1);
294 p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
295 } else {
296 p_regs->sw32.ref_invd_col_0 = 16384;
297 p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
298 p_regs->sw33.ref_invd_col_2 = 16384 / (tmp + 1);
299 }
300
301 //!< future anchor to previous past anchor
302 tmp = p_hal->future2prev_past_dist;
303
304 if (p_hal->first_field) {
305 p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1);
306 p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
307 } else {
308 p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
309 }
310 }
311 } else {
312 RK_S32 tmp = 0;
313 if (p_hal->work0 >= 0) {
314 tmp = (2 * p_syn->pp.pictureDistance -
315 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
316 }
317 if (!tmp) tmp = 2;
318
319 if (!p_hal->first_field) {
320 p_regs->sw30.ref_dist_cur_0 = 1;
321 p_regs->sw31.ref_dist_cur_2 = tmp + 1;
322
323 p_regs->sw28.ref_invd_cur_0 = 512;
324 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp + 1);
325 } else {
326 p_regs->sw30.ref_dist_cur_0 = tmp - 1;
327 p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1);
328 }
329 p_regs->sw30.ref_dist_cur_1 = tmp;
330 p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
331
332 if (p_hal->work1 >= 0) {
333 tmp = (2 * p_syn->pp.pictureDistance -
334 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
335 if (!tmp) tmp = 2;
336 }
337 //!< this will become "future to previous past" for next B
338 p_hal->future2prev_past_dist = tmp;
339 if (p_hal->first_field) {
340 p_regs->sw31.ref_dist_cur_2 = tmp - 1;
341 p_regs->sw31.ref_dist_cur_3 = tmp;
342
343 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1);
344 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
345 } else {
346 p_regs->sw31.ref_dist_cur_3 = tmp;
347 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
348 }
349
350 p_regs->sw32.ref_invd_col_0 = 0;
351 p_regs->sw32.ref_invd_col_1 = 0;
352 p_regs->sw33.ref_invd_col_2 = 0;
353 p_regs->sw33.ref_invd_col_3 = 0;
354 }
355 }
356
357 p_regs->sw48.startmb_x = 0;
358 p_regs->sw48.startmb_y = 0;
359
360 p_regs->sw03.filtering_dis = p_syn->pp.loopFilterDisable;
361 p_regs->sw05.alpha_offset = p_syn->pp.alphaOffset;
362 p_regs->sw05.beta_offset = p_syn->pp.betaOffset;
363 p_regs->sw03.skip_mode = p_syn->pp.skipModeFlag;
364 p_regs->sw04.pic_refer_flag = p_syn->pp.pictureReferenceFlag;
365
366 if (p_syn->pp.picCodingType == PFRAME
367 || (p_syn->pp.picCodingType == IFRAME && !p_hal->first_field)) {
368 p_regs->sw03.write_mvs_e = 1;
369 } else {
370 p_regs->sw03.write_mvs_e = 0;
371 }
372 //!< set mv base
373 p_regs->sw41.dir_mv_base = mpp_buffer_get_fd(p_hal->mv_buf);
374 if (p_hal->first_field ||
375 (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) {
376 } else {
377 RK_U32 frame_width = 0, frame_height = 0, offset = 0;
378 frame_width = (p_syn->pp.horizontalSize + 15) >> 4;
379 if (p_syn->pp.progressiveFrame)
380 frame_height = (p_syn->pp.verticalSize + 15) >> 4;
381 else
382 frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5);
383 offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16;
384 mpp_dev_set_reg_offset(p_hal->dev, 41, offset);
385 }
386 {
387 RK_U32 pic_type = 0;
388 RK_U32 prev_anc_type = 0;
389 if (p_hal->work0 >= 0) {
390 pic_type = p_hal->pic[p_hal->work0].pic_type;
391 }
392 prev_anc_type = !pic_type || (!p_hal->first_field && !p_hal->prev_pic_structure);
393 p_regs->sw18.prev_anc_type = prev_anc_type;
394 }
395 //!< b-picture needs to know if future reference is field or frame coded
396 // p_regs->sw16.refer2_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
397 // p_regs->sw17.refer3_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
398 if (!p_hal->prev_pic_structure) {
399 mpp_dev_set_reg_offset(p_hal->dev, 16, 2);
400 mpp_dev_set_reg_offset(p_hal->dev, 17, 3);
401 }
402
403 p_regs->sw03.dec_out_dis = 0;
404 p_regs->sw01.dec_e = 1;
405
406 return MPP_OK;
407 __FAILED:
408 return ret;
409 }
410
update_parameters(AvsdHalCtx_t * p_hal)411 static MPP_RET update_parameters(AvsdHalCtx_t *p_hal)
412 {
413 AvsdSyntax_t *p_syn = &p_hal->syn;
414
415 if (p_syn->pp.pictureStructure == FRAMEPICTURE || !p_hal->first_field) {
416 p_hal->first_field = 1;
417 if (p_syn->pp.picCodingType != BFRAME) {
418 RK_S32 temp = p_hal->work1;
419
420 p_hal->work1 = p_hal->work0;
421 p_hal->work0 = p_hal->work_out;
422
423 if (p_hal->work_out >= 0)
424 p_hal->pic[p_hal->work_out].pic_type = p_syn->pp.picCodingType == IFRAME;
425 p_hal->work_out = temp;
426 p_hal->prev_pic_structure = p_syn->pp.pictureStructure;
427 }
428 p_hal->prev_pic_code_type = p_syn->pp.picCodingType;
429 } else {
430 p_hal->first_field = 0;
431 }
432
433 return MPP_OK;
434 }
435
repeat_other_field(AvsdHalCtx_t * p_hal,HalTaskInfo * task)436 static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task)
437 {
438 RK_U8 i = 0;
439 RK_U8 *pdata = NULL;
440 MppBuffer mbuffer = NULL;
441 MPP_RET ret = MPP_ERR_UNKNOW;
442 AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
443
444 //!< re-find start code and calculate offset
445 p_hal->data_offset = p_regs->sw12.rlc_vlc_base >> 10;
446 p_hal->data_offset += p_hal->syn.bitstream_offset;
447 p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8);
448
449 mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer);
450 pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset;
451
452 while (i < 16) {
453 if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) {
454 p_hal->data_offset += i;
455 break;
456 }
457 i++;
458 }
459 AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no=%d, i=%d, offset=%d\n",
460 p_hal->frame_no, i, p_hal->data_offset);
461 //!< re-generate register
462 FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
463 hal_avsd_vdpu1_start((void *)p_hal, task);
464 hal_avsd_vdpu1_wait((void *)p_hal, task);
465
466 return ret = MPP_OK;
467 __FAILED:
468 return ret;
469 }
470
471 /*!
472 ***********************************************************************
473 * \brief
474 * init
475 ***********************************************************************
476 */
477 //extern "C"
hal_avsd_vdpu1_init(void * decoder,MppHalCfg * cfg)478 MPP_RET hal_avsd_vdpu1_init(void *decoder, MppHalCfg *cfg)
479 {
480 MPP_RET ret = MPP_ERR_UNKNOW;
481 RK_U32 buf_size = 0;
482 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
483
484 AVSD_HAL_TRACE("AVS_vdpu1 In.");
485
486 buf_size = (1920 * 1088) * 2;
487 FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size));
488
489 p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdVdpu1Regs_t));
490 MEM_CHECK(ret, p_hal->p_regs);
491
492 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align);
493 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align);
494 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align);
495
496 p_hal->regs_num = 60;
497 //!< initial for control
498 p_hal->first_field = 1;
499 p_hal->prev_pic_structure = 0; //!< field
500
501 memset(p_hal->pic, 0, sizeof(p_hal->pic));
502 p_hal->work_out = -1;
503 p_hal->work0 = -1;
504 p_hal->work1 = -1;
505
506 AVSD_HAL_TRACE("Out.");
507 (void)cfg;
508 return ret = MPP_OK;
509 __FAILED:
510 return ret;
511 }
512 /*!
513 ***********************************************************************
514 * \brief
515 * deinit
516 ***********************************************************************
517 */
518 //extern "C"
hal_avsd_vdpu1_deinit(void * decoder)519 MPP_RET hal_avsd_vdpu1_deinit(void *decoder)
520 {
521 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
522
523 AVSD_HAL_TRACE("In.");
524
525 if (p_hal->mv_buf) {
526 mpp_buffer_put(p_hal->mv_buf);
527 p_hal->mv_buf = NULL;
528 }
529 MPP_FREE(p_hal->p_regs);
530
531 AVSD_HAL_TRACE("Out.");
532
533 return MPP_OK;
534 }
535 /*!
536 ***********************************************************************
537 * \brief
538 * generate register
539 ***********************************************************************
540 */
541 //extern "C"
hal_avsd_vdpu1_gen_regs(void * decoder,HalTaskInfo * task)542 MPP_RET hal_avsd_vdpu1_gen_regs(void *decoder, HalTaskInfo *task)
543 {
544 MPP_RET ret = MPP_ERR_UNKNOW;
545 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
546
547 AVSD_HAL_TRACE("In.");
548 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
549 !p_hal->dec_cfg->base.disable_error) {
550 goto __RETURN;
551 }
552 p_hal->data_offset = p_hal->syn.bitstream_offset;
553
554 FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
555 __RETURN:
556 AVSD_HAL_TRACE("Out.");
557
558 return ret = MPP_OK;
559 __FAILED:
560 return ret;
561 }
562 /*!
563 ***********************************************************************
564 * \brief h
565 * start hard
566 ***********************************************************************
567 */
568 //extern "C"
hal_avsd_vdpu1_start(void * decoder,HalTaskInfo * task)569 MPP_RET hal_avsd_vdpu1_start(void *decoder, HalTaskInfo *task)
570 {
571 MPP_RET ret = MPP_ERR_UNKNOW;
572 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
573
574 AVSD_HAL_TRACE("In.");
575
576 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
577 !p_hal->dec_cfg->base.disable_error) {
578 goto __RETURN;
579 }
580
581 do {
582 MppDevRegWrCfg wr_cfg;
583 MppDevRegRdCfg rd_cfg;
584 RK_U32 reg_size = 101 * sizeof(RK_U32);
585
586 wr_cfg.reg = p_hal->p_regs;
587 wr_cfg.size = reg_size;
588 wr_cfg.offset = 0;
589
590 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg);
591 if (ret) {
592 mpp_err_f("set register write failed %d\n", ret);
593 break;
594 }
595
596 rd_cfg.reg = p_hal->p_regs;
597 rd_cfg.size = reg_size;
598 rd_cfg.offset = 0;
599
600 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg);
601 if (ret) {
602 mpp_err_f("set register read failed %d\n", ret);
603 break;
604 }
605
606 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL);
607 if (ret) {
608 mpp_err_f("send cmd failed %d\n", ret);
609 break;
610 }
611 } while (0);
612
613 __RETURN:
614 AVSD_HAL_TRACE("Out.");
615 return ret = MPP_OK;
616 }
617 /*!
618 ***********************************************************************
619 * \brief
620 * wait hard
621 ***********************************************************************
622 */
623 //extern "C"
hal_avsd_vdpu1_wait(void * decoder,HalTaskInfo * task)624 MPP_RET hal_avsd_vdpu1_wait(void *decoder, HalTaskInfo *task)
625 {
626 MPP_RET ret = MPP_ERR_UNKNOW;
627 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
628
629 AVSD_HAL_TRACE("In.");
630
631 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
632 !p_hal->dec_cfg->base.disable_error) {
633 goto __SKIP_HARD;
634 }
635
636 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL);
637 if (ret)
638 mpp_err_f("poll cmd failed %d\n", ret);
639
640 __SKIP_HARD:
641 if (p_hal->dec_cb) {
642 DecCbHalDone param;
643
644 param.task = (void *)&task->dec;
645 param.regs = (RK_U32 *)p_hal->p_regs;
646
647 if (!((AvsdVdpu1Regs_t *)p_hal->p_regs)->sw01.dec_rdy_int) {
648 param.hard_err = 1;
649 } else
650 param.hard_err = 0;
651
652 mpp_callback(p_hal->dec_cb, ¶m);
653 AVSD_HAL_DBG(AVSD_HAL_DBG_WAIT, "reg[1]=%08x, ref=%d, dpberr=%d, harderr=%d\n",
654 p_hal->p_regs[1], task->dec.flags.used_for_ref, task->dec.flags.ref_err, param.hard_err);
655 }
656 update_parameters(p_hal);
657 memset(&p_hal->p_regs[1], 0, sizeof(RK_U32));
658 if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE &&
659 ((!task->dec.flags.parse_err && !task->dec.flags.ref_err) ||
660 p_hal->dec_cfg->base.disable_error)) {
661 repeat_other_field(p_hal, task);
662 }
663 p_hal->frame_no++;
664
665 AVSD_HAL_TRACE("Out.");
666 return ret = MPP_OK;
667 }
668 /*!
669 ***********************************************************************
670 * \brief
671 * reset
672 ***********************************************************************
673 */
674 //extern "C"
hal_avsd_vdpu1_reset(void * decoder)675 MPP_RET hal_avsd_vdpu1_reset(void *decoder)
676 {
677 MPP_RET ret = MPP_ERR_UNKNOW;
678 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
679
680 AVSD_HAL_TRACE("In.");
681
682 p_hal->first_field = 1;
683 p_hal->prev_pic_structure = 0; //!< field
684
685 memset(p_hal->pic, 0, sizeof(p_hal->pic));
686 p_hal->work_out = -1;
687 p_hal->work0 = -1;
688 p_hal->work1 = -1;
689
690 AVSD_HAL_TRACE("Out.");
691
692 return ret = MPP_OK;
693 }
694 /*!
695 ***********************************************************************
696 * \brief
697 * flush
698 ***********************************************************************
699 */
700 //extern "C"
hal_avsd_vdpu1_flush(void * decoder)701 MPP_RET hal_avsd_vdpu1_flush(void *decoder)
702 {
703 MPP_RET ret = MPP_ERR_UNKNOW;
704
705 AVSD_HAL_TRACE("In.");
706
707 (void)decoder;
708
709 AVSD_HAL_TRACE("Out.");
710
711 return ret = MPP_OK;
712 }
713 /*!
714 ***********************************************************************
715 * \brief
716 * control
717 ***********************************************************************
718 */
719 //extern "C"
hal_avsd_vdpu1_control(void * decoder,MpiCmd cmd_type,void * param)720 MPP_RET hal_avsd_vdpu1_control(void *decoder, MpiCmd cmd_type, void *param)
721 {
722 MPP_RET ret = MPP_ERR_UNKNOW;
723
724 AVSD_HAL_TRACE("In.");
725
726 (void)decoder;
727 (void)cmd_type;
728 (void)param;
729
730 AVSD_HAL_TRACE("Out.");
731
732 return ret = MPP_OK;
733 }
734