之所以写这篇文章是因为有朋友对IPB帧的设置比较感兴趣,回复中说得比较简单,因此在这里详细的写一下,虽然说一般情况下我们很少去设置这个IPB帧,不过,如果真的学好了,并且清楚的了解了这个IPB帧的概念和设置后,我们能够在渲染成品的时候更加好的掌控视频的质量与体积。

在说怎么设置之前,我们先了解一下IPB帧的概念,网络上其实蛮多的,我这里稍微做一点自己的改变和理解,这样更加方便我们理解。

首先说到IPB帧,就不得不说一下帧内压缩和帧间压缩:关于压缩,我想不需要做更多的解释,简单点,就是为了在保证我们可以接受的质量前提下,尽可能缩小原始音视频的体积,这样的一个过程就是压缩。

帧内压缩(Intraframe compression),也称之为空间压缩。就是指在压缩时,只计算单帧画面内的信息,不考虑前后帧的关联,单帧压缩会丢掉该帧内无用的信息或者根据设置,丢掉更多我们认为不重要的画面信息,因此,相对而言,帧内压缩可以极大程度保留画面清晰度、色彩范围以及其他信息。同时,因为帧内压缩是对单帧画面的完整压缩,不牵涉到其他相邻的帧画面,因此在播放器解码时,所需要消耗的资源也是比较小的。因为其不考虑与其他帧的冗余信息,因此,和我们一般常用的静态图像压缩类似,属于有损压缩。

帧间压缩(Interframe compression),也称之为时间压缩。是指在压缩时,需要计算相邻帧之间的画面信息差异,即在相邻的单帧画面中,会存在冗余信息,压缩这些冗余信息就可以进一步提高压缩量,减少压缩比。采用帧间压缩的方式,就是专门用于处理连续图像的一种编码压缩,这样的压缩,会导致画面信息更多的丢失,但是,却可以极大的减小音视频文件的体积,所以,我们现在大部分使用的压缩编码,都是以帧间压缩为主,帧内压缩为辅的方式。

那么,提到了帧间压缩,我们就会牵涉到最常见的IPB帧的概念:
I帧表示关键帧,I帧画面完整保留,只采取帧内压缩,解码时只需要本帧数据就可以完成(因为包含完整画面)。
P帧是向前预测编码帧(也叫差别帧),表示这一帧跟之前的一个关键帧(或P帧)的差别,P帧没有完整画面数据,只有与前一帧的画面差别的数据,因此解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。
B帧是双向预测编码帧(双向差别帧),B帧记录的是当前帧与前后帧的差别,换言之,解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。

其中P帧与B帧的压缩都基于I帧,显而易见B帧压缩率最高,但是解码时CPU会不断的进行前后帧的对比,因此会消耗大量的系统资源。

我们经常会在摄像机或者记录下的视频文件中看到自己拍摄视频所采用的压缩算法,常见的有All-I,以及IPB。
如果视频流只采用了All-I压缩(全部帧都是I帧关键帧),那么解码器可以不管后面的数据,边读边解码,线性前进。如果视频流压缩采用了IPB,有B帧,则需要缓存前面和当前的视频帧,待后面视频帧获得后,再进行解码。

在当前的网络流媒体中,为什么很多网络直播会有延时,很大程度上就是因为IPB的压缩算法,在网络条件较好的地区,延时会少很多,或许只有几秒钟,网络条件差的地方,以及计算机配置不太好的服务器和播放端,延迟的时间就会比较长。

说了以上那么多,相信有的人已经一头雾水了,其实关于IPB帧,他们自己还有很多专属的特点,这里不一一赘述。接下来,我们引入一个概念:GOP(帧组)。

