两次调用 avformat_find_stream_info() 崩溃

Posted

技术标签:

【中文标题】两次调用 avformat_find_stream_info() 崩溃【英文标题】:twice call avformat_find_stream_info() crashed 【发布时间】:2022-01-22 05:22:40 【问题描述】:

我的 FFmpeg 版本是 4.4。 我的代码中有一个逻辑连续调用 avformat_find_stream_info() 两次,但我不明白为什么它在这里崩溃。我尝试了单步调试,但没有成功。这是我可以直接运行的简单代码:

#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>

int main()

    av_log_set_level(AV_LOG_DEBUG);
    const char* in_filename_a = "aoutput.aac";
    AVFormatContext* ifmt_ctx_a = NULL;
    int ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0);
    if (ret < 0)
    
        fprintf(stderr, "Could not open input_a %s", in_filename_a);
        return -1;
    
    fprintf(stderr, "before ifmt_ctx_a=0x%x\n", ifmt_ctx_a->streams[0]);
    ret = avformat_find_stream_info(ifmt_ctx_a, 0);
    if (ret < 0)
    
        fprintf(stderr, "Could not find input_a stream info");
        return -1;
    
    fprintf(stderr, "after ifmt_ctx_a=0x%x\n", ifmt_ctx_a->streams[0]);
    /// crashed here
    ret = avformat_find_stream_info(ifmt_ctx_a, 0);
    if (ret < 0)
    
        fprintf(stderr, "Could not find input_a stream info");
        return -1;
    


【问题讨论】:

“崩溃”到底是什么意思?它是否引发了 SEGV(分段错误)?它刚刚退出了吗?你必须更具体。另外,您是否尝试过使用多个不同的文件? 你确定 nb_streams 是 gt 0 吗? 这是一个分段错误。我尝试过使用多个不同的文件。 nb_strams 为 1。 【参考方案1】:

很少有暗示暗示我们不应执行avformat_find_stream_info 两次。

文档说:“检查过的数据包可能会被缓冲以供以后处理。” 有一个变化是第一次执行缓冲的数据包很少,第二次执行尝试再次缓冲数据包而不分配额外的空间。 控制台将日志消息打印为:

在 avformat_find_stream_info() 之前 pos: 0 bytes read:65696 seeks:4 nb_streams:1 avformat_find_stream_info() 后 pos: 27420 bytes read:65696 seeks:4 frames:50

       这些消息暗示职位从0 上升到27420ifmt_ctx_a-&gt;streams[0]的地址是一样的,但是第一次执行avformat_find_stream_info做了一些寻找(所以第二次执行和第一次不一样)。

使用调试器,我们可以看到ifmt_ctx_a-&gt;pb[0].buf_ptr在第一次执行avformat_find_stream_info之后增加了。

注意:

我不知道崩溃是正常行为还是 Libavformat 库中的错误。 Libavformat的源码我没试过。

要阅读两次,您可以关闭并重新打开ifmt_ctx_a

avformat_close_input(&ifmt_ctx_a);   
ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0);

我认为没有任何理由这样做......


其他选项是打开另一个 AVFormatContext:

AVFormatContext* ifmt_ctx_a = NULL;
int ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0);
if (ret < 0)

    fprintf(stderr, "Could not open input_a %s", in_filename_a);
    return -1;


ret = avformat_find_stream_info(ifmt_ctx_a, NULL);
if (ret < 0)

    fprintf(stderr, "Could not find input_a stream info");
    return -1;


//Opening another AVFormatContext:
////////////////////////////////////////////////////////////////////////////
AVFormatContext* ifmt_ctx_a2 = NULL;
ret = avformat_open_input(&ifmt_ctx_a2, in_filename_a, 0, 0);
if (ret < 0)

    fprintf(stderr, "Could not open input_a %s", in_filename_a);
    return -1;


ret = avformat_find_stream_info(ifmt_ctx_a2, NULL);
if (ret < 0)

    fprintf(stderr, "Could not find input_a stream info");
    return -1;

////////////////////////////////////////////////////////////////////////////

【讨论】:

以上是关于两次调用 avformat_find_stream_info() 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ngAfterContentInit 钩子被调用两次?

Firebase 身份验证被调用两次

为啥 ngOnInit 被调用两次?

ViewDidLoad 调用了两次

目标动作被调用两次

getItem 函数在 FragmentStatePagerAdapter 中调用两次?