C++ 调用avformat_find_stream_info阻止解码简单PNG图像?

C++ 调用avformat_find_stream_info阻止解码简单PNG图像?,c++,ffmpeg,libavcodec,libav,libavformat,C++,Ffmpeg,Libavcodec,Libav,Libavformat,我在用libav解码一个简单的PNG图像时遇到了一个问题。调用avcodec\u decode\u video2后的decode\u ok标志设置为0,即使数据包包含整个图像。通过一些实验,我成功地找出了问题所在,它似乎与调用avformat\u find\u stream\u info有关。如果删除了调用,则示例将成功运行。但是,我想对其他媒体使用相同的代码,在文档中建议调用avformat\u find\u stream\u info 下面的最小示例说明了该行为(遗憾的是仍然有点长): av

我在用libav解码一个简单的PNG图像时遇到了一个问题。调用
avcodec\u decode\u video2
后的
decode\u ok
标志设置为
0
,即使数据包包含整个图像。通过一些实验,我成功地找出了问题所在,它似乎与调用
avformat\u find\u stream\u info
有关。如果删除了调用,则示例将成功运行。但是,我想对其他媒体使用相同的代码,在文档中建议调用
avformat\u find\u stream\u info

下面的最小示例说明了该行为(遗憾的是仍然有点长):

avformat\u find\u stream\u info
之后的格式转储打印:

Input #0, image2, from '/path/to/test.png': Duration: N/A, bitrate: N/A Stream #0:0, 0, 1/25: Video: png, 25 tbn Input #0, image2, from '/path/to/test.png': Duration: 00:00:00.04, start: 0.000000, bitrate: N/A Stream #0:0, 1, 1/25: Video: png, rgba, 512x512 [SAR 3780:3780 DAR 1:1], 1/25, 25 tbr, 25 tbn, 25 tbc 下面是当解码失败时调用
avformat\u find\u stream\u info
得到的结果:

Statistics: 52125 bytes read, 0 seeks detected 8 logical cores 统计数据:读取52125字节,0 检测到8个逻辑核
图像是52125字节,因此整个文件都被读取。我不确定逻辑核指的是什么。

似乎是libav中的一些多线程问题。 禁用多线程解决了这个问题

codecContext->thread_count=1;
if ((ret = avcodec_open2(codecContext, codec, nullptr)) < 0)
{
    std::cerr << "Failed to open codec context." << std::endl;
    return nullptr;
}
codecContext->thread\u count=1;
if((ret=avcodec_open2(codecContext,codec,nullptr))<0)
{

std::cerr代码在我看来很好。请遵循并使用vprintf(szFmt,varg);让我们知道libav发出了什么调试文本。@杰克感谢您仔细查看代码,特别是因为libav的性质导致代码有点冗长。我添加了请求的调试输出,但遗憾的是,它不是很多(其他格式的解码器更健谈)。的确,这就解决了问题。好问题!我想知道通常禁用多线程是否是一个好主意,它会对性能产生怎样的影响。如果您的目标是解码单独的图像,则不会对序列性能产生影响。正如我所知,ffmpeg并行化基本上是基于一次解码多个视频帧,而不是在mul中解码一个帧多线程。这听起来很合理。我想在我的图像加载函数中禁用多线程现在是一个令人满意的解决方案。希望这个问题最终会得到解决。Libav与线程的关系一直很奇怪。大多数流/上下文的设置都必须得到仔细的保护,但我从来没有见过编解码器失败,因为内部的。很好的发现。 Statistics: 52125 bytes read, 0 seeks detected 8 logical cores
codecContext->thread_count=1;
if ((ret = avcodec_open2(codecContext, codec, nullptr)) < 0)
{
    std::cerr << "Failed to open codec context." << std::endl;
    return nullptr;
}