简介
网络提取层(NAL network abstraction layer )和视频编码层(VCL video coding)
码率、帧率、分辨率
其它
总结
视频编解码网上介绍很多,整理了不少笔记,经过近一年的学习,把整理的笔记反馈到社区,也加深一遍自己的理解。欢迎指正错误和讨论学习,谢谢浏览。
H264是一种视频压缩标准。
根据不同类别,编码器会使用不同类型的帧,I帧、P帧和B帧。
I帧:自身可以通过视频解压算法解压成一张单独的完整的图片。P帧只需要参考前面的I帧或P帧,而B帧则需要同时参考前面和后面的I帧或P帧。
在H.264基准类中,仅使用I帧和P帧以实现低延时,因此是网络摄像机和视频编码器的理想选择。
H264有严格的规范,以00 00 00 01分割之后的下一个字节就是NALU类型,用来描述此帧的意义。
NALU类型:
(1)第1位禁止位,值为1表示语法出错
(2)第2~3位为参考级别
(3)第4~8为是nal单元类型
以通常的首帧来看:
打印出来为103(用十六进制软件分析的话值为67),转为二进制为0110 0111,4-8为00111,转为十进制为7,释义见下:
0,未使用
1,不分区,非IDR图像的片
2,片分区A 3,片分区B 4,片分区C
5,IDR图像的片段
6,补充增强信息单元(SEI)
7,序列参数集sps
8,图像参数集pps
9,分界符 10,序列结束符 11,流结束符 12填充 13..23保留 24..31未使用
即是sps,仔细看还有第二个分隔符,为104释义为8,即pps。这一帧内包含了H264的大部分精华,在使用中把此帧喂入解码器是很关键的,简单介绍一下:
SPS:包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
PPS:包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)
在后面的实践Demo中会观察到此帧的重要性。
接下来的第二帧是实际意义上的关键帧(I帧):
101释义是5,代码表示的话是:
int value = buf[4] & 0x0f;//nalu, 5是I帧, 7是sps 8是pps.
VCL即编码处理的输出,它表示被压缩编码后的视频数据序列,这里有几个知识点,差分编码、运动补偿、帧内预测,有心的朋友可以去详细搜索学习,知识点这里用笔记里的记录做一个简单介绍:
这三个参数直观的影响到视频流的大小,视频清晰度等观看体验。码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。分辨率一定的情况下,码率与清晰度成正比关系,码率越高,图像越清晰;码率越低,图像越不清晰。
下面是一张参考图:
分辨率常用的有:
720*480(标清480p)
1280*720(高清720p)
1920*1080(全高清1080p, 1920*2 * 1080*2 = 4k)
3840×2160(八百万像素的超高清4k,往上再4倍就是8k超高清)
其实含480p以下为标清,480p以上为高清,经典的有720p、1080i、1080p,1080p又称全高清,1080p以上都为超清。(i隔行扫描多用于电视机信号,p逐行扫描)
帧率:
在1秒钟时间里传输的图片的帧数,影响画面流畅度,常说的24帧电影、在游戏上的FPS,都是这个概念,通常手机上20帧左右即可。
ps:Gop是指多少秒一个I帧。
码率:
右键看一个视频的属性,详细里有一个总比特率,计算方式是:
【码率】(kbps)=【文件大小】(字节 )X8 /【时间】(秒)
码率单位是kbps即千位每秒。也就是取样率(和音频的采样率有区别,采样率单位是Hz,表示每秒采样次数),单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真。码率越高越清晰,反之则画面粗糙而多马赛克,1080P不一定比720P清晰,打开看码率对比最实际~
IDR帧和I帧:首个I帧叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像,不过I帧不一定是IDR图像。H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将参考帧队列清空(DPB,DecodedPictureBuffer 参考帧列表),将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
H265和H264
同样的画质和同样的码率,H.265比H.264 占用的存储空间要少理论50%;如果存储空间一样大,那么意味着,在一样的码率下H.265会比H2.64 画质要高一些理论值是30%~40%,但是因为部分专利价太高(部分公司创建联盟,收取专利费),计算复杂度(编码要求的硬件性能较高) 普及难度直线上升。
逐行扫描和隔行扫描:详细画面效果参见下
http://blog.csdn.net/syb773849846/article/details/52120030
带宽,码流,在线人数之间的关系:
带宽 / (码流 * 8) = 同时在线人数
文件大小 = 时间×码率/8
一个视频文件的大小为5.86M,播放时长为3分7秒:
1:该文件对应的码流就是
5.86 * 1024 * 1024 * 8 / (3 * 60 + 7) =262872.95657754bps
2:10M独享带宽能支撑的同时在线人数
10* 1024 * 1024 / 262872.95657754 =39.889078498294
3:支撑1000人同时在线的系统最少需要的带宽数为
262872* 1000 / (1024 * 1024) = 250.69427490234M
场频:画面刷新次数。
行频:屏幕的水平扫描频率,以Hz为单位。它越大就意味着显示器可以提供的分辨率越高,稳定性越好。
行频 = height(垂直分辨率) * 1.04~1.08 * 场频
YUV格式:一种颜色编码方式,可以转化成我们常用的RGB色值。Y代表亮度,UV代表色值,Y可以显示一张完整的黑白图像。这样的设计解决了黑白电视和彩色电视的兼容,并且YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。
基本概念整理:
DTS:Decode Time Stamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.在display的时候使用.在没有B frame的情况下.DTS和PTS的输出顺序是一样的.
SPS(序列的参数集):包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
PPS(图像的参数集):包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)
流地址:HLT、RTMP等视频流地址的话,开源的很多,分享一个从直播流程到搭建服务器的良心博客:
http://blog.csdn.net/huaxun66/article/details/53427771
音视频解决方案很多,ffmpeg是绕不过去的开源技术,ndk开发在这一块的重要性可想而知。当然,无论是视频流地址还是各种开源的播放器,也都离不开协议这一基础概念。了解H264,窥一斑而知全豹,渐进学习慢慢就能看到整个音视频领域的大致规模。共勉~
录屏用udp发送到其它屏幕显示