h264和h265_h264 宏块大小是固定的吗_~怎么回事啊~的博客-程序员宅基地

技术标签: ffmpeg  

1 使用ffmepg抽离视频中的视频流和音频流

抽离音频:

ffmpeg -i    h264.mp4   -acodec copy -vn  audio.aac

-i的意思是input,后接输入源。-codec的意思是直接复制流

使用ffplay播放

ffplay audio.aac

抽离视频:

ffmpeg -i h264.mp4      -vcodec copy  -bsf    h264_mp4toannexb -f h264  out.h264

说明:

 -i h264.mp4 :是输入的MP4文件

-vcodec copy:从MP4封装中进行拷贝

-bsf h264_mp4toannexb:从MP4拷贝到annexB封装

-f h264:采用h.264格式

out.h264:输出的文件名称

播放:

ffplay   out.h264

可以使用notepad++ 安装十六进制的插件查看out.h264中的内容https://jingyan.baidu.com/article/ceb9fb100476ebcdac2ba057.html

这些内容的含义在后面解释

抽离h265

ffmpeg -i h265.mp4  -vcodec copy -f hevc out.h265

H261 

H.261 用于视频通信,会产生多个国家的互通困难的问题,不同国家采用不同的彩电制式,不可能直接互通。 H.261 采用一种公共中间格式(CIF, Common Intermediate Format),不论何种彩色格式,发送方先把自己国家的彩电制式转换成 CIF 格式,经 H.261 编码后再由CIF 格式转换到接收方彩电制式.

        视频信源编码器用于视频信号的码率压缩,主要采用混合编码方法;视频复合编码器将每帧图像数据编排成四层结构,并通过熵编码对视频数据进一步压缩输出。传输缓冲器和码率控制器用于保证输出码流尽可能稳定。传输编码器则用于视频数据的误码检测和纠正。解码器各部分功能与编码器相反。

H.261信源编码器框图如下所示,输入以MB(宏块)为单位

 

基于宏块的编码:

        宏块存在的意义:解决帧内压缩。是信源编码器通过算法划分的网格。

H264的基本原理其实非常简单,下我们就简单的描述一下H264压缩数据的过程。通过摄像头采集到的视频帧(按每秒 30 帧算),被送到 H264 编码器的缓冲区中。编码器先要为每一幅图片划分宏块。

以下面这张图为例:

划分宏块

H264默认是使用 16X16 大小的区域作为一个宏块,也可以划分成 8X8 大小。

 划分好宏块后,计算宏块的像素值。

以此类推,计算一幅图像中每个宏块的像素值,所有宏块都处理完后如下面的样子。

划分子块

        H264对比较平坦的图像使用 16X16 大小的宏块。但为了更高的压缩率,还可以在 16X16 的宏块上更划分出更小的子块。子块的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4非常的灵活。

上幅图中,红框内的 16X16 宏块中大部分是蓝色背景,而三只鹰的部分图像被划在了该宏块内,为了更好的处理三只鹰的部分图像,H264就在 16X16 的宏块内又划分出了多个子块。

一幅图像被划分好宏块后,对每个宏块可以进行 9 种模式的预测。找出与原图最接近的一种预测模式。

 

 

      宏块越大,视频压缩越高

      H.264的宏块,也是编码标准的基本处理单元,通常它的大小也为16x16像素。但在H.264的简介一文中我们就说过,H.264的预测图块可以小到4x4像素。所以这也促成了,16x16像素的宏块,可以接着再划分成子宏块这一操作。

        在这里插入图片描述

        在实际的H.264编码时,可能会使用8x8、或4x8、或8x4、或4x4像素的子宏块,也有可能是它们的组合。
        像素块越小,编码的复杂度也会随之增加,编码效率自然就会降低。但是这样是值得的,因为图像的压缩效率有了显著提高,也就是编码后得到的相同质量的图像,H.264的压缩比更大,占用的空间及带宽更小。  

使用的软件:VideoEye.exe 

 

 可以看出大部分宏块大小是16x16,信源编码器的作用就是 划分宏块,H264一般宏块大小16x16,h265的宏块大小最大能到64x64.

使用HEVC analyzer分析h265码流:宏块大小64x64 到 8x8

h264 固定为16x16,h265的宏块称为CTU

