H.264的CAVLC(编码.解码)过程详解

看264也看到CAVLC来了,把这方面的资料贴在这里:

编码过程:
假设有一个4*4数据块 (变化,量化后就送入熵编码)
{
   0 , 3 , -1 , 0,
   0, -1 ,   1, 0,
   1 , 0 , 0 , 0,
   0 , 0 , 0 , 0
}
数据重排列:0301-1-1010……

1
初始值设定:
非零系数的数目(TotalCoeffs = 5
拖尾系数的数目(TrailingOnes= 3
最后一个非零系数前零的数目(Total_zeros = 3
变量NC=1;
(说明:NC值的确定:色度的直流系数NC=-1;其他系数类型NC值是根据当前块左边4*4块的非零系数数目(NA)当前块上面4*4块的非零系数数目(NB)求得的,见毕厚杰书P1206.10
suffixLength = 0

i = TotalCoeffs = 5; (
反序编码)

2 编码coeff_token

查标准(BS ISO/IEC 14496-10:2003Table 9-5,可得:
If (TotalCoeffs == 5 && TrailingOnes == 3 && 0 <= NC < 2)
coeff_token = 0000 100;
Code output = 0000 100;

3
编码所有TrailingOnes的符号:
逆序编码,三个拖尾系数的符号依次是+(0),-(1),-(1);
:
TrailingOne sign[i--] = 0;
TrailingOne sign[i--] = 1;
TrailingOne sign[i--] = 1;
Code output = 0000 100    0 11;
4
编码除了拖尾系数以外非零系数幅值Levels:( 毕书这个例子说的不是很细,而且有个小错误)
过程如下:
1)将有符号的Level[ i ]转换成无符号的levelCode
如果Level[ i ]是正的,levelCode = (Level[ i ]<<1) – 2;  
如果Level[ i ]是负的,levelCode = - (Level[ i ]<<1) – 1;
2)计算level_prefixlevel_prefix = levelCode / (1<<suffixLength)
查表9-6可得所对应的bit string
3)计算level_suffixlevel_suffix = levelCode % (1<<suffixLength)
4)根据suffixLength的值来确定后缀的长度;
5suffixLength   updata
If ( suffixLength == 0 )
      suffixLength++

else if ( levelCode > (3<<suffixLength-1) && suffixLength <6)

注:大于预置值就suffixLength++;
     suffixLength++;

回到例子中,依然按照逆序,Level[i--] = 1;(此时i = 1)
levelCode = 0;level_prefix = 0;
查表9-6,可得level_prefix = 0时对应的bit string = 1;
因为suffixLength初始化为0,故该Level没有后缀;
因为suffixLength = 0,故suffixLength++;
Code output = 0000 100 011 1;
编码下一个Level:Level[0] = 3;
levelCode = 4;level_prefix = 2;查表得bit string = 001;
level_suffix = 0;suffixLength = 1;故码流为0010;
Code output = 0000 100 011 1 0010 ;
i = 0,编码Level结束。

5)编码最后一个非零系数前零的数目(TotalZeros):
查表9-7,当TotalCoeffs = 5,total_zero = 3时,bit string = 111;
Code output = 0000 100 011 1 0010 111;

6) 对每个非零系数前零的个数(RunBefore)进行编码:
i = TotalCoeffs = 5;ZerosLeft = Total_zeros = 3;查表9-10:
依然按照逆序编码
ZerosLeft =3, run_before = 1, run_before[4]=10;
ZerosLeft =2, run_before = 0 ,run_before[3]=1;
ZerosLeft =2, run_before = 0, run_before[2]=1;
ZerosLeft =2, run_before = 1, run_before[1]=01;
ZerosLeft =1, run_before = 1, run_before[0] 最后一个非零系数不需要码流来表示
Code output = 0000 100 011 1 0010 111 10 1 1 01 ;
编码完毕。(CAVLC主要是查表,标准中的表是通过大量实验的出来的!)

 

 

解码过程:


接收码流为:0000 1000 1110 0101 1110 1101

计算NC = 1
解码详细过程如下:
1.       根据Coeff_token和NC查表(见标准表9-5),得到非零系数数目TotalCoeffs和拖尾系数数目TrailingOnes
NC = 1选择对应的表,Coeff_token为0000100,查表得到TotalCoeffs=5 TrailingOnes=3
输出序列:无
2. 解析拖尾系数
由第一步得到拖尾系数有3个,输入拖尾系数符号编码码流011,得到两个拖尾系数由先到后是 -1,-1,1
output :-1,-1,1(反序输出)
3.       解析除拖尾系数外的非零系数的幅值(level)
(1)       确定后缀长度SuffixLength
(2)       根据码流查表9-6得到前缀LevelPrefix
(3)       根据前缀和后缀,得到

              LevelCode=(levelprefix<<suffixlength)+levelsuffix
