【问题标题】:FFmpeg - avcodec_receive_frame returns AVERROR(EAGAIN)FFmpeg - avcodec_receive_frame 返回 AVERROR(EAGAIN)
【发布时间】:2019-11-09 01:26:28
【问题描述】:

我正在使用 QOpenGL 小部件来绘制框架。但是,我很难通过使用avcodec_receive_frame 来获取帧。它在 else if (ret == AVERROR(EAGAIN)) 块内结束并返回 -11。我不知道是什么造成了这种情况。我还检查了编解码器是否正常,所以我猜这个问题不是由编解码器引起的。

MyDemux.cpp

AVPacket* MyDemux::allocatePacket()
{
    AVPacket* packet = av_packet_alloc();
    return packet;
}

AVFrame* MyDemux::allocateFrame()
{
    AVFrame* frame = av_frame_alloc();
    return frame;
}

int MyDemux::readFrame(AVPacket* packet)
{
    mux.lock();
    if (!formatCtx) {
        std::cout << "formaetCtx is null" << std::endl;
        mux.unlock();
        return -1;
    }
    int ret = av_read_frame(formatCtx, packet);
    if (ret == AVERROR_EOF) {
        return -2;
    }
    if (ret != 0) {
        mux.unlock();
        av_packet_free(&packet);
        return -1;
    }
    media_type = packet->stream_index;
    mux.unlock();
    return 0;
}

MyDecode.cpp

void MyDecode::decode(AVFrame* frame, AVPacket* packet)
{
    int ret;
    ret = avcodec_send_packet(codecCtx, packet); // this returned 0
    while (ret == 0) {
        ret = avcodec_receive_frame(codecCtx, frame); // this returned -11
        if (ret == AVERROR(EINVAL)) {
            std::cout << "codec issue" << std::endl;
            av_frame_free(&frame);
            return;
        }
        else if (ret == AVERROR(EAGAIN)) { // program ends here
            std::cout << "output is not available this state" << std::endl;
            av_frame_free(&frame);
            return;
        }
        else if (ret == AVERROR(EINVAL)) {
            std::cout << "no more frames" << std::endl;
            av_frame_free(&frame);
            return;
        }
    }
}

ma​​in.cpp

class MyThread : public QThread
{
public:

    MyDemux demux;
    MyDecode video_decode;
    myDecode audio_decode;
    MyVideoWidget* videoWidget;
    AVPacket* packet;
    AVFrame* frame;

    void initThread()
    {
        char* url = "demo.mp4";
        demux.openFile(url);
        video_decode.openCodec(demux.copy_video_codec_par());
        audio_decode.openCodec(demux.copy_audio_codec_par());
        packet = demux.allocatePacket();
        frame = demux.allocateFrame();
    }
    void run()
    {
        while (demux.readFrame(packet) != -2) {
            if (demux.get_media_type() == 0) {
                video_decode.decode(frame, packet);
                videoWidget->paintFrame(frame);
            }
            else if (demux.get_media_type() == 1) {
            }
        }
        video_decode.decode(frame, nullptr);
        demux.clear();
        demux.close();
    }
};

【问题讨论】:

    标签: ffmpeg decoding


    【解决方案1】:

    发送和接收帧之间存在延迟。当接收返回 EAGAIN 时,您应该使用下一个编码帧调用发送,然后再次调用接收。

    【讨论】:

    • 对不起,我不太清楚你的意思。 avcodec_send_packet 位于 avcodec_receive_frame 之前。而且它们也是在 main 方法中的 while 循环中实现的
    • 您必须继续使用新数据调用 avcodec_send_frame,直到 avcode_receive_frame 返回有效帧。
    【解决方案2】:

    当您调用 avcodec_receive_frame 并收到 EAGAIN 错误时,这意味着您的解码器没有获得足够的数据来解码(例如,您在视频中发送了 B 帧)。因此,每次遇到该错误时,您都应该忽略它并转到下一个 avcodec_send_packet

    【讨论】:

      猜你喜欢
      • 2019-11-29
      • 2012-07-19
      • 2018-09-10
      • 2019-06-14
      • 2018-01-03
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      相关资源
      最近更新 更多