ffmpeg开发教程(3) : 关于视频的一些基本概念

后续教程参考ffmpeg-libav-tutorialAn ffmpeg and SDL Tutorial, 对代码进行了一些修改,而且采用C++作为开发语言(其实为C++和C混合编程,ffmpeg 软件包提供的API为C语言接口)

视频

我们知道视频其实是利用的人的视觉暂留现象(比如1秒钟显示24帧图像),经过我们的大脑处理后就成了连贯的图像。

编解码 Codec –压缩数据

原始的视频图像,如果没有经过压缩,那我们来计算一个30分钟的视频,假定图像的分辨率为 1080X1920,采用RGB格式(3个字节,16,777,216种颜色),帧率为24/秒。

toppf = 1080 * 1920 //total_of_pixels_per_frame
cpp = 3 //cost_per_pixel
tis = 30 * 60 //time_in_seconds
fps = 24 //frames_per_second

required_storage = tis * fps * toppf * cpp

那么这段30分钟视频大约需要250.28G的存储空间,带宽需要1.11Gbps。数据量很大,因此需要对图像进行压缩,这也是我们为什么需要编解码codec 算法。常见的codec 算法有h264。

视频文件 — 存储音频和视频

一般的影像同时包含图像和声音,如何有效的将图像和声音保存在一个文件,并提供图像和声音的同步,比如我们常见的视频文件avi, mp4, mkv就是不同的视频文件格式,有些视频同时还包含了字幕信息。这些视频文件就像一个包装盒,将不同的声音,图像和其它比如字幕信息有效的管理保存起来。

FFmpeg libav 基本架构

下图是libav解码的一个基本流程:

ffmpeg开发的一个基本过程就是先把视频文件(比如bunny.mp4) 载入到一个AVFormatContext 结构中(实际是读入视频文件头信息)

然后从载入的视频头信息中,我们可以从中了解到该视频有几个视频,几个音频(比如左右声道),我们本教程只关心视频。可以将视频读入到AVStream数据结构中。

从AVSteam (Stream,流意为连续的数据流)。可以分解出视频数据包AVPacket。AVPacket 还是编码过(压缩)的数据,需要经过解码后(使用相应的AVCodec)得到AVFrame,AVFrame 不在是压缩的,可以直接显示在屏幕上。有了AVFrame后,FFmpeg提供了很多滤镜算法,可以对图像进行处理后再显示,或者在使用不同的编解码器(Codec)转换成其它视频格式,比如从mp4到webm等等。