HermanChen / mpp

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

解码 hevc 码流一直报错 PPS id out of range: 0 #56

Closed iysheng closed 11 months ago

iysheng commented 1 year ago

在 RK3568 平台,使用编译出来最新的 mpp 库,解码对方发送的 hevc 码流时,一直报错如下:

mpp[873]: H265D_PARSER: PPS id out of range: 0
mpp[873]: H265D_PARSER: hls_slice_header error ret = -1004
mpp[873]: H265D_PARSER: Error parsing NAL unit #0,error ret = 0xd.
mpp[873]: H265D_PARSER: current stream is no right skip it (nil)

导致无法显示任何图像,请问可能是什么原因呢?

HermanChen commented 1 year ago

估计是开始的 vps / sps / pps 数据给丢了

iysheng commented 1 year ago
  1. 但是用 ffplay 使用软解码是可以解出来并显示的,😂
  2. 请问这种情况还可以有办法使用 mpp 硬解码解出来么?
HermanChen commented 1 year ago

看看 init 的时候有没有 extra_data 没送进来

iysheng commented 1 year ago

这是我的 mpp 初始化函数

  1. 请问你说的 init 的时候,是说的我这边配置解码器的时候么?
  2. 请问你说的 extra_data 是指的是什么呢?
    
    int mpp_hardware_init(MpiDecLoopData *data)
    {
    MPP_RET ret         = MPP_OK;
    size_t file_size    = 0;
// base flow context
MppCtx ctx          = NULL;
MppApi *mpi         = NULL;

// input / output
MppPacket packet    = NULL;
MppFrame  frame     = NULL;

MpiCmd mpi_cmd      = MPP_CMD_BASE;
MppParam param      = NULL;
RK_U32 need_split   = 1;

// MppPollType timeout = 5;

// paramter for resource malloc
RK_U32 width        = 2560;
RK_U32 height       = 1440;
MppCodingType type  = MPP_VIDEO_CodingAVC;

// resources
char *buf           = NULL;
size_t packet_size  = 8*1024;
MppBuffer pkt_buf   = NULL;
MppBuffer frm_buf   = NULL;

printf("mpi_dec_test start\n");
memset(data, 0, sizeof(MpiDecLoopData));

// decoder demo
ret = mpp_create(&ctx, &mpi);

if (MPP_OK != ret) {
    printf("mpp_create failed\n");
    deInit(&packet, &frame, ctx, buf, data);
}

// NOTE: decoder split mode need to be set before init
mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
param = &need_split;
ret = mpi->control(ctx, mpi_cmd, param);
if (MPP_OK != ret) {
    printf("format mpi->control failed\n");
    deInit(&packet, &frame, ctx, buf, data);
}

mpi_cmd = MPP_SET_INPUT_BLOCK;
param = &need_split;
ret = mpi->control(ctx, mpi_cmd, param);
if (MPP_OK != ret) {
    printf("mpi->control failed\n");
    deInit(&packet, &frame, ctx, buf, data);
}

ret = mpp_init(ctx, MPP_CTX_DEC, type);
if (MPP_OK != ret) {
    printf("mpp_init failed\n");
    deInit(&packet, &frame, ctx, buf, data);
}

if 0

mpi_cmd = MPP_DEC_SET_OUTPUT_FORMAT; MppFrameFormat rgba_format = MPP_FMT_ARGB8888;//MPP_FMT_YUV420SP;// MPP_FMT_YUV420SP;//MPP_FMT_RGBA8888; param = &rgba_format; ret = mpi->control(ctx, mpi_cmd, param); if (MPP_OK != ret) { printf("mpi->control failed aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"); deInit(&packet, &frame, ctx, buf, data); } else { printf("mpi->control success bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"); }

endif

data->ctx            = ctx;
data->mpi            = mpi;
data->eos            = 0;
data->packet_size    = packet_size;
data->frame          = frame;
data->frame_count    = 0;

return 0;

}

HermanChen commented 11 months ago

ffmpeg 解封装的时候,会把封装里的 sps/pps 这些数据用一包 extra_data 送下来,如果少了这些数据,后面的码流数据就无法解码了