在为h264调用avcodec时收到FFmpeg AVERROR(EAGAIN)错误

时间:2019-03-29 16:38:58

标签: c++ ffmpeg h.264 decoding

我正在使用ffmpeg 4.1,并且正在显示多个摄像机(h264和h265)的实时流。

我的程序收集相同帧的数据包,然后调用encodeVideo函数。实际上,它会一次发送一帧的所有数据包。

如果没有丢失的数据包,程序运行良好。当我删除随机I帧中的数据包时,h264和h265流均按预期工作(会跳过几秒钟,但仍继续流传输)。

当我从h265流中删除随机P帧中的数据包时,avcodec_send_packet函数将给出AVERROR_INVALIDDATA,并且流将继续。

但是,当我从h264流中删除随机P帧中的数据包时,avcodec_send_packet函数将给出0。然后,avcodec_receive_frame函数将连续给出AVERROR(EAGAIN)并且流冻结。

void decodeVideo(array<uint8_t>^ data, int length, AvFrame^ finishedFrame)
{   
    AVPacket* videoPacket = new AVPacket();
    av_init_packet(videoPacket);
    pin_ptr<unsigned char> dataPtr = &data[0];
    videoPacket->data = dataPtr;
    videoPacket->size = length;             

    int retVal = avcodec_send_packet((AVCodecContext*)context, videoPacket);
    if(retVal < 0)
    {
        if (retVal == AVERROR_EOF)
            Utility::Log->ErrorFormat("avcodec_send_packet() return value is AVERROR_EOF.");
        else if( retVal == AVERROR_INVALIDDATA)
            Utility::Log->ErrorFormat("avcodec_send_packet() INVALID DATA!");
        else
            Utility::Log->ErrorFormat("avcodec_send_packet() return value is negative:{0}",retVal);
    }
    else
    {                   
        int receive_frame = avcodec_receive_frame((AVCodecContext*)context, (AVFrame*)finishedFrame);

        if (receive_frame == AVERROR(EAGAIN))
            Utility::Log->ErrorFormat("avcodec_receive_frame() returns AVERROR(EAGAIN)");
        else if(receive_frame == AVERROR_EOF)
            Utility::Log->ErrorFormat("avcodec_receive_frame() returns AVERROR(AVERROR_EOF)");
        else
            Utility::Log->ErrorFormat("avcodec_receive_frame() return value is negative:{0}",receive_frame);
    }   

    av_packet_unref(videoPacket);
    delete videoPacket;
}

编辑

当我如图所示添加avcodec_flush_buffers时,我的问题得到了暂时解决。但是一段时间后它再次冻结。

if(receive_frame == AVERROR(EAGAIN))
{
    Utility::Log->ErrorFormat("avcodec_receive_frame() returns AVERROR(EAGAIN)");
    avcodec_flush_buffers((AVCodecContext*)context);
}

使用ffmpeg版本4.1.1测试了相同的结果。

查找ffmpeg版本,例如2.5解码功能是不同的,但是当我删除数据包时没有问题。但是我也正在使用h265流。

EDIT2

AVCodecID id = AVCodecID::AV_CODEC_ID_H264;
AVCodec* dec = avcodec_find_decoder(id);
AVCodecContext* decContext = avcodec_alloc_context3(dec);

在这些行之后,我的代码包括以下行。 当我删除它们时,现在没有问题。

if(dec->capabilities & AV_CODEC_CAP_TRUNCATED)
    decContext->flags |= AV_CODEC_FLAG_TRUNCATED;

decContext->flags2 |= AV_CODEC_FLAG2_CHUNKS;

0 个答案:

没有答案