xref: /rockchip-linux_mpp/mpp/hal/rkdec/avsd/hal_avsd_plus.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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, &param);
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