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