1.简介
解封装:如下图所示,就是将FLV、MKV、MP4等文件解封装为视频H.264或H.265压缩数据,音频MP3或AAC的压缩数据,下图为常用的基本操作。
2.流程
下图是解封装的基本流程图。
2.1 在使用FFmpeg API之前,需要先注册API,然后才能使用API。当然,新版本的库不需要再调用下面的方法。
av_register_all()
2.2 构建AVFormatContext
声明输入的封装结构体,通过输入文件或者流地址作为封装结构的句柄。韩国电视台的流地址rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp。
AVFormatContext* inputFmtCtx = nullptr;
const char* inputUrl = "rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp";
///打开输入的流,获取数据 begin
int ret = avformat_open_input(&inputFmtCtx, inputUrl, NULL, NULL);
2.3 查找音视频流信息,通过下面的接口与AVFormatContext中建立输入文件对应的流信息。
//查找;
if (avformat_find_stream_info(inputFmtCtx, NULL) < 0)
{
printf("Couldn't find stream information.\n");
return false;
}
2.4 读取音视频流,采用av_read_frame来读取数据包,读出来的数据存储在AVPacket中,确定其为音频、视频、字幕数据,最后解码,或者存储。
AVPacket* pkt = NULL;
pkt = av_packet_alloc();
while (av_read_frame(inputFmtCtx, pkt) >= 0)
{
//获取数据包
//.....解码或者存储
//重置
av_packet_unref(pkt);
}
上述代码所示,通过循环调用av_read_frame()读取到pkt包,然后可以进行解码或者存储数据,如果读取的数据结束,则退出循环,开始指向结束操作。
2.5 执行结束后关闭输入文件,释放资源。
//关闭
avformat_close_input(&inputFmtCtx);
//释放资源
av_packet_free(&pkt);
3.源码
int main()
{
//av_register_all();
avformat_network_init();
AVDictionary* options = NULL;
av_dict_set(&options, "buffer_size", "1024000", 0);
av_dict_set(&options, "max_delay", "500000", 0);
av_dict_set(&options, "stimeout", "2000000", 0);
av_dict_set(&options, "rtsp_transport", "tcp", 0);
AVFormatContext* inputFmtCtx = nullptr;
const char* inputUrl = "rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp";
///打开输入的流,获取数据 begin
int ret = avformat_open_input(&inputFmtCtx, inputUrl, NULL, NULL);
if (ret != 0)
{
printf("Couldn't open input stream.\n");
return -1;
}
int vIndex = -1;
int aIndex = -1;
//查找;
if (avformat_find_stream_info(inputFmtCtx, NULL) < 0)
{
printf("Couldn't find stream information.\n");
return false;
}
AVPacket* pkt = NULL;
pkt = av_packet_alloc();
while (av_read_frame(inputFmtCtx, pkt) >= 0)
{
//获取数据包
//.....解码或者存储
//重置
av_packet_unref(pkt);
}
//关闭
avformat_close_input(&inputFmtCtx);
//释放资源
av_packet_free(&pkt);
return 0;
}