c - 如果我在 FFmpeg 中使用 av_read_frame 会丢失多个帧

标签 c ffmpeg

我有一个 3500 帧的 HEVC 序列,我正在编写一个解码器来读取它(逐帧读取并转储到 yuv)。在我的 main() 中,我有一个调用 decoder() 3500 次的 for 循环(我假设在这个阶段 main() 知道有多少帧)。

因此,每次调用 decoder() 时,我都需要返回一个完整的帧。这就是解码器()的样子..

bool decode(pFormatCtx, pCodecCtx)
{
    int gotaFrame=0;

    while (gotaFrame==0) {

        printf("1\t");

        if ( !av_read_frame(pFormatCtx, &packet) ) { 
            if(packet.stream_index==videoStreamIndex) {

                // try decoding
                avcodec_decode_video2(pCodecCtx, pFrame, &gotaFrame, &packet);

                if (gotaFrame) {  // decode success.

                    printf("2\t");

                    // dump to yuv ... not shown here. 

                    // cleanup
                    av_frame_unref(pFrame);
                    av_frame_free(&pFrame);
                    av_free_packet(&packet);

                    return true;
                }
            }
        }
    }
}

行为是这样的: 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 ...... 看起来它在解码一帧之前读取了几帧?第一帧是 I 帧,所以不应该立即解码吗?

使用这段代码,我最终丢失了几帧(由 1 系列表示)。有人可以帮我吗?我的代码有什么地方做错了吗?

更新:测试剪辑只有视频。没有音频。

最佳答案

您看到的是正确的行为。解码器缓冲一些帧以提高多线程效率。并且它可能需要几个帧才能“启动泵”。基本上,为了让您的程序保持响应,avcodec_decode_video2 将帧排队等待解码,然后返回。这样可以防止你的程序长时间阻塞。对于解码顺序可能与显示顺序不同的B帧,也绝对需要延迟解码。

那么,如何不丢失这些帧呢?在 av_read_frame 停止返回新帧后,您必须通过使用空数据包调用 avcodec_decode_video2 来刷新解码器,直到不再有帧返回。

关于c - 如果我在 FFmpeg 中使用 av_read_frame 会丢失多个帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25526075/

相关文章:

c - C中结构的strcpy问题

c - 向 binutils 2.25 添加新指令

php - Ffmpeg & PHP - 质量好的小剪辑

audio - 将每分钟的 MP3 导出为单独的 WAV

android - 为android交叉编译C程序

c - C 中的方形问题

audio - 将 2 个音频文件与 ffmpeg 中的视频合并

使用 FFMPEG 的 PHP 和 Mysql 当前视频持续时间

c - 指针访问和数组访问之间的值差异

ffmpeg.js 过滤命令不带引号