xref: /OK3568_Linux_fs/external/mpp/mpp/hal/vpu/jpege/hal_jpege_vepu1_v2.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 "hal_jpege_vepu1"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_common.h"
23 #include "mpp_mem.h"
24 #include "mpp_platform.h"
25 
26 #include "mpp_enc_hal.h"
27 #include "vcodec_service.h"
28 
29 #include "hal_jpege_debug.h"
30 #include "hal_jpege_api_v2.h"
31 #include "hal_jpege_base.h"
32 
33 #define VEPU_JPEGE_VEPU1_NUM_REGS 164
34 
35 typedef struct jpege_vepu1_reg_set_t {
36     RK_U32  val[VEPU_JPEGE_VEPU1_NUM_REGS];
37 } jpege_vepu1_reg_set;
38 
hal_jpege_vepu1_init(void * hal,MppEncHalCfg * cfg)39 static MPP_RET hal_jpege_vepu1_init(void *hal, MppEncHalCfg *cfg)
40 {
41     MPP_RET ret = MPP_OK;
42     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
43 
44     mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
45     hal_jpege_dbg_func("enter hal %p cfg %p\n", hal, cfg);
46 
47     /* update output to MppEnc */
48     cfg->type = VPU_CLIENT_VEPU1;
49     ret = mpp_dev_init(&cfg->dev, cfg->type);
50     if (ret) {
51         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
52         return ret;
53     }
54     ctx->dev = cfg->dev;
55 
56     jpege_bits_init(&ctx->bits);
57     mpp_assert(ctx->bits);
58 
59     ret = hal_jpege_vepu_init_rc(&ctx->hal_rc);
60     if (ret)
61         return ret;
62 
63     ctx->cfg = cfg->cfg;
64     ctx->reg_size = sizeof(RK_U32) * VEPU_JPEGE_VEPU1_NUM_REGS;
65     ctx->regs = mpp_calloc_size(void, ctx->reg_size + EXTRA_INFO_SIZE);
66     if (NULL == ctx->regs) {
67         mpp_err_f("failed to malloc vepu1 regs\n");
68         return MPP_NOK;
69     }
70 
71     ctx->regs_out = mpp_calloc_size(void, ctx->reg_size + EXTRA_INFO_SIZE);
72     if (NULL == ctx->regs_out) {
73         mpp_err_f("failed to malloc vepu2 regs\n");
74         return MPP_NOK;
75     }
76 
77     hal_jpege_dbg_func("leave hal %p\n", hal);
78     return MPP_OK;
79 }
80 
hal_jpege_vepu1_deinit(void * hal)81 static MPP_RET hal_jpege_vepu1_deinit(void *hal)
82 {
83     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
84 
85     hal_jpege_dbg_func("enter hal %p\n", hal);
86 
87     if (ctx->bits) {
88         jpege_bits_deinit(ctx->bits);
89         ctx->bits = NULL;
90     }
91 
92     if (ctx->dev) {
93         mpp_dev_deinit(ctx->dev);
94         ctx->dev = NULL;
95     }
96 
97     hal_jpege_vepu_deinit_rc(&ctx->hal_rc);
98 
99     MPP_FREE(ctx->regs);
100     MPP_FREE(ctx->regs_out);
101     hal_jpege_dbg_func("leave hal %p\n", hal);
102     return MPP_OK;
103 }
104 
hal_jpege_vepu1_get_task(void * hal,HalEncTask * task)105 static MPP_RET hal_jpege_vepu1_get_task(void *hal, HalEncTask *task)
106 {
107     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
108     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
109     hal_jpege_dbg_func("enter hal %p\n", hal);
110 
111     memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
112     /* Set rc paramters */
113     hal_jpege_dbg_input("rc_mode %d\n", ctx->cfg->rc.rc_mode);
114     if (ctx->cfg->rc.rc_mode != MPP_ENC_RC_MODE_FIXQP) {
115         if (!ctx->hal_rc.q_factor) {
116             task->rc_task->info.quality_target = syntax->q_factor ? (100 - syntax->q_factor) : 80;
117             task->rc_task->info.quality_min = 100 - syntax->qf_max;
118             task->rc_task->info.quality_max = 100 - syntax->qf_min;
119             task->rc_task->frm.is_intra = 1;
120         } else {
121             task->rc_task->info.quality_target = ctx->hal_rc.last_quality;
122             task->rc_task->info.quality_min = 100 - syntax->qf_max;
123             task->rc_task->info.quality_max = 100 - syntax->qf_min;
124         }
125     }
126     ctx->hal_start_pos = mpp_packet_get_length(task->packet);
127 
128     /* prepare for part encoding */
129     ctx->mcu_y = 0;
130     ctx->mcu_h = syntax->mcu_h;
131     ctx->sw_bit = 0;
132     ctx->part_bytepos = 0;
133     ctx->part_x_fill = 0;
134     ctx->part_y_fill = 0;
135     task->part_first = 1;
136     task->part_last = 0;
137 
138     hal_jpege_dbg_func("leave hal %p\n", hal);
139 
140     return MPP_OK;
141 }
142 
hal_jpege_vepu1_set_extra_info(MppDev dev,JpegeSyntax * syntax,RK_U32 start_mbrow)143 static MPP_RET hal_jpege_vepu1_set_extra_info(MppDev dev, JpegeSyntax *syntax,
144                                               RK_U32 start_mbrow)
145 {
146     MppFrameFormat fmt  = syntax->format;
147     RK_U32 hor_stride   = syntax->hor_stride;
148     RK_U32 ver_stride   = syntax->ver_stride;
149     RK_U32 offset = 0;
150     MppDevRegOffsetCfg trans_cfg;
151 
152     switch (fmt) {
153     case MPP_FMT_YUV420SP :
154     case MPP_FMT_YUV420P : {
155         if (start_mbrow) {
156             offset = 16 * start_mbrow * hor_stride;
157 
158             trans_cfg.reg_idx = 11;
159             trans_cfg.offset = offset;
160             mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
161         }
162 
163         offset = hor_stride * ver_stride + hor_stride * start_mbrow * 16 / 2;
164         if (fmt == MPP_FMT_YUV420P)
165             offset = hor_stride * start_mbrow * 16 / 4 + hor_stride * ver_stride;
166 
167         trans_cfg.reg_idx = 12;
168         trans_cfg.offset = offset;
169         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
170 
171         if (fmt == MPP_FMT_YUV420P)
172             offset = hor_stride * start_mbrow * 16 / 4 + hor_stride * ver_stride * 5 / 4;
173 
174         trans_cfg.reg_idx = 13;
175         trans_cfg.offset = offset;
176         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
177     } break;
178     default : {
179         if (start_mbrow) {
180             offset = start_mbrow * hor_stride;
181 
182             trans_cfg.reg_idx = 11;
183             trans_cfg.offset = offset;
184             mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
185         }
186     } break;
187     }
188 
189     return MPP_OK;
190 }
191 
hal_jpege_vepu1_gen_regs(void * hal,HalEncTask * task)192 static MPP_RET hal_jpege_vepu1_gen_regs(void *hal, HalEncTask *task)
193 {
194     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
195     MppBuffer input  = task->input;
196     MppBuffer output = task->output;
197     JpegeSyntax *syntax = &ctx->syntax;
198     RK_U32 width        = syntax->width;
199     RK_U32 width_align  = MPP_ALIGN(width, 16);
200     RK_U32 height       = syntax->height;
201     MppFrameFormat fmt  = syntax->format;
202     RK_U32 hor_stride   = 0;
203     RK_U32 ver_stride   = MPP_ALIGN(height, 16);
204     JpegeBits bits      = ctx->bits;
205     RK_U32 *regs = (RK_U32 *)ctx->regs;
206     size_t length = mpp_packet_get_length(task->packet);
207     RK_U8  *buf = mpp_buffer_get_ptr(output);
208     size_t size = mpp_buffer_get_size(output);
209     const RK_U8 *qtable[2];
210     RK_S32 bitpos;
211     RK_S32 bytepos;
212     RK_U32 x_fill = 0;
213     RK_U32 y_fill = 0;
214     VepuFormatCfg fmt_cfg;
215     RK_U32 rotation = 0;
216 
217     hal_jpege_dbg_func("enter hal %p\n", hal);
218 
219     // do not support mirroring
220     if (syntax->mirroring)
221         mpp_err_f("Warning: do not support mirroring\n");
222 
223     if (syntax->rotation == MPP_ENC_ROT_90)
224         rotation = 1;
225     else if (syntax->rotation == MPP_ENC_ROT_270)
226         rotation = 2;
227     else if (syntax->rotation != MPP_ENC_ROT_0)
228         mpp_err_f("Warning: only support 90 or 270 degree rotate, request rotate %d", syntax->rotation);
229     if (rotation) {
230         MPP_SWAP(RK_U32, width, height);
231         MPP_SWAP(RK_U32, width_align, ver_stride);
232     }
233 
234     hor_stride = get_vepu_pixel_stride(&ctx->stride_cfg, width,
235                                        syntax->hor_stride, fmt);
236 
237     //hor_stride must be align with 8, and ver_stride mus align with 2
238     if ((hor_stride & 0x7) || (ver_stride & 0x1) || (hor_stride >= (1 << 15))) {
239         mpp_err_f("illegal resolution, hor_stride %d, ver_stride %d, width %d, height %d\n",
240                   syntax->hor_stride, syntax->ver_stride,
241                   syntax->width, syntax->height);
242     }
243 
244     x_fill = (width_align - width) / 4;
245     y_fill = (ver_stride - height);
246     mpp_assert(x_fill <= 3);
247     mpp_assert(y_fill <= 15);
248     ctx->part_x_fill = x_fill;
249     ctx->part_y_fill = y_fill;
250 
251     /* write header to output buffer */
252     jpege_bits_setup(bits, buf, (RK_U32)size);
253     /* seek length bytes data */
254     jpege_seek_bits(bits, length << 3);
255     /* NOTE: write header will update qtable */
256     if (ctx->cfg->rc.rc_mode != MPP_ENC_RC_MODE_FIXQP) {
257         hal_jpege_vepu_rc(ctx, task);
258         qtable[0] = ctx->hal_rc.qtable_y;
259         qtable[1] = ctx->hal_rc.qtable_c;
260     } else {
261         qtable[0] = NULL;
262         qtable[1] = NULL;
263     }
264     write_jpeg_header(bits, syntax, qtable);
265 
266     memset(regs, 0, sizeof(RK_U32) * VEPU_JPEGE_VEPU1_NUM_REGS);
267     regs[11] = mpp_buffer_get_fd(input);
268     regs[12] = mpp_buffer_get_fd(input);
269     regs[13] = regs[12];
270 
271     bitpos = jpege_bits_get_bitpos(bits);
272     bytepos = (bitpos + 7) >> 3;
273     ctx->base = buf;
274     ctx->size = size;
275     ctx->sw_bit = bitpos;
276     ctx->part_bytepos = bytepos;
277 
278     get_msb_lsb_at_pos(&regs[22], &regs[23], buf, bytepos);
279 
280     if (!get_vepu_fmt(&fmt_cfg, fmt)) {
281         RK_U32 deflt_cfg = ((0  & (255)) << 24) |
282                            ((0  & (255)) << 16) |
283                            ((1  & (1)) << 15) |
284                            ((16 & (63)) << 8) |
285                            ((0  & (1)) << 6) |
286                            ((0  & (1)) << 5) |
287                            ((1  & (1)) << 4) |
288                            ((1  & (1)) << 3) |
289                            ((1  & (1)) << 1);
290 
291         regs[2] = deflt_cfg | (fmt_cfg.swap_8_in & 1) |
292                   (fmt_cfg.swap_32_in & 1) << 2 |
293                   (fmt_cfg.swap_16_in & 1) << 14;
294     }
295 
296     regs[5] = mpp_buffer_get_fd(output);
297     if (bytepos)
298         mpp_dev_set_reg_offset(ctx->dev, 5, bytepos);
299 
300     regs[14] = (1 << 31) |
301                (0 << 30) |
302                (0 << 29) |
303                ((width_align >> 4) << 19) |
304                ((ver_stride >> 4) << 10) |
305                (1 << 3) | (2 << 1);
306 
307     regs[15] = (0 << 29) |
308                (0 << 26) |
309                (hor_stride << 12) |
310                (x_fill << 10) |
311                (y_fill << 6) |
312                (fmt_cfg.format << 2) | rotation;
313 
314     regs[24] = size - bytepos;
315 
316     regs[37] = ((bytepos & 7) * 8) << 23;
317 
318     {
319         RK_U32 coeffA;
320         RK_U32 coeffB;
321         RK_U32 coeffC;
322         RK_U32 coeffE;
323         RK_U32 coeffF;
324 
325         switch (syntax->color_conversion_type) {
326         case 0 : {  /* BT.601 */
327             /*
328              * Y  = 0.2989 R + 0.5866 G + 0.1145 B
329              * Cb = 0.5647 (B - Y) + 128
330              * Cr = 0.7132 (R - Y) + 128
331              */
332             coeffA = 19589;
333             coeffB = 38443;
334             coeffC = 7504;
335             coeffE = 37008;
336             coeffF = 46740;
337         } break;
338         case 1 : {  /* BT.709 */
339             /*
340              * Y  = 0.2126 R + 0.7152 G + 0.0722 B
341              * Cb = 0.5389 (B - Y) + 128
342              * Cr = 0.6350 (R - Y) + 128
343              */
344             coeffA = 13933;
345             coeffB = 46871;
346             coeffC = 4732;
347             coeffE = 35317;
348             coeffF = 41615;
349         } break;
350         case 2 : {
351             coeffA = syntax->coeffA;
352             coeffB = syntax->coeffB;
353             coeffC = syntax->coeffC;
354             coeffE = syntax->coeffE;
355             coeffF = syntax->coeffF;
356         } break;
357         default : {
358             mpp_err("invalid color conversion type %d\n",
359                     syntax->color_conversion_type);
360             coeffA = 19589;
361             coeffB = 38443;
362             coeffC = 7504;
363             coeffE = 37008;
364             coeffF = 46740;
365         } break;
366         }
367 
368         regs[53] = coeffA | (coeffB << 16);
369         regs[54] = coeffC | (coeffE << 16);
370         regs[55] = ((fmt_cfg.b_mask & 0x1f) << 26) |
371                    ((fmt_cfg.g_mask & 0x1f) << 21) |
372                    ((fmt_cfg.r_mask & 0x1f) << 16) | coeffF;
373     }
374 
375     regs[20] = ((syntax->part_rows & 0xff) << 16) | jpege_restart_marker[0];
376 
377     regs[14] |= 0x001;
378 
379     {
380         RK_S32 i;
381 
382         for (i = 0; i < 16; i++) {
383             /* qtable need to reorder in particular order */
384             regs[i + 64] = qtable[0][qp_reorder_table[i * 4 + 0]] << 24 |
385                            qtable[0][qp_reorder_table[i * 4 + 1]] << 16 |
386                            qtable[0][qp_reorder_table[i * 4 + 2]] << 8 |
387                            qtable[0][qp_reorder_table[i * 4 + 3]];
388         }
389         for (i = 0; i < 16; i++) {
390             /* qtable need to reorder in particular order */
391             regs[i + 80] = qtable[1][qp_reorder_table[i * 4 + 0]] << 24 |
392                            qtable[1][qp_reorder_table[i * 4 + 1]] << 16 |
393                            qtable[1][qp_reorder_table[i * 4 + 2]] << 8 |
394                            qtable[1][qp_reorder_table[i * 4 + 3]];
395         }
396     }
397 
398     hal_jpege_dbg_func("leave hal %p\n", hal);
399     return MPP_OK;
400 }
401 
hal_jpege_vepu1_start(void * hal,HalEncTask * task)402 static MPP_RET hal_jpege_vepu1_start(void *hal, HalEncTask *task)
403 {
404     MPP_RET ret = MPP_OK;
405     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
406 
407     hal_jpege_dbg_func("enter hal %p\n", hal);
408 
409     hal_jpege_vepu1_set_extra_info(ctx->dev, &ctx->syntax, 0);
410 
411     do {
412         MppDevRegWrCfg wr_cfg;
413         MppDevRegRdCfg rd_cfg;
414         RK_U32 reg_size = ctx->reg_size;
415 
416         wr_cfg.reg = ctx->regs;
417         wr_cfg.size = reg_size;
418         wr_cfg.offset = 0;
419 
420         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
421         if (ret) {
422             mpp_err_f("set register write failed %d\n", ret);
423             break;
424         }
425 
426         rd_cfg.reg = ctx->regs;
427         rd_cfg.size = reg_size;
428         rd_cfg.offset = 0;
429 
430         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
431         if (ret) {
432             mpp_err_f("set register read failed %d\n", ret);
433             break;
434         }
435 
436         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
437         if (ret) {
438             mpp_err_f("send cmd failed %d\n", ret);
439             break;
440         }
441     } while (0);
442 
443     hal_jpege_dbg_func("leave hal %p\n", hal);
444     (void)task;
445     return ret;
446 }
447 
hal_jpege_vepu1_wait(void * hal,HalEncTask * task)448 static MPP_RET hal_jpege_vepu1_wait(void *hal, HalEncTask *task)
449 {
450     MPP_RET ret = MPP_OK;
451     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
452     JpegeBits bits = ctx->bits;
453     RK_U32 *regs = (RK_U32 *)ctx->regs;
454     JpegeFeedback *feedback = &ctx->feedback;
455     RK_U32 val;
456     RK_U32 sw_bit = 0;
457     RK_U32 hw_bit = 0;
458 
459     hal_jpege_dbg_func("enter hal %p\n", hal);
460 
461     if (ctx->dev) {
462         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
463         if (ret)
464             mpp_err_f("poll cmd failed %d\n", ret);
465     }
466 
467     val = regs[1];
468     hal_jpege_dbg_output("hw_status %08x\n", val);
469     feedback->hw_status = val & 0x70;
470     val = regs[24];
471 
472     sw_bit = jpege_bits_get_bitpos(bits);
473     hw_bit = val;
474 
475     // NOTE: hardware will return 64 bit access byte count
476     feedback->stream_length = ((sw_bit / 8) & (~0x7)) + hw_bit / 8;
477     task->length = feedback->stream_length;
478     task->hw_length = task->length - ctx->hal_start_pos;
479     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
480                          sw_bit, hw_bit, feedback->stream_length, task->hw_length);
481 
482     hal_jpege_dbg_func("leave hal %p\n", hal);
483     return ret;
484 }
485 
hal_jpege_vepu1_part_start(void * hal,HalEncTask * task)486 static MPP_RET hal_jpege_vepu1_part_start(void *hal, HalEncTask *task)
487 {
488     MPP_RET ret = MPP_OK;
489     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
490     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
491     RK_U32 mcu_w = syntax->mcu_w;
492     RK_U32 mcu_h = syntax->mcu_h;
493     RK_U32 mcu_y = ctx->mcu_y;
494     RK_U32 part_mcu_h = syntax->part_rows;
495     RK_U32 *regs = (RK_U32 *)ctx->regs;
496     RK_U32 part_enc_h;
497     RK_U32 part_enc_mcu_h;
498     RK_U32 part_y_fill;
499     RK_U32 part_not_end;
500 
501     hal_jpege_dbg_func("enter part start %p\n", hal);
502 
503     /* Fix register for each part encoding */
504     task->part_first = !mcu_y;
505     if (mcu_y + part_mcu_h < mcu_h) {
506         part_enc_h = part_mcu_h * 16;
507         part_enc_mcu_h = part_mcu_h;
508         part_y_fill = 0;
509         part_not_end = 1;
510         task->part_last = 0;
511     } else {
512         part_enc_h = syntax->height - mcu_y * 16;
513         part_enc_mcu_h = MPP_ALIGN(part_enc_h, 16) / 16;;
514         part_y_fill = ctx->part_y_fill;
515         part_not_end = 0;
516         task->part_last = 1;
517     }
518 
519     hal_jpege_dbg_detail("part first %d last %d\n", task->part_first, task->part_last);
520 
521     get_msb_lsb_at_pos(&regs[22], &regs[23], ctx->base, ctx->part_bytepos);
522 
523     regs[24] = ctx->size - ctx->part_bytepos;
524 
525     regs[15] = (regs[15] & 0xfffffc3f) | (part_y_fill << 6);
526 
527     regs[37] = ((ctx->part_bytepos & 7) * 8) << 23;
528 
529     regs[5] = mpp_buffer_get_fd(task->output);
530     if (ctx->part_bytepos)
531         mpp_dev_set_reg_offset(ctx->dev, 5, ctx->part_bytepos);
532 
533     regs[14] = (1 << 31) |
534                (0 << 30) |
535                (0 << 29) |
536                (mcu_w << 19) |
537                (part_enc_mcu_h << 10) |
538                (1 << 3) | (2 << 1) | 1;
539 
540     regs[20] = part_not_end << 24 | jpege_restart_marker[ctx->rst_marker_idx & 7];
541     ctx->rst_marker_idx++;
542 
543     hal_jpege_vepu1_set_extra_info(ctx->dev, syntax, mcu_y);
544     ctx->mcu_y += part_enc_mcu_h;
545 
546     do {
547         MppDevRegWrCfg wr_cfg;
548         MppDevRegRdCfg rd_cfg;
549         RK_U32 reg_size = ctx->reg_size;
550 
551         wr_cfg.reg = ctx->regs;
552         wr_cfg.size = reg_size;
553         wr_cfg.offset = 0;
554 
555         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
556         if (ret) {
557             mpp_err_f("set register write failed %d\n", ret);
558             break;
559         }
560 
561         rd_cfg.reg = ctx->regs_out;
562         rd_cfg.size = reg_size;
563         rd_cfg.offset = 0;
564 
565         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
566         if (ret) {
567             mpp_err_f("set register read failed %d\n", ret);
568             break;
569         }
570 
571         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
572         if (ret) {
573             mpp_err_f("send cmd failed %d\n", ret);
574             break;
575         }
576     } while (0);
577 
578     hal_jpege_dbg_func("leave part start %p\n", hal);
579     (void)task;
580     return ret;
581 }
582 
hal_jpege_vepu1_part_wait(void * hal,HalEncTask * task)583 static MPP_RET hal_jpege_vepu1_part_wait(void *hal, HalEncTask *task)
584 {
585     MPP_RET ret = MPP_OK;
586     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
587     RK_U32 *regs = ctx->regs_out;
588     JpegeFeedback *feedback = &ctx->feedback;
589     RK_U32 hw_bit = 0;
590 
591     hal_jpege_dbg_func("enter part wait %p\n", hal);
592 
593     if (ctx->dev) {
594         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
595         if (ret)
596             mpp_err_f("poll cmd failed %d\n", ret);
597     }
598 
599     hal_jpege_dbg_detail("hw_status %08x\n", regs[1]);
600 
601     hw_bit = regs[24];
602 
603     hal_jpege_dbg_detail("byte pos %d -> %d\n", ctx->part_bytepos,
604                          (ctx->part_bytepos & (~7)) + (hw_bit / 8));
605     ctx->part_bytepos = (ctx->part_bytepos & (~7)) + (hw_bit / 8);
606 
607     feedback->stream_length = ctx->part_bytepos;
608     task->length = ctx->part_bytepos;
609     task->hw_length = task->length - ctx->hal_start_pos;
610 
611     hal_jpege_dbg_detail("stream_length %d, hw_byte %d",
612                          feedback->stream_length, hw_bit / 8);
613 
614     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
615                          ctx->sw_bit, hw_bit, feedback->stream_length, task->hw_length);
616 
617     hal_jpege_dbg_func("leave part wait %p\n", hal);
618     return ret;
619 }
620 
hal_jpege_vepu1_ret_task(void * hal,HalEncTask * task)621 static MPP_RET hal_jpege_vepu1_ret_task(void *hal, HalEncTask *task)
622 {
623     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
624 
625     ctx->hal_rc.last_quality = task->rc_task->info.quality_target;
626     task->rc_task->info.bit_real = ctx->feedback.stream_length * 8;
627     task->hal_ret.data = &ctx->feedback;
628     task->hal_ret.number = 1;
629 
630     return MPP_OK;
631 }
632 
633 const MppEncHalApi hal_jpege_vepu1 = {
634     .name       = "hal_jpege_vepu1",
635     .coding     = MPP_VIDEO_CodingMJPEG,
636     .ctx_size   = sizeof(HalJpegeCtx),
637     .flag       = 0,
638     .init       = hal_jpege_vepu1_init,
639     .deinit     = hal_jpege_vepu1_deinit,
640     .prepare    = NULL,
641     .get_task   = hal_jpege_vepu1_get_task,
642     .gen_regs   = hal_jpege_vepu1_gen_regs,
643     .start      = hal_jpege_vepu1_start,
644     .wait       = hal_jpege_vepu1_wait,
645     .part_start = hal_jpege_vepu1_part_start,
646     .part_wait  = hal_jpege_vepu1_part_wait,
647     .ret_task   = hal_jpege_vepu1_ret_task,
648 };
649