Использование ffmpeg avcodec_receive_frame () и почему я иногда получаю эти вертикальные линии в декодированном изображении - PullRequest
0 голосов
/ 07 июля 2019

Я использую современный API ffmpeg, который инструктирует меня использовать avcodec_send_packet и avcodec_receive_frame.Буквально нет примеров использования в github , поэтому я не мог сравнить с другим кодом.

Мой код вроде работает, но иногда, менее чем за секунду или две, видео декодируется так:

enter image description here

Я подумал, что это проблема размера буфера, поэтому я увеличил значение с

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;
        }
    }

}

Я думаю, что людикто знает, как работает декодирование, может сразу узнать, почему изображение декодируется таким образом.Было бы очень полезно узнать почему.Спасибо!

...