(4)       Levelcode为偶数 level=(level+2)/2
                Levelcode为奇数 level=(-level-1)/2
(5)       根据设定的阈值确定是否update Suffixlegth
回到例子中,按照逆序
i=0, Sufixlegth=0,查表9-6,1对应的前缀levelprefix=0,levelcode=0,

     计算得到level=1 , i++ , sufixlegth++(第一次都要加)
i=1,sufixlegth=1,查表0010(3为前缀,1位后缀)对应的前缀      levelprefix=2,计算levelcode=4,level=3,i++
i=2 >= TotalCoeffs-TrailingOnes,除拖尾系数外的非零系数解析完毕
output:3,1,-1,-1,1
4.       解析每个非零系数前零的个数
根据TotalCoeffs=5和输入码流111查表9-7得到TotalZeros=3
初始i=TotalCoeffs-1=4 ,zeroleft=TotalZeros=3 , 5个非零系数前零的数目解析如下:
i=4,zeroleft=3,根据码流10,查表9-10,runbefor=1,

   输出序列:3,1,-1,-1,0,1
i=3,zeroleft=3-1=2,根据码流1,查表runbefore=0,

输出序列:3,1,-1,-1,0,1
i=2,zeroleft=2-0=2,根据码流1,查表runbefore=0,

输出序列:3,1,-1,-1,0,1
i=1,zeroleft=2-0=2,根据码流01,查表runbefore=1,

输出序列:3,0,1,-1,-1,0,1
i=0,zeroleft=2-1=1,输出序列:0,3,0,1,-1,-1,0,1
5. 解码完毕,将剩下的元素用0补齐,反序排列就可以得到4*4矩阵。
6. 最后还原为一个4*4数据块
{
   0 , 3 , -1 , 0,
   0,   -1 , 1,   0,
   1 ,   0 , 0 , 0,
   0 ,   0 , 0 , 0
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/455442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python进程通信方式有几种_python全栈开发基础【第二十一篇】互斥锁以及进程之间的三种通信方式(IPC)以及生产者个消费者模型...

一、互斥锁进程之间数据隔离&#xff0c;但是共享一套文件系统&#xff0c;因而可以通过文件来实现进程直接的通信&#xff0c;但问题是必须自己加锁处理。注意&#xff1a;加锁的目的是为了保证多个进程修改同一块数据时&#xff0c;同一时间只能有一个修改&#xff0c;即串行…

Python实现修改图片尺寸

起步 很多小伙伴从网上找的图片可能图片尺寸与自己的需求不符合 今天小编就教大家使用python写一个简单脚本程序实现修改图片的尺寸 环境准备 首先我们需要python环境,它的安装可以参考:python安装以及版本检测 其次我们还需要安装一个python图形化的库PIL PIL的安装,这里…

数据集

https://zhuanlan.zhihu.com/p/25138563转载于:https://www.cnblogs.com/zhangbojiangfeng/p/7039725.html

常见的攻击手段及其防御方式

本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击)CSRF&#xff08;跨站请求伪造&#xff09;SQL注入DDOSXSS 概念 全称是跨站脚本攻击&#xff08;Cross Site Scripting&#xff09;&#xff0c;指攻击者在网页中嵌入恶意脚本程序。案列 比如说我写了一个博客网站…

使用ffmpeg进行h.264编码

m_fmt->video_codec CODEC_ID_H264; /* 添加视频流 */ m_video_st av_new_stream(m_oc, 0); if (!m_video_st) { return 0; } m_videocavcodec_alloc_context(); m_videoc m_video_st->codec; /* 视频相关参数 */ m_videoc->codec_id m_fmt->video_codec; m_…

关于java的关键字 transient

我们都知道一个对象只要实现了Serilizable接口&#xff0c;这个对象就可以被序列化&#xff0c;Java的这种序列化模式为开发者提供了很多便利&#xff0c;我们可以不必关系具体序列化的过程&#xff0c;只要这个类实现了Serilizable接口&#xff0c;这个的所有属性和方法都会自…

python中文件变化监控-watchdog

起步 在python中文件监控主要有两个库&#xff0c;一个是pyinotify&#xff0c;一个是watchdog。pyinotify依赖于Linux平台的inotify&#xff0c;后者则对不同平台的的事件都进行了封装。因为我主要用于Windows平台&#xff0c;所以下面着重介绍watchdog&#xff08;推荐大家阅…

python决策树分类鸢尾花_基于决策树—鸢尾花分类

