【音视频】技术提升2.0

一、视频

1. 视频即连续的图片

  • 所谓视频,就是连续的图片
  • 每一张图片称为一帧,每秒播放多少幅图片称为帧率

2. “原始”视频

  • 原始“视频”即一张一张连续存储的“原始”图片。
  • 所谓“原始”,就是逐像素描述一张图,从左上角第一个点,到右下角最后一个点。
  • 每个像素点用3个数字表示它的红(R)绿(G)蓝(B)程度,即 RGB 格式图片。
  • 跟 RGB 类似的还有 YUV,也是每个像素点用3个数字来表示,Y表示亮度,U、V表示色度。

2.1 RGB 和 YUV 的格式

  • 说是用 3 个数字(即 3 个字节)表示一个像素点,其实并不全是。
  • 比如 RGB 可以再加一个字节用来表示透明度,这就需要 4 个字节才能表示一个像素。这就是所谓的 RGBA 或者 RGB32。而正常的 3 个字节表示一个像素的,一般叫做 RGB24。
  • YUV 就更复杂一些。比较常见的一种情况是,让 4 个临近的点使用同一个 U 和 同一个 V,而 Y 是每个像素点使用各自的。这样就相当于每个像素点只使用了 1 + 1/4 + 1/4 个字节,即1.5个字节就可以表示一个像素。这种 YUV 我们称之为 YUV420。
  • 除此之外还有临近的 2 个像素点共用 U、V分量的,即 YUV422。而那种 每个像素都用自己的 Y、U、V的,就叫做 YUV444。

其实 YUV 不仅在每个点使用的字节数上分为几类,还有这些字节的存储顺序也有分类。这里就不展开了。以后单独发一篇来说明。

2.2 原始视频的大小

  • 因为原始视频是由原始图片组成的,而原始图片只要知道了它每个像素几字节,以及它一共有几个像素(即宽乘以高),就可以计算出大小。
  • 举例:一个YUV420格式的,分辨率为 1280x720 的视频文件,该视频共有7200帧,请问该视频文件的大小是多少?
  • 答:1.5Byte x 1280 x 720 x 7200 = 9.27 GB。
  • 7200 帧,按照 24 帧/秒 的速度播放,只能播 5 分钟,却占用了 9G+ 的磁盘空间。这显然是不可接受的。
  • 所以我们要压缩。不过在谈压缩之前,我们先看看如何播放原始视频。

2.3 “原始”视频的播放

  • 播放“原始”视频,需要手动输入视频的分辨率,格式(是YUV422还是RGB24?),帧率,才能正常播放。市面上常见的 YUV、RGB 播放器,都需要手动输入分辨率,格式,帧率才可以正常播放。
  • 因为“原始”视频记录的仅仅是像素内容,播放器不知道第一个字节表示的是R还是Y,不知道从第几个像素开始是图像的下一行,不知道该以多块的速度播放出下一帧图片。
  • 分辨率告诉播放器,每幅图像从哪里开始是下一行。
  • 格式告诉播放器YUV是怎么存储的。
  • 帧率告诉播放器要以多快的速度播放每一幅图像。
  • 原始视频播放器的实现极为简单,它只需要把每个像素画到屏幕上就可以了。这种播放器已经称不上播放器了,它只能算是现在泛指的播放器的一个组件——渲染组件。因为它只负责把像素交给屏幕。

3. 压缩

  • 原始视频体积过大,所以压缩是必然的。
  • 单张图片(了解即可)
    * 找出点和点之间的关系,用数学方法进行计算,不再逐像素的存储,大大节省空间。
    * jpg,png 等常见的图片,都是压缩过的。
  • 连续的图片——视频
    * 视频的第一张图片按照图片来压缩。
    * 后面的图片仅记录跟第一张图片的差异,大大节省空间。
  • I帧、P帧、B帧
    * I帧就是“关键帧”、“KeyFrame”,以它作为标准,后续图片只记录跟它之间的差异。
    * P帧就是仅仅记录了差异量的图片,所以光有P帧是无法表达一张图的,得找到它参考的那个I帧才可以。
    * B帧跟P帧类似,只是B帧不光参考它前面的那个I帧,还参考它后面的I帧(或者P帧)。
  • 现实中的视频都是压缩过的,比如 mp4、rmvb、flv、mkv、wmv等等。
  • 压缩过程实际上是复杂的数学运算,不同的数学方法会带来不同的压缩效果。

4. codec & format

  • 我们把某种压缩的数学方法,称为一种 codec。常见的有:h.264、h.265(hevc)、vp9、realvideo7、8、9,wmv7、8、9 等等。
  • codec只是负责压缩,压缩后我们同样需要告诉播放器分辨率、帧率这些信息,播放器才能正确的播放。
  • 所以我们在codec压缩过的数据之外又包了一层数据,称之为“封装”。或者叫“mux”,“container”,“复用”,“format”,这些词指的都是这一层。
  • 常见的封装格式有: mp4、rmvb、flv、mkv、wmv等等。即我们常见的后缀名。
  • 因为 format 层已经记录了分辨率、帧率等信息,所以我们播放封装过的视频文件时,就不需要手动输入了,双击即可播放。(播放器软件去“封装”里读出相应的参数)
  • 某种封装格式只能封装特定的几种codec,具体可以去维基百科查,或者查这种格式的文档。

5. 码率

  • 压缩后的视频大小,不再是简单的换算,因为不再是逐个像素存储视频。
  • 用压缩后的视频大小除以视频时长,得到的这个数,我们称之为码率。
  • 一般来说,同一种codec,码率越大则视频质量越高(压缩过程损失的越少)。
  • 不同的codec,如果在视频质量相同的情况下,码率越小,说明他的压缩效果越好。

