1 /*
2 *
3 * Copyright 2015 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
18 #define MODULE_TAG "jpegd_parser"
19
20 #include <string.h>
21
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_soc.h"
25 #include "mpp_debug.h"
26 #include "mpp_bitread.h"
27 #include "mpp_packet_impl.h"
28
29 #include "jpegd_api.h"
30 #include "jpegd_parser.h"
31
32 RK_U32 jpegd_debug = 0x0;
33
34 /* return the 8 bit start code value and update the search
35 state. Return 0 if no start code found */
jpegd_find_marker(const RK_U8 ** pbuf_ptr,const RK_U8 * buf_end)36 static RK_U8 jpegd_find_marker(const RK_U8 **pbuf_ptr, const RK_U8 *buf_end)
37 {
38 const RK_U8 *buf_ptr = NULL;
39 RK_U8 val = 0;
40 RK_U8 start_code = 0xff;
41 RK_U32 buf_size = buf_end - *pbuf_ptr + 1;
42
43 while (*pbuf_ptr < buf_end) {
44 buf_ptr = memchr(*pbuf_ptr, start_code, buf_size);
45
46 if (!buf_ptr) {
47 mpp_err("Start codec not found!\n");
48 return 0;
49 }
50
51 RK_U8 marker = *(buf_ptr + 1);
52 if (marker >= 0xc0 && marker <= 0xfe) {
53 val = *(buf_ptr + 1);
54 jpegd_dbg_marker("find_marker skipped %d bytes\n", buf_ptr - *pbuf_ptr);
55 *pbuf_ptr = buf_ptr;
56 return val;
57 } else {
58 jpegd_dbg_marker("0x%x is not a marker\n", marker);
59 (*pbuf_ptr)++;
60 }
61 }
62 return 0;
63 }
64
jpegd_find_eoi(const RK_U8 ** pbuf_ptr,const RK_U8 * buf_end)65 static MPP_RET jpegd_find_eoi(const RK_U8 **pbuf_ptr, const RK_U8 *buf_end)
66 {
67 const RK_U8 *buf_ptr = NULL;
68 RK_S32 eoi = 0xffd9;
69 RK_U32 buf_size = buf_end - *pbuf_ptr + 1;
70
71 buf_ptr = memchr(*pbuf_ptr, eoi, buf_size);
72
73 if (buf_ptr && (buf_end > buf_ptr)) {
74 return MPP_OK;
75 }
76
77 return MPP_NOK;
78 }
79
jpeg_judge_yuv_mode(JpegdCtx * ctx)80 static MPP_RET jpeg_judge_yuv_mode(JpegdCtx *ctx)
81 {
82 MPP_RET ret = MPP_OK;
83 JpegdSyntax *s = ctx->syntax;
84
85 /* check input format */
86 if (s->nb_components == 3) {
87 if (s->h_count[0] == 2 && s->v_count[0] == 2 &&
88 s->h_count[1] == 1 && s->v_count[1] == 1 &&
89 s->h_count[2] == 1 && s->v_count[2] == 1) {
90 jpegd_dbg_marker("YCbCr Format: YUV420(2*2:1*1:1*1)\n");
91 s->yuv_mode = JPEGDEC_YUV420;
92 s->output_fmt = MPP_FMT_YUV420SP;
93 } else if (s->h_count[0] == 2 && s->v_count[0] == 1 &&
94 s->h_count[1] == 1 && s->v_count[1] == 1 &&
95 s->h_count[2] == 1 && s->v_count[2] == 1) {
96 jpegd_dbg_marker("YCbCr Format: YUV422(2*1:1*1:1*1)\n");
97 s->yuv_mode = JPEGDEC_YUV422;
98 s->output_fmt = MPP_FMT_YUV422SP;
99
100 /* check if fill needed */
101 if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
102 s->fill_bottom = 1;
103 }
104 } else if (s->h_count[0] == 1 && s->v_count[0] == 2 &&
105 s->h_count[1] == 1 && s->v_count[1] == 1 &&
106 s->h_count[2] == 1 && s->v_count[2] == 1) {
107 jpegd_dbg_marker("YCbCr Format: YUV440(1*2:1*1:1*1)\n");
108 s->yuv_mode = JPEGDEC_YUV440;
109 s->output_fmt = MPP_FMT_YUV440SP;
110
111 /* check if fill needed */
112 if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
113 s->fill_right = 1;
114 }
115 } else if (s->h_count[0] == 1 && s->v_count[0] == 1 &&
116 s->h_count[1] == 1 && s->v_count[1] == 1 &&
117 s->h_count[2] == 1 && s->v_count[2] == 1) {
118 jpegd_dbg_marker("YCbCr Format: YUV444(1*1:1*1:1*1)\n");
119 s->yuv_mode = JPEGDEC_YUV444;
120 s->output_fmt = MPP_FMT_YUV444SP;
121
122 /* check if fill needed */
123 if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
124 s->fill_right = 1;
125 }
126
127 if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
128 s->fill_bottom = 1;
129 }
130 } else if (s->h_count[0] == 4 && s->v_count[0] == 1 &&
131 s->h_count[1] == 1 && s->v_count[1] == 1 &&
132 s->h_count[2] == 1 && s->v_count[2] == 1) {
133 jpegd_dbg_marker("YCbCr Format: YUV411(4*1:1*1:1*1)\n");
134 s->yuv_mode = JPEGDEC_YUV411;
135 s->output_fmt = MPP_FMT_YUV411SP;
136
137 /* check if fill needed */
138 if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
139 s->fill_bottom = 1;
140 }
141 } else {
142 mpp_err_f("Unsupported YCbCr Format: (%d*%d:%d*%d:%d*%d)\n",
143 s->h_count[0], s->v_count[0],
144 s->h_count[1], s->v_count[1],
145 s->h_count[2], s->v_count[2]);
146 ret = MPP_ERR_STREAM;
147 }
148 } else if (s->nb_components == 1) {
149 if (s->h_count[0] == s->v_count[0] && s->h_count[0] != 0) {
150 s->yuv_mode = JPEGDEC_YUV400;
151 s->output_fmt = MPP_FMT_YUV400;
152 if (s->output_fmt != ctx->output_fmt) {
153 mpp_err_f("unsupported upsampling(%d*%d)\n", s->output_fmt,
154 ctx->output_fmt);
155 ret = MPP_ERR_STREAM;
156 }
157 /* check if fill needed */
158 if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
159 s->fill_right = 1;
160 }
161
162 if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
163 s->fill_bottom = 1;
164 }
165 } else {
166 mpp_err_f("unsupported format(%d*%d)\n", s->h_count[0],
167 s->v_count[0]);
168 ret = MPP_ERR_STREAM;
169 }
170 } else {
171 mpp_err_f("unsupported format, nb_components=%d\n", s->nb_components);
172 ret = MPP_ERR_STREAM;
173 }
174
175 return ret;
176 }
177
jpegd_read_len(BitReadCtx_t * gb)178 static inline RK_U16 jpegd_read_len(BitReadCtx_t *gb)
179 {
180 RK_U8 lh, ll;
181 READ_BITS(gb, 8, &lh);
182 READ_BITS(gb, 8, &ll);
183 return (((RK_U16)lh) << 8) | ((RK_U16)ll);
184
185 __BITREAD_ERR:
186 return 0;
187 }
188
jpegd_skip_section(JpegdCtx * ctx)189 static MPP_RET jpegd_skip_section(JpegdCtx *ctx)
190 {
191 BitReadCtx_t *gb = ctx->bit_ctx;
192 RK_U16 len = 0;
193
194 if (gb->bytes_left_ < 2)
195 return MPP_ERR_READ_BIT;
196 len = jpegd_read_len(gb);
197 if (len < 2 /* invalid marker */ || (RK_U32)len - 2 > gb->bytes_left_) {
198 /* too short length or bytes is not enough */
199 return MPP_ERR_READ_BIT;
200 }
201 if (len > 2)
202 SKIP_BITS(gb, (len - 2) * 8);
203
204 return MPP_OK;
205
206 __BITREAD_ERR:
207 return MPP_NOK;
208 }
209
jpegd_decode_dht(JpegdCtx * ctx)210 static MPP_RET jpegd_decode_dht(JpegdCtx *ctx)
211 {
212 MPP_RET ret = MPP_NOK;
213 BitReadCtx_t *gb = ctx->bit_ctx;
214 JpegdSyntax *syntax = ctx->syntax;
215 RK_U32 len, num, value;
216 RK_U32 table_type, table_id;
217 RK_U32 i, code_max;
218
219 len = jpegd_read_len(gb);
220 len -= 2; /* Huffman Table Length */
221
222 if (len > gb->bytes_left_) {
223 mpp_err_f("dht: len %d is too large\n", len);
224 return MPP_ERR_STREAM;
225 }
226 jpegd_dbg_marker("dht: huffman tables length=%d\n", len);
227
228 while (len > 0) {
229 if (len < MAX_HUFFMAN_CODE_BIT_LENGTH + 1) {
230 mpp_err_f("dht: len %d is too small\n", len);
231 return MPP_ERR_STREAM;
232 }
233
234 READ_BITS(gb, 4, &table_type); /* 0 - DC; 1 - AC */
235 if (table_type >= HUFFMAN_TABLE_TYPE_BUTT) {
236 mpp_err_f("table type %d error\n", table_type);
237 return MPP_ERR_STREAM;
238 }
239
240 READ_BITS(gb, 4, &table_id);
241 if (table_id >= HUFFMAN_TABLE_ID_TWO) {
242 mpp_err_f("table id %d is unsupported for baseline\n", table_id);
243 return MPP_ERR_STREAM;
244 }
245
246 num = 0;
247 if (table_type == HUFFMAN_TABLE_TYPE_DC) {
248 DcTable *ptr = &(syntax->dc_table[table_id]);
249 for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
250 READ_BITS(gb, 8, &value);
251 ptr->bits[i] = value;
252 num += value;
253 }
254
255 ptr->actual_length = num;
256 } else {
257 AcTable *ptr = &(syntax->ac_table[table_id]);
258 for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
259 READ_BITS(gb, 8, &value);
260 ptr->bits[i] = value;
261 num += value;
262 }
263
264 ptr->actual_length = num;
265 }
266
267 len -= 17;
268 if (len < num ||
269 (num > MAX_DC_HUFFMAN_TABLE_LENGTH && table_type == HUFFMAN_TABLE_TYPE_DC) ||
270 (num > MAX_AC_HUFFMAN_TABLE_LENGTH && table_type == HUFFMAN_TABLE_TYPE_AC)) {
271 mpp_err_f("table type %d, code word number %d error\n", table_type, num);
272 return MPP_ERR_STREAM;
273 }
274
275 code_max = 0;
276 if (table_type == HUFFMAN_TABLE_TYPE_DC) {
277 DcTable *ptr = &(syntax->dc_table[table_id]);
278
279 syntax->htbl_entry |= 1 << (table_id * 2);
280
281 for (i = 0; i < num; i++) {
282 READ_BITS(gb, 8, &value);
283 ptr->vals[i] = value;
284 if (ptr->vals[i] > code_max)
285 code_max = ptr->vals[i];
286 }
287 } else {
288 AcTable *ptr = &(syntax->ac_table[table_id]);
289
290 syntax->htbl_entry |= 1 << ((table_id * 2) + 1);
291
292 for (i = 0; i < num; i++) {
293 READ_BITS(gb, 8, &value);
294 ptr->vals[i] = value;
295 if (ptr->vals[i] > code_max)
296 code_max = ptr->vals[i];
297 }
298 }
299 len -= num;
300
301 jpegd_dbg_marker("dht: type=%d id=%d code_word_num=%d, code_max=%d, len=%d\n",
302 table_type, table_id, num, code_max, len);
303 }
304 ret = MPP_OK;
305
306 __BITREAD_ERR:
307 if (ret != MPP_OK)
308 jpegd_dbg_syntax("bit read error!\n");
309
310 return ret;
311 }
312
313 /* quantize tables */
jpegd_decode_dqt(JpegdCtx * ctx)314 static MPP_RET jpegd_decode_dqt(JpegdCtx *ctx)
315 {
316 MPP_RET ret = MPP_NOK;
317 BitReadCtx_t *gb = ctx->bit_ctx;
318 JpegdSyntax *syntax = ctx->syntax;
319 RK_U32 len;
320 int index, i;
321 RK_U16 value;
322
323 len = jpegd_read_len(gb);
324 len -= 2; /* quantize tables length */
325
326 if (len > gb->bytes_left_) {
327 mpp_err_f("dqt: len %d is too large\n", len);
328 return MPP_ERR_STREAM;
329 }
330
331 while (len >= 65) {
332 RK_U16 pr;
333 READ_BITS(gb, 4, &pr);
334 if (pr > 1) {
335 mpp_err_f("dqt: invalid precision\n");
336 return MPP_ERR_STREAM;
337 }
338
339 READ_BITS(gb, 4, &index);
340 if (index >= QUANTIZE_TABLE_ID_BUTT) {
341 mpp_err_f("dqt: invalid quantize tables ID\n");
342 return MPP_ERR_STREAM;
343 }
344 jpegd_dbg_marker("quantize tables ID=%d\n", index);
345
346 /* read quant table */
347 for (i = 0; i < QUANTIZE_TABLE_LENGTH; i++) {
348 READ_BITS(gb, pr ? 16 : 8, &value);
349 syntax->quant_matrixes[index][i] = value;
350 }
351 syntax->qtbl_entry++;
352 if (syntax->qtbl_entry > MAX_COMPONENTS)
353 mpp_err_f("%d entries qtbl is not supported\n", syntax->qtbl_entry);
354
355 if (jpegd_debug & JPEGD_DBG_TABLE) {
356 /* debug code */
357 mpp_log("******Start to print quantize table %d******\n", index);
358
359 for (i = 0; i < QUANTIZE_TABLE_LENGTH; i += 8) {
360 mpp_log("%2d~%2d 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
361 i, i + 7,
362 syntax->quant_matrixes[index][i + 0],
363 syntax->quant_matrixes[index][i + 1],
364 syntax->quant_matrixes[index][i + 2],
365 syntax->quant_matrixes[index][i + 3],
366 syntax->quant_matrixes[index][i + 4],
367 syntax->quant_matrixes[index][i + 5],
368 syntax->quant_matrixes[index][i + 7],
369 syntax->quant_matrixes[index][i + 7]);
370 }
371 mpp_log("******Quantize table %d End******\n", index);
372 }
373
374 // XXX FIXME fine-tune, and perhaps add dc too
375 syntax->qscale[index] = MPP_MAX(syntax->quant_matrixes[index][1],
376 syntax->quant_matrixes[index][8]) >> 1;
377
378 jpegd_dbg_marker("qscale[%d]: %d\n", index, syntax->qscale[index]);
379 len -= 1 + 64 * (1 + pr);
380 }
381 ret = MPP_OK;
382
383 __BITREAD_ERR:
384 if (ret != MPP_OK)
385 jpegd_dbg_syntax("bit read error!\n");
386
387 return ret;
388 }
389
jpegd_decode_sof(JpegdCtx * ctx)390 static MPP_RET jpegd_decode_sof(JpegdCtx *ctx)
391 {
392 MPP_RET ret = MPP_NOK;
393 BitReadCtx_t *gb = ctx->bit_ctx;
394 JpegdSyntax *syntax = ctx->syntax;
395 RK_U32 len, bits, i;
396 RK_U32 width, height;
397 RK_U32 nb_components, value;
398
399 len = jpegd_read_len(gb);
400 if (len > gb->bytes_left_) {
401 mpp_err_f("len %d is too large\n", len);
402 return MPP_ERR_STREAM;
403 }
404
405 READ_BITS(gb, 8, &bits);
406 if (bits > 16 || bits < 1) {
407 /* usually bits is 8 */
408 mpp_err_f("bits %d is invalid\n", bits);
409 return MPP_ERR_STREAM;
410 }
411 syntax->sample_precision = bits;
412
413 READ_BITS(gb, 16, &height);
414 READ_BITS(gb, 16, &width);
415 syntax->height = height;
416 syntax->width = width;
417 syntax->hor_stride = MPP_ALIGN(width, 16);
418 syntax->ver_stride = MPP_ALIGN(height, 16);
419
420 jpegd_dbg_marker("sof0: picture: %dx%d, stride: %dx%d\n", width, height,
421 syntax->hor_stride, syntax->ver_stride);
422
423 READ_BITS(gb, 8 , &nb_components);
424 if ((nb_components != 1) && (nb_components != MAX_COMPONENTS)) {
425 mpp_err_f("components number %d error\n", nb_components);
426 return MPP_ERR_STREAM;
427 }
428
429 if (len != (8 + (3 * nb_components)))
430 mpp_err_f("decode_sof0: error, len(%d) mismatch nb_components(%d)\n",
431 len, nb_components);
432
433 syntax->nb_components = nb_components;
434 syntax->h_max = 1;
435 syntax->v_max = 1;
436 for (i = 0; i < nb_components; i++) {
437 /* component id */
438 READ_BITS(gb, 8 , &value);
439 syntax->component_id[i] = value - 1; /* start from zero */
440
441 READ_BITS(gb, 4, &value);
442 syntax->h_count[i] = value; /* Horizontal sampling factor */
443
444 READ_BITS(gb, 4, &value);
445 syntax->v_count[i] = value; /* Vertical sampling factor */
446
447 if (!syntax->h_count[i] || !syntax->v_count[i]) {
448 mpp_err_f("Invalid sampling factor in component %d %d:%d\n",
449 i, syntax->h_count[i], syntax->v_count[i]);
450 return MPP_ERR_STREAM;
451 }
452
453 /* compute hmax and vmax (only used in interleaved case) */
454 if (syntax->h_count[i] > syntax->h_max)
455 syntax->h_max = syntax->h_count[i];
456 if (syntax->v_count[i] > syntax->v_max)
457 syntax->v_max = syntax->v_count[i];
458
459 /* Quantization table destination selector */
460 READ_BITS(gb, 8, &value);
461 syntax->quant_index[i] = value;
462
463 if (syntax->quant_index[i] >= QUANTIZE_TABLE_ID_BUTT) {
464 mpp_err_f("quant_index %d is invalid\n", syntax->quant_index[i]);
465 return MPP_ERR_STREAM;
466 }
467
468 jpegd_dbg_marker("component %d %d:%d id: %d quant_id:%d\n",
469 i, syntax->h_count[i], syntax->v_count[i],
470 syntax->component_id[i], syntax->quant_index[i]);
471 }
472
473 /* judge yuv mode from sampling factor */
474 ret = jpeg_judge_yuv_mode(ctx);
475
476 __BITREAD_ERR:
477 if (ret != MPP_OK)
478 jpegd_dbg_syntax("bit read error!\n");
479
480 return ret;
481 }
482
jpegd_decode_sos(JpegdCtx * ctx)483 static MPP_RET jpegd_decode_sos(JpegdCtx *ctx)
484 {
485 MPP_RET ret = MPP_NOK;
486 BitReadCtx_t *gb = ctx->bit_ctx;
487 JpegdSyntax *syntax = ctx->syntax;
488 RK_U32 len, nb_components, value;
489 RK_U32 id, i, index;
490
491 len = jpegd_read_len(gb);
492 if (len > gb->bytes_left_) {
493 mpp_err_f("len %d is too large\n", len);
494 return MPP_ERR_STREAM;
495 }
496 syntax->sos_len = len; /* used for calculating stream offset */
497
498 READ_BITS(gb, 8, &nb_components);
499 if ((nb_components != 1) && (nb_components != MAX_COMPONENTS)) {
500 mpp_err_f("decode_sos: nb_components %d unsupported\n", nb_components);
501 return MPP_ERR_STREAM;
502 }
503
504 if (len != 6 + 2 * nb_components) {
505 mpp_err_f("decode_sos: invalid len (%d), nb_components:%d\n",
506 len, nb_components);
507 return MPP_ERR_STREAM;
508 }
509 syntax->qtable_cnt = nb_components;
510
511 for (i = 0; i < nb_components; i++) {
512 READ_BITS(gb, 8, &value);
513 id = value - 1;
514 jpegd_dbg_marker("sos component: %d\n", id);
515
516 /* find component index */
517 for (index = 0; index < syntax->nb_components; index++)
518 if (id == syntax->component_id[index])
519 break;
520
521 if (index == syntax->nb_components) {
522 mpp_err_f("decode_sos: index(%d) out of components\n", index);
523 return MPP_ERR_STREAM;
524 }
525
526 READ_BITS(gb, 4, &value);
527 syntax->dc_index[i] = value;
528
529 READ_BITS(gb, 4, &value);
530 syntax->ac_index[i] = value;
531
532 jpegd_dbg_marker("component:%d, dc_index:%d, ac_index:%d\n",
533 id, syntax->dc_index[i], syntax->ac_index[i]);
534
535 if (syntax->dc_index[i] > HUFFMAN_TABLE_ID_ONE ||
536 syntax->ac_index[i] > HUFFMAN_TABLE_ID_ONE) {
537 /* for baseline */
538 mpp_err_f("Huffman table id error\n");
539 return MPP_ERR_STREAM;
540 }
541 }
542
543 READ_BITS(gb, 8, &value);
544 syntax->scan_start = value;
545
546 READ_BITS(gb, 8, &value);
547 syntax->scan_end = value;
548
549 READ_BITS(gb, 4, &value);
550 syntax->prev_shift = value;
551
552 READ_BITS(gb, 4, &value);
553 syntax->point_transform = value;
554
555 if (syntax->scan_start != 0 || syntax->scan_end != 0x3F ||
556 syntax->prev_shift != 0 || syntax->point_transform != 0) {
557 /* for baseline */
558 mpp_err_f("unsupported sos parameter: scan_start:%d,\n"
559 "\t\tscan_end:%d, prev_shift:%d, point_transform:%d\n",
560 syntax->scan_start, syntax->scan_end,
561 syntax->prev_shift, syntax->point_transform);
562 return MPP_ERR_STREAM;
563 }
564 ret = MPP_OK;
565
566 __BITREAD_ERR:
567 if (ret != MPP_OK)
568 jpegd_dbg_syntax("bit read error!\n");
569
570 return ret;
571 }
572
jpegd_decode_dri(JpegdCtx * ctx)573 static MPP_RET jpegd_decode_dri(JpegdCtx *ctx)
574 {
575 MPP_RET ret = MPP_NOK;
576 BitReadCtx_t *gb = ctx->bit_ctx;
577 JpegdSyntax *s = ctx->syntax;
578 RK_U32 len;
579
580 len = jpegd_read_len(gb);
581 if (len != DRI_MARKER_LENGTH) {
582 mpp_err_f("DRI length %d error\n", len);
583 return MPP_ERR_STREAM;
584 }
585
586 READ_BITS(gb, 16, &s->restart_interval);
587 jpegd_dbg_marker("restart interval: %d\n", s->restart_interval);
588
589 ret = MPP_OK;
590
591 __BITREAD_ERR:
592 if (ret != MPP_OK)
593 jpegd_dbg_syntax("bit read error!\n");
594
595 return ret;
596 }
597
jpegd_setup_default_dht(JpegdCtx * ctx)598 static MPP_RET jpegd_setup_default_dht(JpegdCtx *ctx)
599 {
600 jpegd_dbg_func("enter\n");
601 JpegdSyntax *s = ctx->syntax;
602 AcTable *ac_ptr = NULL;
603 DcTable *dc_ptr = NULL;
604 const RK_U8 *bits_tmp = NULL;
605 const RK_U8 *val_tmp = NULL;
606 RK_U32 tmp_len = 0;
607 RK_U32 i, k;
608
609 /* Set up the standard Huffman tables (cf. JPEG standard section K.3)
610 * IMPORTANT: these are only valid for 8-bit data precision!
611 */
612 static const RK_U8 bits_dc_luminance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
613 { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
614
615 /* luminance and chrominance all use it */
616 static const RK_U8 val_dc[MAX_DC_HUFFMAN_TABLE_LENGTH] =
617 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
618
619 static const RK_U8 bits_dc_chrominance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
620 { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
621
622 static const RK_U8 bits_ac_luminance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
623 { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
624
625 /* 162 Bytes */
626 static const RK_U8 val_ac_luminance[MAX_AC_HUFFMAN_TABLE_LENGTH] = {
627 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
628 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
629 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
630 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
631 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
632 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
633 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
634 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
635 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
636 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
637 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
638 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
639 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
640 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
641 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
642 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
643 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
644 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
645 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
646 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
647 0xf9, 0xfa
648 };
649
650 static const RK_U8 bits_ac_chrominance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
651 { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
652
653 static const RK_U8 val_ac_chrominance[MAX_AC_HUFFMAN_TABLE_LENGTH] = {
654 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
655 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
656 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
657 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
658 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
659 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
660 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
661 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
662 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
663 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
664 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
665 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
666 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
667 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
668 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
669 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
670 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
671 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
672 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
673 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
674 0xf9, 0xfa
675 };
676
677 const RK_U8 *bits_table[4] = {
678 bits_ac_luminance,
679 bits_ac_chrominance,
680 bits_dc_luminance,
681 bits_dc_chrominance
682 };
683
684 const RK_U8 *val_table[4] = {
685 val_ac_luminance,
686 val_ac_chrominance,
687 val_dc,
688 val_dc
689 };
690
691 /* AC Table */
692 for (k = 0; k < 2; k++) {
693 ac_ptr = &(s->ac_table[k]);
694 bits_tmp = bits_table[k];
695 val_tmp = val_table[k];
696
697 tmp_len = 0;
698 for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
699 /* read in the values of list BITS */
700 tmp_len += ac_ptr->bits[i] = bits_tmp[i];
701 }
702
703 ac_ptr->actual_length = tmp_len; /* set the table length */
704 for (i = 0; i < tmp_len; i++) {
705 /* read in the HUFFVALs */
706 ac_ptr->vals[i] = val_tmp[i];
707 }
708 }
709
710 /* DC Table */
711 for (k = 0; k < 2; k++) {
712 dc_ptr = &(s->dc_table[k]);
713 bits_tmp = bits_table[k + 2];
714 val_tmp = val_table[k + 2];
715
716 tmp_len = 0;
717 for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
718 /* read in the values of list BITS */
719 tmp_len += dc_ptr->bits[i] = bits_tmp[i];
720 }
721
722 dc_ptr->actual_length = tmp_len; /* set the table length */
723 for (i = 0; i < tmp_len; i++) {
724 /* read in the HUFFVALs */
725 dc_ptr->vals[i] = val_tmp[i];
726 }
727 }
728
729 jpegd_dbg_func("exit\n");
730 return MPP_OK;
731 }
732
jpegd_decode_frame(JpegdCtx * ctx)733 static MPP_RET jpegd_decode_frame(JpegdCtx *ctx)
734 {
735 jpegd_dbg_func("enter\n");
736 MPP_RET ret = MPP_OK;
737 const RK_U8 *const buf = ctx->buffer;
738 RK_U32 buf_size = ctx->buf_size;
739 BitReadCtx_t *gb = ctx->bit_ctx;
740 JpegdSyntax *syntax = ctx->syntax;
741 RK_S32 start_code = 0xffd8;
742
743 const RK_U8 *buf_ptr = buf;
744 const RK_U8 *const buf_end = buf + buf_size;
745
746 syntax->htbl_entry = 0;
747 syntax->qtbl_entry = 0;
748
749 if (buf_size < 8 || !memchr(buf_ptr, start_code, 8)) {
750 // not jpeg
751 ret = MPP_ERR_STREAM;
752 goto fail;
753 }
754
755 while (buf_ptr < buf_end) {
756 /* find start marker */
757 start_code = jpegd_find_marker(&buf_ptr, buf_end);
758 if (start_code <= 0) {
759 jpegd_dbg_marker("start code not found\n");
760 break;
761 } else {
762 buf_ptr += 2;
763 }
764
765 jpegd_dbg_marker("marker = 0x%x, avail_size_in_buf = %d\n",
766 start_code, buf_end - buf_ptr);
767 ctx->start_code = start_code;
768
769 /* setup bit read context */
770 mpp_set_bitread_ctx(gb, (RK_U8 *)buf_ptr, buf_end - buf_ptr);
771
772 /* process markers */
773 if (start_code >= RST0 && start_code <= RST7) {
774 /* nothing to do with RSTn */
775 jpegd_dbg_syntax("restart marker: %d\n", start_code & 0x0f);
776 }
777
778 if (start_code > SOF0 && start_code <= SOF15 && start_code != DHT) {
779 mpp_err_f("Only baseline DCT is supported, unsupported entropy encoding 0x%x", start_code);
780 ret = MPP_ERR_STREAM;
781 goto fail;
782 }
783
784 switch (start_code) {
785 case SOI:
786 /* nothing to do on SOI */
787 syntax->dht_found = 0;
788 syntax->eoi_found = 0;
789 syntax->sof0_found = 0;
790 syntax->qtable_cnt = 0;
791 syntax->qtbl_entry = 0;
792 syntax->htbl_entry = 0;
793 break;
794 case DHT:
795 if ((ret = jpegd_decode_dht(ctx)) != MPP_OK) {
796 mpp_err_f("huffman table decode error\n");
797 goto fail;
798 }
799 syntax->dht_found = 1;
800 break;
801 case DQT:
802 if ((ret = jpegd_decode_dqt(ctx)) != MPP_OK) {
803 mpp_err_f("quantize tables decode error\n");
804 goto fail;
805 }
806 break;
807 case SOF0:
808 if ((ret = jpegd_decode_sof(ctx)) != MPP_OK) {
809 mpp_err_f("sof0 decode error\n");
810 goto fail;
811 }
812 if (ctx->syntax->sample_precision != 8) {
813 mpp_err_f("Illegal sample precision %d.\n\
814 For baseline, it should be 8\n", ctx->syntax->sample_precision);
815 goto fail;
816 }
817
818 syntax->sof0_found = 1;
819 break;
820 case EOI:
821 syntax->eoi_found = 1;
822 jpegd_dbg_marker("still exists %d bytes behind EOI marker\n",
823 buf_end - buf_ptr);
824 goto done;
825 break;
826 case SOS:
827 if (!syntax->sof0_found) {
828 mpp_err_f("Warning: only support baseline type\n");
829 goto fail;
830 }
831
832 if ((ret = jpegd_decode_sos(ctx)) != MPP_OK) {
833 mpp_err_f("sos decode error\n");
834 goto fail;
835 }
836
837 /* stream behind SOS is decoded by hardware */
838 syntax->strm_offset = buf_ptr - buf + syntax->sos_len;
839 syntax->cur_pos = (RK_U8 *)buf + syntax->strm_offset;
840 syntax->pkt_len = ctx->buf_size;
841 jpegd_dbg_marker("This packet owns %d bytes,\n"
842 "\t\thas been decoded %d bytes by software\n"
843 "\t\tbuf_ptr:%p, buf:%p, sos_len:%d\n"
844 "\t\thardware start address:%p",
845 syntax->pkt_len,
846 syntax->strm_offset, buf_ptr, buf,
847 syntax->sos_len, syntax->cur_pos);
848
849 if (syntax->strm_offset >= ctx->buf_size) {
850 mpp_err_f("stream offset %d is larger than buffer size %d\n",
851 syntax->strm_offset, ctx->buf_size);
852 ret = MPP_ERR_UNKNOW;
853 goto fail;
854 }
855
856 if ((syntax->strm_offset + 2) < ctx->buf_size &&
857 buf_ptr[syntax->sos_len] == 0xff && buf_ptr[syntax->sos_len + 1] == 0xd8) {
858 jpegd_dbg_marker("Encontered SOI again, parse again!\n");
859 break;
860 }
861 if (!ctx->scan_all_marker) {
862 jpegd_dbg_marker("just scan parts of markers!\n");
863 goto done;
864 }
865
866 break;
867 case DRI:
868 if ((ret = jpegd_decode_dri(ctx)) != MPP_OK) {
869 mpp_err_f("dri decode error\n");
870 goto fail;
871 }
872 break;
873 default:
874 jpegd_dbg_marker("unhandled coding type(0x%x) in switch..case..\n",
875 start_code);
876 if ((ret = jpegd_skip_section(ctx)) != MPP_OK) {
877 jpegd_dbg_marker("Fail to skip section 0xFF%02x!\n",
878 start_code);
879 goto fail;
880 }
881 break;
882 }
883
884 buf_ptr = ctx->bit_ctx->data_;
885 }
886
887 done:
888 if (!syntax->dht_found) {
889 jpegd_dbg_marker("sorry, DHT is not found!\n");
890 jpegd_setup_default_dht(ctx);
891 syntax->htbl_entry = 0x0f;
892 }
893 if (!syntax->eoi_found) {
894 if (MPP_OK != jpegd_find_eoi(&buf_ptr, buf_end)) {
895 mpp_err_f("EOI marker not found!\n");
896 ret = MPP_ERR_STREAM;
897 }
898 }
899 jpegd_dbg_func("exit\n");
900 return ret;
901
902 fail:
903 ret = MPP_ERR_STREAM;
904 jpegd_dbg_func("exit\n");
905 return ret;
906 }
907
908 static MPP_RET
jpegd_split_frame(RK_U8 * src,RK_U32 src_size,RK_U8 * dst,RK_U32 dst_size,RK_U32 * copy_length)909 jpegd_split_frame(RK_U8 *src, RK_U32 src_size,
910 RK_U8 *dst, RK_U32 dst_size, RK_U32 *copy_length)
911 {
912 jpegd_dbg_func("enter\n");
913 MPP_RET ret = MPP_OK;
914 if (NULL == src || NULL == dst || src_size <= 0) {
915 mpp_err_f("NULL pointer or wrong src_size(%d)", src_size);
916 return MPP_ERR_NULL_PTR;
917 }
918 RK_U8 *tmp;
919 RK_U32 str_size = (src_size + 255) & (~255);
920
921 if (src[6] == 0x41 && src[7] == 0x56 && src[8] == 0x49 && src[9] == 0x31) {
922 //distinguish 310 from 210 camera
923 RK_U32 i;
924 RK_U32 copy_len = 0;
925 tmp = src;
926 jpegd_dbg_parser("distinguish 310 from 210 camera");
927
928 for (i = 0; i < src_size - 4; i++) {
929 if (tmp[i] == 0xff) {
930 if (tmp[i + 1] == 0x00 && tmp[i + 2] == 0xff && ((tmp[i + 3] & 0xf0) == 0xd0))
931 i += 2;
932 }
933 *dst++ = tmp[i];
934 copy_len++;
935 }
936 for (; i < src_size; i++) {
937 *dst++ = tmp[i];
938 copy_len++;
939 }
940 if (copy_len < src_size)
941 memset(dst, 0, src_size - copy_len);
942 *copy_length = copy_len;
943 } else {
944 memcpy(dst, src, src_size);
945 memset(dst + src_size, 0, str_size > dst_size ? dst_size - src_size : str_size - src_size);
946 *copy_length = src_size;
947 }
948
949 jpegd_dbg_func("exit\n");
950 return ret;
951 }
952
jpegd_prepare(void * ctx,MppPacket pkt,HalDecTask * task)953 static MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task)
954 {
955 jpegd_dbg_func("enter\n");
956 MPP_RET ret = MPP_OK;
957 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
958 if (!JpegCtx->copy_flag) {
959 /* no need to copy stream, handle packet from upper application directly*/
960 JpegCtx->input_packet = pkt;
961 }
962
963 MppPacket input_packet = JpegCtx->input_packet;
964 RK_U32 copy_length = 0;
965 void *base = mpp_packet_get_pos(pkt);
966 RK_U8 *pos = base;
967 RK_U32 pkt_length = (RK_U32)mpp_packet_get_length(pkt);
968 RK_U32 eos = (pkt_length) ? (mpp_packet_get_eos(pkt)) : (1);
969
970 JpegCtx->pts = mpp_packet_get_pts(pkt);
971
972 task->valid = 0;
973 task->flags.eos = eos;
974 JpegCtx->eos = eos;
975
976 jpegd_dbg_parser("pkt_length %d eos %d\n", pkt_length, eos);
977
978 if (!pkt_length) {
979 jpegd_dbg_parser("it is end of stream.");
980 return ret;
981 }
982
983 if (pkt_length > JpegCtx->bufferSize) {
984 jpegd_dbg_parser("Huge Frame(%d Bytes)! bufferSize:%d",
985 pkt_length, JpegCtx->bufferSize);
986 mpp_free(JpegCtx->recv_buffer);
987 JpegCtx->recv_buffer = NULL;
988
989 JpegCtx->recv_buffer = mpp_calloc(RK_U8, pkt_length + 1024);
990 if (NULL == JpegCtx->recv_buffer) {
991 mpp_err_f("no memory!");
992 return MPP_ERR_NOMEM;
993 }
994
995 JpegCtx->bufferSize = pkt_length + 1024;
996 }
997
998 if (JpegCtx->copy_flag)
999 jpegd_split_frame(base, pkt_length, JpegCtx->recv_buffer,
1000 JpegCtx->bufferSize, ©_length);
1001
1002 pos += pkt_length;
1003 mpp_packet_set_pos(pkt, pos);
1004 if (copy_length != pkt_length) {
1005 jpegd_dbg_parser("packet prepare, pkt_length:%d, copy_length:%d\n",
1006 pkt_length, copy_length);
1007 }
1008
1009 /* debug information */
1010 if (jpegd_debug & JPEGD_DBG_IO) {
1011 static FILE *jpg_file;
1012 static char name[32];
1013
1014 snprintf(name, sizeof(name) - 1, "/data/input%02d.jpg",
1015 JpegCtx->input_jpeg_count);
1016 jpg_file = fopen(name, "wb+");
1017 if (jpg_file) {
1018 jpegd_dbg_io("frame_%02d input jpeg(%d Bytes) saving to %s\n",
1019 JpegCtx->input_jpeg_count, pkt_length, name);
1020 fwrite(base, pkt_length, 1, jpg_file);
1021 fclose(jpg_file);
1022 JpegCtx->input_jpeg_count++;
1023 }
1024 }
1025
1026 if (JpegCtx->copy_flag) {
1027 mpp_packet_set_data(input_packet, JpegCtx->recv_buffer);
1028 mpp_packet_set_size(input_packet, pkt_length);
1029 mpp_packet_set_length(input_packet, pkt_length);
1030 memcpy(base, JpegCtx->recv_buffer, pkt_length);
1031 }
1032
1033 JpegCtx->streamLength = pkt_length;
1034 task->input_packet = input_packet;
1035 task->valid = 1;
1036 jpegd_dbg_parser("input_packet:%p, recv_buffer:%p, pkt_length:%d",
1037 input_packet,
1038 JpegCtx->recv_buffer, pkt_length);
1039
1040 jpegd_dbg_func("exit\n");
1041 return ret;
1042 }
1043
jpegd_allocate_frame(JpegdCtx * ctx)1044 static MPP_RET jpegd_allocate_frame(JpegdCtx *ctx)
1045 {
1046 jpegd_dbg_func("enter\n");
1047 JpegdSyntax *s = ctx->syntax;
1048 MppBufSlots slots = ctx->frame_slots;
1049 MppFrame output = ctx->output_frame;
1050 RK_S32 slot_idx = ctx->frame_slot_index;
1051
1052 if (slot_idx == -1) {
1053 RK_U32 value;
1054 MppFrameFormat fmt = MPP_FMT_YUV420SP;
1055
1056 switch (s->yuv_mode) {
1057 case JPEGDEC_YUV420: {
1058 fmt = MPP_FMT_YUV420SP;
1059 } break;
1060 case JPEGDEC_YUV422: {
1061 fmt = MPP_FMT_YUV422SP;
1062 } break;
1063 case JPEGDEC_YUV444: {
1064 fmt = MPP_FMT_YUV444SP;
1065 } break;
1066 case JPEGDEC_YUV400: {
1067 fmt = MPP_FMT_YUV400;
1068 } break;
1069 default : {
1070 fmt = MPP_FMT_YUV420SP;
1071 } break;
1072 }
1073
1074 mpp_frame_set_fmt(output, fmt);
1075 mpp_frame_set_width(output, s->width);
1076 mpp_frame_set_height(output, s->height);
1077 mpp_frame_set_hor_stride(output, s->hor_stride);
1078 mpp_frame_set_ver_stride(output, s->ver_stride);
1079 mpp_frame_set_pts(output, ctx->pts);
1080
1081 if (ctx->eos)
1082 mpp_frame_set_eos(output, 1);
1083
1084 mpp_buf_slot_get_unused(slots, &slot_idx);
1085 ctx->frame_slot_index = slot_idx;
1086 jpegd_dbg_parser("frame_slot_index:%d\n", slot_idx);
1087
1088 value = 2;
1089 mpp_slots_set_prop(slots, SLOTS_NUMERATOR, &value);
1090 value = 1;
1091 mpp_slots_set_prop(slots, SLOTS_DENOMINATOR, &value);
1092 if (mpp_buf_slot_set_prop(slots, slot_idx, SLOT_FRAME, output))
1093 return MPP_ERR_VALUE;
1094 mpp_buf_slot_set_flag(slots, slot_idx, SLOT_CODEC_USE);
1095 mpp_buf_slot_set_flag(slots, slot_idx, SLOT_HAL_OUTPUT);
1096 }
1097
1098 jpegd_dbg_func("exit\n");
1099 return MPP_OK;
1100 }
1101
jpegd_update_frame(JpegdCtx * ctx)1102 static MPP_RET jpegd_update_frame(JpegdCtx *ctx)
1103 {
1104 jpegd_dbg_func("enter\n");
1105
1106 mpp_buf_slot_clr_flag(ctx->frame_slots, ctx->frame_slot_index,
1107 SLOT_CODEC_USE);
1108 ctx->frame_slot_index = -1;
1109
1110 jpegd_dbg_func("exit\n");
1111 return MPP_OK;
1112 }
1113
jpegd_parse(void * ctx,HalDecTask * task)1114 static MPP_RET jpegd_parse(void *ctx, HalDecTask *task)
1115 {
1116 jpegd_dbg_func("enter\n");
1117 MPP_RET ret = MPP_OK;
1118 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1119 task->valid = 0;
1120
1121 JpegCtx->buffer = (RK_U8 *)mpp_packet_get_data(JpegCtx->input_packet);
1122 JpegCtx->buf_size = (RK_U32)mpp_packet_get_size(JpegCtx->input_packet);
1123
1124 memset(JpegCtx->syntax, 0, sizeof(JpegdSyntax));
1125
1126 ret = jpegd_decode_frame(JpegCtx);
1127 if (MPP_OK == ret) {
1128 if (jpegd_allocate_frame(JpegCtx))
1129 return MPP_ERR_VALUE;
1130
1131 task->syntax.data = (void *)JpegCtx->syntax;
1132 task->syntax.number = sizeof(JpegdSyntax);
1133 task->output = JpegCtx->frame_slot_index;
1134 task->valid = 1;
1135
1136 jpegd_update_frame(JpegCtx);
1137 }
1138
1139 jpegd_dbg_func("exit\n");
1140 return ret;
1141 }
1142
jpegd_deinit(void * ctx)1143 static MPP_RET jpegd_deinit(void *ctx)
1144 {
1145 jpegd_dbg_func("enter\n");
1146 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1147
1148 if (JpegCtx->recv_buffer) {
1149 mpp_free(JpegCtx->recv_buffer);
1150 JpegCtx->recv_buffer = NULL;
1151 }
1152
1153 if (JpegCtx->output_frame) {
1154 mpp_frame_deinit(&JpegCtx->output_frame);
1155 }
1156
1157 if (JpegCtx->copy_flag) {
1158 if (JpegCtx->input_packet) {
1159 mpp_packet_deinit(&JpegCtx->input_packet);
1160 }
1161 } else {
1162 JpegCtx->input_packet = NULL;
1163 }
1164
1165 if (JpegCtx->bit_ctx) {
1166 mpp_free(JpegCtx->bit_ctx);
1167 JpegCtx->bit_ctx = NULL;
1168 }
1169
1170 if (JpegCtx->syntax) {
1171 mpp_free(JpegCtx->syntax);
1172 JpegCtx->syntax = NULL;
1173 }
1174
1175 JpegCtx->output_fmt = MPP_FMT_YUV420SP;
1176 JpegCtx->pts = 0;
1177 JpegCtx->eos = 0;
1178 JpegCtx->input_jpeg_count = 0;
1179
1180 jpegd_dbg_func("exit\n");
1181 return 0;
1182 }
1183
jpegd_init(void * ctx,ParserCfg * parser_cfg)1184 static MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg)
1185 {
1186 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1187 const MppDecHwCap *hw_info = parser_cfg->hw_info;
1188
1189 jpegd_dbg_func("enter\n");
1190
1191 if (NULL == JpegCtx) {
1192 JpegCtx = (JpegdCtx *)mpp_calloc(JpegdCtx, 1);
1193 if (NULL == JpegCtx) {
1194 mpp_err_f("NULL pointer");
1195 return MPP_ERR_NULL_PTR;
1196 }
1197 }
1198
1199 mpp_env_get_u32("jpegd_debug", &jpegd_debug, 0);
1200 // mpp only support baseline
1201 JpegCtx->scan_all_marker = 0;
1202
1203 if (hw_info && hw_info->cap_hw_jpg_fix) {
1204 /*
1205 * no need to copy stream when decoding jpeg;
1206 * just scan parts of markers to reduce CPU's occupancy
1207 */
1208 JpegCtx->copy_flag = 0;
1209 } else {
1210 // TODO: do not copy if input provides valid fd and virtual ptr
1211 JpegCtx->copy_flag = 1;
1212 }
1213
1214 JpegCtx->frame_slots = parser_cfg->frame_slots;
1215 JpegCtx->packet_slots = parser_cfg->packet_slots;
1216 JpegCtx->frame_slot_index = -1;
1217 mpp_buf_slot_setup(JpegCtx->frame_slots, 1);
1218
1219 JpegCtx->recv_buffer = mpp_calloc(RK_U8, JPEGD_STREAM_BUFF_SIZE);
1220 if (NULL == JpegCtx->recv_buffer) {
1221 mpp_err_f("no memory!");
1222 return MPP_ERR_NOMEM;
1223 }
1224 JpegCtx->bufferSize = JPEGD_STREAM_BUFF_SIZE;
1225 if (JpegCtx->copy_flag) {
1226 mpp_packet_init(&JpegCtx->input_packet,
1227 JpegCtx->recv_buffer, JPEGD_STREAM_BUFF_SIZE);
1228 } else {
1229 JpegCtx->input_packet = NULL;
1230 }
1231
1232 mpp_frame_init(&JpegCtx->output_frame);
1233 if (!JpegCtx->output_frame) {
1234 mpp_err_f("Failed to allocate output frame buffer");
1235 return MPP_ERR_NOMEM;
1236 }
1237
1238 JpegCtx->bit_ctx = mpp_calloc(BitReadCtx_t, 1);
1239 if (JpegCtx->bit_ctx == NULL) {
1240 mpp_err_f("allocate bit_ctx failed\n");
1241 return MPP_ERR_MALLOC;
1242 }
1243
1244 JpegCtx->syntax = mpp_calloc(JpegdSyntax, 1);
1245 if (JpegCtx->syntax == NULL) {
1246 mpp_err_f("allocate syntax failed\n");
1247 return MPP_ERR_MALLOC;
1248 }
1249 memset(JpegCtx->syntax, 0, sizeof(JpegdSyntax));
1250
1251 JpegCtx->output_fmt = MPP_FMT_YUV420SP;
1252 JpegCtx->pts = 0;
1253 JpegCtx->eos = 0;
1254 JpegCtx->input_jpeg_count = 0;
1255
1256 jpegd_dbg_func("exit\n");
1257 return MPP_OK;
1258 }
1259
jpegd_flush(void * ctx)1260 static MPP_RET jpegd_flush(void *ctx)
1261 {
1262 jpegd_dbg_func("enter\n");
1263 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1264 (void)JpegCtx;
1265 jpegd_dbg_func("exit\n");
1266 return MPP_OK;
1267 }
1268
jpegd_reset(void * ctx)1269 static MPP_RET jpegd_reset(void *ctx)
1270 {
1271 jpegd_dbg_func("enter\n");
1272 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1273
1274 (void)JpegCtx;
1275
1276 jpegd_dbg_func("exit\n");
1277 return MPP_OK;
1278 }
1279
jpegd_control(void * ctx,MpiCmd cmd,void * param)1280 static MPP_RET jpegd_control(void *ctx, MpiCmd cmd, void *param)
1281 {
1282 jpegd_dbg_func("enter\n");
1283 MPP_RET ret = MPP_OK;
1284 JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1285 if (NULL == JpegCtx) {
1286 mpp_err_f("NULL pointer");
1287 return MPP_ERR_NULL_PTR;
1288 }
1289
1290 switch (cmd) {
1291 case MPP_DEC_SET_OUTPUT_FORMAT: {
1292 JpegCtx->output_fmt = *((RK_U32 *)param);
1293 jpegd_dbg_parser("output_format:%d\n", JpegCtx->output_fmt);
1294 } break;
1295 default :
1296 ret = MPP_NOK;
1297 }
1298 jpegd_dbg_func("exit\n");
1299 return ret;
1300 }
1301
jpegd_callback(void * ctx,void * err_info)1302 static MPP_RET jpegd_callback(void *ctx, void *err_info)
1303 {
1304 jpegd_dbg_func("enter\n");
1305 (void) ctx;
1306 (void) err_info;
1307 jpegd_dbg_func("exit\n");
1308 return MPP_OK;
1309 }
1310
1311 const ParserApi api_jpegd_parser = {
1312 .name = "jpegd_parse",
1313 .coding = MPP_VIDEO_CodingMJPEG,
1314 .ctx_size = sizeof(JpegdCtx),
1315 .flag = 0,
1316 .init = jpegd_init,
1317 .deinit = jpegd_deinit,
1318 .prepare = jpegd_prepare,
1319 .parse = jpegd_parse,
1320 .reset = jpegd_reset,
1321 .flush = jpegd_flush,
1322 .control = jpegd_control,
1323 .callback = jpegd_callback,
1324 };
1325
1326
1327