xref: /OK3568_Linux_fs/external/mpp/mpp/hal/vpu/jpegd/hal_jpegd_vdpu1.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *
3  * Copyright 2017 Rockchip Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #define MODULE_TAG "HAL_JPEGD_VDPU1"
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdint.h>
22 
23 #include "mpp_env.h"
24 #include "mpp_mem.h"
25 #include "mpp_debug.h"
26 #include "mpp_frame.h"
27 #include "mpp_common.h"
28 
29 #include "jpegd_syntax.h"
30 #include "hal_jpegd_common.h"
31 #include "hal_jpegd_vdpu1.h"
32 #include "hal_jpegd_vdpu1_reg.h"
33 
34 static void
jpegd_write_code_word_number(JpegdHalCtx * ctx,JpegdSyntax * syntax)35 jpegd_write_code_word_number(JpegdHalCtx *ctx, JpegdSyntax *syntax)
36 {
37     jpegd_dbg_func("enter\n");
38     JpegdSyntax *s = syntax;
39     AcTable *ac_ptr0 = NULL, *ac_ptr1 = NULL;
40     DcTable *dc_ptr0 = NULL, *dc_ptr1 = NULL;
41 
42     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
43     JpegRegSet *reg = &info->regs;
44 
45     /* first, select the table we'll use.
46      * this trick is done because hardware always wants luma
47      * table as AC hardware table 0.
48      */
49     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
50         /* Luma's AC uses Huffman table zero */
51         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
52         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
53     } else {
54         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
55         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
56     }
57 
58     /* write AC table 1 (luma) */
59     reg->reg16.sw_ac1_code1_cnt = ac_ptr0->bits[0];
60     reg->reg16.sw_ac1_code2_cnt = ac_ptr0->bits[1];
61     reg->reg16.sw_ac1_code3_cnt = ac_ptr0->bits[2];
62     reg->reg16.sw_ac1_code4_cnt = ac_ptr0->bits[3];
63     reg->reg16.sw_ac1_code5_cnt = ac_ptr0->bits[4];
64     reg->reg16.sw_ac1_code6_cnt = ac_ptr0->bits[5];
65 
66     reg->reg17.sw_ac1_code7_cnt = ac_ptr0->bits[6];
67     reg->reg17.sw_ac1_code8_cnt = ac_ptr0->bits[7];
68     reg->reg17.sw_ac1_code9_cnt = ac_ptr0->bits[8];
69     reg->reg17.sw_ac1_code10_cnt = ac_ptr0->bits[9];
70 
71     reg->reg18.sw_ac1_code11_cnt = ac_ptr0->bits[10];
72     reg->reg18.sw_ac1_code12_cnt = ac_ptr0->bits[11];
73     reg->reg18.sw_ac1_code13_cnt = ac_ptr0->bits[12];
74     reg->reg18.sw_ac1_code14_cnt = ac_ptr0->bits[13];
75 
76     reg->reg19.sw_ac1_code15_cnt = ac_ptr0->bits[14];
77     reg->reg19.sw_ac1_code16_cnt = ac_ptr0->bits[15];
78 
79     /* table AC2 (the not-luma table) */
80     reg->reg19.sw_ac2_code1_cnt = ac_ptr1->bits[0];
81     reg->reg19.sw_ac2_code2_cnt = ac_ptr1->bits[1];
82     reg->reg19.sw_ac2_code3_cnt = ac_ptr1->bits[2];
83     reg->reg19.sw_ac2_code4_cnt = ac_ptr1->bits[3];
84 
85     reg->reg20.sw_ac2_code5_cnt = ac_ptr1->bits[4];
86     reg->reg20.sw_ac2_code6_cnt = ac_ptr1->bits[5];
87     reg->reg20.sw_ac2_code7_cnt = ac_ptr1->bits[6];
88     reg->reg20.sw_ac2_code8_cnt = ac_ptr1->bits[7];
89 
90     reg->reg21.sw_ac2_code9_cnt = ac_ptr1->bits[8];
91     reg->reg21.sw_ac2_code10_cnt = ac_ptr1->bits[9];
92     reg->reg21.sw_ac2_code11_cnt = ac_ptr1->bits[10];
93     reg->reg21.sw_ac2_code12_cnt = ac_ptr1->bits[11];
94 
95     reg->reg22.sw_ac2_code13_cnt = ac_ptr1->bits[12];
96     reg->reg22.sw_ac2_code14_cnt = ac_ptr1->bits[13];
97     reg->reg22.sw_ac2_code15_cnt = ac_ptr1->bits[14];
98     reg->reg22.sw_ac2_code16_cnt = ac_ptr1->bits[15];
99 
100     /* first, select the table we'll use.
101      * this trick is done because hardware always wants luma
102      * table as DC hardware table 0.
103      */
104     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
105         /* Luma's DC uses Huffman table zero */
106         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
107         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
108     } else {
109         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
110         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
111     }
112 
113     /* write DC table 1 (luma) */
114     reg->reg23.sw_dc1_code1_cnt = dc_ptr0->bits[0];
115     reg->reg23.sw_dc1_code2_cnt = dc_ptr0->bits[1];
116     reg->reg23.sw_dc1_code3_cnt = dc_ptr0->bits[2];
117     reg->reg23.sw_dc1_code4_cnt = dc_ptr0->bits[3];
118     reg->reg23.sw_dc1_code5_cnt = dc_ptr0->bits[4];
119     reg->reg23.sw_dc1_code6_cnt = dc_ptr0->bits[5];
120     reg->reg23.sw_dc1_code7_cnt = dc_ptr0->bits[6];
121     reg->reg23.sw_dc1_code8_cnt = dc_ptr0->bits[7];
122 
123     reg->reg24.sw_dc1_code9_cnt = dc_ptr0->bits[8];
124     reg->reg24.sw_dc1_code10_cnt = dc_ptr0->bits[9];
125     reg->reg24.sw_dc1_code11_cnt = dc_ptr0->bits[10];
126     reg->reg24.sw_dc1_code12_cnt = dc_ptr0->bits[11];
127     reg->reg24.sw_dc1_code13_cnt = dc_ptr0->bits[12];
128     reg->reg24.sw_dc1_code14_cnt = dc_ptr0->bits[13];
129     reg->reg24.sw_dc1_code15_cnt = dc_ptr0->bits[14];
130     reg->reg24.sw_dc1_code16_cnt = dc_ptr0->bits[15];
131 
132     /* table DC2 (the not-luma table) */
133     reg->reg25.sw_dc2_code1_cnt = dc_ptr1->bits[0];
134     reg->reg25.sw_dc2_code2_cnt = dc_ptr1->bits[1];
135     reg->reg25.sw_dc2_code3_cnt = dc_ptr1->bits[2];
136     reg->reg25.sw_dc2_code4_cnt = dc_ptr1->bits[3];
137     reg->reg25.sw_dc2_code5_cnt = dc_ptr1->bits[4];
138     reg->reg25.sw_dc2_code6_cnt = dc_ptr1->bits[5];
139     reg->reg25.sw_dc2_code7_cnt = dc_ptr1->bits[6];
140     reg->reg25.sw_dc2_code8_cnt = dc_ptr1->bits[7];
141 
142     reg->reg26.sw_dc2_code9_cnt = dc_ptr1->bits[8];
143     reg->reg26.sw_dc2_code10_cnt = dc_ptr1->bits[9];
144     reg->reg26.sw_dc2_code11_cnt = dc_ptr1->bits[10];
145     reg->reg26.sw_dc2_code12_cnt = dc_ptr1->bits[11];
146     reg->reg26.sw_dc2_code13_cnt = dc_ptr1->bits[12];
147     reg->reg26.sw_dc2_code14_cnt = dc_ptr1->bits[13];
148     reg->reg26.sw_dc2_code15_cnt = dc_ptr1->bits[14];
149     reg->reg26.sw_dc2_code16_cnt = dc_ptr1->bits[15];
150 
151     jpegd_dbg_func("exit\n");
152     return;
153 }
154 
155 static void
jpegd_set_stream_offset(JpegdHalCtx * ctx,JpegdSyntax * syntax)156 jpegd_set_stream_offset(JpegdHalCtx *ctx, JpegdSyntax *syntax)
157 {
158     jpegd_dbg_func("enter\n");
159     JpegdSyntax *s = syntax;
160     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
161     JpegRegSet *reg = &info->regs;
162     RK_U32 offset = 0, byte_cnt = 0;
163     RK_U32 bit_pos_in_byte = 0;
164     RK_U32 strm_len_by_hw = 0;
165 
166     /* calculate and set stream start address to hw,
167      * the offset must be 8-byte aligned.
168      */
169     offset = (s->strm_offset & (~7));
170     reg->reg12_input_stream_base = ctx->pkt_fd;
171     if (offset) {
172         mpp_dev_set_reg_offset(ctx->dev, 12, offset);
173     }
174 
175     /* calculate and set stream start bit to hardware
176      * change current pos to bus address style
177      * remove three lowest bits and add the difference to bitPosInWord
178      * used as bit pos in word not as bit pos in byte actually...
179      */
180     byte_cnt = ((uintptr_t) s->cur_pos & (7));
181     bit_pos_in_byte = byte_cnt * 8; /* 1 Byte = 8 bits */
182     reg->reg5.sw_strm0_start_bit = bit_pos_in_byte;
183 
184     /* set up stream length for HW.
185      * length = size of original buffer - stream we already decoded in SW
186      */
187     strm_len_by_hw = s->pkt_len - offset;
188     reg->reg6_stream_info.sw_stream_len = strm_len_by_hw;
189     reg->reg5.sw_jpeg_stream_all = 1;
190 
191     jpegd_dbg_func("exit\n");
192     return;
193 }
194 
195 static void
jpegd_set_chroma_table_id(JpegdHalCtx * ctx,JpegdSyntax * syntax)196 jpegd_set_chroma_table_id(JpegdHalCtx *ctx, JpegdSyntax *syntax)
197 {
198     jpegd_dbg_func("enter\n");
199     JpegdSyntax *s = syntax;
200     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
201     JpegRegSet *reg = &info->regs;
202 
203     /* this trick is done because hw always wants
204      * luma table as ac hw table 1
205      */
206     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
207         reg->reg5.sw_cb_ac_vlctable = s->ac_index[1];
208         reg->reg5.sw_cr_ac_vlctable = s->ac_index[2];
209     } else {
210         if (s->ac_index[0] == s->ac_index[1])
211             reg->reg5.sw_cb_ac_vlctable = 0;
212         else
213             reg->reg5.sw_cb_ac_vlctable = 1;
214 
215         if (s->ac_index[0] == s->ac_index[2])
216             reg->reg5.sw_cr_ac_vlctable = 0;
217         else
218             reg->reg5.sw_cr_ac_vlctable = 1;
219     }
220 
221     /* Third DC table selectors */
222     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
223         reg->reg5.sw_cb_dc_vlctable = s->dc_index[1];
224         reg->reg5.sw_cr_dc_vlctable = s->dc_index[2];
225     } else {
226         if (s->dc_index[0] == s->dc_index[1])
227             reg->reg5.sw_cb_dc_vlctable = 0;
228         else
229             reg->reg5.sw_cb_dc_vlctable = 1;
230 
231         if (s->dc_index[0] == s->dc_index[2])
232             reg->reg5.sw_cr_dc_vlctable = 0;
233         else
234             reg->reg5.sw_cr_dc_vlctable = 1;
235     }
236 
237     reg->reg5.sw_cr_dc_vlctable3 = 0;
238     reg->reg5.sw_cb_dc_vlctable3 = 0;
239 
240     jpegd_dbg_func("exit\n");
241     return;
242 }
243 
jpegd_setup_pp(JpegdHalCtx * ctx,JpegdSyntax * syntax)244 static MPP_RET jpegd_setup_pp(JpegdHalCtx *ctx, JpegdSyntax *syntax)
245 {
246     jpegd_dbg_func("enter\n");
247     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
248     JpegRegSet *regs = &info->regs;
249     post_processor_reg *post = &regs->post;
250     JpegdSyntax *s = syntax;
251 
252     RK_U32 in_color = ctx->pp_info.pp_in_fmt;
253     RK_U32 out_color = ctx->pp_info.pp_out_fmt;
254     RK_U32 dither = ctx->pp_info.dither_enable;
255     RK_U32 crop_width = ctx->pp_info.crop_width;
256     RK_U32 crop_height = ctx->pp_info.crop_height;
257     RK_U32 crop_x = ctx->pp_info.crop_x;
258     RK_U32 crop_y = ctx->pp_info.crop_y;
259     RK_U32 in_width = s->hor_stride;
260     RK_U32 in_height = s->ver_stride;
261     RK_U32 out_width = s->hor_stride;
262     RK_U32 out_height = s->ver_stride;
263     RK_U32 uv_offset = s->hor_stride * s->ver_stride;
264 
265     int video_range = 1;
266 
267     post->reg61_dev_conf.sw_pp_axi_rd_id = 0;
268     post->reg61_dev_conf.sw_pp_axi_wr_id = 0;
269     post->reg61_dev_conf.sw_pp_scmd_dis = 1;
270     post->reg61_dev_conf.sw_pp_max_burst = 16;
271     post->reg61_dev_conf.sw_pp_in_a2_endsel = 1;
272     post->reg61_dev_conf.sw_pp_in_a1_swap32 = 1;
273     post->reg61_dev_conf.sw_pp_in_a1_endian = 1;
274     post->reg61_dev_conf.sw_pp_in_swap32_e = 1;
275     post->reg61_dev_conf.sw_pp_in_endian = 1;
276     post->reg61_dev_conf.sw_pp_out_endian = 1;
277     post->reg61_dev_conf.sw_pp_out_swap32_e = 1;
278 
279     post->reg63_pp_in_lu_base = 0;
280 
281     post->reg88_mask_1_size.sw_ext_orig_width = in_width >> 4;
282 
283     post->reg61_dev_conf.sw_pp_clk_gate_e = 0;
284     post->reg61_dev_conf.sw_pp_ahb_hlock_e = 1;
285     post->reg61_dev_conf.sw_pp_data_disc_e = 1;
286 
287     if (crop_width <= 0) {
288         post->reg92_display.sw_pp_in_w_ext = (((in_width / 16) & 0xE00) >> 9);
289         post->reg72_crop.sw_pp_in_width = ((in_width / 16) & 0x1FF);
290         post->reg92_display.sw_pp_in_h_ext = (((in_height / 16) & 0x700) >> 8);
291         post->reg72_crop.sw_pp_in_height = ((in_height / 16) & 0x0FF);
292     } else {
293         post->reg92_display.sw_pp_in_w_ext =
294             (((crop_width / 16) & 0xE00) >> 9);
295         post->reg72_crop.sw_pp_in_width = ((crop_width / 16) & 0x1FF);
296         post->reg92_display.sw_pp_in_h_ext =
297             (((crop_height / 16) & 0x700) >> 8);
298         post->reg72_crop.sw_pp_in_height = ((crop_height / 16) & 0x0FF);
299 
300         post->reg92_display.sw_crop_startx_ext =
301             (((crop_x / 16) & 0xE00) >> 9);
302         post->reg71_color_coeff_1.sw_crop_startx =
303             ((crop_x / 16) & 0x1FF);
304         post->reg92_display.sw_crop_starty_ext =
305             (((crop_y / 16) & 0x700) >> 8);
306         post->reg72_crop.sw_crop_starty =
307             ((crop_y / 16) & 0x0FF);
308 
309         if (crop_width & 0x0F) {
310             post->reg85_ctrl.sw_pp_crop8_r_e = 1;
311         } else {
312             post->reg85_ctrl.sw_pp_crop8_r_e = 0;
313         }
314         if (crop_height & 0x0F) {
315             post->reg85_ctrl.sw_pp_crop8_d_e = 1;
316         } else {
317             post->reg85_ctrl.sw_pp_crop8_d_e = 0;
318         }
319         in_width = crop_width;
320         in_height = crop_height;
321     }
322 
323     post->reg92_display.sw_display_width = out_width;
324     post->reg85_ctrl.sw_pp_out_width = out_width;
325     post->reg85_ctrl.sw_pp_out_height = out_height;
326     post->reg66_pp_out_lu_base = ctx->frame_fd;
327 
328     switch (in_color) {
329     case    PP_IN_FORMAT_YUV422INTERLAVE:
330     case    PP_IN_FORMAT_YUV420SEMI:
331     case    PP_IN_FORMAT_YUV420PLANAR:
332     case    PP_IN_FORMAT_YUV400:
333     case    PP_IN_FORMAT_YUV422SEMI:
334     case    PP_IN_FORMAT_YUV420SEMITIELED:
335     case    PP_IN_FORMAT_YUV440SEMI:
336         post->reg85_ctrl.sw_pp_in_format = in_color;
337         break;
338     case    PP_IN_FORMAT_YUV444_SEMI:
339         post->reg85_ctrl.sw_pp_in_format = 7;
340         post->reg86_mask_1.sw_pp_in_format_es = 0;
341         break;
342     case    PP_IN_FORMAT_YUV411_SEMI:
343         post->reg85_ctrl.sw_pp_in_format = 0;
344         post->reg86_mask_1.sw_pp_in_format_es = 1;
345         break;
346     default:
347         mpp_err_f("unsupported format:%d", in_color);
348         return -1;
349     }
350 
351     post->reg72_crop.sw_rangemap_coef_y = 9;
352     post->reg86_mask_1.sw_rangemap_coef_c = 9;
353     /*  brightness */
354     post->reg71_color_coeff_1.sw_color_coefff = BRIGHTNESS;
355 
356     if (out_color <= PP_OUT_FORMAT_ARGB) {
357         /*Bt.601*/
358         unsigned int    a = 298;
359         unsigned int    b = 409;
360         unsigned int    c = 208;
361         unsigned int    d = 100;
362         unsigned int    e = 516;
363 
364         /*Bt.709
365         unsigned int    a = 298;
366         unsigned int    b = 459;
367         unsigned int    c = 137;
368         unsigned int    d = 55;
369         unsigned int    e = 544;*/
370 
371         int satur = 0, tmp;
372         if (video_range != 0) {
373             /*Bt.601*/
374             a = 256;
375             b = 350;
376             c = 179;
377             d = 86;
378             e = 443;
379             /*Bt.709
380             a = 256;
381             b = 403;
382             c = 120;
383             d = 48;
384             e = 475;*/
385 
386             post->reg79_scaling_0.sw_ycbcr_range = video_range;
387         }
388         int contrast = CONTRAST;
389         if (contrast != 0) {
390             int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2;
391             if (video_range == 0) {
392                 int tmp1, tmp2;
393                 /* Contrast */
394                 thr1 = (219 * (contrast + 128)) / 512;
395                 thr1y = (219 - 2 * thr1) / 2;
396                 thr2 = 219 - thr1;
397                 thr2y = 219 - thr1y;
398 
399                 tmp1 = (thr1y * 256) / thr1;
400                 tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
401                 off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256;
402                 off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256;
403 
404                 tmp1 = (64 * (contrast + 128)) / 128;
405                 tmp2 = 256 * (128 - tmp1);
406                 a1 = (tmp2 + off2) / thr1;
407                 a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1);
408             } else {
409                 /* Contrast */
410                 thr1 = (64 * (contrast + 128)) / 128;
411                 thr1y = 128 - thr1;
412                 thr2 = 256 - thr1;
413                 thr2y = 256 - thr1y;
414                 a1 = (thr1y * 256) / thr1;
415                 a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
416                 off1 = thr1y - (a2 * thr1) / 256;
417                 off2 = thr2y - (a1 * thr2) / 256;
418             }
419 
420             if (a1 > 1023)
421                 a1 = 1023;
422             else if (a1 < 0)
423                 a1 = 0;
424 
425             if (a2 > 1023)
426                 a2 = 1023;
427             else if (a2 < 0)
428                 a2 = 0;
429 
430             if (thr1 > 255)
431                 thr1 = 255;
432             else if (thr1 < 0)
433                 thr1 = 0;
434 
435             if (thr2 > 255)
436                 thr2 = 255;
437             else if (thr2 < 0)
438                 thr2 = 0;
439 
440             if (off1 > 511)
441                 off1 = 511;
442             else if (off1 < -512)
443                 off1 = -512;
444 
445             if (off2 > 511)
446                 off2 = 511;
447             else if (off2 < -512)
448                 off2 = -512;
449 
450             post->reg68_contrast_adjust.sw_contrast_thr1 = thr1;
451             post->reg69.sw_contrast_thr2 = thr2;
452             post->reg68_contrast_adjust.sw_contrast_off1 = off1;
453             post->reg68_contrast_adjust.sw_contrast_off2 = off2;
454 
455             post->reg69.sw_color_coeffa1 = a1;
456             post->reg69.sw_color_coeffa2 = a2;
457         } else {
458             post->reg68_contrast_adjust.sw_contrast_thr1 = 55;
459             post->reg69.sw_contrast_thr2 = 165;
460             post->reg68_contrast_adjust.sw_contrast_off1 = 0;
461             post->reg68_contrast_adjust.sw_contrast_off2 = 0;
462 
463             tmp = a;
464             if (tmp > 1023)
465                 tmp = 1023;
466             else if (tmp < 0)
467                 tmp = 0;
468 
469             post->reg69.sw_color_coeffa1 = tmp;
470             post->reg69.sw_color_coeffa2 = tmp;
471         }
472 
473         /* saturation */
474         satur = 64 + SATURATION;
475 
476         tmp = (satur * (int) b) / 64;
477         if (tmp > 1023)
478             tmp = 1023;
479         else if (tmp < 0)
480             tmp = 0;
481         post->reg70_color_coeff_0.sw_color_coeffb = (unsigned int) tmp;
482 
483         tmp = (satur * (int) c) / 64;
484         if (tmp > 1023)
485             tmp = 1023;
486         else if (tmp < 0)
487             tmp = 0;
488         post->reg70_color_coeff_0.sw_color_coeffc = (unsigned int) tmp;
489 
490         tmp = (satur * (int) d) / 64;
491         if (tmp > 1023)
492             tmp = 1023;
493         else if (tmp < 0)
494             tmp = 0;
495         post->reg70_color_coeff_0.sw_color_coeffd = (unsigned int) tmp;
496 
497         tmp = (satur * (int) e) / 64;
498         if (tmp > 1023)
499             tmp = 1023;
500         else if (tmp < 0)
501             tmp = 0;
502         post->reg71_color_coeff_1.sw_color_coeffe = (unsigned int) tmp;
503     }
504 
505     if (out_color <= PP_OUT_FORMAT_ARGB) {
506         PpRgbCfg *cfg = get_pp_rgb_Cfg(ctx->output_fmt);
507         post->reg82_r_mask = cfg->r_mask;
508         post->reg83_g_mask = cfg->g_mask;
509         post->reg84_b_mask = cfg->b_mask;
510         post->reg79_scaling_0.sw_rgb_r_padd = cfg->r_padd;
511         post->reg79_scaling_0.sw_rgb_g_padd = cfg->g_padd;
512         post->reg80_scaling_1.sw_rgb_b_padd = cfg->b_padd;
513 
514         if (dither) {
515             jpegd_dbg_hal("we do dither.");
516             post->reg91_pip_2.sw_dither_select_r = cfg->r_dither;
517             post->reg91_pip_2.sw_dither_select_r = cfg->g_dither;
518             post->reg91_pip_2.sw_dither_select_r = cfg->b_dither;
519         } else {
520             jpegd_dbg_hal("we do not dither.");
521         }
522 
523         post->reg79_scaling_0.sw_rgb_pix_in32 = cfg->rgb_in_32;
524         post->reg85_ctrl.sw_pp_out_swap16_e = cfg->swap_16;
525         post->reg61_dev_conf.sw_pp_out_swap32_e = cfg->swap_32;
526         post->reg61_dev_conf.sw_pp_out_endian = cfg->out_endian;
527 
528         post->reg85_ctrl.sw_pp_out_format = 0;
529 
530     } else if (out_color == PP_OUT_FORMAT_YUV422INTERLAVE) {
531         post->reg85_ctrl.sw_pp_out_format = 3;
532     } else if (out_color == PP_OUT_FORMAT_YUV420INTERLAVE) {
533         post->reg85_ctrl.sw_pp_out_format = 5;
534     } else {
535         mpp_err_f("unsuppotred format:%d", out_color);
536         return -1;
537     }
538 
539     post->reg71_color_coeff_1.sw_rotation_mode = 0;
540 
541     unsigned int inw, inh;
542     unsigned int outw, outh;
543 
544     inw = in_width - 1;
545     inh = in_height - 1;
546     outw = out_width - 1;
547     outh = out_height - 1;
548 
549     if (inw < outw) {
550         post->reg80_scaling_1.sw_hor_scale_mode = 1;
551         post->reg79_scaling_0.sw_scale_wratio = (outw << 16) / inw;
552         post->reg81_scaling_2.sw_wscale_invra = (inw << 16) / outw;
553     } else if (inw > outw) {
554         post->reg80_scaling_1.sw_hor_scale_mode = 2;
555         post->reg81_scaling_2.sw_wscale_invra = ((outw + 1) << 16) / (inw + 1);
556     } else
557         post->reg80_scaling_1.sw_hor_scale_mode = 0;
558 
559     if (inh < outh) {
560         post->reg80_scaling_1.sw_ver_scale_mode = 1;
561         post->reg80_scaling_1.sw_scale_hratio = (outh << 16) / inh;
562         post->reg81_scaling_2.sw_hscale_invra = (inh << 16) / outh;
563     } else if (inh > outh) {
564         post->reg80_scaling_1.sw_ver_scale_mode = 2;
565         post->reg81_scaling_2.sw_hscale_invra =
566             ((outh + 1) << 16) / (inh + 1) + 1;
567     } else
568         post->reg80_scaling_1.sw_ver_scale_mode = 0;
569 
570     post->reg60_interrupt.sw_pp_pipeline_e = ctx->pp_info.pp_enable;
571 
572     if (ctx->pp_info.pp_enable) {
573         post->reg60_interrupt.sw_pp_pipeline_e = 1;
574         regs->reg3.sw_dec_out_dis = 1;
575 
576         regs->reg13_cur_pic_base = 0;
577         regs->reg14_sw_jpg_ch_out_base = 0;
578 
579         post->reg66_pp_out_lu_base = ctx->frame_fd;
580         post->reg67_pp_out_ch_base = ctx->frame_fd;
581 
582         if (uv_offset)
583             mpp_dev_set_reg_offset(ctx->dev, 67, uv_offset);
584 
585         jpegd_dbg_hal("output_frame_fd:%x, reg67:%x", ctx->frame_fd,
586                       post->reg67_pp_out_ch_base);
587     } else {
588         // output without pp
589         post->reg60_interrupt.sw_pp_pipeline_e = 0;
590         regs->reg3.sw_dec_out_dis = 0;
591 
592         post->reg66_pp_out_lu_base = 0;
593         post->reg67_pp_out_ch_base = 0;
594 
595         regs->reg13_cur_pic_base = ctx->frame_fd;
596         regs->reg14_sw_jpg_ch_out_base = ctx->frame_fd;
597 
598         if (uv_offset)
599             mpp_dev_set_reg_offset(ctx->dev, 14, uv_offset);
600 
601         jpegd_dbg_hal("output_frame_fd:%x, reg14:%x", ctx->frame_fd,
602                       regs->reg14_sw_jpg_ch_out_base);
603     }
604 
605     jpegd_dbg_func("exit\n");
606     return 0;
607 }
608 
jpegd_regs_init(JpegRegSet * reg)609 static MPP_RET jpegd_regs_init(JpegRegSet *reg)
610 {
611     jpegd_dbg_func("enter\n");
612     memset(reg, 0, sizeof(JpegRegSet));
613     reg->reg2_dec_ctrl.sw_dec_out_tiled_e = 0;
614     reg->reg2_dec_ctrl.sw_dec_scmd_dis = DEC_VDPU1_SCMD_DISABLE;
615     reg->reg2_dec_ctrl.sw_dec_latency = DEC_VDPU1_LATENCY_COMPENSATION;
616 
617     reg->reg2_dec_ctrl.sw_dec_in_endian = DEC_VDPU1_BIG_ENDIAN;
618     reg->reg2_dec_ctrl.sw_dec_out_endian = DEC_VDPU1_LITTLE_ENDIAN;
619     reg->reg2_dec_ctrl.sw_dec_strendian_e = DEC_VDPU1_LITTLE_ENDIAN;
620     reg->reg2_dec_ctrl.sw_dec_outswap32_e = DEC_VDPU1_LITTLE_ENDIAN;
621     reg->reg2_dec_ctrl.sw_dec_inswap32_e = 1;
622     reg->reg2_dec_ctrl.sw_dec_strswap32_e = 1;
623 
624     reg->reg1_interrupt.sw_dec_irq_dis = 0;
625 
626     reg->reg2_dec_ctrl.sw_dec_axi_rn_id = 0xff;
627     reg->reg3.sw_dec_axi_wr_id = 0;
628     reg->reg2_dec_ctrl.sw_dec_max_burst = DEC_VDPU1_BUS_BURST_LENGTH_16;
629     reg->reg2_dec_ctrl.sw_dec_data_disc_e = DEC_VDPU1_DATA_DISCARD_ENABLE;
630 
631     reg->reg2_dec_ctrl.sw_dec_timeout_e = 1;
632     reg->reg2_dec_ctrl.sw_dec_clk_gate_e = 1;
633 
634     jpegd_dbg_func("exit\n");
635     return MPP_OK;
636 }
637 
jpegd_gen_regs(JpegdHalCtx * ctx,JpegdSyntax * syntax)638 static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
639 {
640     jpegd_dbg_func("enter\n");
641     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
642     JpegRegSet *reg = &info->regs;
643     JpegdSyntax *s = syntax;
644 
645     jpegd_regs_init(reg);
646 
647     /* Enable jpeg mode */
648     reg->reg1_interrupt.sw_dec_e = 1;
649 
650     reg->reg3.sw_filtering_dis = 1;
651 
652     /* JPEG decoder */
653     reg->reg3.sw_dec_mode = 3;
654     reg->reg3.sw_pjpeg_e = 0;  /* Set JPEG operation mode */
655     reg->reg3.sw_dec_out_dis = 0;
656     reg->reg3.sw_rlc_mode_e = 0;
657 
658     /* frame size, round up the number of mbs */
659     reg->reg4.sw_pic_mb_h_ext = ((((s->ver_stride) >> (4)) & 0x700) >> 8);
660     reg->reg4.sw_pic_mb_w_ext = ((((s->hor_stride) >> (4)) & 0xE00) >> 9);
661     reg->reg4.sw_pic_mb_width = ((s->hor_stride) >> (4)) & 0x1FF;
662     reg->reg4.sw_pic_mb_height_p = ((s->ver_stride) >> (4)) & 0x0FF;
663 
664     reg->reg7.sw_pjpeg_fildown_e = s->fill_bottom;
665     /* Set spectral selection start coefficient */
666     reg->reg7.sw_pjpeg_ss = s->scan_start;
667     /* Set spectral selection end coefficient */
668     reg->reg7.sw_pjpeg_se = s->scan_end;
669     /* Set the point transform used in the preceding scan */
670     reg->reg7.sw_pjpeg_ah = s->prev_shift;
671     /* Set the point transform value */
672     reg->reg7.sw_pjpeg_al = s->point_transform;
673 
674     reg->reg5.sw_jpeg_qtables = s->qtable_cnt;
675     reg->reg5.sw_jpeg_mode = s->yuv_mode;
676     reg->reg5.sw_jpeg_filright_e = s->fill_right;
677 
678     reg->reg15.sw_jpeg_slice_h = 0;
679     /*
680      * Set bit 21 of reg148 to 1, notifying hardware to decode
681      * jpeg including DRI segment
682      */
683     reg->reg5.sw_sync_marker_e = 1;
684 
685     /* tell hardware that height is 8-pixel aligned, but not 16-pixel aligned */
686     if ((s->height % 16) && ((s->height % 16) <= 8) &&
687         (s->yuv_mode == JPEGDEC_YUV422 ||
688          s->yuv_mode == JPEGDEC_YUV444 ||
689          s->yuv_mode == JPEGDEC_YUV411)) {
690         reg->reg15.sw_jpeg_height8_flag = 1;
691     }
692 
693     /* write VLC code word number to register */
694     jpegd_write_code_word_number(ctx, s);
695 
696     /* Create AC/DC/QP tables for hardware */
697     jpegd_write_qp_ac_dc_table(ctx, s);
698 
699     /* Select which tables the chromas use */
700     jpegd_set_chroma_table_id(ctx, s);
701 
702     /* write table base */
703     reg->reg40_qtable_base = mpp_buffer_get_fd(ctx->pTableBase);
704 
705     /* set up stream position for HW decode */
706     jpegd_set_stream_offset(ctx, s);
707 
708     /* set restart interval */
709     if (s->restart_interval) {
710         reg->reg5.sw_sync_marker_e = 1;
711         /*
712          * If exists DRI segment, bit 0 to bit 15 of reg8
713          * is set to restart interval
714          */
715         reg->reg8.sw_pjpeg_rest_freq = s->restart_interval;
716     } else {
717         reg->reg5.sw_sync_marker_e = 0;
718     }
719 
720     jpegd_setup_pp(ctx, syntax);
721 
722     jpegd_dbg_func("exit\n");
723     return MPP_OK;
724 }
725 
hal_jpegd_vdpu1_init(void * hal,MppHalCfg * cfg)726 MPP_RET hal_jpegd_vdpu1_init(void *hal, MppHalCfg *cfg)
727 {
728     MPP_RET ret = MPP_OK;
729     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
730 
731     mpp_assert(JpegHalCtx);
732     jpegd_dbg_func("enter\n");
733 
734     //configure
735     JpegHalCtx->packet_slots = cfg->packet_slots;
736     JpegHalCtx->frame_slots  = cfg->frame_slots;
737     JpegHalCtx->dev_type     = VPU_CLIENT_VDPU1;
738 
739     ret = mpp_dev_init(&JpegHalCtx->dev, JpegHalCtx->dev_type);
740     if (ret) {
741         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
742         return ret;
743     }
744     cfg->dev = JpegHalCtx->dev;
745 
746     /* allocate regs buffer */
747     if (JpegHalCtx->regs == NULL) {
748         JpegHalCtx->regs = mpp_calloc_size(void, sizeof(JpegdIocRegInfo));
749         if (JpegHalCtx->regs == NULL) {
750             mpp_err("hal jpegd reg alloc failed\n");
751 
752             jpegd_dbg_func("exit\n");
753             return MPP_ERR_NOMEM;
754         }
755     }
756     JpegdIocRegInfo *info = (JpegdIocRegInfo *)JpegHalCtx->regs;
757     memset(info, 0, sizeof(JpegdIocRegInfo));
758 
759     //malloc hw buf
760     if (JpegHalCtx->group == NULL) {
761         ret = mpp_buffer_group_get_internal(&JpegHalCtx->group,
762                                             MPP_BUFFER_TYPE_ION);
763         if (ret) {
764             mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
765             return ret;
766         }
767     }
768 
769     ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->frame_buf,
770                          JPEGD_STREAM_BUFF_SIZE);
771     if (ret) {
772         mpp_err_f("get frame buffer failed ret %d\n", ret);
773         return ret;
774     }
775 
776     ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->pTableBase,
777                          JPEGD_BASELINE_TABLE_SIZE);
778     if (ret) {
779         mpp_err_f("get table buffer failed ret %d\n", ret);
780         return ret;
781     }
782 
783     PPInfo *pp_info = &(JpegHalCtx->pp_info);
784     memset(pp_info, 0, sizeof(PPInfo));
785     pp_info->pp_enable = 0;
786     pp_info->pp_in_fmt = PP_IN_FORMAT_YUV420SEMI;
787     pp_info->pp_out_fmt = PP_OUT_FORMAT_YUV420INTERLAVE;
788     jpegd_check_have_pp(JpegHalCtx);
789 
790     JpegHalCtx->output_fmt = MPP_FMT_YUV420SP;
791     JpegHalCtx->set_output_fmt_flag = 0;
792 
793     /* init dbg stuff */
794     JpegHalCtx->hal_debug_enable = 0;
795     JpegHalCtx->frame_count = 0;
796     JpegHalCtx->output_yuv_count = 0;
797 
798     jpegd_dbg_func("exit\n");
799     return MPP_OK;
800 }
801 
hal_jpegd_vdpu1_deinit(void * hal)802 MPP_RET hal_jpegd_vdpu1_deinit(void *hal)
803 {
804     MPP_RET ret = MPP_OK;
805     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
806 
807     jpegd_dbg_func("enter\n");
808 
809     if (JpegHalCtx->dev) {
810         mpp_dev_deinit(JpegHalCtx->dev);
811         JpegHalCtx->dev = NULL;
812     }
813 
814     if (JpegHalCtx->frame_buf) {
815         ret = mpp_buffer_put(JpegHalCtx->frame_buf);
816         if (ret) {
817             mpp_err_f("put buffer failed\n");
818             return ret;
819         }
820     }
821 
822     if (JpegHalCtx->pTableBase) {
823         ret = mpp_buffer_put(JpegHalCtx->pTableBase);
824         if (ret) {
825             mpp_err_f("put buffer failed\n");
826             return ret;
827         }
828     }
829 
830     if (JpegHalCtx->group) {
831         ret = mpp_buffer_group_put(JpegHalCtx->group);
832         if (ret) {
833             mpp_err_f("group free buffer failed\n");
834             return ret;
835         }
836     }
837 
838     if (JpegHalCtx->regs) {
839         mpp_free(JpegHalCtx->regs);
840         JpegHalCtx->regs = NULL;
841     }
842 
843     JpegHalCtx->output_fmt = MPP_FMT_YUV420SP;
844     JpegHalCtx->set_output_fmt_flag = 0;
845     JpegHalCtx->hal_debug_enable = 0;
846     JpegHalCtx->frame_count = 0;
847     JpegHalCtx->output_yuv_count = 0;
848 
849     jpegd_dbg_func("exit\n");
850     return MPP_OK;
851 }
852 
hal_jpegd_vdpu1_gen_regs(void * hal,HalTaskInfo * syn)853 MPP_RET hal_jpegd_vdpu1_gen_regs(void *hal,  HalTaskInfo *syn)
854 {
855     jpegd_dbg_func("enter\n");
856     if (NULL == hal || NULL == syn) {
857         mpp_err_f("NULL pointer");
858         return MPP_ERR_NULL_PTR;
859     }
860 
861     MPP_RET ret = MPP_OK;
862     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
863     JpegdSyntax *syntax = (JpegdSyntax *)syn->dec.syntax.data;
864     MppBuffer streambuf = NULL;
865     MppBuffer outputBuf = NULL;
866 
867     ret = jpeg_image_check_size(syntax->hor_stride, syntax->ver_stride);
868     if (ret)
869         goto RET;
870 
871     if (syn->dec.valid) {
872         jpegd_setup_output_fmt(JpegHalCtx, syntax, syn->dec.output);
873         if (ret) {
874             mpp_err_f("setup output format %x failed\n", syntax->output_fmt);
875             goto RET;
876         }
877 
878         /* input stream address */
879         mpp_buf_slot_get_prop(JpegHalCtx->packet_slots, syn->dec.input,
880                               SLOT_BUFFER, &streambuf);
881         JpegHalCtx->pkt_fd = mpp_buffer_get_fd(streambuf);
882         syntax->pkt_len = jpegd_vdpu_tail_0xFF_patch(streambuf, syntax->pkt_len);
883 
884         /* output picture address */
885         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, syn->dec.output,
886                               SLOT_BUFFER, &outputBuf);
887         JpegHalCtx->frame_fd = mpp_buffer_get_fd(outputBuf);
888 
889         ret = jpegd_gen_regs(JpegHalCtx, syntax);
890         if (ret) {
891             mpp_err_f("generate registers failed\n");
892             goto RET;
893         }
894     }
895 
896 RET:
897     if (ret)
898         syn->dec.valid = 0;
899 
900     jpegd_dbg_func("exit\n");
901     return ret;
902 }
903 
hal_jpegd_vdpu1_start(void * hal,HalTaskInfo * task)904 MPP_RET hal_jpegd_vdpu1_start(void *hal, HalTaskInfo *task)
905 {
906     MPP_RET ret = MPP_OK;
907     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
908     RK_U32 *regs = (RK_U32 *)JpegHalCtx->regs;
909 
910     jpegd_dbg_func("enter\n");
911 
912     do {
913         MppDevRegWrCfg wr_cfg;
914         MppDevRegRdCfg rd_cfg;
915         RK_U32 reg_size = mpp_get_ioctl_version() ?
916                           sizeof(((JpegdIocRegInfo *)0)->regs) :
917                           sizeof(JpegdIocRegInfo) - EXTRA_INFO_SIZE;
918 
919         wr_cfg.reg = regs;
920         wr_cfg.size = reg_size;
921         wr_cfg.offset = 0;
922 
923         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_WR, &wr_cfg);
924         if (ret) {
925             mpp_err_f("set register write failed %d\n", ret);
926             break;
927         }
928 
929         reg_size = sizeof(((JpegdIocRegInfo *)0)->regs);
930 
931         rd_cfg.reg = regs;
932         rd_cfg.size = reg_size;
933         rd_cfg.offset = 0;
934 
935         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_RD, &rd_cfg);
936         if (ret) {
937             mpp_err_f("set register read failed %d\n", ret);
938             break;
939         }
940 
941         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_SEND, NULL);
942         if (ret) {
943             mpp_err_f("send cmd failed %d\n", ret);
944             break;
945         }
946     } while (0);
947 
948     (void)task;
949     jpegd_dbg_func("exit\n");
950     return ret;
951 }
952 
hal_jpegd_vdpu1_wait(void * hal,HalTaskInfo * task)953 MPP_RET hal_jpegd_vdpu1_wait(void *hal, HalTaskInfo *task)
954 {
955     MPP_RET ret = MPP_OK;
956     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
957     JpegRegSet *reg_out = JpegHalCtx->regs;
958     RK_U32 errinfo = 1;
959     MppFrame tmp = NULL;
960 
961     jpegd_dbg_func("enter\n");
962 
963     ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_POLL, NULL);
964     if (ret)
965         mpp_err_f("poll cmd failed %d\n", ret);
966 
967     if (reg_out->reg1_interrupt.sw_dec_bus_int) {
968         mpp_err_f("IRQ BUS ERROR!");
969     } else if (reg_out->reg1_interrupt.sw_dec_error_int) {
970         /*
971          * NOTE: It is a bug of VDPU1, when sample color is YUV422,
972          * YUV444, YUV411, the height could be aligned with 8 but not 16
973          */
974         if (JpegHalCtx->output_fmt != MPP_FMT_YUV420SP)
975             ret = 0;
976         else
977             mpp_err_f("IRQ STREAM ERROR! %d", JpegHalCtx->output_fmt);
978     } else if (reg_out->reg1_interrupt.sw_dec_timeout) {
979         mpp_err_f("IRQ TIMEOUT!");
980     } else if (reg_out->reg1_interrupt.sw_dec_buffer_int) {
981         mpp_err_f("IRQ BUFFER EMPTY!");
982     } else if (reg_out->reg1_interrupt.sw_dec_irq) {
983         errinfo = 0;
984         jpegd_dbg_hal("DECODE SUCCESS!");
985     }
986 
987     mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output,
988                           SLOT_FRAME_PTR, &tmp);
989     mpp_frame_set_errinfo(tmp, errinfo);
990 
991     /* debug information */
992     if (jpegd_debug & JPEGD_DBG_IO) {
993         static FILE *jpg_file;
994         static char name[32];
995         MppBuffer outputBuf = NULL;
996         void *base = NULL;
997         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output,
998                               SLOT_BUFFER, &outputBuf);
999         base = mpp_buffer_get_ptr(outputBuf);
1000 
1001         snprintf(name, sizeof(name) - 1, "/tmp/output%02d.yuv",
1002                  JpegHalCtx->output_yuv_count);
1003         jpg_file = fopen(name, "wb+");
1004         if (jpg_file) {
1005             JpegdSyntax *s = (JpegdSyntax *)task->dec.syntax.data;
1006             RK_U32 width = s->hor_stride;
1007             RK_U32 height = s->ver_stride;
1008 
1009             fwrite(base, width * height * 3 / 2, 1, jpg_file);
1010             jpegd_dbg_io("frame_%02d output YUV(%d*%d) saving to %s\n",
1011                          JpegHalCtx->output_yuv_count,
1012                          width, height, name);
1013 
1014             fclose(jpg_file);
1015             JpegHalCtx->output_yuv_count++;
1016         }
1017     }
1018 
1019     memset(&reg_out->reg1_interrupt, 0, sizeof(RK_U32));
1020 
1021     jpegd_dbg_func("exit\n");
1022     return ret;
1023 }
1024 
hal_jpegd_vdpu1_reset(void * hal)1025 MPP_RET hal_jpegd_vdpu1_reset(void *hal)
1026 {
1027     jpegd_dbg_func("enter\n");
1028     MPP_RET ret = MPP_OK;
1029     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
1030     (void)JpegHalCtx;
1031 
1032     return ret;
1033 }
1034 
hal_jpegd_vdpu1_flush(void * hal)1035 MPP_RET hal_jpegd_vdpu1_flush(void *hal)
1036 {
1037     jpegd_dbg_func("enter\n");
1038     MPP_RET ret = MPP_OK;
1039 
1040     (void)hal;
1041     return ret;
1042 }
1043 
hal_jpegd_vdpu1_control(void * hal,MpiCmd cmd_type,void * param)1044 MPP_RET hal_jpegd_vdpu1_control(void *hal, MpiCmd cmd_type, void *param)
1045 {
1046     jpegd_dbg_func("enter\n");
1047     MPP_RET ret = MPP_OK;
1048     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
1049     if (NULL == JpegHalCtx) {
1050         mpp_err_f("NULL pointer");
1051         return MPP_ERR_NULL_PTR;
1052     }
1053 
1054     switch (cmd_type) {
1055     case MPP_DEC_SET_OUTPUT_FORMAT: {
1056         JpegHalCtx->output_fmt = *((MppFrameFormat *)param);
1057         JpegHalCtx->set_output_fmt_flag = 1;
1058         jpegd_dbg_hal("output_format:%d\n", JpegHalCtx->output_fmt);
1059 
1060         if (!MPP_FRAME_FMT_IS_YUV(JpegHalCtx->output_fmt) && !MPP_FRAME_FMT_IS_RGB(JpegHalCtx->output_fmt)) {
1061             mpp_err_f("output format %d is invalid.\n", JpegHalCtx->output_fmt);
1062             ret = MPP_ERR_VALUE;
1063         }
1064     } break;
1065     default :
1066         break;
1067     }
1068     jpegd_dbg_func("exit ret %d\n", ret);
1069     return  ret;
1070 }
1071