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