mpp
mpp copied to clipboard
mpp_dec_parser线程解码MJPEG崩溃
平台:RK3399
解码库: mpp[28787]: mpp_info: mpp version: 33784aca author: Yandong Lin 2021-05-21 [rkv_enc_cmd]: Fix check info err when enc_cfg_set
结论:问题主要是我这边代码错误处理不好;同时有发现mpp有个空指针没有判断,麻烦完善一下。
详细信息: 崩溃栈如下
[root@root:/sn_app/apps/lib]# gdb node /app_data/core-mpp_dec_parser
GNU gdb (GDB) 8.1.1
[New LWP 28801]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
bt
Core was generated by `'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 mpp_frame_set_width (s=s@entry=0x0, v=1920)
at /media/xys/ssdext4/rk3399_linux_release/buildroot/output/rockchip_rk3399/build/mpp-release/mpp/base/mpp_frame.cpp:279
279 /media/xys/ssdext4/rk3399_linux_release/buildroot/output/rockchip_rk3399/build/mpp-release/mpp/base/mpp_frame.cpp: No such file or directory.
[Current thread is 1 (Thread 0x7f421ff1c0 (LWP 28901))]
(gdb) bt
#0 mpp_frame_set_width (s=s@entry=0x0, v=1920)
at /media/xys/ssdext4/rk3399_linux_release/buildroot/output/rockchip_rk3399/build/mpp-release/mpp/base/mpp_frame.cpp:279
#1 0x0000007f8d0a0f5c in mpp_dec_advanced_thread (data=0x18f6faa0)
at /media/xys/ssdext4/rk3399_linux_release/buildroot/output/rockchip_rk3399/build/mpp-release/mpp/codec/mpp_dec.cpp:1425
#2 0x0000007fa6c607e4 in start_thread () from /lib/libpthread.so.0
#3 0x0000007fa6bb96bc in ?? () from /lib/libc.so.6
(gdb)
最开始是在旧版mpp库发现的崩溃,后面确认原因后在新库确认了一下,也会出现这个问题(因为相关代码没改) 有点奇怪的是旧库会在串口打印如下内容,但是新库没打印
mpp[2304]: jpegd_parser: jpegd_decode_frame EOI marker not found!
mpp[2304]: mpp_dec: mpp_dec_advanced_thread something wrong with mpp_parser_parse!
只搜到打印了这些内容
mpp[28787]: mpp_frame: check_is_mpp_frame pointer (nil) failed on check
mpp[28787]: mpp_buffer: mpp_buffer_get_size invalid NULL input from mpp_dec_advanced_thread
mpp[28787]: mpp_dec: mpp_dec_advanced_thread required buffer size 4177920 is larger than input buffer size 0
mpp[28787]: mpp_dec: Assertion slot_size <= buffer_size failed at mpp_dec_advanced_thread:1405
mpp[28787]: mpp_buf_slot: mpp_buf_slot_set_prop found invalid input slots 0x18f708a0 type 2 val (nil)
mpp[28787]: mpp_buffer: mpp_buffer_get_fd invalid NULL input from hal_jpegd_vdpu2_gen_regs
[66947.499251] rk_vcodec: reg_init:1487: error: translate reg address failed, dumping regs
[66947.500324] rk-vcodec ff650000.vpu_service: reg[00]: 00000030
错误原因大概分析:
- MJPEG数据来自一个USB摄像头,由于某些原因收到了一些不完整的MJPEG数据,4096字节,然后只有0xFFD8(SOI)没有0xFFD9(EOI),调用程序直接把这个数据送入mpp了
- mpp会在处理到这样的线程的时候报错 但是调用者没有做好错误处理,相关的内存没释放
- 导致在崩溃前,调用者调用
mpp_buffer_get()
取不到之前导入的外部内存,然后调用mpi->enqueue(ctx, MPP_PORT_INPUT, task)
时候,task附带的KEY_OUTPUT_FRAME实际是个空指针。 - 最后
mpp_dec_advanced_thread
在取到task
的时候只判断packet是否为空,没有判断frame是否为空:
mpp_task_meta_get_packet(mpp_task, KEY_INPUT_PACKET, &packet);
mpp_task_meta_get_frame (mpp_task, KEY_OUTPUT_FRAME, &frame);
if (NULL == packet) {
mpp_port_enqueue(input, mpp_task);
task.status.mpp_pkt_in_rdy = 0;
continue;
}
我会去好好修正一下调用程序的代码,然后mpp这边的错误检测麻烦完善一下,谢谢