1、什么是音视频?
音频:以震动频率和震动幅度记录的数据
视频:以连续的很多图像的记录的数据
2、为什么有那么多视频格式和编码格式?
基于对音视频的定义,是可以直接使用音频+图片集的形式表示一段视频的。但是,这样做的代价是存储或带宽(网络传输)太大,特别是视频的图片数据。所以现在有很多封装格式(flv mp4)和编码格式(vp6、vp8、vp9、h264),这些都是为了提高单位大小内的信息容量。
当然,这种做法是典型的时间换空间,因为经过封装和编码之后,对应的使用端需要进行解封装和解码。
3、使用ffmpeg api进行开发过程中哪些概念需要明确?
一种格式的文件(.mp4)或数据流(rtsp),常常对应了封装格式MP4/AVI/MKV,封装格式定义了音频、视频、字幕是如何存放以及对应的元数据(描述信息),数据结构为AvFormatContext。
在AvFormatContext定义了AVStream集合,用来表示各种流(音频、字幕、视频)。
在AVStream中,定义了流的类型、数据单元AVPacket、编码格式(音频编码AAC OPUS ; 视频编码H264 vp9)。
4、如何获取"原始"音视频数据
"原始"是指解压后的原始格式数据(RGB或YUV等原始图像格式的数据),并不是指原始的图片,因为编码过程会有损耗,只是目前的编码算法能在视觉上保持与原始图像一致。
获取的过程
1、读取AVStream中的数据包AVPacket(压缩过的)
2、解码需要通过解码器AVCodec进行,而解码器运行在解码上下文中AVCodecContext。 因此,需要通过AVStream的编解码参数AVCodecParameters查找解码器,并在AVCodecContext中打开,然后不断将AVPacket发送给解码上下文avcodec_send_packet,并通过获取原始数据的接口avcodec_receive_frame得到解码后的原始数据,即可得到原始图像数据(常见的YUV格式数据)。
总结:
文件~容器 <===> AVFormatContext <===>N* AVStream
AVStream包含了AVCodecParameters 和原始数据包AVPacket,可见AVStream是完整的是自描述的,容器AVFormatContext仅仅是定义了不同Stream之间的存储规则。
编码和解码都是在AVCodecContext中进行的,AVCodecContext中包含了编解码参数和编解码器AVCodec
编码: 原始数据AVFrame------->AVCodecContext -------> 编码数据AVPacket
解码: 编码数据AVPacket------->AVCodecContext ------->原始数据AVFrame