• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute  it and/or modify it
5  * under  the terms of  the GNU General  Public License as published by the
6  * Free Software Foundation;  either version 2 of the  License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Description: jpegd main file.
18  */
19 #include "jpegd_image.h"
20 #include "jpegd_drv.h"
21 #include "jpegd_entry.h"
22 
23 static const unsigned char g_zigzag_for_qtable[ZIGZAG_TABLE_SIZE] = {
24     0,  1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,
25     12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,
26     35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
27     58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
28 };
29 
30 motion_jpeg_obj g_jpegd_ctx;
31 
jpegd_dec_baseline(motion_jpeg_obj * jpegd_hdl_ctx,unsigned char ** str,unsigned int * flag,unsigned int * idx,unsigned int len)32 int jpegd_dec_baseline(motion_jpeg_obj *jpegd_hdl_ctx, unsigned char **str, unsigned int *flag,
33     unsigned int *idx, unsigned int len)
34 {
35     unsigned char *stream = *str;
36     int result = HI_SUCCESS;
37     if (*flag == 1) {
38         int tmp_len = (stream[0] << 8) + stream[1]; /* shift left 8 bits */
39         tmp_len = MIN(tmp_len, len - *idx);
40         jpegd_hdl_ctx->stream_buffer = stream;
41         *idx += (tmp_len + 2); /* 2 number of bytes */
42         stream += (tmp_len);
43         result = decode_sof0(jpegd_hdl_ctx, jpegd_hdl_ctx->stream_buffer);
44         if (result == HI_JPEG_DEC_OK) {
45             *flag = 2; /* 2 decode sof0 success */
46         }
47     }
48     *str = stream;
49     return result;
50 }
51 
jpegd_dec_dht(motion_jpeg_obj * jpegd_hdl_ctx,unsigned char ** str,unsigned int len,unsigned int * idx)52 int jpegd_dec_dht(motion_jpeg_obj *jpegd_hdl_ctx, unsigned char **str, unsigned int len, unsigned int *idx)
53 {
54     unsigned char *stream = *str;
55     unsigned int tmp_len = (stream[0] << 8) + stream[1]; /* shift left 8 bits */
56     tmp_len = MIN(tmp_len, len - *idx);
57     jpegd_hdl_ctx->stream_buffer = stream;
58     *idx += (tmp_len + 2); /* 2 number of bytes */
59     stream += (tmp_len);
60 
61     if (decode_dht(jpegd_hdl_ctx, jpegd_hdl_ctx->stream_buffer)) {
62         return HI_FAILURE;
63     }
64     *str = stream;
65     return HI_SUCCESS;
66 }
67 
jpegd_dec_sos(motion_jpeg_obj * jpegd_hdl_ctx,unsigned char ** str,unsigned int * flag,unsigned int * idx,unsigned int len)68 int jpegd_dec_sos(motion_jpeg_obj *jpegd_hdl_ctx, unsigned char **str, unsigned int *flag, unsigned int *idx,
69     unsigned int len)
70 {
71     unsigned char *stream = *str;
72     int result = HI_SUCCESS;
73     if (*flag == 2) { /* 2 decode sof0 success */
74         int tmp_len = (stream[0] << 8) + stream[1]; /* shift left 8 bits */
75         tmp_len = MIN(tmp_len, len - *idx);
76         jpegd_hdl_ctx->stream_buffer = stream;
77         *idx += (tmp_len);
78         stream += (tmp_len);
79         jpegd_hdl_ctx->first_mcu = 0;
80         result = decode_sos(jpegd_hdl_ctx, jpegd_hdl_ctx->stream_buffer);
81         if (result == HI_JPEG_DEC_OK) {
82             *flag = 3;  /* 3 scan header decoding success */
83         } else {
84             return HI_FAILURE;
85         }
86     }
87     *str = stream;
88     return HI_SUCCESS;
89 }
90 
jpegd_dec_dqt(motion_jpeg_obj * jpegd_hdl_ctx,unsigned char ** str,unsigned int * idx,unsigned int len)91 int jpegd_dec_dqt(motion_jpeg_obj *jpegd_hdl_ctx, unsigned char **str, unsigned int *idx, unsigned int len)
92 {
93     unsigned char *stream = *str;
94     int tmp_len = (stream[0] << 8) + stream[1]; /* shift left 8 bits */
95     tmp_len = MIN(tmp_len, len - *idx);
96     jpegd_hdl_ctx->stream_buffer = stream;
97     *idx += (tmp_len + 2); /* 2 DQT number of bytes */
98     stream += (tmp_len);
99 
100     if (decode_dqt(jpegd_hdl_ctx, jpegd_hdl_ctx->stream_buffer)) {
101         return HI_FAILURE;
102     }
103     *str = stream;
104     return HI_SUCCESS;
105 }
106 
jpegd_dec_dri(motion_jpeg_obj * jpegd_hdl_ctx,unsigned char ** str,unsigned int * flag,unsigned int * idx)107 int jpegd_dec_dri(motion_jpeg_obj *jpegd_hdl_ctx, unsigned char **str, unsigned int *flag, unsigned int *idx)
108 {
109     unsigned char *stream = *str;
110     jpegd_hdl_ctx->stream_buffer = stream;
111     if (decode_dri(jpegd_hdl_ctx, jpegd_hdl_ctx->stream_buffer)) { /* 4 dri len */
112         *flag = 0;
113         return HI_FAILURE;
114     }
115     *idx += 6; /* 6 define restart interval */
116     stream += 4; /* 4 define restart interval */
117     *str = stream;
118     return HI_SUCCESS;
119 }
120 
jpegd_dec_err(unsigned char ** str,unsigned int * idx,unsigned int type,unsigned int * flag)121 int jpegd_dec_err(unsigned char **str, unsigned int *idx, unsigned int type, unsigned int *flag)
122 {
123     unsigned char *stream = *str;
124     int result = HI_SUCCESS;
125     if ((type & 0xE0) == 0xE0) { /* 0xE0:APP_0 value */
126         int tmp_len = (stream[0] << 8) + stream[1]; /* shift left 8 bits */
127         *idx += (tmp_len + 2); /* 2 number of bytes */
128         stream += (tmp_len);
129     } else if ((type & 0xF0) == 0xC0) { /* 0xF0:JPG_0 0xC0:baseline */
130         *flag = 0;
131         result = HI_FAILURE;
132     } else {
133         *idx += 2; /* 2 number of bytes */
134     }
135     *str = stream;
136     return result;
137 }
138 
jpegd_dec_sos_success(motion_jpeg_obj * jpegd_hdl_ctx,mjpeg_dec_frame * tmp_dec_frame,bool quant_table_valid,bool huffman_table_valid,unsigned int idx)139 void jpegd_dec_sos_success(motion_jpeg_obj *jpegd_hdl_ctx, mjpeg_dec_frame *tmp_dec_frame,
140     bool quant_table_valid, bool huffman_table_valid, unsigned int idx)
141 {
142     jpegd_hdl_ctx->stream_offest = idx + 2; /* 2 number of bytes */
143     tmp_dec_frame->width = jpegd_hdl_ctx->frame.y_width;
144     tmp_dec_frame->height = jpegd_hdl_ctx->frame.y_height;
145     tmp_dec_frame->y_stride = jpegd_hdl_ctx->y_stride;
146     tmp_dec_frame->c_stride = jpegd_hdl_ctx->c_stride;
147     tmp_dec_frame->pic_format = jpegd_hdl_ctx->pic_format;
148     tmp_dec_frame->pts = jpegd_hdl_ctx->stream.pts;
149     tmp_dec_frame->reserved = 0;
150     tmp_dec_frame->user_data = NULL;
151     jpegd_hdl_ctx->valid_frame ^= 0x1;  /*  0x1:change to another buffer */
152 
153     if (quant_table_valid == HI_FALSE) {
154         init_default_quant_table(jpegd_hdl_ctx);
155     }
156     if (huffman_table_valid == HI_FALSE) {
157         init_default_huffman_table(jpegd_hdl_ctx);
158     }
159     return;
160 }
161 
jpegd_dec_sos_failed(mjpeg_dec_frame * tmp_dec_frame)162 void jpegd_dec_sos_failed(mjpeg_dec_frame *tmp_dec_frame)
163 {
164     tmp_dec_frame->y = NULL;
165     tmp_dec_frame->u = NULL;
166     tmp_dec_frame->v = NULL;
167     tmp_dec_frame->width = 0;
168     tmp_dec_frame->height = 0;
169     tmp_dec_frame->y_stride = 0;
170     tmp_dec_frame->c_stride = 0;
171     tmp_dec_frame->pic_format = PICTURE_FORMAT_BUTT;
172     tmp_dec_frame->pts = 0;
173     tmp_dec_frame->reserved = 0;
174     tmp_dec_frame->user_data = NULL;
175     return;
176 }
177 
178 /* decode jpeg picture */
jpegd_dec_frame(jpegd_handle handle,unsigned int flags)179 int jpegd_dec_frame(jpegd_handle handle, unsigned int flags)
180 {
181     motion_jpeg_obj *jpegd_hdl_ctx = (motion_jpeg_obj *)handle;
182     unsigned int i;
183     unsigned int jpeg_flag = 0;
184     int result = 0;
185     unsigned int type;
186     unsigned char *stream = NULL;
187     unsigned int len;
188     mjpeg_dec_frame *tmp_dec_frame = NULL;
189     mjpeg_dec_frame dec_frame;
190     hi_bool quant_table_valid = HI_FALSE;
191     hi_bool huffman_table_valid = HI_FALSE;
192 
193     if (jpegd_hdl_ctx == NULL) {
194         hi_trace("jpegd handle is null!\n");
195         return HI_MJPEG_ERR_HANDLE;
196     }
197 
198     stream = jpegd_hdl_ctx->stream.vir_addr;
199     len = jpegd_hdl_ctx->stream.len;
200     tmp_dec_frame = &dec_frame;
201 
202     if (stream == NULL) {
203         hi_trace("jpegd stream vir_addr is null!\n");
204         return HI_MJPEG_ERR_HANDLE;
205     }
206     tmp_dec_frame->error_code = 0;
207     tmp_dec_frame->error = 0;
208     jpegd_hdl_ctx->frame.restart_interval = 0;
209 
210     for (i = 0; i < len;) {
211         type = 0xFF; /* 0xFF:jpeg maker */
212         while ((i < len) && (*(stream++) != 0xff)) { /* 0xFF:jpeg maker */
213             i++;
214         }
215         type = *(stream++);
216         while ((i < len) && (type == 0xff)) { /* 0xFF:jpeg maker */
217             type = *(stream++);
218             i++;
219         }
220         switch (type) {
221             case BASELINE: {  /* sequential DCT */
222                 result = jpegd_dec_baseline(jpegd_hdl_ctx, &stream, &jpeg_flag, &i, len);
223                 if (result != HI_SUCCESS) {
224                     tmp_dec_frame->error_code = result;
225                     hi_trace("jpeg decode DCT error!\n");
226                     goto end;
227                 }
228             }
229             break;
230 
231             case DHT: {  /* DHT */
232                 result = jpegd_dec_dht(jpegd_hdl_ctx, &stream, len, &i);
233                 if (result != HI_SUCCESS) {
234                     tmp_dec_frame->error_code += HI_ERR_HUFFMAN_TABLE;
235                     hi_trace("jpeg decode huffman error!\n");
236                     goto end;
237                 }
238                 huffman_table_valid = HI_TRUE;
239             }
240             break;
241 
242             case SOS: {  /* scan header */
243                 result = jpegd_dec_sos(jpegd_hdl_ctx, &stream, &jpeg_flag, &i, len);
244                 if (result != HI_SUCCESS) {
245                     hi_trace("jpeg decode SOS error!\n");
246                     goto end;  /* scan header decoding error */
247                 }
248                 goto end;
249             }
250             break;
251 
252             case SOI: {  /* a new jpeg picture */
253                 i += 2; /* 2 SOI number of bytes */
254                 jpeg_flag = 1;
255             }
256             break;
257 
258             case EOI: {  /* end of jpeg picture */
259                 i += 2; /* 2 EOI number of bytes */
260                 goto end;
261             }
262 
263             case DQT: {
264                 result = jpegd_dec_dqt(jpegd_hdl_ctx, &stream, &i, len);
265                 if (result != HI_SUCCESS) {
266                     tmp_dec_frame->error_code += HI_ERR_HUFFMAN_TABLE;
267                     hi_trace("jpeg decode DQT error!\n");
268                     goto end;
269                 }
270                 quant_table_valid = HI_TRUE;
271             }
272             break;
273 
274             case DNL: {
275                 i += 6; /* 6 define number of lines */
276                 stream += 4; /* 4 number of lines' size */
277                 jpeg_flag = 0;
278             }
279             break;
280 
281             case DRI: {
282                 result = jpegd_dec_dri(jpegd_hdl_ctx, &stream, &jpeg_flag, &i);
283                 if (result != HI_SUCCESS) {
284                     tmp_dec_frame->error_code = HI_ERR_RESTART_ERROR;
285                     hi_trace("jpeg decode DRI error!\n");
286                     goto end;
287                 }
288             }
289             break;
290 
291             default: {  /* do not support */
292                 result = jpegd_dec_err(&stream, &i, type, &jpeg_flag);
293                 if (result != HI_SUCCESS) {
294                     tmp_dec_frame->error_code = HI_ERR_NOT_BASELINE;
295                     hi_trace("jpeg decode error, unsupport type!\n");
296                     goto end;
297                 }
298             }
299             break;
300         }
301     }
302 
303 end:
304     if (jpeg_flag == 3) { /* 3 scan header decoding success */
305         jpegd_dec_sos_success(jpegd_hdl_ctx, tmp_dec_frame, quant_table_valid, huffman_table_valid, i);
306         return HI_MJPEG_DEC_OK;
307     } else {
308         jpegd_dec_sos_failed(tmp_dec_frame);
309         return HI_MJPEG_NO_PICTURE;
310     }
311 }
312 
313 /* create a JPEG decoder handle */
jpegd_get_handle(void)314 jpegd_handle jpegd_get_handle(void)
315 {
316     motion_jpeg_obj *mjpeg = &g_jpegd_ctx;
317     int pic_size;
318 
319     mjpeg->max_width = JPEGD_MAX_WIDTH;
320     mjpeg->max_height = JPEGD_MAX_HEIGHT;
321 
322     pic_size = mjpeg->max_width * mjpeg->max_height;
323     mjpeg->buf_size = pic_size + 0x10000; /* 0x10000:extra mem */
324     mjpeg->stream_buffer = NULL;
325     mjpeg->pic_buffer = NULL;
326     mjpeg->valid_frame = 0;
327     mjpeg->width_in_mcu = 1;
328     mjpeg->height_in_mcu = 0;
329     mjpeg->y_stride = 0;
330     mjpeg->c_stride = 0;
331     mjpeg->pic_format = PICTURE_FORMAT_BUTT;
332     mjpeg->first_mcu = 0;
333     mjpeg->bits.bit_len = 0;
334     mjpeg->bits.bit_offset = 0;
335     mjpeg->bits.buffer = NULL;
336     mjpeg->frame.nf = 0;
337     mjpeg->frame.y_height = 0;
338     mjpeg->frame.y_width = 0;
339     mjpeg->frame.restart_interval = 0;
340     mjpeg->frame.restart_interval_logic = 0;
341     mjpeg->frame.max_mcu_number = 0;
342 
343     init_default_huffman_table(mjpeg);
344     init_default_quant_table(mjpeg);
345 
346     mjpeg->state = STATE_IDLE;
347 
348     return (jpegd_handle)mjpeg;
349 }
350 
jpegd_config_huffman_dc(motion_jpeg_obj * jpeg_hdl_ctx,unsigned int * huffman_table,unsigned int cs)351 void jpegd_config_huffman_dc(motion_jpeg_obj *jpeg_hdl_ctx, unsigned int *huffman_table, unsigned int cs)
352 {
353     huffman_tab *huf_tab = &jpeg_hdl_ctx->h_tab[cs];
354     unsigned int i, num, j, index;
355     for (index = 0, i = 0; i < JPEGD_CODE_LEN; i++) {
356         num = huf_tab->len[i];
357         for (j = 0; (j < num) && (index < 12); j++, index++) { /* 12 max index */
358             int pos = huf_tab->huffman_val[index];
359             if (cs == 1) {
360                 huffman_table[pos] |= ((i + 1) << 20) + /* shift left 20 bits 0xFF000:overflow protection */
361                 (((j + (unsigned int)huf_tab->min_code[i]) << 12) & 0xFF000); /* shift left 12 bits */
362             } else {
363                 huffman_table[pos] |=
364                 ((i + 1) << 8) + ((j + (unsigned int)huf_tab->min_code[i]) & 0xFF); /* shift left 8 bits */
365             }
366         }
367     }
368     return;
369 }
370 
jpegd_config_huffman_ac(motion_jpeg_obj * jpeg_hdl_ctx,unsigned char * ac_min_table,unsigned char * ac_base_table,unsigned int idx)371 void jpegd_config_huffman_ac(motion_jpeg_obj *jpeg_hdl_ctx, unsigned char *ac_min_table,
372     unsigned char *ac_base_table, unsigned int idx)
373 {
374     huffman_tab *huf_tab = &jpeg_hdl_ctx->h_tab[idx];
375     int i;
376 
377     for (i = 0; i < JPEGD_CODE_LEN; i++) {
378         unsigned int base_code = 0;
379 
380         if (huf_tab->len[i]) {
381             base_code = huf_tab->huffman_val_ptr[i] - huf_tab->min_code[i];
382         }
383 
384         ac_min_table[i] = ((unsigned int)huf_tab->min_code[i]) & 0xFF; /* 0xFF:get low 8 bits */
385         ac_base_table[i] = base_code & 0xFF; /* 0xFF:get low 8 bits */
386     }
387     return;
388 }
389 
jpegd_config_huffman_table(motion_jpeg_obj * jpeg_hdl_ctx)390 void jpegd_config_huffman_table(motion_jpeg_obj *jpeg_hdl_ctx)
391 {
392     unsigned int i;
393     unsigned int huffman_table[HDC_TABLE_SIZE] = {0};
394     unsigned char luma_ac_min_table[JPEGD_CODE_LEN]    = {0};
395     unsigned char luma_ac_base_table[JPEGD_CODE_LEN]   = {0};
396     unsigned char chroma_ac_min_table[JPEGD_CODE_LEN]  = {0};
397     unsigned char chroma_ac_base_table[JPEGD_CODE_LEN] = {0};
398 
399     /* config huffman dc */
400     jpegd_config_huffman_dc(jpeg_hdl_ctx, huffman_table, 1);
401     jpegd_config_huffman_dc(jpeg_hdl_ctx, huffman_table, 0);
402 
403     /* config huffman ac */
404     jpegd_config_huffman_ac(jpeg_hdl_ctx, luma_ac_min_table, luma_ac_base_table, 2); /* 2:table index */
405     jpegd_config_huffman_ac(jpeg_hdl_ctx, chroma_ac_min_table, chroma_ac_base_table, 3); /* 3:table index */
406 
407     /* config huffman table */
408     for (i = 0; i < HDC_TABLE_SIZE; i++) {
409         jpeg_hdl_ctx->vpu_config.huffman_table[i] = huffman_table[i];
410     }
411 
412     /* config huffman_min_table table */
413     for (i = 0; i < HAC_MIN_TABLE_SIZE; i++) {
414         jpeg_hdl_ctx->vpu_config.huffman_min_table[i] =
415             (chroma_ac_min_table[2 * i + 1] << 24) + /* 2 config chroma ac table shift left 24 bits */
416             (chroma_ac_min_table[2 * i] << 16) + /* 2 config chroma ac table shift left 16 bits */
417             (luma_ac_min_table[2 * i + 1] << 8) + /* 2 config luma ac table shift left 8 bits */
418             (luma_ac_min_table[2 * i]); /* 2 config luma ac min table */
419     }
420 
421     /* config huffman_base_table table */
422     for (i = 0; i < HAC_BASE_TABLE_SIZE; i++) {
423         jpeg_hdl_ctx->vpu_config.huffman_base_table[i] =
424             (chroma_ac_base_table[2 * i + 1] << 24) + /* 2 config chroma ac base table shift left 24 bits */
425             (chroma_ac_base_table[2 * i] << 16) + /* 2 config chroma ac base table shift left 16 bits */
426             (luma_ac_base_table[2 * i + 1] << 8) + /* 2 config luma ac base table shift left 8 bits */
427             (luma_ac_base_table[2 * i]); /* 2 config luma ac base table */
428     }
429 
430     /* config huffman_symbol_table table */
431     for (i = 0; i < HAC_SYMBOL_TABLE_SIZE; i++) {
432         jpeg_hdl_ctx->vpu_config.huffman_symbol_table[i] =
433             (jpeg_hdl_ctx->h_tab[3].huffman_val[i] << 8) + /* table 3 shift left 8 bits */
434             jpeg_hdl_ctx->h_tab[2].huffman_val[i]; /* plus table 2 */
435     }
436     return;
437 }
438 
jpegd_config_quant_table(motion_jpeg_obj * jpeg_hdl_ctx)439 void jpegd_config_quant_table(motion_jpeg_obj *jpeg_hdl_ctx)
440 {
441     unsigned int i;
442     unsigned int q_tab_y_index = jpeg_hdl_ctx->frame.tq[COM0] & 3; /* 3 overflow protection */
443     unsigned int q_tab_u_index = jpeg_hdl_ctx->frame.tq[COM1] & 3; /* 3 overflow protection */
444     unsigned int q_tab_v_index = jpeg_hdl_ctx->frame.tq[COM2] & 3; /* 3 overflow protection */
445 
446     unsigned char *q_cr = (unsigned char *)&jpeg_hdl_ctx->q_tab[q_tab_v_index];
447     unsigned char *q_cb = (unsigned char *)&jpeg_hdl_ctx->q_tab[q_tab_u_index];
448     unsigned char *q_y = (unsigned char *)&jpeg_hdl_ctx->q_tab[q_tab_y_index];
449     int pos;
450 
451     for (i = 0; i < QUANT_TABLE_SIZE; i++) {
452         pos = g_zigzag_for_qtable[i & 0x3f]; /* 0x3f:get low 6bits */
453         jpeg_hdl_ctx->vpu_config.quant_table[pos] =
454             q_y[i] + (q_cb[i] << 8) + (q_cr[i] << 16); /* shift left 8 bits shift left 16 bits */
455     }
456 
457     return;
458 }
459 
jpegd_config_rgb_info(motion_jpeg_obj * jpeg_hdl_ctx)460 void jpegd_config_rgb_info(motion_jpeg_obj *jpeg_hdl_ctx)
461 {
462     if (jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
463         jpeg_hdl_ctx->vpu_config.out_yuv = HI_TRUE;
464     } else {
465         jpeg_hdl_ctx->vpu_config.out_yuv = HI_FALSE;
466         if ((jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_ARGB_8888) ||
467             (jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_ABGR_8888)) {
468             jpeg_hdl_ctx->vpu_config.rgb_stride = align_up(jpeg_hdl_ctx->frame.y_width * 4, 16); /* 4,16 align up */
469         } else if ((jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_ARGB_1555) ||
470                    (jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_ABGR_1555)) {
471             jpeg_hdl_ctx->vpu_config.rgb_stride = align_up(jpeg_hdl_ctx->frame.y_width * 2, 16); /* 2,16 align up */
472         } else if ((jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_RGB_888) ||
473                    (jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_BGR_888)) {
474             jpeg_hdl_ctx->vpu_config.rgb_stride = align_up(jpeg_hdl_ctx->frame.y_width * 3, 16); /* 3,16 align up */
475         } else if ((jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_RGB_565) ||
476                    (jpeg_hdl_ctx->vpu_config.pixel_format == PIXEL_FORMAT_BGR_565)) {
477             jpeg_hdl_ctx->vpu_config.rgb_stride = align_up(jpeg_hdl_ctx->frame.y_width * 2, 16); /* 2,16 align up */
478         }
479     }
480     return;
481 }
482 
jpegd_prepare_pic_type(picture_format pic_format)483 unsigned int jpegd_prepare_pic_type(picture_format pic_format)
484 {
485     unsigned int pic_type = 0;
486     switch (pic_format) {
487         case PICTURE_FORMAT_YUV420:
488             pic_type = 3; /* 3: value of hardware regulation */
489             break;
490         case PICTURE_FORMAT_YUV422:
491             pic_type = 4; /* 4: value of hardware regulation */
492             break;
493         case PICTURE_FORMAT_YUV444:
494             pic_type = 6; /* 6: value of hardware regulation */
495             break;
496         case PICTURE_FORMAT_YUV422V:
497             pic_type = 5; /* 5: value of hardware regulation */
498             break;
499         case PICTURE_FORMAT_YUV400:
500             pic_type = 0; /* 0: value of hardware regulation */
501             break;
502         default:
503             printf("Unkonwn picture format %d!", pic_format);
504     }
505     return pic_type;
506 }
507 
508 /* Prepare the jpegd Hardware Info */
jpegd_prepare_hardware_info(motion_jpeg_obj * jpeg_hdl_ctx)509 int jpegd_prepare_hardware_info(motion_jpeg_obj *jpeg_hdl_ctx)
510 {
511     unsigned int ysize;
512 
513     ysize = align_up(jpeg_hdl_ctx->frame.y_width, 64) * /* 64 align up */
514         align_up(jpeg_hdl_ctx->frame.y_height, 16); /* 16 align up */
515     jpeg_hdl_ctx->vpu_config.width = jpeg_hdl_ctx->frame.y_width;
516     jpeg_hdl_ctx->vpu_config.height = jpeg_hdl_ctx->frame.y_height;
517     jpeg_hdl_ctx->vpu_config.width_in_mcu = jpeg_hdl_ctx->width_in_mcu;
518     jpeg_hdl_ctx->vpu_config.height_in_mcu = jpeg_hdl_ctx->height_in_mcu;
519     jpeg_hdl_ctx->vpu_config.c_phy_addr = jpeg_hdl_ctx->vpu_config.y_phy_addr + ysize;
520     jpeg_hdl_ctx->vpu_config.y_stride = align_up(jpeg_hdl_ctx->frame.y_width, 64); /* 64 align up */
521     jpeg_hdl_ctx->vpu_config.c_stride = align_up(jpeg_hdl_ctx->frame.y_width, 64); /* 64 align up */
522     jpeg_hdl_ctx->vpu_config.phy_str_start = jpeg_hdl_ctx->vpu_config.phy_str_start + jpeg_hdl_ctx->stream_offest;
523     jpeg_hdl_ctx->vpu_config.y_fac = jpeg_hdl_ctx->frame.h[0];
524     jpeg_hdl_ctx->vpu_config.u_fac = jpeg_hdl_ctx->frame.h[1];
525     jpeg_hdl_ctx->vpu_config.v_fac = jpeg_hdl_ctx->frame.h[2]; /* 2 array index */
526     jpeg_hdl_ctx->vpu_config.dri = jpeg_hdl_ctx->frame.restart_interval_logic;
527     jpeg_hdl_ctx->vpu_config.pic_format = jpeg_hdl_ctx->pic_format;
528     jpeg_hdl_ctx->vpu_config.pic_type = jpegd_prepare_pic_type(jpeg_hdl_ctx->vpu_config.pic_format);
529 
530     /* config RGB info */
531     jpegd_config_rgb_info(jpeg_hdl_ctx);
532 
533     /* config quant table */
534     jpegd_config_quant_table(jpeg_hdl_ctx);
535 
536     /* config huffman table */
537     jpegd_config_huffman_table(jpeg_hdl_ctx);
538 
539     return HI_SUCCESS;
540 }
541 
jpegd_start_one_frame(jpegd_handle handle,unsigned int flags)542 int jpegd_start_one_frame(jpegd_handle handle, unsigned int flags)
543 {
544     int ret;
545     motion_jpeg_obj *jpegd_hdl_ctx = (motion_jpeg_obj *)handle;
546 
547     ret = jpegd_dec_frame(handle, flags);
548     if (ret != HI_SUCCESS) {
549         hi_trace("vdec_start_one_frame: decode stream fail for 0x%x\n", ret);
550         return ret;
551     }
552 
553     ret = jpegd_prepare_hardware_info(jpegd_hdl_ctx);
554     if (ret != HI_SUCCESS) {
555         hi_trace("vdec_start_one_frame: decode stream fail for 0x%x\n", ret);
556         return ret;
557     }
558 
559     return HI_SUCCESS;
560 }
561 
562 /* write the jpegd register */
jpegd_write_regs(jpegd_handle handle,S_JPGD_REGS_TYPE * reg_base)563 void jpegd_write_regs(jpegd_handle handle, S_JPGD_REGS_TYPE *reg_base)
564 {
565     motion_jpeg_obj *jpeg_hdl_ctx = (motion_jpeg_obj *)handle;
566 
567     jpegd_drv_write_regs(reg_base, &jpeg_hdl_ctx->vpu_config);
568     return;
569 }
570 
571 /* read the jpegd register */
jpegd_read_regs(jpegd_handle handle,S_JPGD_REGS_TYPE * reg_base)572 void jpegd_read_regs(jpegd_handle handle, S_JPGD_REGS_TYPE *reg_base)
573 {
574     motion_jpeg_obj *jpeg_hdl_ctx = (motion_jpeg_obj *)handle;
575 
576     jpegd_drv_read_regs(reg_base, &jpeg_hdl_ctx->vpu_status);
577     return;
578 }
579 
jpegd_start_decoding(jpegd_handle handle)580 int jpegd_start_decoding(jpegd_handle handle)
581 {
582     motion_jpeg_obj *jpegd_hld_ctx = NULL;
583     int ret;
584 
585     jpegd_hld_ctx = (motion_jpeg_obj *)handle;
586     jpegd_hld_ctx->vpu_config.y_phy_addr = get_video_data_base();
587     jpegd_hld_ctx->vpu_config.phy_str_buf_start = get_hilogo();
588     jpegd_hld_ctx->vpu_config.phy_str_buf_end = get_hilogo() + align_up(get_jpeg_size_val(), 128); /* 128 align up */
589     jpegd_hld_ctx->vpu_config.phy_str_start = get_hilogo();
590     jpegd_hld_ctx->vpu_config.phy_str_end = get_hilogo() + get_jpeg_size_val();
591     jpegd_hld_ctx->vpu_config.phy_emar_buffer0 = get_jpegd_emar_buf();
592     jpegd_hld_ctx->vpu_config.phy_emar_buffer1 = get_jpegd_emar_buf() + ONE_EMAR_BUF_SIZE;
593     jpegd_hld_ctx->stream.vir_addr = (unsigned char *)(uintptr_t)get_hilogo();
594     jpegd_hld_ctx->stream.len = get_jpeg_size_val();
595     jpegd_hld_ctx->stream.phy_addr = get_hilogo();
596     jpegd_hld_ctx->stream.pts = 0;
597     jpegd_hld_ctx->vpu_config.chn_id = 0;
598     jpegd_hld_ctx->vpu_config.alpha = 255; /* 255 transparency */
599 
600     if (get_output_format() == 0) {
601         jpegd_hld_ctx->vpu_config.pixel_format = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
602     } else if (get_output_format() == 1) {
603         jpegd_hld_ctx->vpu_config.pixel_format = PIXEL_FORMAT_ARGB_1555;
604     } else if (get_output_format() == 2) { /* 2 output format */
605         jpegd_hld_ctx->vpu_config.pixel_format = PIXEL_FORMAT_ARGB_8888;
606     } else {
607         jpegd_hld_ctx->vpu_config.pixel_format = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
608     }
609 
610     ret = jpegd_start_one_frame(handle, 0);
611     if (ret != HI_SUCCESS) {
612         hi_trace("jpegd_start_decoding: decode stream fail for 0x%x\n", ret);
613         return ret;
614     }
615 
616     jpegd_set_clock_en(0, HI_TRUE);
617     jpegd_reset(0);
618     jpegd_set_time_out(0, 0xFFFFFFFF); /* 0xFFFFFFFF:time out value */
619 
620     jpegd_write_regs(handle, (S_JPGD_REGS_TYPE *)JPEGD_REGS_ADDR);
621 
622     jpegd_start_vpu(0);
623 
624     return HI_SUCCESS;
625 }
626 
jpegd_finish_decoding(jpegd_handle handle)627 void jpegd_finish_decoding(jpegd_handle handle)
628 {
629     unsigned int int_statue;
630     unsigned int cnt = 0;
631     motion_jpeg_obj *jpegd_hld_ctx = (motion_jpeg_obj *)handle;
632 
633     while (1) {
634         udelay(10); /* 10 delay time */
635         int_statue = jpegd_read_int(0);
636         if (int_statue & 0x1f) {
637             break;
638         }
639         if (cnt++ > 2000) { /* 2000:Maximum decoding time */
640             hi_trace("jpeg decode over time\n");
641             break;
642         }
643     }
644 
645     jpegd_read_regs(handle, (S_JPGD_REGS_TYPE *)JPEGD_REGS_ADDR);
646     if (jpegd_hld_ctx->vpu_status.int_dec_finish == 0) {
647         printf("hardware decoding error!\n");
648     } else {
649         if (jpegd_hld_ctx->vpu_config.out_yuv != HI_TRUE) {
650             printf("hardware decoding success! %ux%u, stride %u.\n",
651                    jpegd_hld_ctx->frame.y_width, jpegd_hld_ctx->frame.y_height, jpegd_hld_ctx->vpu_config.rgb_stride);
652         } else {
653             printf("hardware decoding success! %ux%u, stride %u.\n",
654                    jpegd_hld_ctx->frame.y_width, jpegd_hld_ctx->frame.y_height, jpegd_hld_ctx->vpu_config.y_stride);
655         }
656     }
657 
658     jpegd_clear_int(0);
659     jpegd_reset_select(0, HI_TRUE);
660 
661     return;
662 }
663 
664