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