6. 编码器和播放器

  • 摄像头/DV/采集卡等设备(得到原始YUV)—》编码器进行压缩(codec:encode)—》编码器进行封装(format:mux)—》输出.mp4等文件
  • mp4等文件—》播放器的解封装组件进行解封装(format:demux)----》播放器的解码组件进行解码,还原出YUV(codec:decode)-----》交给显卡进行显示
  • 注1:摄像头/DV/采集卡等硬解设备,只能一个像素一个像素的捕捉图像,得到的是“原始”图像
  • 注2:显卡等硬解设备,也只能一个像素一个像素的显示图像,需要的也是“原始”图像

7. 前处理和后处理(了解即可)

  • 前处理和后处理指的都是对原始图像的处理,所谓“前”指的是编码前,“后”指的是解码后。
  • 前处理一般为了让codec的压缩更简单更快,比如一种简单粗暴的前处理是把原始图像每相邻的两个像素丢掉一个,相当于分辨率减半,然后再送给codec进行编码,这样编码速度大大加快,但画质损失严重。
  • 后处理一般为了增强画质,在把压缩的视频解码成像素图像后,再逐像素的处理一下,比如进行边缘锐化等。
  • 提高codec压缩算法的效率,让压缩过程损失最少的画质是提高视频质量的主要方法。进行前处理和后处理是辅助方法。

二、音频

1. 音频:连续的采样

  • 所谓(数字)音频:就是连续的采样(Sample)
  • 每秒多少个采样称为采样率,常见的有 44100、48000等

2. 原始音频:Sample-format 和 channel

  • 用多少个字节,什么字节格式描述一个采样就是所谓的 Sample-format
  • 比如可以用1个字节无符号整数来描述一个Sample(u8),也可以用32位浮点数来描述一个Sample(flt)
  • 声道:采样率指的是单个声道每秒钟有多少个采样,如果是2声道,则整个音频每秒的采样数就要乘以2

3. 压缩

  • 音频的压缩实际上也是一系列的数学运算,把原本比较大的采样压缩成比较小的数据存放。

4. codec & format

  • 跟视频类似,音频也有codec和format的概念,不再重复叙述。
  • 音频常见的codec有:aac,ac3,wma1、2,mp3等等
  • 音频常见的封装格式有:mp3、wma等
  • “复用”:实际上,“复用”/“mux” 这个词指的是视频和音频共用一个文件来存储,即mp4、flv等format里即放了视频数据也放了音频数据。所以说,“复用” 和 “format” 等词,指的是同一层的东西。

5. 码率

  • 音频码率跟视频码率类似,不再赘述

三、FFmpeg

  • 几乎涵盖了音视频处理的各个阶段的各种功能
  • 可以把原始视频/音频进行压缩,进行封装,产生 mp4/flv 等常见视频文件
  • 也可以把压缩后的 mp4/flv 等文件进行解封装和解压缩,产生出原始像素数据和原始音频采样数据。
  • 不包括采集原始视频、音频的功能:这属于摄像机,麦克风等硬件的工作范围
  • 也不包括把原始音视频数据显示到屏幕上或者耳机里的功能:这是显卡,声卡等硬件的工作范围
  • ffmpeg 主要贡献是提供了一套源码/库,我们可以基于这些源码/库做开发,比如做播放器,转码器。
  • ffmpeg 顺便的贡献是提供了几个可执行程序,分别是 ffmpeg.exe, ffprobe.exe, ffplay.exe

1. ffmpeg.exe

  • 解码
    * mp4等文件—》解封装(demux)----》解码(decode)----》YUV原始像素序列文件
    * ffmpeg -i a.mp4 -vcodec rawvideo a.yuv
  • 编码
    * YUV----》压缩(encode) ----》封装(mux) ---- 》mp4等文件
    * ffmpeg -s 965x540 -r 24 -i a.yuv -vcodec h264 a.mp4
  • 转码:把一种压缩格式转换成另外一种压缩格式。即把编码和解码两个步骤一次完成。
    * ffmpeg -i a.mp4 -vcodec h264 -s 320x240 -b:v 500K -acodec mp3 b.mp4

2. ffprobe.exe

2.1 stream: 流

  • ffmpeg 里用 stream 来表示音频和者视频。
  • 一个文件里,既有音频又有视频,把文件里的音频称作音频流,视频称作视频流。
  • 一个文件里可能有多条视频流和多条音频流,不一定非得是一个视频一个音频。比如英语、汉语、法语、各自一条音频流。高码率、中码率、低码率各自一条视频流等等。
  • 除了音频流和视频流,文件里还可能有字幕流。

2.2 ffprobe:把文件里的所有stream的信息打印出来

  • ffprobe a.mp4

3. ffplay.exe

  • 一个完整的播放器: ffplay a.mp4。可以用键盘控制快进快退暂停等。
  • 因为ffmpeg本身不负责音频和视频的输出,上文说过,是显卡声卡等负责。所以ffplay借助了其他开源库来实现音视频的最终输出。就是SDL。
  • SDL封装了各种各种平台的音视频显示层,使你不用在意底层到底用的是什么声卡什么显卡,是OpenGL还是DirectShow来,SDL会自动识别并调用。你只需要把原始的音频、视频交给SDL去显示就可以了。
  • ffplay 就是用 ffmpeg 把文件解码成原始音视频,然后交给SDL做了显示。

你可能感兴趣的:(音视频,音视频)