error: ‘avcodec_send_packet’ was not declared in this scope

error: ‘avcodec_send_packet’ was not declared in this scope

以下 ffmpeg-based 代码片段正在 Windows VC2012、VC20155、VC2017 上构建和运行。

在 Ubuntu LTS 16.04 上使用 gcc 这给我带来了问题,更具体地说,它似乎无法识别 avcodec_send_packet avcodec_receive_framestruct AVCodecParameters,可能还有更多我目前没有使用的函数和结构。

错误:“AVCodecParameters”未在此范围内声明 错误:“avcodec_send_packet”未在此范围内声明 错误:“avcodec_receive_frame”未在此范围内声明

代码片段是:

// the includes are actually in a precompiled header, included in cmake
extern "C" {

#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
#include <libpostproc/postprocess.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>   
#include <libavutil/avassert.h>
#include <libavutil/avstring.h>
#include <libavutil/bprint.h>
#include <libavutil/display.h>
#include <libavutil/mathematics.h>  
#include <libavutil/imgutils.h>
//#include <libavutil/libm.h>
#include <libavutil/parseutils.h>
#include <libavutil/pixdesc.h>
#include <libavutil/eval.h>
#include <libavutil/dict.h>
#include <libavutil/opt.h>
#include <libavutil/cpu.h>
#include <libavutil/ffversion.h>
#include <libavutil/version.h>

}

//
... 
{
    if (av_read_frame(m_FormatContext, m_Packet) < 0) {
        av_packet_unref(m_Packet);
        m_AllPacketsSent = true;
    } else {
        if (m_Packet->stream_index == m_StreamIndex) {                  
            avcodec_send_packet(m_CodecContext, m_Packet);
        }
    }
}
...

我阅读了 ffmpeg 的历史,了解到在基于 Debian 的系统上,他们曾一度遵循 fork to libavutil,然后最近一些平台由于以下原因切换回 ffmpeg 分支事实上,ffmpeg 在错误修复、功能和支持方面得到了更积极的支持。结果,某些接口可能已损坏。

我看到 git 修复了一个名为 mediatombs 的库,它似乎遇到了与 codecpar 相同但不是非常相似的问题(我最初也遇到过并以相同的方式修复):

https://github.com/gerbera/gerbera/issues/52

https://github.com/gerbera/gerbera/commit/32efd463f138557c54535225d84136df95bab3dd#diff-af3b638bc2a3e6c650974192a53c7291

这里提交似乎通过将重命名的 codecpar 字段包装回编解码器来解决他们的特定问题,我也应用并工作了。

我想知道是否有人知道哪些函数可以用于上面给出的错误,因为事实上这些函数本身根据 ffmpeg avcodec.hheader评论。 (https://www.ffmpeg.org/doxygen/trunk/avcodec_8h_source.html)。我希望这并不意味着我必须回到 avcodec_encode_video2() 类型的函数?

更新:

作为参考,它似乎也出现在这里:https://github.com/Motion-Project/motion/issues/338。如果您可以重建您的 ffmpeg 堆栈,该问题似乎已解决。

更新:

为了解决版本 API 混合问题,我最终清除了所有 ffmpeg 引用并从源代码中重建了 ffmpeg。这似乎将事情推向了正确的方向;我的源代码编译正确,但我将它们链接在一起的方式仍然存在问题。

此外,我正在使用 CMake 来设置我的 makefile,并使用 find_package 来处理一些依赖项,并使用手写的 find_path / find_library 来处理其他所有内容。我看到其他人抱怨以下链接问题,并且有大量 case-specific 回复,但其中 none 确实揭示了实际问题所在。我安装的 Ubuntu 版本的 ALSA 是 1.1.xx 但我仍然收到关于我应该链接的 0.9 版本的投诉。有人知道这有什么问题吗?

此外,我的 libasound.so 是链接到 libasound.so.2.0.0 的符号,如果这能解决任何问题。 (希望最后的双斜杠路径也是正确的)。

/usr/bin/ld: /usr/lib/ffmpeg/libavdevice.a(alsa.o): undefined reference to symbol 'snd_pcm_hw_params_any@@ALSA_0.9' //usr/lib/x86_64-linux-gnu/libasound.so.2: 

所以问题确实是 avcodec 和 ffmpeg 源的版本混淆,我会链接到正确的库但针对错误的源包进行编译。我按照 Andrew 的建议检查 header 中的 API 版本。

正如 halfelf 所建议的那样,解决方案是卸载 ffmpeg 和 avcodec,然后从最新版本的 ffmpeg 手动下载源主干,并从源代码构建。这是一个相当大的过程,但一切顺利并解决了链接问题。