1、解封装(解释文件格式)
第一步注册函数
av_register_all(): 注册所有的封装格式:加封装格式和解封装格式
也可以单独注册mp4或者其他格式
第二步打开封装
在open之前要调用注册函数(调用一次就行),否则解封装文件会失败
avformat_network_init(): 初始化网络模块,该模块通过网络直接解封装rtsp(监控摄像机、或者支持rtsp协议的摄像机),http(将视频放在web服务器里,传http地址同样可以解封装)
为什么有这些函数?要先初始化这些?
因为ffmpeg是用c语言写的,没有类,需要统一先注册好,后面就不需要再调用。
C++可以有构造函数、初始化来完成操作。
avformat_open_input(…) 打开一个输入的封装器,(文件), 并且解析出文件格式,比如音频流、视频流、音频流和视频流参数、还有视频帧的索引
int avformat_open_input
在调用前需要确保av_register_all avformat_network_init已调用
参数如下:
AVFormatContext **ps: ——格式化的上下文,**ps表示指针的指针,其实就是指针的地址,这样才能改变指针的指向
第一种情况:可以存一个null值,存AVFormatContext的一个指针, 指针值为null,将这个指针的地址传给ps,传了一个指针地址,指针指向空的空间,在内部会创建空间;
第二种情况:直接创建AVFormatContext结构体 ,创建好再传进来,会把解封装的内容写到创建好的结构体里。但是清理可能会出问题。。因为动态链接库创建的空间只能在动态空间来清理,外部空间在动态空间中清理会出问题,因为他们的内存是分割开的。
因此,如果是自己创建的空间要自己清理,如果传的是AVFormatContext的指针,指针本身指向一个空,那么空间直接用close来清理就行。
const char *url: 地址,网络打开的话支持rtsp、http以及本地文件,地址打开,会把地址存到AVFormatContext 中的filename成员中,支持断开重连
AVInputFormat *fmt:指定输入的封装格式,一般传null就行(开销不大),让函数自行探测;极端需求,用量并发数量多的时候需要
AVDictionary **options:字典数组,包含了key和value,也可以直接传null
#include <iostream>
extern "C" {
#include "libavformat/avformat.h"
}
using namespace std;