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