一,播放器框架
二 常用音视频术语
容器/文件(Conainer/File):
即特定格式的多媒体文件, 比如mp4、flv、mkv等。
媒体流(Stream):
表示时间轴上的一段连续数据,如一 段
声音数据
、一段
视频数据
或一段
字幕数据
,可以是压缩 的,也可以是非压缩的,压缩的数据需要关联特定的编解 码器(有些码流音频他是纯PCM)。一般对于 一个 mp4文件, 通过解复用器,就可以将mp4中的 视频流和 音频流,甚至字符流都分离出来。
数据帧/数据包(Frame/Packet):
通常,一个媒体流是 由大量的数据帧组成的,对于压缩数据,
帧对应着编解码 器的最小处理单元
,分属于不同媒体流的数据帧交错存储 于容器之中。
一般来说,压缩后的数据,我们认为是packet
解码后的数据,我们认为是frame的概念。
帧对应着编解码 器的最小处理单元 这句话的理解如下:
对于视频,一个frame实际上就是一张图片了
对于音频,一个frame,对于 aac 是1024个采样点为一帧,mp3 则是1152个采样点为一帧。
编解码器:
编解码器是以帧为单位实现压缩数据和原始数 据之间的相互转换的。
三 常用概念-复用器
四 常用概念-编解码器
五 FFmpeg库简介
FFMPEG有8个常用库:
•
AVUtil
:核心工具库,下面的许多其他模块都会依赖该库做一些基本的音 视频处理操作。
•
AVFormat
:文件格式和协议库,该模块是最重要的模块之一,封装了 Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透 明的。
•
AVCodec
:编解码库,封装了Codec层,但是有一些Codec是具备自己的 License的,FFmpeg是不会默认添加像
libx264、FDK-AAC
等库的,但是 FFmpeg就像一个平台一样,可以将其他的第三方的Codec以插件的方式 添加进来,然后为开发者提供统一的接口。
•
AVFilter
:音视频滤镜库,该模块提供了包括音频特效和视频特效的处理, 在使用FFmpeg的API进行编解码的过程中,直接使用该模块为音视频数 据做特效处理是非常方便同时也非常高效的一种方式。
•
AVDevice
:输入输出设备库,比如,需要编译出播放声音或者视 频的工具ffplay,就需要确保该模块是打开的,同时也需要SDL的 预先编译,因为该设备模块播放声音与播放视频使用的都SDL库。
•
SwrRessample
:该模块可用于
音频重采样
,可以对数字音频进行
声道数、数据格式、采样率
等多种基本信息的转换。
•
SWScale
:该模块是将图像进行格式转换的模块,比如,可以将 YUV的数据转换为RGB的数据,缩放尺寸由1280*720变为800*480。
•
PostProc
:该模块可用于进行后期处理,当我们使用AVFilter的时 候需要打开该模块的开关,因为Filter中会使用到该模块的一些基 础函数。
六 FFmpeg函数简介
◼ av_register_all():注册所有组件,4.0已经弃用
◼ avdevice_register_all()对设备进行注册,比如V4L2等。
#include <libavdevice/avdevice.h>
/**
* Initialize libavdevice and register all the input and output devices.
*/
void avdevice_register_all(void);
◼ avformat_network_init();初始化网络库以及网络加密协议相关 的库(比如openssl)
#include <libavformat/avformat.h>
int avformat_network_init(void);
七 FFmpeg函数简介-封装格式相关
◼ avformat_alloc_context();负责申请一个AVFormatContext 结构的内存,并进行简单初始化
#include <libavformat/avformat.h>
/**
* Allocate an AVFormatContext.
* avformat_free_context() can be used to free the context and everything
* allocated by the framework within it.
*/
AVFormatContext *avformat_alloc_context(void);
## AVFormatContext:它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体,
其中比较重要的几个如下解释:
typedef struct AVFormatContext {
const AVClass *av_class; // 一个类,用于保存指向父对象的链接,用于日志记录
struct AVInputFormat *iformat; // 用于指定输入文件的格式以及文件读取的操作函数
struct AVOutputFormat *oformat; // 用于指定输出文件的格式以及文件写入的操作函数
void *priv_data; // 指向 AVFormatContext(容器上下文)的私有数据
AVIOContext *pb; // 用于读取和写入媒体数据的 I/O 上下文
int nb_streams; // 流的数量,包括音频、视频、字幕等
AVStream **streams; // 指向 AVStream 结构体的指针,用于存储所有流的信息
char *filename; // 用于存储文件名的字符串
int64_t start_time, duration;// 媒体文件的起始时间戳和持续时间
int64_t bit_rate; // 比特率,以 bit/s 计算
uint8_t *buffer; // 用于暂存数据的缓冲区
int buffer_size; // 缓冲区的大小
} AVFormatContext;
AVFormatContext 结构体的各个成员变量的作用详见以下介绍。
成员变量介绍
AVClass *av_class: 一个类,用于保存指向父对象的链接,用于日志记录;
AVClass是FFmpeg中libavutil库中的一个结构体,用于在FFmpeg中实现类及其对象的日志和调试功能。AVClass提供了一种标准的方式来管理类及其对象,在不同的库和插件之间提供了统一的日志记录和调试接口。
AVInputFormat *iformat:用于指定输入文件的格式以及文件读取的操作函数;
AVOutputFormat *oformat: 用于指定输出文件的格式以及文件写入的操作函数;
void *priv_data: 指向 AVFormatContext(容器上下文)的私有数据;
priv_data成员可以用于存储和传递特定协议下使用的私有数据,常见的使用场景是实现自定义输入或输出协议。
AVIOContext *pb:用于读取和写入媒体数据的 I/O 上下文;
AVIOContext 是libavformat库中一个表示访问媒体文件的I/O环境的结构体。它封装了对媒体文件的读取和写入操作,提供了和具体I/O操作系统相关的操作的抽象接口,实现了独立于实际操作系统的媒体文件访问接口。
int nb_streams: 流的数量,包括音频、视频、字幕等;
AVStream **streams:指向 AVStream 结构体的指针,用于存储所有流的信息;
AVStream是FFmpeg中libavformat库中的一个数据结构,用于表示媒体文件中的一个音频或视频流。在FFmpeg中,一个媒体文件通常包含多个音视频流,每个流对应着媒体文件中的一个轨道。AVStream通过存储音视频流的各种属性信息,方便解码和编码,对于多媒体处理和视频编辑有着至关重要的作用。
AVStream包含了一个媒体流的所有基本信息,如类型、编解码器、时间戳、时长、帧率、码率等等。常用的成员变量有:
char *filename: 用于存储文件名的字符串;
int64_t start_time: 媒体文件的起始时间戳;
int64_t duration: 媒体文件的持续时间;
int64_t bit_rate: 比特率,以 bit/s 计算;
uint8_t *buffer: 用于暂存数据的缓冲区;
int buffer_size: 缓冲区的大小。
◼ avformat_free_context();释放该结构里的所有东西以及该 结构本身
#include <libavformat/avformat.h>
/**
* Free an AVFormatContext and all its streams.
* @param s context to free
*/
void avformat_free_context(AVFormatContext *s);
◼ avformat_open_input();打开输入视频文件
在avformat_alloc_context()方法中,我们申请了一个avformatcontext,这个context中现在只有框架,没有实际的内容。
/**
* Open an input stream and read the header. The codecs are not opened.
* The stream must be closed with avformat_close_input().
*
* @param ps Pointer to user-supplied AVFormatContext (allocated by
* avformat_alloc_context). May be a pointer to NULL, in
* which case an AVFormatContext is allocated by this
* function and written into ps.
* Note that a user-supplied AVFormatContext will be freed
* on failure.
* @param url URL of the stream to open.
* @param fmt If non-NULL, this parameter forces a specific input format.
* Otherwise the format is autodetected.
* @param options A dictionary filled with AVFormatContext and demuxer-private
* options.
* On return this parameter will be destroyed and replaced with
* a dict containing options that were not found. May be NULL.
*
* @return 0 on success, a negative AVERROR on failure.
*
* @note If you want to use custom IO, preallocate the format context and set its pb field.
*/
int avformat_open_input(AVFormatContext **ps, const char *url,
const AVInputFormat *fmt, AVDictionary **options);
◼
avformat_close_input();
关闭解复用器。关闭后就不再需要 使用avformat_free_context 进行释放。
◼
avformat_find_stream_info()
:获取
音视频
文件信息
◼
av_read_frame();
读取
音视频
包
,这里更加合理的命令应该是av_read_packet();因为这里读取的并不是yuv或者pcm的frame数据,而是打包了的h264或者aac数据,是一包数据,但是由于ffmpeg历史原因,这里一直是av_read_frame();
◼
avformat_seek_file();
定位文件
◼
av_seek_frame():
定位文件
八 FFmpeg解码函数简介-解码器相关
•
avcodec_alloc_context3():
分配解码器上下文
•
avcodec_find_decoder():
根据ID查找解码器
•
avcodec_find_decoder_by_name():
根据解码器名字
•
avcodec_open2():
打开
编
解
码器
•
avcodec_decode_video2():
解码一帧视频数据
•
avcodec_decode_audio4():
解码一帧音频数据
•
avcodec_send_packet():
发送编码数据包
•
avcodec_receive_frame():
接收解码后数据
•
avcodec_free_context():
释放解码器上下文,包含了 avcodec_close()
•
avcodec_close():
关闭解码器