帧分组

         视频播放的本质是宏块的运动

        对于视频数据主要有两类数据冗余,一类是时间上的数据冗余,另一类是空间上的数据冗余。其中时间上的数据冗余是最大的。下面我们就先来说说视频数据时间上的冗余问题。

        为什么说时间上的冗余是最大的呢?假设摄像头每秒抓取30帧,这30帧的数据大部分情况下都是相关联的。也有可能不止30帧的的数据,可能几十帧,上百帧的数据都是关联特别密切的。

        对于这些关联特别密切的帧,其实我们只需要保存一帧的数据,其它帧都可以通过这一帧再按某种规则预测出来,所以说视频数据在时间上的冗余是最多的。

        为了达到相关帧通过预测的方法来压缩数据,就需要将视频帧进行分组。那么如何判定某些帧关系密切,可以划为一组呢?我们来看一下例子,下面是捕获的一组运动的台球的视频帧,台球从右上角滚到了左下角。

         H264编码器会按顺序,每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度。如下图:

        通过宏块扫描与宏块搜索可以发现这两个帧的关联度是非常高的。进而发现这一组帧的关联度都是非常高的。因此,上面这几帧就可以划分为一组。其算法是:在相邻几幅图像画面中,一般有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。

        在这样一组帧中,经过编码后,我们只保留第一帖的完整数据,其它帧都通过参考上一帧计算出来。我们称第一帧为IDR/I帧,其它帧我们称为P B帧,这样编码后的数据帧组我们称为GOP。

      一个可以播放的帧的帧类型是I帧,与I帧的差异程度在5%,P帧与I帧的差异程度在30%;

      I帧保存了一幅完整的图像,I帧的数量越多,视频越大,I帧间隔越大,视频文件越小;

     P帧含有运动矢量和差异信息

GOP

      在视频编码序列中,GOP即Group of picture(图像组),强相关的一组帧

编码顺序:编码I帧后,向后找到相似程度相差30%的P帧,然后向前编码B帧

  所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多,画面细节更多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。

  需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。

  同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作(找I帧)的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。

      从上面的解释看,我们知道I和P的解码算法比较简单,资源占用也比较少,I只要自己完成就行了,P呢,也只需要解码器把前一个画面缓存一下,遇到P时就使用之前缓存的画面就好了,如果视频流只有I和P,解码器可以不管后面的数据,边读边解码,线性前进,大家很舒服。
但网络上的电影很多都采用了B帧,因为B帧记录的是前后帧的差别,比P帧能节约更多的空间,但这样一来,文件小了,解码器就麻烦了,因为在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面(也就是说要预读预解码),而且,B帧不能简单地丢掉,因为B帧其实也包含了画面信息,如果简单丢掉,并用之前的画面简单重复,就会造成画面卡(其实就是丢帧了),并且由于网络上的电影为了节约空间,往往使用相当多的B帧,B帧用的多,对不支持B帧的播放器就造成更大的困扰,画面也就越卡。
 
        一般平均来说,I的压缩率是7(跟JPG差不多),P是20,B可以达到50,可见使用B帧能节省大量空间,节省出来的空间可以用来保存多一些I帧,这样在相同码率下,可以提供更好的画质。

运动估计与补偿

        在H264编码器中将帧分组后,就要计算帧组内物体的运动矢量了。还以上面运动的台球视频帧为例,我们来看一下它是如何计算运动矢量的。 

H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么就可以计算出物体的运动矢量了。下面这幅图就是搜索后的台球移动的位置。

通过上图中台球位置相差,就可以计算出台图运行的方向和距离。H264依次把每一帧中球移动的距离和方向都记录下来就成了下面的样子。

运动矢量计算出来后,将相同部分(也就是绿色部分)减去,就得到了补偿数据。我们最终只需要将补偿数据进行压缩保存,以后在解码时就可以恢复原图了。压缩补偿后的数据只需要记录很少的一点数据。如下所示:

我们把运动矢量与补偿称为帧间压缩技术,它解决的是视频帧在时间上的数据冗余。除了帧间压缩,帧内也要进行数据压缩,帧内数据压缩解决的是空间上的数据冗余。下面我们就来介绍一下帧内压缩技术。

 运动矢量分析:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/LIJIWEI0611/article/details/119752067

智能推荐

HDU5521 双向最短路+优先队列优化_NineFailure的博客-程序员宅基地

Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his fences they were separated into different blocks. John’s farm are divided into blocks labe

动态规划算法下的序列问题:最长公共子序列问题和最大子段和问题_最大子段和填表_My Turn的博客-程序员宅基地

