HermanChen / mpp

Rockchip MPP(Media Process Platfrom)
162 stars 73 forks source link

JPEG持续编码段错误(除数为零) #30

Closed Justa-Cai closed 3 years ago

Justa-Cai commented 3 years ago

测试分支

develop

对应commit

d1e47f8137c8c568fe47c42fa9723b88aa016d8f

问题描述

jpeg持续编码,会出现除数为零的异常错误

测试命令

adb shell /app/bin/mpi_enc_test -i /tmp/1.yuv -o /tmp/1.jpg -t 8 -f 0 -w 1920 -h 1080

测试文件

1.yuv.zip

crash信息

11-18 01:43:31.772 5706 5706 F DEBUG : Build fingerprint: 'rockchip/rk3288/XL10:9/PQ3B.190801.002/111631.910.230.101.43:userdebug/dev-keys' 11-18 01:43:31.772 5706 5706 F DEBUG : Revision: '0' 11-18 01:43:31.772 5706 5706 F DEBUG : ABI: 'arm' 11-18 01:43:31.773 5706 5706 F DEBUG : pid: 5701, tid: 5703, name: mpp_enc >>> /app/bin/mpi_enc_test <<< 11-18 01:43:31.773 5706 5706 F DEBUG : signal 8 (SIGFPE), code -6 (SI_TKILL), fault addr -------- 11-18 01:43:31.773 5706 5706 F DEBUG : r0 00000000 r1 00001647 r2 00000008 r3 083522a0 11-18 01:43:31.773 5706 5706 F DEBUG : r4 083522a0 r5 00000000 r6 b2d9bd50 r7 0000010c 11-18 01:43:31.773 5706 5706 F DEBUG : r8 b29c7000 r9 000000a0 r10 0005451c r11 00000000 11-18 01:43:31.773 5706 5706 F DEBUG : ip 00771078 sp b2941550 lr b2d5e504 pc b2be47c8 11-18 01:43:31.787 5706 5706 F DEBUG : 11-18 01:43:31.787 5706 5706 F DEBUG : backtrace: 11-18 01:43:31.787 5706 5706 F DEBUG : #00 pc 000557c8 /system/lib/libc.so (tgkill+12) 11-18 01:43:31.787 5706 5706 F DEBUG : #01 pc 000d6500 /vendor/lib/libmpp.so (aeabi_idiv0+8) 11-18 01:43:31.787 5706 5706 F DEBUG : #02 pc 000b5658 /vendor/lib/libmpp.so (bits_model_alloc+68) 11-18 01:43:31.787 5706 5706 F DEBUG : #03 pc 000b5e50 /vendor/lib/libmpp.so (calc_vbr_ratio+124) 11-18 01:43:31.788 5706 5706 F DEBUG : #04 pc 000b7810 /vendor/lib/libmpp.so (rc_model_v2_start+508) 11-18 01:43:31.788 5706 5706 F DEBUG : #05 pc 00023938 /vendor/lib/libmpp.so (mpp_enc_thread(void*)+5988) 11-18 01:43:31.788 5706 5706 F DEBUG : #06 pc 00064303 /system/lib/libc.so (pthread_start(void*)+22) 11-18 01:43:31.788 5706 5706 F DEBUG : #07 pc 0001df8d /system/lib/libc.so (__start_thread+32)

对应堆栈信息

bits_model_alloc
/home/justa/work/opensource/mpp-master/mpp/codec/rc/rc_model_v2.c:337

image

测试修改补丁

 diff --git a/mpp/codec/rc/rc_model_v2.c b/mpp/codec/rc/rc_model_v2.c
 index 731514db..a74b6076 100644
 --- a/mpp/codec/rc/rc_model_v2.c
 +++ b/mpp/codec/rc/rc_model_v2.c
 @@ -332,6 +332,8 @@ MPP_RET bits_model_alloc(RcModelV2Ctx *ctx, EncRcTaskInfo *cfg, RK_S64 total_bit
      RK_S32 vi_scale = ctx->vi_scale;
      RK_S32 alloc_bits = 0;
 +    // 这里是出错位置,除数为0,不确认是否能否这样子规避,这只是段错误的原点,但理论应该有逻辑错误
 +    // if (ctx->p_sumbits == 0)
 +    //     ctx->p_sumbits = 1;
      ctx->i_scale = 80 * ctx->i_sumbits / (2 * ctx->p_sumbits);
      i_scale = ctx->i_scale;

 diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c
 index 4e7b45b8..03ad8a6f 100644
 --- a/test/mpi_enc_test.c
 +++ b/test/mpi_enc_test.c
 @@ -140,7 +140,7 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd)
      p->num_frames   = cmd->num_frames;
      if (cmd->type == MPP_VIDEO_CodingMJPEG && p->num_frames == 0) {
          mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
 -        p->num_frames   = 1;
 +        p->num_frames   = 30*10;
      }
      p->gop_mode     = cmd->gop_mode;
      p->gop_len      = cmd->gop_len;
 @@ -500,6 +500,7 @@ MPP_RET test_mpp_run(MpiEncTestData *p)
                      clearerr(p->fp_input);
                      rewind(p->fp_input);
                      p->frm_eos = 0;
 +                    rewind(p->fp_output);
                      mpp_log("%p loop times %d\n", ctx, ++p->loop_times);
                      continue;
                  }
HermanChen commented 3 years ago

问下,上层 mpi_enc_test 有修改哪些实现? 正常 jpeg 编码是单帧模式,是否在修改为多帧模式时有所遗漏? 这个点的确是需要修正,但问题的根源可能是在其他地方。

Justa-Cai commented 3 years ago

mpi_enc_test 修改如下:

 index 4e7b45b8..03ad8a6f 100644
 --- a/test/mpi_enc_test.c
 +++ b/test/mpi_enc_test.c
 @@ -140,7 +140,7 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd)
      p->num_frames   = cmd->num_frames;
      if (cmd->type == MPP_VIDEO_CodingMJPEG && p->num_frames == 0) {
          mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
 -        p->num_frames   = 1;
 +        p->num_frames   = 30*10;
      }
      p->gop_mode     = cmd->gop_mode;
      p->gop_len      = cmd->gop_len;
 @@ -500,6 +500,7 @@ MPP_RET test_mpp_run(MpiEncTestData *p)
                      clearerr(p->fp_input);
                      rewind(p->fp_input);
                      p->frm_eos = 0;
 +                    rewind(p->fp_output);
                      mpp_log("%p loop times %d\n", ctx, ++p->loop_times);
                      continue;
                  }