【问题标题】:FFmpeg av_read_frame not reading frames properly?FFmpeg av_read_frame 不能正确读取帧?
【发布时间】:2016-08-02 06:39:14
【问题描述】:

好的,我已经下载了一些 .yuv 格式的原始 UHD 序列,并在 .mp4 容器中使用 ffmpeg 对它们进行了编码(h264 4:4:4,100% 质量,25fps)。当我使用 ffprobe 找出编码了多少帧时,我得到了 600,所以这是 24 秒的视频。

但是,当我通过av_read_frame() 运行这些编码的视频序列时,我只得到了在av_read_frame() 返回错误代码-12 之前处理的帧的 40-50%。所以我猜测流中间有一些数据包被av_read_frame()读取并强制函数返回-12

我的问题是,我应该如何处理这个问题,以便我可以编码全部帧数(600)?当av_read_frame() 返回的值与0 不同时,我应该av_free_packet() 并继续阅读下一帧吗?由于av_read_frame() 为错误代码返回值< 0,所以EOF 使用哪个错误代码,所以我可以隔离文件代码的结尾?

【问题讨论】:

    标签: video ffmpeg


    【解决方案1】:

    虽然很难说你的解码出了什么问题,但-12仍然不是一个无法理解的神奇数字。

    printf("%s\n", av_err2str(-12));
    

    这将打印Cannot allocate memory,这是真正的问题。

    当从av_read_frame() 得到一个正的返回值时,就可以继续了。

    av_free_packet() 已被弃用,而是在每个 av_read_frame() 循环结束时使用 av_packet_unref()

    while(av_read_frame(fmt_ctx, &pkt) >= 0) {
        // decode packet and other stuff
        av_packet_unref(&pkt); 
    }
    

    最后,通常不需要担心EOF,因为av_decode_video2()或其他解码函数会设置一个int参数为适当的值,指示是否有帧需要解压。

    如果您使用的是相当新的 ffmpeg(>=3.1) 解码/编码 API 或确实需要处理 EOF,请将返回值与 AVERROR_EOF 进行比较。

    【讨论】:

    • 不幸的是,我使用的是旧版本的 ffmpeg,我必须使用 av_free_packet
    • 无论如何,现在可以了。谢谢您的回答。我在阅读函数时应该更加小心。
    • libav 返回的错误编号是否定的标准 Unix 错误。 -12 来自:#define ENOMEM 12
    【解决方案2】:

    对于某些版本的 libav,实用程序 av_err2str 未编译,我使用以下技巧:

    #undef  av_err2str
    #define av_err2str(errnum) av_make_error_string((char*)__builtin_alloca(AV_ERROR_MAX_STRING_SIZE), AV_ERROR_MAX_STRING_SIZE, errnum)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 2015-01-07
      相关资源
      最近更新 更多