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