最近学习openCV的时候,感觉opencv对视频的处理能力不是很强,才开始接触ffmpeg。
- ffmpeg是用C语言写的,里面都是结构体与库函数,没有类,所以在C++文件中添加头文件是一般会这样写:
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
};
这样做是因为C++的编译器会对程序中符号进行修饰,这个过程在编译器中叫符号修饰(Name Decoration)或者符号改编(Name Mangling)。我们知道C++是能够兼容C的,如果我们有了一个C语言的头文件和其对应的库,在C++中如何使用它呢?在include该头文件的时候当然要加入extern "C",否则按照C++的符号进行符号修饰,那么在库中就会找不到该符号了。
另外,C语言不支持extern "C"语法,如果我们想写一个头文件,同时支持被C和C++引用,该怎么办?可以使用C++的宏 "__cplusplus"来判断是不是C++编译器。
#ifdef __cplusplus
extern "C" {
#endif
// 正式定义。。。
#ifdef __cplusplus
}
#endif
- 接下来创建一些可能用到的变量,启用ffmpeg的api
AVFormatContext *pFormatCtx; //封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。
int i,videoindex; //
AVCodecContext *pCodecCtx; //编码器上下文结构体,保存了视频(音频)编码相关信息。
AVCodec *pCodec; //每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体。
AVFrame *pFrame,*pFrameYUV; //存储一帧解码后像素(采样)数据。
uint8_t *out_buffer; //
AVPacket *packet; //存储一帧压缩编码数据。
对于上述的几种结构体,对于一个完整的ffmpeg程序是必不可少的下面我们简略介绍一下:
AVFormatContext
封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息
iformat:输入视频的AVInputFormat
nb_streams :输入视频的AVStream个数
streams :输入视频的AVStream[]数组
duration :输入视频