xref: /rockchip-linux_mpp/mpp/codec/enc/jpeg/jpege_api_v2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "jpege_api_v2"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_err.h"
22*437bfbebSnyanmisaka #include "mpp_env.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "mpp_2str.h"
26*437bfbebSnyanmisaka #include "mpp_enc_cfg.h"
27*437bfbebSnyanmisaka #include "mpp_bitwrite.h"
28*437bfbebSnyanmisaka #include "mpp_soc.h"
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #include "jpege_debug.h"
31*437bfbebSnyanmisaka #include "jpege_api_v2.h"
32*437bfbebSnyanmisaka #include "jpege_syntax.h"
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka typedef struct {
35*437bfbebSnyanmisaka     MppEncCfgSet    *cfg;
36*437bfbebSnyanmisaka     JpegeSyntax     syntax;
37*437bfbebSnyanmisaka } JpegeCtx;
38*437bfbebSnyanmisaka 
39*437bfbebSnyanmisaka /*
40*437bfbebSnyanmisaka  *  from RFC435 spec.
41*437bfbebSnyanmisaka  */
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka RK_U32 jpege_debug = 0;
44*437bfbebSnyanmisaka 
jpege_init_v2(void * ctx,EncImplCfg * cfg)45*437bfbebSnyanmisaka static MPP_RET jpege_init_v2(void *ctx, EncImplCfg *cfg)
46*437bfbebSnyanmisaka {
47*437bfbebSnyanmisaka     JpegeCtx *p = (JpegeCtx *)ctx;
48*437bfbebSnyanmisaka 
49*437bfbebSnyanmisaka     mpp_env_get_u32("jpege_debug", &jpege_debug, 0);
50*437bfbebSnyanmisaka     jpege_dbg_func("enter ctx %p\n", ctx);
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     p->cfg = cfg->cfg;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     mpp_assert(cfg->coding = MPP_VIDEO_CodingMJPEG);
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     {
57*437bfbebSnyanmisaka         /* init default rc config */
58*437bfbebSnyanmisaka         MppEncRcCfg *rc = &p->cfg->rc;
59*437bfbebSnyanmisaka         MppEncJpegCfg *jpeg_cfg = &p->cfg->jpeg;
60*437bfbebSnyanmisaka 
61*437bfbebSnyanmisaka         rc->fps_in_flex = 0;
62*437bfbebSnyanmisaka         rc->fps_in_num = 30;
63*437bfbebSnyanmisaka         rc->fps_in_denom = 1;
64*437bfbebSnyanmisaka         rc->fps_out_flex = 0;
65*437bfbebSnyanmisaka         rc->fps_out_num = 30;
66*437bfbebSnyanmisaka         rc->fps_out_denom = 1;
67*437bfbebSnyanmisaka         rc->rc_mode = MPP_ENC_RC_MODE_FIXQP;
68*437bfbebSnyanmisaka 
69*437bfbebSnyanmisaka         /* set quant to invalid value */
70*437bfbebSnyanmisaka         jpeg_cfg->quant = -1;
71*437bfbebSnyanmisaka         jpeg_cfg->quant_ext = -1;
72*437bfbebSnyanmisaka     }
73*437bfbebSnyanmisaka 
74*437bfbebSnyanmisaka     jpege_dbg_func("leave ctx %p\n", ctx);
75*437bfbebSnyanmisaka     return MPP_OK;
76*437bfbebSnyanmisaka }
77*437bfbebSnyanmisaka 
jpege_deinit_v2(void * ctx)78*437bfbebSnyanmisaka static MPP_RET jpege_deinit_v2(void *ctx)
79*437bfbebSnyanmisaka {
80*437bfbebSnyanmisaka     jpege_dbg_func("enter ctx %p\n", ctx);
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka     jpege_dbg_func("leave ctx %p\n", ctx);
83*437bfbebSnyanmisaka     return MPP_OK;
84*437bfbebSnyanmisaka }
85*437bfbebSnyanmisaka 
jpege_proc_cfg(void * ctx,MpiCmd cmd,void * param)86*437bfbebSnyanmisaka static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
87*437bfbebSnyanmisaka {
88*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
89*437bfbebSnyanmisaka 
90*437bfbebSnyanmisaka     jpege_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param);
91*437bfbebSnyanmisaka 
92*437bfbebSnyanmisaka     switch (cmd) {
93*437bfbebSnyanmisaka     case MPP_ENC_SET_CFG :
94*437bfbebSnyanmisaka     case MPP_ENC_SET_IDR_FRAME :
95*437bfbebSnyanmisaka     case MPP_ENC_SET_OSD_PLT_CFG :
96*437bfbebSnyanmisaka     case MPP_ENC_SET_OSD_DATA_CFG :
97*437bfbebSnyanmisaka     case MPP_ENC_GET_SEI_DATA :
98*437bfbebSnyanmisaka     case MPP_ENC_SET_SEI_CFG : {
99*437bfbebSnyanmisaka     } break;
100*437bfbebSnyanmisaka     default:
101*437bfbebSnyanmisaka         mpp_err_f("No correspond cmd(%08x) found, and can not config!", cmd);
102*437bfbebSnyanmisaka         ret = MPP_NOK;
103*437bfbebSnyanmisaka         break;
104*437bfbebSnyanmisaka     }
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka     jpege_dbg_func("leave ret %d\n", ret);
107*437bfbebSnyanmisaka     return ret;
108*437bfbebSnyanmisaka }
109*437bfbebSnyanmisaka 
jpege_start(void * ctx,HalEncTask * task)110*437bfbebSnyanmisaka static MPP_RET jpege_start(void *ctx, HalEncTask *task)
111*437bfbebSnyanmisaka {
112*437bfbebSnyanmisaka     JpegeCtx *p = (JpegeCtx *)ctx;
113*437bfbebSnyanmisaka     JpegeSyntax syntax = p->syntax;
114*437bfbebSnyanmisaka     MppPacket pkt = task->packet;
115*437bfbebSnyanmisaka     RK_U8 *ptr = mpp_packet_get_pos(pkt);
116*437bfbebSnyanmisaka     size_t buf_size = mpp_packet_get_size(pkt);
117*437bfbebSnyanmisaka     RK_S32 size = 0;
118*437bfbebSnyanmisaka     MppWriteCtx bit_ctx;
119*437bfbebSnyanmisaka     MppWriteCtx *bits = &bit_ctx;
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka     mpp_writer_init(bits, ptr, buf_size);
122*437bfbebSnyanmisaka 
123*437bfbebSnyanmisaka     /* add SOI and APP0 data */
124*437bfbebSnyanmisaka     /* SOI */
125*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0xFFD8, 16);
126*437bfbebSnyanmisaka     /* APP0 */
127*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0xFFE0, 16);
128*437bfbebSnyanmisaka     /* length */
129*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x0010, 16);
130*437bfbebSnyanmisaka     /* "JFIF" ID */
131*437bfbebSnyanmisaka     /* Ident1 */
132*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x4A46, 16);
133*437bfbebSnyanmisaka     /* Ident2 */
134*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x4946, 16);
135*437bfbebSnyanmisaka     /* Ident3 */
136*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x00, 8);
137*437bfbebSnyanmisaka     /* Version */
138*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x0102, 16);
139*437bfbebSnyanmisaka 
140*437bfbebSnyanmisaka     if (syntax.density_x && syntax.density_y) {
141*437bfbebSnyanmisaka         /* Units */
142*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, syntax.units_type, 8);
143*437bfbebSnyanmisaka         /* Xdensity */
144*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, syntax.density_x, 16);
145*437bfbebSnyanmisaka         /* Ydensity */
146*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, syntax.density_y, 16);
147*437bfbebSnyanmisaka     } else {
148*437bfbebSnyanmisaka         /* Units */
149*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, 0, 8);
150*437bfbebSnyanmisaka         /* Xdensity */
151*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, 0, 8);
152*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, 1, 8);
153*437bfbebSnyanmisaka         /* Ydensity */
154*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, 1, 16);
155*437bfbebSnyanmisaka     }
156*437bfbebSnyanmisaka     /* XThumbnail */
157*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x00, 8);
158*437bfbebSnyanmisaka     /* YThumbnail */
159*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bits, 0x00, 8);
160*437bfbebSnyanmisaka     /* Do NOT write thumbnail */
161*437bfbebSnyanmisaka     size = mpp_writer_bytes(bits);
162*437bfbebSnyanmisaka     mpp_packet_set_length(pkt, size);
163*437bfbebSnyanmisaka     task->length += size;
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     return MPP_OK;
166*437bfbebSnyanmisaka }
167*437bfbebSnyanmisaka 
init_jpeg_component_info(JpegeSyntax * syntax)168*437bfbebSnyanmisaka static MPP_RET init_jpeg_component_info(JpegeSyntax *syntax)
169*437bfbebSnyanmisaka {
170*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
171*437bfbebSnyanmisaka     JPEGCompInfo *comp_info = (JPEGCompInfo *)syntax->comp_info;
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka     jpege_dbg_input("Chroma format %d\n", syntax->format_out);
174*437bfbebSnyanmisaka 
175*437bfbebSnyanmisaka     if (syntax->format_out == MPP_CHROMA_UNSPECIFIED)
176*437bfbebSnyanmisaka         syntax->format_out = MPP_CHROMA_420;
177*437bfbebSnyanmisaka 
178*437bfbebSnyanmisaka     memset(comp_info, 0, sizeof(JPEGCompInfo) * MAX_NUMBER_OF_COMPONENTS);
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka     switch (syntax->format_out) {
181*437bfbebSnyanmisaka     case MPP_CHROMA_400:
182*437bfbebSnyanmisaka         syntax->nb_components = 1;
183*437bfbebSnyanmisaka         comp_info[0].val = 1 | 1 << 8 | 1 << 16;
184*437bfbebSnyanmisaka         break;
185*437bfbebSnyanmisaka     case MPP_CHROMA_420:
186*437bfbebSnyanmisaka         syntax->nb_components = 3;
187*437bfbebSnyanmisaka         comp_info[0].val = 1 | 2 << 8 | 2 << 16;
188*437bfbebSnyanmisaka         comp_info[1].val = 2 | 1 << 8 | 1 << 16 | 1 << 24;
189*437bfbebSnyanmisaka         comp_info[2].val = 3 | 1 << 8 | 1 << 16 | 1 << 24;
190*437bfbebSnyanmisaka         break;
191*437bfbebSnyanmisaka     case MPP_CHROMA_422:
192*437bfbebSnyanmisaka         syntax->nb_components = 3;
193*437bfbebSnyanmisaka         comp_info[0].val = 1 | 2 << 8 | 1 << 16;
194*437bfbebSnyanmisaka         comp_info[1].val = 2 | 1 << 8 | 1 << 16 | 1 << 24;
195*437bfbebSnyanmisaka         comp_info[2].val = 3 | 1 << 8 | 1 << 16 | 1 << 24;
196*437bfbebSnyanmisaka         break;
197*437bfbebSnyanmisaka     case MPP_CHROMA_444:
198*437bfbebSnyanmisaka         syntax->nb_components = 3;
199*437bfbebSnyanmisaka         comp_info[0].val = 1 | 1 << 8 | 1 << 16;
200*437bfbebSnyanmisaka         comp_info[1].val = 2 | 1 << 8 | 1 << 16 | 1 << 24;
201*437bfbebSnyanmisaka         comp_info[2].val = 3 | 1 << 8 | 1 << 16 | 1 << 24;
202*437bfbebSnyanmisaka         break;
203*437bfbebSnyanmisaka     default:
204*437bfbebSnyanmisaka         syntax->nb_components = 1;
205*437bfbebSnyanmisaka         comp_info[0].val = 1 | 1 << 8 | 1 << 16;
206*437bfbebSnyanmisaka         mpp_err("Unsupported chroma format %d\n", syntax->format_out);
207*437bfbebSnyanmisaka         ret = MPP_ERR_VALUE;
208*437bfbebSnyanmisaka         break;
209*437bfbebSnyanmisaka     }
210*437bfbebSnyanmisaka 
211*437bfbebSnyanmisaka     syntax->mcu_width = comp_info[0].h_sample_factor * DCT_SIZE;
212*437bfbebSnyanmisaka     syntax->mcu_height = comp_info[0].v_sample_factor * DCT_SIZE;
213*437bfbebSnyanmisaka     syntax->mcu_hor_cnt = (syntax->width + syntax->mcu_width - 1) / syntax->mcu_width;
214*437bfbebSnyanmisaka     syntax->mcu_ver_cnt = (syntax->height + syntax->mcu_height - 1) / syntax->mcu_height;
215*437bfbebSnyanmisaka     syntax->mcu_cnt = syntax->mcu_hor_cnt * syntax->mcu_ver_cnt;
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     return ret;
218*437bfbebSnyanmisaka }
219*437bfbebSnyanmisaka 
jpege_proc_hal(void * ctx,HalEncTask * task)220*437bfbebSnyanmisaka static MPP_RET jpege_proc_hal(void *ctx, HalEncTask *task)
221*437bfbebSnyanmisaka {
222*437bfbebSnyanmisaka     JpegeCtx *p = (JpegeCtx *)ctx;
223*437bfbebSnyanmisaka     MppFrame frame = task->frame;
224*437bfbebSnyanmisaka     JpegeSyntax *syntax = &p->syntax;
225*437bfbebSnyanmisaka     MppEncCfgSet *cfg = p->cfg;
226*437bfbebSnyanmisaka     MppEncPrepCfg *prep = &cfg->prep;
227*437bfbebSnyanmisaka     MppEncJpegCfg *jpeg = &cfg->jpeg;
228*437bfbebSnyanmisaka     MppEncSliceSplit *split = &cfg->split;
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     jpege_dbg_func("enter ctx %p\n", ctx);
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     syntax->width       = prep->width;
233*437bfbebSnyanmisaka     syntax->height      = prep->height;
234*437bfbebSnyanmisaka     syntax->hor_stride  = prep->hor_stride;
235*437bfbebSnyanmisaka     syntax->ver_stride  = prep->ver_stride;
236*437bfbebSnyanmisaka     syntax->format      = prep->format;
237*437bfbebSnyanmisaka     syntax->format_out  = prep->format_out;
238*437bfbebSnyanmisaka     syntax->color       = prep->color;
239*437bfbebSnyanmisaka     syntax->rotation    = prep->rotation;
240*437bfbebSnyanmisaka     syntax->mirroring   = prep->mirroring;
241*437bfbebSnyanmisaka     syntax->offset_x    = mpp_frame_get_offset_x(frame);
242*437bfbebSnyanmisaka     syntax->offset_y    = mpp_frame_get_offset_y(frame);
243*437bfbebSnyanmisaka     syntax->q_mode      = jpeg->q_mode;
244*437bfbebSnyanmisaka     syntax->quant       = jpeg->quant;
245*437bfbebSnyanmisaka     syntax->q_factor    = jpeg->q_factor;
246*437bfbebSnyanmisaka     syntax->qf_min      = jpeg->qf_min;
247*437bfbebSnyanmisaka     syntax->qf_max      = jpeg->qf_max;
248*437bfbebSnyanmisaka     syntax->qtable_y    = jpeg->qtable_y;
249*437bfbebSnyanmisaka     syntax->qtable_u    = jpeg->qtable_u;
250*437bfbebSnyanmisaka     syntax->qtable_v    = jpeg->qtable_v;
251*437bfbebSnyanmisaka     syntax->part_rows   = 0;
252*437bfbebSnyanmisaka     syntax->restart_ri  = 0;
253*437bfbebSnyanmisaka     syntax->low_delay   = 0;
254*437bfbebSnyanmisaka 
255*437bfbebSnyanmisaka     init_jpeg_component_info(syntax);
256*437bfbebSnyanmisaka 
257*437bfbebSnyanmisaka     if (split->split_mode) {
258*437bfbebSnyanmisaka         RK_U32 mb_w = syntax->mcu_hor_cnt;
259*437bfbebSnyanmisaka         RK_U32 mb_h = syntax->mcu_ver_cnt;
260*437bfbebSnyanmisaka         RK_U32 part_rows = 0;
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka         if (split->split_mode == MPP_ENC_SPLIT_BY_CTU) {
263*437bfbebSnyanmisaka             RK_U32 part_mbs = split->split_arg;
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka             if (part_mbs > 0 && part_mbs <= syntax->mcu_cnt) {
266*437bfbebSnyanmisaka                 part_rows = (part_mbs + mb_w - 1) / mb_w;
267*437bfbebSnyanmisaka                 if (part_rows >= mb_h)
268*437bfbebSnyanmisaka                     part_rows = 0;
269*437bfbebSnyanmisaka             } else {
270*437bfbebSnyanmisaka                 mpp_err_f("warning: invalid split arg %d > max %d\n",
271*437bfbebSnyanmisaka                           part_mbs, syntax->mcu_cnt);
272*437bfbebSnyanmisaka             }
273*437bfbebSnyanmisaka         } else {
274*437bfbebSnyanmisaka             mpp_err_f("warning: only mcu split is supported\n");
275*437bfbebSnyanmisaka         }
276*437bfbebSnyanmisaka 
277*437bfbebSnyanmisaka         if (part_rows) {
278*437bfbebSnyanmisaka             syntax->part_rows   = part_rows;
279*437bfbebSnyanmisaka             if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3576 && split->split_arg <= syntax->mcu_cnt)
280*437bfbebSnyanmisaka                 syntax->restart_ri = split->split_arg;
281*437bfbebSnyanmisaka             else
282*437bfbebSnyanmisaka                 syntax->restart_ri  = syntax->mcu_hor_cnt * part_rows;
283*437bfbebSnyanmisaka             syntax->low_delay   = cfg->base.low_delay && part_rows;
284*437bfbebSnyanmisaka             jpege_dbg_func("Split by CTU, part_rows %d, restart_ri %d",
285*437bfbebSnyanmisaka                            syntax->part_rows, syntax->restart_ri);
286*437bfbebSnyanmisaka         }
287*437bfbebSnyanmisaka     }
288*437bfbebSnyanmisaka 
289*437bfbebSnyanmisaka     task->valid = 1;
290*437bfbebSnyanmisaka     task->syntax.data = syntax;
291*437bfbebSnyanmisaka     task->syntax.number = 1;
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka     jpege_dbg_func("leave ctx %p\n", ctx);
294*437bfbebSnyanmisaka     return MPP_OK;
295*437bfbebSnyanmisaka }
296*437bfbebSnyanmisaka 
jpege_add_Prefix(MppPacket pkt,RK_S32 * len,RK_U8 uuid[16],const void * data,RK_S32 size)297*437bfbebSnyanmisaka static MPP_RET jpege_add_Prefix(MppPacket pkt, RK_S32 *len, RK_U8 uuid[16],
298*437bfbebSnyanmisaka                                 const void *data, RK_S32 size)
299*437bfbebSnyanmisaka {
300*437bfbebSnyanmisaka     RK_U8 *ptr = mpp_packet_get_pos(pkt);
301*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(pkt);
302*437bfbebSnyanmisaka     size_t buf_size = mpp_packet_get_size(pkt);
303*437bfbebSnyanmisaka     MppWriteCtx bit_ctx;
304*437bfbebSnyanmisaka     MppWriteCtx *bits = &bit_ctx;
305*437bfbebSnyanmisaka     const RK_U8 *user_data = data;
306*437bfbebSnyanmisaka     RK_S32 i = 0, app_size = 0;
307*437bfbebSnyanmisaka 
308*437bfbebSnyanmisaka     mpp_writer_init(bits, ptr + length, buf_size - length);
309*437bfbebSnyanmisaka 
310*437bfbebSnyanmisaka     if ((size > 8) && user_data[0] == 0xFF && user_data[1] == 0xE1 &&
311*437bfbebSnyanmisaka         user_data[4] == 0x45 && user_data[5] == 0x78 &&
312*437bfbebSnyanmisaka         user_data[6] == 0x69 && user_data[7] == 0x66) {
313*437bfbebSnyanmisaka         jpege_dbg_func("write EXIF data, total length %d\n", size);
314*437bfbebSnyanmisaka     } else if ((size > 8) && user_data[0] == 0xFF && user_data[1] == 0xE2 &&
315*437bfbebSnyanmisaka                user_data[4] == 0x4D && user_data[5] == 0x50 &&
316*437bfbebSnyanmisaka                user_data[6] == 0x46 && user_data[7] == 0x00) {
317*437bfbebSnyanmisaka         jpege_dbg_func("write MPF data, total length %d\n", size);
318*437bfbebSnyanmisaka     } else {
319*437bfbebSnyanmisaka         /* add user data to APP7 */
320*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, 0xFFE7, 16);
321*437bfbebSnyanmisaka         /* length */
322*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, size + 2, 16);
323*437bfbebSnyanmisaka     }
324*437bfbebSnyanmisaka 
325*437bfbebSnyanmisaka     /* data */
326*437bfbebSnyanmisaka     for (i = 0; i < size; i++)
327*437bfbebSnyanmisaka         mpp_writer_put_raw_bits(bits, user_data[i], 8);
328*437bfbebSnyanmisaka 
329*437bfbebSnyanmisaka     app_size = mpp_writer_bytes(bits);
330*437bfbebSnyanmisaka     *len = app_size;
331*437bfbebSnyanmisaka     length += app_size;
332*437bfbebSnyanmisaka     mpp_packet_set_length(pkt, length);
333*437bfbebSnyanmisaka     (void)uuid;
334*437bfbebSnyanmisaka     return MPP_OK;
335*437bfbebSnyanmisaka }
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka const EncImplApi api_jpege = {
338*437bfbebSnyanmisaka     .name       = "jpege_control",
339*437bfbebSnyanmisaka     .coding     = MPP_VIDEO_CodingMJPEG,
340*437bfbebSnyanmisaka     .ctx_size   = sizeof(JpegeCtx),
341*437bfbebSnyanmisaka     .flag       = 0,
342*437bfbebSnyanmisaka     .init       = jpege_init_v2,
343*437bfbebSnyanmisaka     .deinit     = jpege_deinit_v2,
344*437bfbebSnyanmisaka     .proc_cfg   = jpege_proc_cfg,
345*437bfbebSnyanmisaka     .gen_hdr    = NULL,
346*437bfbebSnyanmisaka     .start      = jpege_start,
347*437bfbebSnyanmisaka     .proc_dpb   = NULL,
348*437bfbebSnyanmisaka     .proc_hal   = jpege_proc_hal,
349*437bfbebSnyanmisaka     .add_prefix = jpege_add_Prefix,
350*437bfbebSnyanmisaka     .sw_enc     = NULL,
351*437bfbebSnyanmisaka };
352