简单的理解GOP就是两个I帧之间的间隔。
我们可以打一个比方,假设我们现在有一个每秒15帧,时长3秒的动画视频,我们设定第一帧为I帧关键帧,设定第15帧为P帧差别帧,那么,中间第2帧~第14帧则为B帧双向差别帧。这总共15帧就组成了一个GOP帧组,也即是说,这个时长3秒的动画视频,一共有3个GOP。
在流媒体服务器上,都会设定是否在客户请求时直接将缓存数据发送给客户,还是等到有I帧的时候再发送。如果设定的是有I帧的时候发送,那么播放客户端只有在获得I帧后才会有完整的视频流,客户端缓冲时间较长,但是延迟至少是一个GOP,套用刚才的例子就是1秒。如果直接发送,不等I帧,客户端得到的画面会残缺,但是延迟则较低。

当然,实际的情况中我们可以自行设定多少才是一个完整的GOP,一般情况下,一个GOP,短的可以设置5~6秒钟,即第1帧为I帧,第5帧为P帧,2、3、4帧为B帧,那么在这样的设置下,我们即可以得到一个压缩比较高,但是画面信息也相对更完整的视频流。

我这里使用Vegas中的Mpeg-2的IPB帧设置来进行参考。(其他的编码虽然在Vegas中没有IPB帧的设置,但并非不存在,只是因为IPB是Mpeg-2的标准压缩方式)
<ignore_js_op>

通常的情况下,每12~15帧就必须要传输一个I帧的信息,因此,在Vegas中默认的I帧参数是12,同时,在压缩计算时,如果画面场景进行了切换(或者转场),那么则该帧必须定义为I帧。当然,你可以进行自定义。
默认情况下,B帧的长度是2。此时,整个GOP帧组的顺序为IBBPBBPBBPBB,此后继续重复IBBPBBPBBPBB。
那么在这里,我们就可以对这两个参数进行更改和设置,如果我们设置I帧为5,B帧设置为3的话,那么就如同我刚才所说的,第1帧为I帧,第5帧为P帧,2、3、4帧为B帧,顺序为IBBBP,这5帧成为一个完整的GOP帧组,之后类推。

那么,说到这里,我相信很多人应该能够理解了,有时候两个同样的视频文件,码率一样,时长一样,分辨率一样,但是体积不一样,很大程度上是因为GOP(或者IPB)的不一样,试想一下,一个视频中有大量的I帧存在,而另一个则没有,那么,同样的压缩,所产生的视频文件体积当然会有不同。
同样,我们过去常说的一个文件压缩多次之后,画面质量下降,体积变小,也正是由于IPB的设置所导致的。

现在我们引申一下,谈谈的恒定比特率和动态比特率:
恒定比特率就是从视频一开始到结束,每一秒的码率都是恒定不变的,这样,不管画面信息是复杂还是简单,转场有多少,码率都是同一个,能够保证画面始终是我们想要的质量,但是文件体积很大。
动态比特率则计算在画面信息量大,动态场景多的地方使用码率最大值,画面信息简单,转场不复杂的地方使用最小值,其他地方计算平均值进行浮动,这样虽然某些画面在转场或者信息量大的地方可能会产生马赛克等画面残次,但文件体积可以压缩控制。

那么问题来了,在压缩的时候,计算机又是如何知道该在什么地方采用最大值或者最小值呢?依旧是刚才的图:
<ignore_js_op>

根据我刚才讲解的IPB以及GOP的知识,就可以知道,计算机是根据IPB和GOP的设置来进行动态比特率的调整的。
而动态比特率中的二次编码,指的就是在第一次计算过程中,只计算画面的IPB帧设置与画面信息,而不进行编码压缩,完成第一次编码后第二次才进行视频压缩,二次编码的压缩速度远慢于一次编码,但是同样的设置,二次编码得到的画面质量会高于一次编码。

根据我从业多年的经验,经常会遇到客户有这样的要求:体积控制在150M以内,分辨率720*576或720*480,帧数25帧,格式Mpg、Mov、Rmvb、Wmv。
针对这样的需求,往往半小时左右时长的DVD是很难控制在150M以内的,当然,如果控制在100M一下,大家可以想象一下Mpg-2这个格式下,低码率的动态画面是有多么不堪入目,此时我们就不能选择Mpg-2这样采用帧间压缩的视频格式,而需要使用Wmv等采用帧内压缩的格式,因为这样的格式虽然在单帧画面中可能没有很高的清晰度,但是,能保证的是画面与画面之间流畅的衔接而不会出现马赛克这样的情况。

