前天准备使用ffmpeg来做个视频文件的解析程序,由于,一直没有关注过这个库,就以opencv的使用习惯去用这个库,结果,坑了整整两天。
一、头文件需要extern “C”
先上ffmpeg的头文件正确include的写法:
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
如果,不加extern “C”,编译不报错,就是链接失败,一大堆的
error LNK2001: 无法解析的外部符号
:
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avformat_open_input(struct AVFormatContext * *,char const *,struct AVInputFormat const *,struct AVDictionary * *)" (?avformat_open_input@@YAHPEAPEAUAVFormatContext@@PEBDPEBUAVInputFormat@@PEAPEAUAVDictionary@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_receive_packet(struct AVCodecContext *,struct AVPacket *)" (?avcodec_receive_packet@@YAHPEAUAVCodecContext@@PEAUAVPacket@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct AVCodec const * __cdecl avcodec_find_decoder(enum AVCodecID)" (?avcodec_find_decoder@@YAPEBUAVCodec@@W4AVCodecID@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl av_read_frame(struct AVFormatContext *,struct AVPacket *)" (?av_read_frame@@YAHPEAUAVFormatContext@@PEAUAVPacket@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct SwsContext * __cdecl sws_getContext(int,int,enum AVPixelFormat,int,int,enum AVPixelFormat,int,struct SwsFilter *,struct SwsFilter *,double const *)" (?sws_getContext@@YAPEAUSwsContext@@HHW4AVPixelFormat@@HH0HPEAUSwsFilter@@1PEBN@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl sws_scale(struct SwsContext *,unsigned char const * const * const,int const * const,int,int,unsigned char * const * const,int const * const)" (?sws_scale@@YAHPEAUSwsContext@@QEBQEBEQEBHHHQEBQEAE2@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_parameters_to_context(struct AVCodecContext *,struct AVCodecParameters const *)" (?avcodec_parameters_to_context@@YAHPEAUAVCodecContext@@PEBUAVCodecParameters@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "void __cdecl av_packet_free(struct AVPacket * *)" (?av_packet_free@@YAXPEAPEAUAVPacket@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "void __cdecl av_frame_free(struct AVFrame * *)" (?av_frame_free@@YAXPEAPEAUAVFrame@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_send_frame(struct AVCodecContext *,struct AVFrame const *)" (?avcodec_send_frame@@YAHPEAUAVCodecContext@@PEBUAVFrame@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_receive_frame(struct AVCodecContext *,struct AVFrame *)" (?avcodec_receive_frame@@YAHPEAUAVCodecContext@@PEAUAVFrame@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_open2(struct AVCodecContext *,struct AVCodec const *,struct AVDictionary * *)" (?avcodec_open2@@YAHPEAUAVCodecContext@@PEBUAVCodec@@PEAPEAUAVDictionary@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct AVCodec const * __cdecl avcodec_find_encoder(enum AVCodecID)" (?avcodec_find_encoder@@YAPEBUAVCodec@@W4AVCodecID@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct AVCodecContext * __cdecl avcodec_alloc_context3(struct AVCodec const *)" (?avcodec_alloc_context3@@YAPEAUAVCodecContext@@PEBUAVCodec@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct AVPacket * __cdecl av_packet_alloc(void)" (?av_packet_alloc@@YAPEAUAVPacket@@XZ)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avcodec_send_packet(struct AVCodecContext *,struct AVPacket const *)" (?avcodec_send_packet@@YAHPEAUAVCodecContext@@PEBUAVPacket@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "void __cdecl av_packet_unref(struct AVPacket *)" (?av_packet_unref@@YAXPEAUAVPacket@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl av_frame_get_buffer(struct AVFrame *,int)" (?av_frame_get_buffer@@YAHPEAUAVFrame@@H@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "int __cdecl avformat_find_stream_info(struct AVFormatContext *,struct AVDictionary * *)" (?avformat_find_stream_info@@YAHPEAUAVFormatContext@@PEAPEAUAVDictionary@@@Z)
1>main.obj : error LNK2001: 无法解析的外部符号 "struct AVFrame * __cdecl av_frame_alloc(void)" (?av_frame_alloc@@YAPEAUAVFrame@@XZ)
二、avformat_open_input的中文路径
这个就是更加了,也不知我的VS哪里设置有问题,我折腾了整整一天,avformat_open_input
函数一直返回失败。直到后面,我把视频文件放到非中文路径,读取成功,我才怀疑路径字符的编码问题。
解决办法,加u8:
const char* url = u8"D:/DataSet/自制素材/20241230/VID_20241230_134824.mp4";
如果,大家有别的解决方案,可以在评论区留言讨论。
三、小结下
算法搞多了,动手编码的能力下降了,程序员的基本素养得提高。