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