说到这里,我做个小的总结:
现在我们做片子,已经很少会牵涉到IPB帧的设置了一般默认就可以,而恒定码率和动态码率的设置,根据现在的全国网速来看,其实也已经没有太大的关系。当年网络流媒体需要设置动态码率,是因为带宽普遍只有2M甚至更低,而这个参数在如今的网速面前,其实已经没有什么必要,因此,一般采用默认的IPB,恒定码率,就已经可以满足在线视频的高清流畅播放了。

转载自:

  [原创] 关于IPB帧与恒定比特率、动态比特率的详解

关于IPB帧与恒定比特率、动态比特率的详解的更多相关文章

  1. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

  2. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  3. 【转】java的动态代理机制详解

    java的动态代理机制详解   在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们 ...

  4. java的动态代理机制详解-----https://www.cnblogs.com/xiaoluo501395377/p/3383130.html

    java的动态代理机制详解-----https://www.cnblogs.com/xiaoluo501395377/p/3383130.html

  5. 动态内存管理详解:malloc/free/new/delete/brk/mmap

    c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...

  6. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  7. java的动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  8. JNI_Android项目中调用.so动态库实现详解

    转自:http://www.yxkfw.com/?p=7223 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.java package com.wwj. ...

  9. JNI_Android项目中调用.so动态库实现详解【转】

    转自 http://www.cnblogs.com/sevenyuan/p/4202759.html 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.ja ...

随机推荐

  1. ECMAScript 6 开篇准备

    1前言 该系列文章均为学习阮一峰老师<ECMAScript 6 入门>一书的学习笔记.原著:http://es6.ruanyifeng.com/ 各大浏览器的最新版本,对ES6的支持可以查 ...

  2. ASP.NET实现微信功能(1)(创建菜单,验证,给菜单添加事件)

    LZ实在 不知道怎么起名字了,索性就取了这个名字,开始吧,说实在的,想给自己的平常的学习做一个总结,总是忘了总结.也只能给工作做一个总结了. 我打算用2篇文章来写,第一篇是关于订阅号的,就是这个号,另 ...

  3. 用CS的思维可以指导BS的项目吗?

    最近项目上线,越来越觉的让人不爽.1.在录数据的界面领导要求用Enter键一路打下来,用户不用操作鼠标数据就可以录完. 2.CS的项目中用快捷键的确很方便,但是大家在BS的项目中也用快捷键吗? 反正我 ...

  4. ASP.NET MVC使用Areas后怎样获取Area(区域)的名称

    写此随笔,目的只为今后在ASP.NET MVC项目中再用到Area(区域)时作为备查. 获取当前Area(区域)名称的方法是: ViewContext.RouteData.DataTokens[&qu ...

  5. .Net(c#)加密解密之Aes和Des

    .Net(c#)加密解密工具类: /// <summary> /// .Net加密解密帮助类 /// </summary> public class NetCryptoHelp ...

  6. win10下装Ubuntu双系统

    本机状况: ssd在笔记本原来的硬盘位,已经安装win10 机械硬盘在光驱位 现在安装Ubuntukylin16到光驱位的机械硬盘建立双系统,并用Windows管理启动 1,将下载的Ubuntu镜像用 ...

  7. JAVAWEB贵美网上商城完整项目源码(SSH2)

    JAVAWEB贵美网上商城完整项目源码(SSH2) 贵美网上商城原是北大青鸟的一个内部项目,项目采用 struts2+spring4+hibernate4+MySQL等技术实现,数据库连接池采用c3p ...

  8. 转载:《TypeScript 中文入门教程》 8、函数

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 函数是JavaScript应用程序的基础. 它帮助你实现抽象层,模拟类,信息隐藏 ...

  9. GJM :多人在线游戏的设计思路

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  10. MVC丶 (未完待续······)

         希望你看了此小随 可以实现自己的MVC框架     也祝所有的程序员身体健康一切安好                                                     ...