一、视频编解码基础知识

1、视频介绍

视频的本质是图像序列,根据视觉暂留的原理,每秒播放20~25张图像,就会形成连续平滑的视觉效果,人眼将无法区分其中单幅的图像,就这样连续的画面叫做视频。每秒播放的图像数量叫作帧率。图像是由像素构成的,在彩色图像中,每个像素由R、G、B三个分量构成,每个分量用一个字节存储。分辨率用于描述图像的尺寸,例如分辨率1280x720就表示图像宽度是1280个像素、高度是720个像素。

2、压缩视频的原因

为什么要对视频进行压缩?假如有一段时长为60秒视频,它的分辨率是1280x720,帧率是25,那么这段视频的大小等于:60 x 25 x 1280 x 720 x 3 = 4147200000字节,大约是3955MB,如此庞大的数据,如果不进行压缩,那么磁盘空间将会很快被占满。

多媒体数据占了互联网数据量的80%以上,其中大部分都是图像视频数据,未压缩之前的视频非常庞大,不利于存储和传输,因此很有必要对视频进行压缩,视频压缩也叫作视频编码,它利用视频中存在的空间冗余和时间冗余,剔除人眼不敏感的信息,达到数据压缩的目的。

3、视频压缩的依据

视频能够进行压缩的根本原因是信息冗余,视频中存在两种冗余信息:

(1)空间冗余。对于视频的每一帧图像,在一定尺度范围内,像素的变化是非常平缓的,像素之间非常相似,这就是空间冗余。

(2)时间冗余。视频是由连续变化的图像构成的,在一个很短的时间内,相邻图像之间的变化很小,因此相邻图像很相似,这就是时间冗余。

 4、视频编码的原理和细节

由于视频中存在大量的信息冗余,想要对视频进行压缩,就必须找到去除冗余信息的方法,标准的视频编码过程包含下面几个步骤:

(1)预测编码。所谓预测就是利用前面像素值来推算当前的像素值。根据前面的知识我们知道,在空间或者时间上相邻的像素是很相似,因此只要预测方法合适,预测值和实际值会很接近,假设当前像素的实际值是X,预测值是P,那么X和P之间的残差A=X-P。如果我们只对残差数据进行编码,那么将会大大压缩数据量。这就是预测编码的原理。预测编码可以分为空间预测(帧内预测)和时间预测(帧间预测)两种。预测编码可以分为下面几个步骤:

i. 利用前面已经编码并重构像素块预测当前像素块的值

ii. 求当前像素和预测像素的差值

iii. 对像素差值进行编码

iv. 把编码后的数据传输到解码端,在解码端按照同样的方法对像素值进行预测,再加上残差,就可以重构得到原始图像了。

为了得到最佳的预测值,编码器通常需要使用不同预测方法进行预测,然后根据某个评判标准(一般是SAD、STAD、RDO等)得到最优的预测值(注意不是预测值越接近实际值就越优,所谓最优是计算复杂度、失真和码率之间的综合考量),特别对于帧间预测来说,在预测的时候要在参考帧中找到当前块的匹配块,需要大量的计算,因此预测模块一般是编码器中计算量最大的模块,而预测方法的好坏也直接决定了视频的压缩率。

(2)变换编码。变化编码本身不会对数据进行压缩,变换的目的是把空域信息转换为频域信息,去除了信息之间的相关性,在接下来的编码操作中可以得到更高的压缩比,变化编码是为下一步的量化编码做准备的。在视频编码中常见的变换方法是DCT变换和哈达玛变换。

(3)量化编码。量化是视频产生失真的根本原因。经过预测编码、变换编码之后得到的数据被称为变换系数,虽然变换系数相对于原始数据数来说已经很小了,但是系数值的变化范围仍然很大,利用量化把变换系数的连续取值转换成有限的离散值,这样可大大提高压缩率。假设有这样一组数据[16,96,100,600,50],量化参数是25,那么量化之后数据是round([16 / 25, 96 / 25, 100 / 24, 600 / 25, 50 / 25]) = [0,4,4,24,2],可以看到,量化之前的数据范围是16~600,需要大量的比特数才能表示,量化之后的数据范围是0~24,只需要少量比特数就可以表示,实现了压缩数据的目的。编码是一个不可逆的操作,它是失真产生的根本原因。

(4)环路滤波。环路滤波和压缩没有很大关系,却和视频的画面质量有很大关系。视频编码是以块为单位进行的,在经过量化模块时,可能每个块选择的量化系数不同,导致每个块产生的失真不一样,造成像素块的边界不连续,因此人眼观看视频的时会有方块效应(也就是有很多马赛克现象)。为了提高视频质量,有必要对方块效应进行消除,这就是环路滤波模块的功能。经过量化操作之后的数据块,再经过反量化、反变换,然后进行重构,接着进入去方块滤波进行去方块操作,得到的像素块就可以作为参考像素块给预测模块使用。环路滤波是一个可选模块。

