ffmpeg解封装
需要调用ffmpeg的API首先需要引入对应的头文件:
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
1.初始化解封装
//初始化解封装
av_register_all();
//初始化网络,可以直接从服务器拉流
avformat_network_init();
av_register_all()用于注册所有复用器,编码器和协议处理器。如果要指定注册某种编码器可以使用:av_register_input_format() ,av_register_output_format(),ffurl_register_protocol()。av_register_all()调用了avcodec_register_all()。avcodec_register_all()注册了和编解码器有关的组件:硬件加速器,解码器,编码器,Parser,Bitstream Filter。av_register_all()除了调用avcodec_register_all()之外,还注册了复用器,解复用器,协议处理器。
avformat_network_init()用于网络组件的全局初始化。这是可选的,但建议使用,因为它避免了隐式地为每个会话进行安装的开销。如果在某些主要版本中使用网络协议,调用此函数将成为强制性要求。加载socket库以及网络加密协议相关的库,为后续使用网络相关提供支持。
2.打开媒体文件
//打开文件
AVFormatContext *ic = NULL;
char path[] = "/sdcard/1080.mp4";
int re = avformat_open_input(&ic,path,0,0);
if(re == 0)
{
LOGW("avformat_open_input %s success!",path);
}
else
{
LOGW("avformat_open_input failed!:%s",av_err2str(re));
}
ffmpeg打开媒体的的过程开始于avformat_open_input()。在该方法调用之前确保av_register_all(),avformat_network_init()已经被调用。该函数用于打开多媒体数据(输入流)并且获得一些相关的信息(头数据)。对应的关闭流的函数为avformat_close_input()。
该方法中主要完成了:
- 输入输出结构体AVIOContext的初始化;
- 输入数据的协议(例如RTMP,或者file)的识别(通过一套评分机制):1.判断文件名的后缀 2.读取文件头的数据进行比对;
- 使用获得最高分的文件协议对应的URLProtocol,通过函数指针的方式,与FFMPEG连接(非专业用词);
- 剩下的就是调用该URLProtocol的函数进行open,read等操作了。【FFmpeg+SDL播放器开发实现 源码资料】
URLProtocol结构如下,是一大堆函数指针的集合(avio.h文件)
typedef stru