rockchip-linux / mpp

Media Process Platform (MPP) module
468 stars 156 forks source link

关于decode_put_packet的问题 #569

Closed Kevin111369 closed 2 months ago

Kevin111369 commented 2 months ago

MPP实例默认可以接收4个输入码流包在处理队列中,是否意味着开始解码之后,必须等够四帧解码器才开始解码呢?如果是实时解码,开始的时候需要等待四帧才出第一帧,画面延迟有点大,如何设置才能做到送进去第一帧之后就出图呢?

HermanChen commented 2 months ago

有码流包就开始处理了,速度不够才会堆积起来,所以不会等四帧才开始解码 把 base:fast_out 开起来,这个是解码序输出,同时把 base:split_parse 关了,这样就不会做内部分帧,基本上就是进一帧出一帧。 但是这对码流有要求,要是 IPPPP 这样的码流

Kevin111369 commented 2 months ago

base:fast_out

1、只能是IPPPP这种吗?不能带有B帧? 2、我使用base:fast_out第一个I帧送进去可以拿到frame,紧接着的P帧送进去之后get_frame一直为空(通过使用ESEyE查看h264文件,确定第二帧送进去的是完整的P帧)

Kevin111369 commented 2 months ago

@HermanChen 我查看了历史issue,看到您说使用output设置为阻塞式,我使用了这个方法,代码如下:

// NOTE: timeout value please refer to MppPollType definition
//  0   - non-block call (default)
// -1   - block call
// +val - timeout value in ms
{
    MppPollType timeout = MPP_POLL_BLOCK;
    MppParam param = &timeout;
    mpp_ret = mpp_mpi->control(mpp_ctx, MPP_SET_OUTPUT_TIMEOUT, param);
    if (mpp_ret) {
        mpp_err("Failed to set output timeout %d ret %d\n", timeout, mpp_ret);
        return mpp_ret;
    }
}

使用这个方法,程序就会卡在第二帧,输出结果如下:

[dec_simple]-232: av_packet->data:0x3f3da420
[dec_simple]-233: av_packet->size:41808
mpp[15231]: mpi: mpi_decode_put_packet enter ctx 0x3f47af60 packet 0x3f47adc8
mpp[15231]: mpi: mpi_decode_put_packet leave ctx 0x3f47af60 ret 0
mpp[15231]: mpi: mpi_decode_get_frame enter ctx 0x3f47af60 frame 0x7fe6a724d8
mpp[15231]: h264d_sei: SEI type 5, payload size: 681
mpp[15231]: h264d_sei: After parsing SEI 5, bits left int cur byte 0, bits_used 5448, bytes left 0
mpp[15231]: mpi: mpi_decode_get_frame leave ctx 0x3f47af60 ret 0
[dec_simple]-305: 0x3f47af60 decode get frame 0
[dec_simple]-232: av_packet->data:0x3f47b0d0
[dec_simple]-233: av_packet->size:18413
mpp[15231]: mpi: mpi_decode_put_packet enter ctx 0x3f47af60 packet 0x3f47adc8
mpp[15231]: mpi: mpi_decode_put_packet leave ctx 0x3f47af60 ret 0
mpp[15231]: mpi: mpi_decode_get_frame enter ctx 0x3f47af60 frame 0x7fe6a724d8
HermanChen commented 2 months ago

base:fast_out

1、只能是IPPPP这种吗?不能带有B帧? 2、我使用base:fast_out第一个I帧送进去可以拿到frame,紧接着的P帧送进去之后get_frame一直为空(通过使用ESEyE查看h264文件,确定第二帧送进去的是完整的P帧)

  1. 如果要开 fast_out 的话,B 帧的解码序和显示序不一定一致,会有问题
  2. 参考 mpi_dec_test 看下是不是 info change 的帧
Kevin111369 commented 2 months ago

base:fast_out

1、只能是IPPPP这种吗?不能带有B帧? 2、我使用base:fast_out第一个I帧送进去可以拿到frame,紧接着的P帧送进去之后get_frame一直为空(通过使用ESEyE查看h264文件,确定第二帧送进去的是完整的P帧)

  1. 如果要开 fast_out 的话,B 帧的解码序和显示序不一定一致,会有问题
  2. 参考 mpi_dec_test 看下是不是 info change 的帧

@HermanChen 您好,我参考了您在咨询MPP解码block模式 #435中提到的思路:使用纯外部模式分配好,一开始就 commit 进来,info change 的帧都不会出,可以直接出第一帧。请问您说的这个方式就是mpi_dec_test中使用dec_advanced解码的方式吗?

HermanChen commented 2 months ago

advanced 指的是用 enqueue / dequeue 这一套接口,并不是 commit buffer 的这种方式

Kevin111369 commented 2 months ago

advanced 指的是用 enqueue / dequeue 这一套接口,并不是 commit buffer 的这种方式

在mpp初始化的时候,我借鉴了type=MPP_VIDEO_CodingMJPEG的初始化方式,提前初始化了output_frame,mpp_group,并将mpp_group中的mpp_buffer与frame绑定起来,这样是您说的commit buffer方式吗?

HermanChen commented 2 months ago

这种做法只适合 jpeg 格式,视频连续流的格式没法这样处理

Kevin111369 commented 2 months ago

@HermanChen 如果使用dec_simple的方式解码,在第一帧解码完成之后才去初始化frame_buffer,那么第一帧解码的数据就不会被存起来,所以始终会有一帧的延迟?

HermanChen commented 2 months ago

第一帧开始解头的时候,会上报 info change 信息的帧,外部给入 buffer 之后,会自动开始解码第一帧,再去取数据就好,不需要等第二帧数据来

Kevin111369 commented 2 months ago

第一帧开始解头的时候,会上报 info change 信息的帧,外部给入 buffer 之后,会自动开始解码第一帧,再去取数据就好,不需要等第二帧数据来

谢谢你的回答,在读取到info change信息之后,完成buffer配置,然后再调用decode_get_frame就会得到第一帧数据