(5)熵编码。熵编码的目的是去除统计冗余,实现数据的进一步压缩。这么说可能有点抽象,举个例子,假设有这样一组数据[0,4,4,24,2],如果使用定长编码来进行编码,这段数据可以表示为[00000,00100,00100,11000,00010],每个数据需要5 bit来表示,这段数据的总长度是5 bit x 5=25 bit;如果我们使用哈夫曼来编码,这个数组中每个元素概率值分别如下:数值0的概率是20%,数值4的概率是40%,数值24的概率是20%,数值2的概率是20%,即[20%,40%,20%,20%],根据每个元素的概率构造哈夫曼树(节点中括号内的是数组元素值),如下图所示,因此这段数据可以表示为[0,10,110,111],数据的总长度是11 bit。

由此可见使用哈夫曼编码可以去除统计冗余,实现数据压缩的目的,哈夫曼编码就是一种熵编码方法,但是由于哈夫曼编码对错误非常敏感,不适合实际应用,因此实际应用中通常使用变长编码(CAVLC)和算术编码(CABAC)作为熵编码算法。算术编码利用一个0到1之间的浮点数来描述一个信号序列,然后用这个浮点数来表示这个信号序列,极大的压缩了数据。算术编码可以使用一个简单的例子说明,假设有一个二进制串“10101110”,符号0和1的概率值都是50%,算术编码的过程如下:

(1)设置定一个区间,通常这个区间我们设定为[0,1),然后使用low指向区间的下界,用high指向区间的上界,现在low指向0,rhigh指向1.

(2)输入每一个符号,按照符号的不同对low和high进行调整,调整方法如下面公式所示,最后把low指向的浮点数作为这个符号串的码字,表示这个二进制串,可以看到算术编码的压缩效率比哈夫曼编码高很多,在x264中使用CABAC(上下文自适应的二进制算数编码)作为熵编码算法。


二、视频编解码实践

1、Ffmpeg介绍

上面介绍了视频编码的基础知识,让我们看看实际应用中的视频编码是如何操作的。

在实际工程项目中,ffmpeg是应用最多的多媒体处理框架,它提供了音视频采集、编解码、图像处理,格式转换等功能,并且拥有很强的扩展能力,通过ffmpeg可以很容易集成第三方库(例如:x264、openh264等),通过这种能力,它可以实现更强大的功能。Ffmpeg由下面几个部分构成:

Libavformat:音视频格式处理

Libavcodec:音视频编解码

Libavfilter:音视频滤镜

Libavdevice:音视频设备采集

Libswscale:图像缩放、转换

Libswresample:音频重采样

Ffmpeg:一个命令行的转码工具

Ffplay:一个命令行播放器

Ffprobe:简单的媒体格式分析工具

 2、Ffmpeg视频编码

视频编码是ffmpeg提供的基本功能之一,通过ffmpeg可以很容易实现视频编码操作。使用ffmpeg进行视频编码之前需要把x264、openh264等第三方编解码库集成到ffmpeg中才能使用。编码步骤如下:

(1)注册编码器

(2)根据名字或者ID查找你想使用的编码器(例如x264、x265、openh264等)

(3)创建一个编码器上下文对象

(4)在编码器上下文对象中设置编码器参数

(5)打开编码器

(6)读取一帧图像进行编码,一直重复该过程,直到处理结束

(7)关闭编码器

示例代码如下:

avcodec_register_all();// 注册所有可用的编码器codec =avcodec_find_encoder_by_name(“libx264”); // 查找编码器ctx =avcodec_alloc_context3(codec); // 创建编码器上下文ctx->width = 1280; //设置编码器参数ctx->height = 720;// ….其他的参数设置avcodec_open2(ctx,codec, NULL); // 打开编码器while(read_frame(frame)){AVPacket pkt; // 存放编码之后的数据int got_output = 0; // 是否成功编码得到一个图像avcodec_encode_video2(ctx, &pkt, frame, &got_output);// 编码if(got_output){// 得到编码后的数据,进行后续操作}}avcodec_free_context(&ctx);// 关闭编码器

可以看到,ffmpeg隐藏了大部分的编码细节,调用者不需要了解预测、变换、量化、熵编码等细节,这些细节都已经被ffmpeg封装好了,开发者只要把编码参数设置好,然后调用相关的接口函数,即可实现视频编码功能。当然,这只是最基本的编码功能,要想在画面质量和压缩率之间取得平衡,必须了解视频编码的细节,然后设置相应的参数

3、Ffmpeg视频解码

Ffmpeg自带了H264的视频解码器,开发者可选择直接使用ffmpeg自带的H264解码器或者第三方的解码库进行视频解码。和视频编码一样,解码操作的大部分细节都已经被ffmpeg隐藏起来了,开发者只需要设置好相关的解码参数,然后调用接口函数就可以实现解码功了。解码流程如下:

(1)  注册解码器

(2)  查找解码器

(3)  创建解码器上下文对象

(4)  设置解码参数

(5)  打开解码器

(6)  读取数据进行解码,直到结束

(7)  关闭解码器

代码示例如下:

