FFMPEG 之 AVFormat
1 描述
它是一个I/O 和muxing/demuxing库,处理各种媒体容器格式库,主要包括两大功能:demuxing ,如将一个媒体文件拆分成音视频流, muxing,如将音视频数据写入一个媒体文件中。同时它还具有I/O module 可支持各种协议,如文件,tcp,http等等。muing 由AVInputFormat 结构体去描述,相反地,demuxing 由AVOutputFormat 去描述。
AVFormatContext 它是整个AVFormat 的上下文, 所有有关demuxing/muxing 都包含这结构体中。其中最重要的三个成员是:
1 struct AVInputFormat *iformat;/ struct AVOutputFormat *oformat;//muxing/demuxing 上下文
2 AVStream **streams;//存在音视频流
3 AVIOContext *pb;//读取媒体数据。
2 解复用器
解复用器读取媒体文件,并将其分割成数据块(视频/音频/字幕),a packet 包含一个或者多个已编码音视频单元,通过avformat_open_input() 去打开这文件,通过av_read_frame() 去读取数据包,最后通过avformat_close_input去关闭清除。如下表为FFMPEG Demuxing 部分开出来的API ,其定义是在avformat.h 文件中,实现在utils.c 文件中。如下表为demuxing 部分开出的API。在avformat_open_input() 之后,也能读出一些mediainfo 信息,但是要获取更多更完整的mediainfo 信息需要通过avformat_find_stream_info(), 前者只会读取文件头,后者还会解码一些帧。
int av_read_frame(AVFormatContext *s, AVPacket *ptk) 这函数作用是得到stream 的下一帧,如果读取成功将返回0 ,失败或者流结束返回负值, 其中流结束返回的负值是AVERROR_EOF。
函数原型 |
作用 |
AVInputFormat *av_find_input_format(char *name) |
获得一个基于后缀名的AVInputFormat结构体 |
AVInputFormat* av_probe_input_format(AVProbeData*pd , is_opened) |
根据Probe data 去获得一个AVInputFormat结构体 |
AVInputFormat * av_probe_input_format2(*pd, is_opend,*score_max) |
根据Probe dat 去获得一个AVInputFormat结构体,当且只有获得的分数大于指定的分数才行 |
AVInputFormat* av_probe_input_format3(pd,is_opend,*score_ret) |
根据probe data去获得一个AVInPutFormat 结构体,并返回获得score |
av_probe_input_buffer2(AVIOContext*,AVInputFormat*,char *url,logctx,offset,max_probe) |
探测字节流,决定AVInputFormat |
int avformat_open_input(AVFormatContext **, char*url,AVInputFormat *,AVDictionnary*) |
打开一个流,并读取文件头 |
int avformat_find_stream_info(AVFormatContext*,AVDictionary*) |
读取packets, 并获得一些media information |
av_find_best_stream(AVFormatContext*,AVMediaType,AVCodec**) |
根据输入参数找解码器 |
avProgram*av_find_program_from_stream(AVFormatContext *,AVProgram *last,int s) |
获得program |
int av_read_frame(AVFormatContext *s,AVPacket*pkt) |
获取stream next frame |
int av_seek_frame(AVFormatContext *s,int stream_index,int64_t timestamp,int flag) |
seek to the keyframestamp |
int avformat_seek_file(AVFormatContext *s,int stream_index,int min_ts,int ts,int max_ts) |
通过指定min_ts,max_ts,去找最接近target ts timestamp |
int avformat_flush(AVFormatContext *s) |
flush all buffered data |
int av_read_play(AVFormatContext *s) |
开始播放一个网络流 |
int av_read_pause(AVFormatContext *s) |
暂停一个网络流 |
void avformat_close_input(AVFormatContext**) |
关闭一个打开的AVFormatContext |
3 复用器
复用器接收AVPacket 数据,并将其写入到指定的容器格式,avformat_write_header() 用于写文件头,av_write_frame()/av_interleaved_write_frame() 写数据packet, av_write_tailer() 用于完成文件。
Muxers 以AVPackets 形式接收数据,并写入指定的容器格式。其API 定义与avformat.c,实现位于util.c 中.如下表为muxing 部分开出的API。
函数原型 |
作用 |
int avformat_write_header(AVFormatContext *s,AVDictionary **options) |
allocate stream private data,并将stream 头写入container |
int avformat_init_output (AVFormatContext*,AVDictionary **options) |
allocate stream private data,但不写入streame head |
int av_write_frame(AVFomatContext *s,AVPacker*pkt) |
写packet 到输出的文件 |
int av_interleaved_write_frame(AVFormatContext *s,AVPacket *pkt) |
写入packet 到输出文件,其data 必须是interleaved |
int av_write_uncoded_frame(AVFomartContext *s,int stream_index ,AVFrame *frame) |
写未编码的data到输出文件, 其数据格式可以不是interleaved |
int av_interleaved_write_uncoded_frame(AVFormatContext *s,int stream_index,AVFrame *frame) |
写入未编码的data, 其数据格式必须是interleaved |
int av_write_uncoded_frame_query(AVFormatContext *s,int stream_index) |
测试muxer 是否支持写入uncoded 数据 |
int av_write_tailer(AVFormatContext *s) |
将stream 尾写入输出文件,并free private data |
AVOutputFormat *av_guess_format(char *short_name,char *filename,char *mime_type) |
根据输入参数,获得AVOutputForamt |
AVCodecID av_guess_codec(AVOutputFormat *fmt,char *short_name,char*filename,char*mine_type,AVMediaType type) |
根据输入参数获得CodecID |
int av_get_output_timestamp(struct AVFormatContext *s,int stream,int64_t * dts,int64* wall) |
获取当前数据的时序信息 |
4 metadata信息
metadata是描述媒体文件的一些特有信息,比如音乐专辑信息,艺术家等等。被允许在muxing/demuxing 去设置/获取。AVFormatContext,AVStream,AVChapter,和AVProgram 可通过AVDictionary API 设置获取。
5 I/O read/write
ffmpeg 不但可以读取本地文件,同时它还可以读取网络文件,市面上常见的流媒体协议它都支持(如rtmp,rtsp,http等)。同各种容器的媒体文件demuxers一样,不同的协议底层都需有相应的文件去实现,ffmpeg 有对各种协议进行封装,avio.h开出的API 我们可以无感的读取各种协议的数据,如果我们使用ffmpeg 去播放media 的话,关于I/O 操作API 我们都接触不到,因为ffmpeg 内部已经帮我们做好了。AVFormatContext 中有个AVIOContext 结构体,它里面增加I/O读取buff 的管理,在AVIOContext 中的URLContext 成员,对应的就是具体的文件协议,比如rtmp,http,file hls,tcp 等等。它们之间的关系如下图所示:
6 core functions
列出一些查询libavformat 功能,申请core结构体的API。
函数原型 |
作用 |
unsigned avformat_version(void) |
获取ffmpeg 的版本号 |
const char* avformat_configuration() |
返回ffmpeg 编译的配置参数 |
int avformat_network_init(void) |
对网络库进行全局初始化 |
int avformat_network_deinit(void) |
撤销由avformat_network_init()完成的初始化 |
const AVOutputFormat *av_muxer_iterate(void **opaque) |
遍历所有注册的muxers |
const AVInputFormat *av_demux_iterate(void **opaque) |
遍历所有注册的demuxers |
AVFormatContext *avformat_alloc_context() |
allocate an AVFormatContext |
avformat_free_context(AVFormatContext *) |
free an AVFormatContext |
const AVClass *avformat_get_class(void) |
获取AVFormatContext 的AVClass |
AVStream *avformat_new_stream(AVFormatContext *s,const AVCodec *s) |
demuxing 被ffmpeg 内部调用. 在muxing 时, 需要在avformat_write_header() 之前由用户call, 用于创建media stream |
uint8 * av_stream_new_side_date(AVStream *stream,enum AVPacketSideDateType type,int size) |
申请附加信息空间 |
int av_stream_add_side_data(AVStream *st,enum AVPacketSideDataType type, uint8 *data,size_t size) |
在stream 添加side data ,比如解码显示等附加信息 |
int8_t *av_stream_get_side_data(const AVStream *stream ,enum AVPacketSideDateType type,int size) |
获取附加信息 |
AVProgram *av_new_program(AVFormatContext *s, int id ) |
根据AVFormatContext 申请AVprogram 结构体 |
7 utility functions
描述一些与muxing/demuxing 有关的一些工具函数。在实际编程中,av_dump_format()还是用的比较多的, 比如demux 编程中, 我们初始化程序后,通过av_dump_format() 获取获取当前media 的info ,还是检查是否有初始化成功。
函数原型 |
作用 |
void av_hex_dump(FILE *f,const uint8_t *buf,int size ) |
将一段十六进制的数据包输入到一个文件流中 |
void av_hex_dump_log(void *avcl,int level,const uint8_t *buf,int size) |
将一段十六进制的数据包在log 中输出 |
void av_pkt_dump2(FILE *f,const AVPacket *pkt,int dump_payload,const AVStream *st) |
打印AVPacket信息 |
void av_pkt_dump_log2(void *avcl,int level,const AVPacket *pkt,int dump_payload,const AVStream *st) |
AVPacket 信息,在log 中输出 |
enum AVCodecID av_codec_get_id(const struct AVCodecTag const *tag, enum AVCodecID id ) |
通过codec tag 寻找codecID |
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tag,enum AVCodecID id) |
通过Codec Id 找AVCodec Tag |
int av_index_search_timestamp(AVStream *st,int64_t timestamp, int flags) |
获取特定时间撮的索引 |
int av_add_index_entry(AVStream *st,int64_t pos, int64_t timestamp,int size,int distance,int flag) |
将索引条目添加到存储列表中 |
void av_url_split() |
将url拆分成各个组件 |
void av_dump_format(AVFormatContext *ic,int index ,char *url,int is_output) |
打印文件的详细信息,如duration,bitrate,streams,programs |
int av_get_frame_filename2(char *url,int buf_size,) |
return in “buf” the path with “d”,replaced by a number |
int av_filename_number_test(char *filename) |
检查文件名是否是一个编号序列生成 |
int av_sdp_create(AVFormatContext *ac[],int n_flies,char *buf,int size) |
为rtp 会话生成sdp |
int av_match_ext(const char *filename ,const char *extensions) |
检查文件名是否与给定的扩展名相匹配 |
int avformat_query_codec(const AVOutputFormat *ofmt,enum AVCodecId codec_id,int std) |
测试给定的容器是否可以存储指定的编码格式数据 |
AVRational av_guess_sample_aspect_ratio(AVFormatContext *format,AVStream *stream,AVFrame *frame) |
根据stream 和 frame 的比例,猜测样本的比例 |
AVRational av_guess_frame_rate(AVFormatContext *ctx,AVStream *stream ,AVFrame *frame) |
根据容器和编码器猜测帧速率 |
int avformat_match_stream_specifier(AVFormatContext *s,AVStream *st,char*spec) |
检查流是否与流说明的spec相匹配 |
int avformat_transfer_internal_stream_timing_info(const AVOutputFormat,AVStream *ost,const AVStream *ist) |
将内部时序信息从一个流传输到另一个流中 |
AVRational av_stream_get_codec_timebase(const AVStream *st) |
从流内部获得编码器时基 |
FFMPEG 之 AVFormat相关推荐
- FFmpeg 之 AVFormat
1 描述 它是一个I/O 和muxing/demuxing库,处理各种媒体容器格式库,主要包括两大功能:demuxing ,如将一个媒体文件拆分成音视频流, muxing,如将音视频数据写入一个媒体文 ...
- 解密FFmpeg播放track mode控制
上一篇文章(http://www.cnblogs.com/yangdanny/p/4421130.html)我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H ...
- FFMPEG结构体分析之AVFormatContext
它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体. 接口定义文件路径ffmpeg\libavformat\avformat.h, 看完该结构体的定义,就一句感慨,尼玛好长 /** ...
- ffmpeg学习笔记-native原生绘制
上次已将ffmpeg的动态库编译出来了,并且使用了ffmpeg的转码功能,成功将mp4格式视频转化为yuv视频,这篇文章基于上次测试的demo,使用surfaceview显示解码完成的像素数据 布局设 ...
- Windows FFMPEG开发环境配置
1.去FFMPEG网站上下载Dev版本的库,里面有我们需要的头文件和lib文件,然后下载Shared版本的库,里面有我们需要的dll文件 http://ffmpeg.zeranoe.com/build ...
- 详细介绍Qt,ffmpeg 和SDl 教程之间的联系
Qt与 ffmpeg 与 SDl 教程是本文要介绍的内容,从多个角度介绍本文,运用了qmake,先来看内容. 1. 注释 从" #" 开始,到这一行结束. 2. 指定源文件 1 ...
- FFmpeg的C++封装:FFmpegWrapper
下面介绍的API已过时,请下载最新版本的源代码,并参考其注释.新版本主要由John编写,在旧版本的基础上做了很多改进. 什么是FFmpeg? FFmpeg是一套完整的录制.转换.流化音视频的解决方案, ...
- 从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用
从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用 原文地址:http://blog.yundiantech.com/?log=blog&id=10 前面介绍了使用F ...
- 从零开始学习音视频编程技术(四) FFMPEG的使用
零开始学习音视频编程技术(四) FFMPEG的使用 原文地址:http://blog.yundiantech.com/?log=blog&id=7 音视频开发中最常做的就是编解码的操作了,以H ...
最新文章
- 索引使用的限制条件,sql优化有哪些,数据同步问题(缓存和数据库),缓存优化
- java api中最常用的五个包_java 5 个常用的api包
- java 多数据源处理_java – 用于处理多个数据源的Spring事务管理
- 教学5层网络体系结构——分层之后数据的发送和接收
- 终于有人把ROS机器人操作系统讲明白了
- B-Tree及其建立过程
- AIX双机调整DB2配置
- paip.svn服务服务器安装配置
- 沈大海38节jquery强化教程2016视频下载
- Microsoft Office (Visio)安装与激活
- zuc算法c需语言,ZUC算法原理及实现过程(20200921192330).pdf
- Scratch软件编程等级考试四级——20210320
- http中各个状态码的含义
- 最大公因数(Java)
- vue中使用v-if出现的值回显不了的问题
- OC10 -- block / 多态
- STM32G070CBTx使用LL库原生I2C读取FM24C04D
- PHP获取客户端访问的IP来源
- 浙江省计算机一级linux,浙江省大学计算机一级Linux浙江省大学计算机三级Linux网络管理应用.doc...
- JavaScript for、for..in、for..of、forEach的区别
热门文章
- PR视频剪辑基础01
- 如何在WordPress中创建RSVP表单(简易)
- 基于龙贝格观测器的永磁同步电机无感FOC 采用龙伯格观测器提取电机反电势,使用PLL从反电势中获得转子位置和速度信息
- set_false_path 与 set_disable_timing 的区别
- editplus注册码生成器
- 跟着官方学电机,BLDC两种控制策略,学到即赚到
- C++组件测试及应用 — 基于Tessy的测试技术漫谈
- 【华人学者风采】张殷乾 南方科技大学
- 26场景优化 27UV贴图
- 华三交换机配置多个镜像口_H3C交换机配置多个流量镜像观察口