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