决策树算法广泛应用于&#xff1a;语音识别、医疗诊断、客户关系管理、模式识别、专家系统等&#xff0c;在实际工作中&#xff0c;必须根据数据类型的特点及数据集的大小&#xff0c;选择合适的算法。本文选择经典案例——《鸢尾花分类》一、决策树定义决策树算法是一种基于实…

希捷宣布出货双碟装1TB硬盘 单碟500GB上市

希捷今天宣布&#xff0c;单碟容量高达500GB的Barracuda 7200.12 1TB硬盘已经出货。 现有的1TB硬盘产品一般都是三碟装(此前也有四碟装)&#xff0c;包括希捷自家的ST31000340AS&#xff0c;但希捷一进率先将其升级为双碟装&#xff0c;存储密度也达到了329Gb每平方英寸。这样一…

P1334 瑞瑞的木板

题目描述 瑞瑞想要亲自修复在他的一个小牧场周围的围栏。他测量栅栏并发现他需要N&#xff08;1≤N≤20,000&#xff09;根木板&#xff0c;每根的长度为整数Li&#xff08;1≤Li≤50,000&#xff09;。于是&#xff0c;他神奇地买了一根足够长的木板&#xff0c;长度为所需的N…

FFMpeg的output_example.c例子分析

该例子讲了如何输出一个libavformat库所支持格式的媒体文件。 &#xff08;1&#xff09;av_register_all()&#xff0c;初始化libavcodec库&#xff0c;并注册所有的编解码器和格式。 &#xff08;2&#xff09;guess_format()&#xff0c;根据文件名来获取输出文件格式&#…

大量数据+同步+多线程_Vulkan 多线程渲染

1. Overview of Vulkan1.1 计算机图形软件图形软件有两个大类&#xff1a;专用软件包&#xff08;special-purpose packages&#xff09;和通用编程软件包&#xff08;general programming packages&#xff09;。专用软件包通常提供一种UI设计语言&#xff0c;让用户直接生成想…

飞康任命Gartner前分析师担任亚洲区市场总监

在虚拟化、数据保护和数据迁移领域具备15年创新经验的美国飞康软件公司&#xff08;FalconStor Software, Inc.&#xff0c;NASDAQ&#xff1a;FALC&#xff09;近日宣布任命张瑾&#xff08;Jimmie Chang&#xff09;先生担任该公司亚洲区市场部门负责人。 飞康公司近日面向全…

12_登陆案例

13131转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/7044846.html

如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器

http://blog.csdn.net/eplaylity/archive/2008/12/05/3454431.aspx http://www.cnblogs.com/konyel/tag/SDLGuide%E4%B8%AD%E6%96%87%E8%AF%91%E7%89%88/ ffmpeg文档http://blog.sina.com.cn/s/blog_46dc65a90100a91b.html http://dranger.com/ffmpeg/ffmpeg.html VLC核心功能部…

Flask 概述

什么是Web Framework&#xff1f; Web Application Framework&#xff08;Web应用程序框架&#xff09;或简单的Web Framework&#xff08;Web框架&#xff09;表示一个库和模块的集合&#xff0c;使Web应用程序开发人员能够编写应用程序&#xff0c;而不必担心协议&#xff0…

(五)Maven中的聚合和继承

一、为什么要聚合&#xff1f; 定义&#xff1a;我们在开发过程中&#xff0c;创建了2个以上的模块&#xff0c;每个模块都是一个独立的maven project&#xff0c;在开始的时候我们可以独立的编译和测试运行每个模块&#xff0c;但是随着项目的不断变大和复杂化&#xff0c;我们…

python堆栈反向输出列表_python - IPython:将Python脚本的输出重定向到文件(如bash) - 堆栈内存溢出...

IPython有自己的上下文管理器来捕获stdout / err &#xff0c;但它没有重定向到文件&#xff0c;它重定向到一个对象&#xff1a;from IPython.utils import iowith io.capture_output() as captured:%run my_script.pyprint captured.stdout # prints stdout from your script…

关于datagrid

基本在公司使用的datagrid不需要自己写前台代码&#xff0c;只需要自己给grid明确id&#xff0c;url以及列属性即可。 后台需要返回一个数据类型&#xff1a;{recordsFiltered2, data[], drawnull, recordsTotal2}&#xff0c;通常返回这个数据类型的话&#xff0c;只需要调用d…

M-JPEG、MPEG4、H.264都有何区别 依维安防论坛

压缩方式是网络视频服务器和网络摄像机的核心技术&#xff0c;压缩方式很大程度上决定着图像的质量、压缩比、传输效率、传输速度等性能&#xff0c;它是评价网络视频服务器和网络摄像机性能优劣的重要一环。 随着多媒体技术的发展&#xff0c;相继推出了许多压缩编码标准&…