此文章只作为个人学习笔记,侵删。
学习来源:B站:【科普】“视频”是怎么来的?H.264、码率这些词又是什么意思?讲的非常好,推荐观看。
文章目录
基础
一个1080p的视频,60fps,一分钟要占多大的内存?
一帧画面:1920*1080,大约200万像素;
每个像素:4个字节;
一帧画面: 200万*4/1024/1024 大约 7.6M;
一秒视频:7.6M*60 = 456MB
占用空间太大,所以体现了压缩的必要性。
一些基本定义:
-
分辨率:横向像素数 * 纵向像素数
1080p和1080i的区别:p指的是逐行扫描(progressive scanning),i指的是隔行扫描(interlace scanning)。在很久以前,电视台希望提高画面的分辨率,但是带宽又不够,所以将一帧画面分成两帧传输,前一帧是奇数行扫描,后一帧是偶数行扫描,然后两帧拼在一起,这就是隔行扫描的来历。 -
帧率:每秒传输的帧数
为什么有29.97和59.94这种帧数?剩下的0.03帧哪去了:很久以前,美国人电视使用525线分辨率,30帧(美国电力频率60hz的一半)。后来美国提出NTSC制式,希望从黑白电视转为彩色电视。这时他们遇到了一个问题,当时电视信号通过无线电波传输,在无线电波频谱当中,每个电视频道都能分到4.5MHz的频段,黑白电视时期正好能“塞下”视频(灰度或明度)和音频信号,但是如果是彩色电视信号,需要引入色度,此时视频信号会被音频信号干扰, 显示效果比较差。此时采用了逐行反相的技术(line by line phase reversal),需要信号频段的频率可以整除线速率:
4.5 M H z 525 × 30 = 整 数 \frac{4.5MHz}{525\times 30} = 整数 525×304.5MHz=整数
但是这样除下来好像不是整数?改线分辨率525,以前的电视都不能用了,所以只能改传输的帧率为29.97,这样除出来的结果是286。
标准一旦指定改起来就不容易了,所以一直用到了现在。
当然,NTSC是日本和美国使用的,对于中国和欧洲,使用的是PAL制式,就没有这个问题:
6.0 M H z 625 × 25 = 384 ( 整 数 ) \frac{6.0MHz}{625\times 25} = 384(整数) 625×256.0MHz=384(整数) -
视频格式分为:
- 封装格式:存储视频、音频、媒体信息、字幕等。本质上封装格式是一种”容器”,就是一层“皮”,和视频的质量没有任何关系。常见的格式有MP4、FLV、AVI、MOV、MKV、3GP等。所以转封装格式不需要格式工厂,太费时间,直接用mediacoder这样的转码软件,选择好目的容器,音频流、视频流全部选复制,一瞬间就可以转码完毕。
- 编码格式。什么时候需要重新编码?新转换的封装格式不支持原来的编码时,就必须重新编码了。
比如YouTube的视频编码格式为VP8和VP9,需要转MP4时就需要重新编码为H.264。
综上,封装格式和编码格式配合在一起才是完整的视频。
-
码率bitrate:经常会听到人问视频是多少M码率,这个码率就是数据速率的意思,代表每秒钟视频包含的数据量、信息量。
码率会直接影响到视频的大小,也会很大程度上影响视频的质量。
太大码率的视频很占内存,所以直播网站对码率都有限制,视频网站对码率也有“二压线”(同时限制视频码率和视频峰值码率):
如何在有限的码率下提高直播的画质,同时还要照顾到机器的性能是一个很关键的问题。
最常见编码标准:H.264
如何保证质量的情况下减少视频的占用内存,减小视频的码率,靠的是压缩。
视频通过什么方式去压缩,压缩到什么程度靠的就是编码标准。
对于H.264等现代的编码格式来说,视频由帧内压缩和帧间压缩两种压缩构成。
帧内压缩
帧内压缩就是把视频内每一帧画面都压缩成类似jpeg格式的有损帧。jpeg原理是利用人眼对明度、色度敏感性的不同,进行不同程度的压缩(保留亮度信息, 压缩色彩信息):
jpeg的压缩效率非常高,足以缩小90%的视频体积。但仅仅帧内压缩还是压不够狠。
帧间压缩
我们平时看到的视频,每秒只有几帧是原生图像,剩下的都是算法“脑补”出来的:
H.264编码分为I帧、P帧和B帧
I帧就是完整的关键帧,先把I帧分割成88或1616像素的“宏块”:
然后对I帧和它的下一帧每个对应的宏块作比较,
如果发现I帧和下一帧基本相同,或者位置有规律可循,可以通过预测的出来,就把下一帧记为P帧,对前后无变化的宏块直接引用前一帧信息,前后发生变换的宏块,记录变换的信息(颜色、位置等)。
B帧是双向预测帧,是在I帧和P帧的基础上再进行预测
这样的压缩方式也带来了一个问题:
在视频中加入一些火花、乱七八糟的东西,人脸就会变得非常模糊。这是因为画面太复杂了,信息量太大了。首先,这点码率根本就塞不下;其次,电脑根本也没法预测这一帧的这一宏块下一帧会走到哪里。所以P帧和B帧的画面都会严重失真。
遇到这种情况就需要:
- 更高的画质预设
- 可变码率
来设置了。
H.264一些重要的概念
GOP(Group of Picture)
每一组IPB帧的序列包含了多少帧。
即一个I帧之后要经过多少帧才会出现下一个I帧。
同码率下,GOP值越大,B帧与P帧越多,视频质量越高。
三种控制码率的方法CBR、VBR、CRF
CBR 固定码率
视频全程码率恒定,文件大小可预期,编码压力小,直播常用。其局限性是不能根据场景来动态调整码率,简单场景画质好,复杂场景画质差,是空间利用率最低的方式。
VBR 可变码率
码率可变,按需分配。
需要设置一个目标码率,编码的规程中会为简单的场景分配更少的码率,为复杂的场景分配更高的码率。
此外,如果对码率需要更精确的限制,VBR可以选择2-Pass,渲染两遍。第一遍先计算视频的复杂度,一帧一帧的分配好视频各部分的码率,第二遍再渲染视频,从而更精确的控制码率。
CRF 固定质量模式
先给定一个CRF质量值,CRF值越低,视频看起来质量越高,反之亦然。
CRF是以视频的观感画质为目标,码率、文件大小不可预期。
对于没有码率限制的情况,CRF模式是首选。
ABR、CQP等模式
ABR(平均码率)是码率波动更小的VBR,CQP是固定量化参数,相当于比较低级的CRF。这两种模式不怎么会用到。
此外,直播和平时的视频网站是有区别的,直播并没有充足的时间用来编码,为了保证不掉帧,必须牺牲掉一部分画质的质量,需要在画质和编码速度上做取舍。
实验:CPU、GPU编码效果对比
CPU是真滴强。但是对CPU的占用率是真滴高,所以CPU比较差的话还是离不开显卡编码。