avcodec_register_all();//注册解码器codec =avcodec_find_decoder_by_name(“h264”); // 查找解码器ctx =avcodec_alloc_context3(codec); // 创建解码器上下文对象//…设置解码参数avcodec_open2(ctx,codec, NULL); // 打开解码器while(read_packet(pkt)){AVFrame frame; // 存放解码之后的图像数据int got_frame = 0;avcodec_decode_video2(ctx, frame, &got_frame,pkt); // 解码if(got_frame){// 解码得到一帧图像,进行后续操作…}}avcodec_free_context(&ctx);// 关闭解码器


三、结束

可以看到ffmpeg是个非常强大的多媒体处理框架,通过ffmpeg我们可以很容易进行音视频方面的处理。上面介绍的只是ffmpeg的冰山一角,要想熟练使用ffmpeg,必须花很多时间去熟练使用它。

点击下方“阅读原文”,技术干货

↓↓↓

【视频技术解读】编解码的理论和实践相关推荐

  1. 视频编解码的理论和实践2:Ffmpeg视频编解码

    近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术.因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术. 相关阅读推荐 &l ...

  2. 音视频开发(9)--视频编解码的理论和实践

    视频编解码的理论和实践1:基础知识介绍   1.视频介绍 视频的本质是图像序列,根据视觉暂留的原理,每秒播放20~25张图像,就会形成连续平滑的视觉效果,人眼将无法区分其中单幅的图像,就这样连续的画面 ...

  3. 视频编解码的理论和实践1:基础知识介绍

    近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术.因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术. 相关阅读推荐 &l ...

  4. 视频编解码之理论概述 和即时通信

    前言 即时通讯应用中的实时音视频技术,几乎是IM开发中的最后一道高墙.原因在于:实时音视频技术 = 音视频处理技术 + 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的.有关实时 ...

  5. 视频编码零基础入门(1):视频编解码之理论概述

    1.前言 即时通讯应用中的实时音视频技术,几乎是IM开发中的最后一道高墙.原因在于:实时音视频技术 = 音视频处理技术 + 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的.有关 ...

  6. 直播技术总结(四)音视频数据压缩及编解码基础

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/60480109 音视频压缩技术是编 ...

  7. 干货 | 清华大学郑方:语音技术用于身份认证的理论与实践

    本讲座选自清华大学语音和语言技术中心主任郑方教授近期于清华大数据"技术·前沿"系列讲座上所做的题为<语音技术用于身份认证的理论与实践>的演讲. 以下为演讲的主要内容: ...

  8. 浅谈视频监控行业编解码技术的发展与应用

    本文转自 浙江大华技术股份有限公司产品经理 张龙彪  视频监控技术经过多年的发展,监控画面正经历着从最初的D1标清图像,向4K高清.8K超清时代前进.由于CCD与CMOS技术的发展,前端摄像机的像素越 ...

  9. 视频监控行业编解码技术的发展与应用

    视频编码技术是对前端摄像机采集过来的数字视频进行压缩,在保证图像质量的情况下,采用高效的图像压缩方式,以节省传输带宽和视频存储空间.- 一. 编解码技术发展现状分析 目前国内主流视频监控设备厂商如大华 ...

最新文章

  1. Cissp-【第4章 通信与网络安全】-2021-3-12(446页-475页)
  2. hbase的集群搭建
  3. 《深入剖析NGINX》学习记录
  4. TensorBoard使用
  5. Java读取xml数据
  6. math.fabs_带有Python示例的math.fabs()方法
  7. 全连接层的作用_python构建计算图2——全连接层
  8. Honey Tree(超好用的样板代码管理工具)
  9. if else语句linux,linux 中的if else语句
  10. Cocos2d-x3.0-倾斜列表
  11. 【机器学习】如何使用随机网格搜索,以缩短网格搜索速度?
  12. React JsBarcode使用
  13. VIOS挂载ISO文件
  14. 为什么要用“设计模式”?(六大好处)
  15. ctf-2020-12-07
  16. 在虚拟机里安装windows
  17. unity 鼠标拖动UI 滚轮缩放大小
  18. 汉诺塔(递归算法)C语言
  19. Git基本操作和GtHub 特殊技巧
  20. 蓝牙地址解析(NAP/UAP/LAP)

热门文章

  1. BZOJ3738 : [Ontak2013]Kapitał
  2. SQL 触发器 当修改TEST表中的F1字段时,同时根据条件修改F2字段
  3. SigmaPlot 12.0 中文版 for Win 专业的科研绘图下载及教材
  4. firefox 53支持java_Selenium 2.53不使用Firefox 47
  5. uniapp动态显示数组_uni-app学习:4、数据绑定(变量、数组、显示控制)
  6. 查询数据去除后面无用的0_Python数据分析与实战
  7. 服务器上有图片但是app不显示不出来,网络app图片显示不出来的
  8. tensorflow+python flask进行手写识别_使用tensorflow进行手写数字识别
  9. 数字语音信号处理学习笔记——语音信号的数字模型(2)
  10. 自动化交易综述——互联网金融