本篇主要介绍最长公共子序列问题和最大子段和问题1、最长公共子序列问题什么是最长公共子序列给定一个序列X=<x1,x2,x3,x4…,xm>,另一个序列Z=<z1,z2,z3,z4…,zk>,若存在一个严格递增的X的下标序列<i1,i2,i3,…,ik>对所有的1,2,3,…,k,都满足x(ik)=zk,则称Z是X的子序列比如说:比如Z=<B,C,D..._最大子段和填表

JAVA求数组中众数_查找数组众数_秦哲祺的博客-程序员宅基地

根据题目中众数的定义,给的数据中一定会出现次数超过n/2的数,那么如果数组中一次删去两个不同的数,那么最后剩下来的数一定是众数,提供一种不用排序,时间复杂度O(n),空间复杂度O(1)的AC方法 import java.util.Scanner;import static java.lang.System.in;public class Main {public static void main(..._java求数组中的众数

Android中的Service:Binder,Messenger,AIDL_T-bright的博客-程序员宅基地

前言前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等。在这一篇博文里有一些需要前一篇铺垫的东西,建议没有看过前一篇博文的同学先去看一下前一篇: Android中的Service:默默的奉献者 (1) 。但是在前一篇博文中也有一些遗漏的东西——主要是关于bindService()这一块的具体细节。由于这

layui使用--lay-href_lay_href-程序员宅基地

需求: 在操作日志里边 点击用户id, 需要带着这个id跳转到账号列表里, 并且搜索出这个用户的信息:一开始是知道 给a标签设置一个lay-href:<a lay-href="xxx.html">用户id</a>跳转是可以跳转了, 但是有一个问题, 如下:tab的title变成了前一个页面的用户id, 然后, 找了资料, 发现需要这样设置:<a lay-href="xxxx.html" lay-text="账号列表">用户id</..._lay_href

RIP基础知识_曹世宏的博客的博客-程序员宅基地

RIP简介RIP是Routing Information Protocol(路由信息协议)的简称,它是一种较为简单的内部网关协议(Interior Gateway Protocol)。RIP是一种基于距离矢量(Distance-Vector)算法的协议,它使用跳数(Hop Count)作为度量来衡量到达目的网络的距离。RIP通过UDP报文进行路由信息的交换,使用的端口号为520。RIP包括..._rip

随便推点

Activity添加Fragment防止重复添加_czyzy的博客-程序员宅基地

if (savedInstanceState == null) {home = new HomeFragment();getSupportFragmentManager().beginTransaction().add(R.id.main_container, home, "home").commit();} else {home = (SuperHomeFragment) get

Android_RelativeLayout(相对布局)_CATTear的博客-程序员宅基地

布局属性 (以下是不据属性"注意 不是控件属性")如下:int ABOVE: 将 该控件 的 底部 放置于只定 ID 之上android:layout_above="@id/xxx"int BELOW:将 该控件 的 顶部 放置于只定 ID 之下android:layout_below="@id/xxx"int LEFT_OF:将 该控件 的 右边缘 放

【原】音视频基础知识(一)_weixin_30279315的博客-程序员宅基地

一:直播产品的种类1.1泛娱乐化直播:花椒、映客等娱乐直播,斗鱼、熊猫等游戏直播 产品特点:以美女主播展示才艺为主,如唱歌、跳舞等1.2实时互动直播:音视频会议、教育直播等,如思科、全时、声网等 产品特点:多人多视频实时互动二:架构对比2.1泛娱乐化直播架构泛娱乐化直播架构主要由4部分组成,主播端+信令服务器+流媒体云+普罗观众1.主播发起信...

android如何设置自适应大小的背景图片,Android 背景图片自适应方案_Holly皮肤管理师的博客-程序员宅基地

在做移动中间件的过程中,遇到了背景图片自适应的问题,比如一个Button的背景图片,如何让一张图片能够在不同高宽的场景下做到不失真。在做移动中间件的过程中,遇到了背景图片自适应的问题,比如一个Button的背景图片,如何让一张图片能够在不同高宽的场景下做到不失真。方案一: 刚开始想到的一个方案是用android的 nine-patch (又称“九妹”),*.9.png的图片是标准的png格式的图片..._android背景图片自适应

CleanWipe:无需密码彻底卸载Symantec(赛门铁克)-程序员宅基地

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)➤GitHub地址:https://github.com/strengthen/LeetCode➤原文地址:https://www.cnblogs.com/str..._cleanwipe

推荐文章

热门文章

相关标签