首页 > 解决方案 > 使用 ffmpeg 的 avcodec_receive_frame() 以及为什么有时会在解码图像中得到这些垂直线

问题描述

我正在使用现代 ffmpeg API,它指示我使用avcodec_send_packetavcodec_receive_frame. github中几乎没有使用示例,因此我无法与其他代码进行比较。

我的代码有点工作,但有时,不到一两秒,视频就会像这样解码:

在此处输入图像描述

我认为这是一个缓冲区大小问题,所以我从

const size_t bufferSize = 408304;

const size_t bufferSize = 10408304;

只是看看,但问题仍然存在。

(视频尺寸为 1920x1080,即使屏幕几乎没有运动也会发生这种情况)

这是我的解码器类,它将解码后的数据在线发送到 OpenGL this->frameUpdater->updateData(avFrame->data, avFrame->width, avFrame->height);

    void  FfmpegDecoder::decodeFrame(uint8_t* frameBuffer, int frameLength)
{
    if (frameLength <= 0) return;

    int frameFinished = 0;

    AVPacket* avPacket = av_packet_alloc();
    if (!avPacket) std::cout << "av packet error" << std::endl;

    avPacket->size = frameLength;
    avPacket->data = frameBuffer;

    //Disable ffmpeg annoying output
    av_log_set_level(AV_LOG_QUIET); 

    int sendPacketResult = avcodec_send_packet(avCodecContext, avPacket);
    if (!sendPacketResult) {
        int receiveFrameResult = avcodec_receive_frame(avCodecContext, avFrame);
        if (!receiveFrameResult) {
            this->frameUpdater->updateData(avFrame->data, avFrame->width, avFrame->height);
        } else if ((receiveFrameResult < 0) && (receiveFrameResult != AVERROR(EAGAIN)) && (receiveFrameResult != AVERROR_EOF)) {
            std::cout << "avcodec_receive_frame returned error " << receiveFrameResult /*<< *av_err2str(result).c_str()*/ << std::endl;
        } else {
            switch (receiveFrameResult) {
                //Not exactly an error, we just have to wait for more data
                case AVERROR(EAGAIN):
                    break;
                //To be done: what does this error mean? I think it's literally the end of an mp4 file
                case AVERROR_EOF:
                    std::cout << "avcodec_receive_frame AVERROR_EOF" << std::endl;
                    break;
                //To be done: describe what error is this in std cout before stopping
                default:
                    std::cout << "avcodec_receive_frame returned error, stopping..." << receiveFrameResult /*<< av_err2str(result).c_str()*/ << std::endl;
                    break;
                //Error happened, should break anyway
                break;
            }
        }
    } else {
        switch (sendPacketResult) {
            case AVERROR(EAGAIN):
                std::cout << "avcodec_send_packet EAGAIN" << std::endl;
                break;
            case AVERROR_EOF:
                std::cout << "avcodec_send_packet AVERROR_EOF" << std::endl;
                break;
            default:
                break;
        }
    }

}

我认为知道解码如何工作的人可能会立即知道为什么图像会这样解码。知道为什么会很有帮助。谢谢!

标签: c++videoffmpegdecode

解决方案


推荐阅读