dpc算法
A. 音视频压缩:H264码流层次结构和NALU详解
前言:
为什么需要编码呢?比如当前屏幕是1280*720.一秒24张图片.那么我们一秒的视频数据是
1280*720(位像素)*24(张) / 8(1字节8位)(结果:B) / 1024(结果:KB) / 1024 (结果:MB) = 2.64MB
一秒的数据有2.64MB数据量。1分钟就会有100多MB。这对用户来说真心是灾难。所以现在我们需要一种压缩方式减小数据的大小.在更低 比特率(bps)的情况下依然提供清晰的视频。
H264: H264/AVC是广泛采用的一种编码方式。我们这边会带大家了解。从大到小排序依次是 序列,图像,NALU,片,宏块,亚宏块,块,像素。
问题背景:
前面在讲封装格式过程中,都有一个章节讲解如何将H.264的NALU单元如何打包到TS、FLV、RTP中,解装刚好相反,怎么从这些封装格式里面解析出一个个NALU单元。NALU即是编码器的输出数据又是解码器的输入数据,所以在封装和传输时,我们一般处理对象就是NALU,至于NALU内部到底是什么则很少关心。甚至我们在编解码时,我们只需要初始化好x264编码库,然后输入YUV数据,它就会给你经过一系列压缩算法后输出NALU,或者将NALU输入到x264解码库就会输出YUV数据。
这篇文章就初步带你看下NALU能传输那些数据,NALU的类型和结构以及H264码流的层次,最后通过分析工具分析下裸码流记性验证,你可以选择感兴趣章节阅读。
NALU结构:
H.264的基本流(elementary stream),也叫裸流(没有加格式封装),就是一系列NALU的集合,如下图所示:
用Notepad十六进制形式打开,以annexb格式存储的h264裸流文件内容:
NALU结构分为两层,包含了视频编码层(VCL)和网络适配层(NAL):
视频编码层(VCL即Video Coding Layer) :负责高效的视频内容表示,这是核心算法引擎,其中对宏块、片的处理都包含在这个层级上,它输出的数据是SODB;
网络适配层(NAL即Network Abstraction Layer) :以网络所要求的恰当方式对数据进行打包和发送,比较简单,先报VCL吐出来的数据SODB进行字节对齐,形成RBSP,最后再RBSP数据前面加上NAL头则组成一个NALU单元。
分层目的:
这样做的目的:VCL只负责视频的信号处理,包含压缩,量化等处理,NAL解决编码后数据的网络传输,这样可以将VCL和NAL的处理放到不同平台来处理,可以减少因为网络环境不同对VCL的比特流进行重构和重编码;
NLAU结构:
其实NALU的承载数据真实并不是RBSP(Raw Byte Sequence Playload)而是EBSP即(Extent Byte Sequence Payload),EBSP和RBSP的区别就是在 RBSP里面加入防伪起始码字节(0x03),因为H.264规范规定,编码器吐出来的数据需要在每个NALU添加起始码:0x00 00 01或者0x00 00 00 01,用来指示一个NALU的起始和终止位置,那么RBSP数据内部是有可能含有这种字节序列的,为了防止解析错误,所以在RBSP数据流里面碰到0x 00 00 00 01的0x01前面就会加上0x03,解码时将NALU的EBSP中的0x03去掉成为RBSP,称为脱壳操作。
原始字节序列负载 RBSP即Raw Byte Sequence Playload,因为VCL输出的 原始数据比特流 SODB即String Of Data Bits,其长度不一定是8bit的整数倍,为了凑成整数个字节,往往需要对SODB最后一个字节进行填充形成RBSP,所以从SODB到RBSP的示意图如下:
填充方式就是对VCL的输出数据进行8bit进行切分,最后一个不满8bit的字节第一bit位置1,然后后面缺省的bit置0即可
具体填充语法见下文:
原来文档中的解释:
主要的意思我的理解如下:
其中H.264规范规定,编码器吐出来的数据需要在每个NALU添加起始码:0x00 00 01或者0x00 00 00 01,用来指示一个NALU的起始和终止位置。
所以H.264编码器输出的码流中每个帧开头3-4字节的start code起始码为0x00 00 01或者0x00 00 00 01。
上面我们分析了NALU的结构以及每层输出数据的处理方法,但是对于NALU的RBSP数据二进制表示的什么含义并不清楚,下面分析下NALU的类型。
1. NALU Header
头信息协议如上图。
举例说明:
这其中NALU的RBSP除了能承载真实的视频压缩数据,还能传输编码器的配置信息,其中能传输视频压缩数据的为slice。
那么如果NLAU传输视频压缩数据时,编码器没有开启DP(数据分割)机制,则一个片就是一个NALU,一个 NALU 也就是一个片。否则,一个片由三个 NALU 组成,即DPA、DPB和DPC,对应的nal_unit_type 类型为 2、3和4。
通常情况我们看到的NLAU类型就是SPS、PPS、SEI、IDR的slice、非IDR这几种。
上面站在NALU的角度看了NALU的类型、结构、数据来源、分层处理的原因等,其中NLAU最主要的目的就是传输视频数据压缩结果。那么站在对数据本身的理解上,我们看下H.264码流的层次结构。
H.264层次结构:
其实为了理解H.264是如何看待视频数据,先要了解下视频的形成过程。其实你把多副连续的有关联图像连续播就可以形成视频,这主要利用了人视觉系统的暂留效应,当把连续的图片以每秒25张的速度播放,人眼基本就感觉是连续的视频了。动画片就是这个原理:一张图像里面相邻的区域或者一段时间内连续图像的相同位置,像素、亮度、色温差别比较小,所以视频压缩本质就是利于这种空间冗余和时间上冗余进行编码,我们可以选取一段时间第一幅图像的YUV值,后面的只需要记录和这个的完整图像的差别即可,同时即使记录一副图像的YUV值,当有镜头完全切换时,我们又选取切换后的第一张作为基本图像,后面有一篇文章回讲述下目前视频压缩的基本原理。
所以从这里面就可以引申以下几个概念:
所以视频流分析的对象可以用下面的图片描述:
如果站在数据的角度分析NALU的层次关系,如下图:
这里视频帧被划分为一个片或者多个片,其中slice数据主要就是通过NLAU进行传输,其中slice数据又是由:
一个Slice = Silce + Slice Data
一帧图片跟 NALU 的关联 :
一帧图片经过 H.264 编码器之后,就被编码为一个或多个片(slice),而装载着这些片(slice)的载体,就是 NALU 了,我们可以来看看 NALU 跟片的关系(slice)。
引用自: https://www.jianshu.com/p/9522c4a7818d
Slice片类型:
设置片的目的是限制误码的扩散和传输,也就是一帧图像中它们的编码片是互相独立的,这样假设其中一张图像的某一个片有问题导致解码花屏,但是这个影响范围就控制在这个片中,这就是我们平时看视频发现只有局部花屏和绿屏的原因。
Slice Data里面传输的是一个个宏块,宏块中的数据承载各个像素点YUV的压缩数据。一个图像通常被我们划分成宏块来研究,通常有16 16、16 8等格式。我们解码的过程也就是恢复这些像素阵列的过程,如果知道了每个像素点的亮度和色度,就能渲染出一张完整的图像,图像的快速播放即是视频。
刚才提到了宏块.那么什么是宏块呢?
宏块是视频信息的主要承载者。一个编码图像通常划分为多个宏块组成.包含着每一个像素的亮度和色度信息。视频解码最主要的工作则是提供高效的方式从码流中获得宏块中像素阵列。
一个宏块 = 一个16*16的亮度像素 + 一个8×8Cb + 一个8×8Cr彩色像素块组成。(YCbCr 是属于 YUV 家族的一员,在YCbCr 中 Y 是指亮度分量,Cb 指蓝色色度分量,而 Cr 指红色色度分量)
其中宏块MB的类型:
宏块的结构:
H.264码流示例分析:
这里我们分析一下H.264的NLAU数据,其中包括了非VCL的NALU数据和VCL的NALU。
H.264码流的NLAU单元:
4. 这里由于没有数据分割机制,所以一个NALU承载一个片,同时一个片就是一个视频帧;
4.至于NALU的非VCL数据SPS、PPS、SEI各个字段的含义具体解析放到下篇文章,这个信息对于解码器进行播放视频很重要,很多播放问题都是这个数据有问题导致的;
上面看了视频的GOP序列,视频帧信息和片的组成,下面分析片中的宏块信息;
H.264的层次结构:
总结:
本文主要讲述了平时研究和分析视频流对象的层次,然后这些视频数据通过NALU传输时,NALU的类型和层次关系,以及NALU数据在不同层次的输出。最后用视频分析工具分析了H.264裸码流验证了上述层次关系。
所以对H.264数据分析时,一定要了解你现在分析的层次和框架,因为每个层次我们关心的数据处理对象是不一样的,这个非常重要。
一般H.264的分析工具都是收费的,也有一些免费和裁剪版本供大家学习和使用。推荐几个:Elecard StreamEye、CodecVisa、VideoEye、H264Analyzer、H264Visa等,有时需要交叉使用才能完成对你关心信息的分析,这些都放到我的Git上了,大家获取使用即可。
引用原文
25fps i帧间隔50 用分析软件查看可以看出每50帧一个i帧,并发送sps、pps、sei
sps、pps、sei、I帧绑在一起发送
B. 一键转换订阅免流参数
普通订阅转免流订阅 原理 将原来的订阅解析后添加免流host 使用方法 服务器域名/&&订阅链接&&免流host&&转换后服务器前缀 我这里已经在服务器上搭建好了 jttp://jklist.ml:888 白嫖党专属链接 解释 jklist.ml:888/ 为服务器域名 为订阅链接 m.iqiyi.com为免流host iqiyi 为转换后手机上显示的服务器名称前缀可为空则不修(如软件支持中文可使用中文) 更新记录 20210222 更新 鉴于有些订阅里面包含有一个&符号 导致不可用 现更改为两个&&符号来进行分割 20210304 更新 端口筛选+后端http多线程处理 从订阅池或者机场的订阅里面筛选 、 多线程避免因某订阅链接响应过慢导致整个程序等待超时响应 白嫖链接 ws+443较多 适合电信不限端口 订阅池 什么都有 订阅池
你可能感兴趣的资源
newsletter_sub_svc:通讯订阅服务
项目:CN通讯订阅服务 2014-05-20 英里 Poindexter ... 服务网址: 服务将接受 XML 或 JSON 格式的请求。... 如果您的 Content-Type 标头是 json,则响应将采用 JSON。... 订阅/取消订阅服务: URL: 获取新订阅的 xml
subconverter-vercel:在vercel上部署订阅转换
subconverter-vercel 本项目核心是tindy2013的。 本项目只是提供一个自动、免费、无需额外设备的脚本运行方式。 项目说明 利用github action实现每隔7天或在修改项目时获取最新版本的subconverter,并在vercel上进行部署。 需要设置personal access tokens(名称为GITHUB_TOKEN & 需要设置 repo、 admin:repo_hook、 workflow)
w3_MRI_clean_sub_list:为主题列表清洗w3 MRI完整列表以进行预处理
w3_MRI_clean_sub_list:为主题列表清洗w3 MRI完整列表以进行预处理
qtcreator_sub_dir_example:具有多个子目录的QT Creator项目的示例项目
qtcreator_sub_dir_example:具有多个子目录的QT Creator项目的示例项目
...机器人,它将通过简单HTTP调用发送的推送消息转换为您可以订阅...
TeleTelegram机器人,它将通过简单HTTP调用发送的推送消息转换为您可以订阅的Telegram消息。-Golang开发 我将简单的JSONHTTP请求转换为Telegram推送消息,您将getelegram-middleman-bot我是@MiddleMan机器人! 我坐在您想发送的任何消息和电报之间...
clash-conf:在您的冲突订阅中创建组、负载平衡、自动服务器选择...
本项目将解析vmess、ss、trojan订阅链接,并将其内容转换为clash配置文件config.yaml 所有代码均为python 使用环境 python 3.0 需额外安装的库:requests 使用方法 打开并运行 按提示输入相关信息即可 文件介绍 log... ...
Study-SUB:网络和数据库:middle_finger_light_skin_tone:
Study-SUB-master.zip,Study-SUB-master,README.md,Study-NetWork,Day1 :: IP에 대하여.md,Day1 :: NetWork 기본용어.md,Day6 :: 프로토콜에 대하여 .md,Day5 :: Network 토폴로지 lan wan 순서.md,Day2 :: 계층별 ...
SubConfig:subconverter外部配置以及利用动作自动更新订阅转换
子配置 subconverter外部配置以及利用动作自动更新订阅转换 重点在利用动作更新订阅转换并发布到自己的服务器, 入门 fork后点击右上角的Star星星按钮即可试用,需要使用发布功能的话需要配置几个秘密 SUBSCRIBE订阅链接,一行一个订阅,支持tg格式的http代理socks5代理, tg://http?server=1.2.3.4&port=233&user=user&pass=pass&remarks=Example UPLOAD_SECRET配置生成打包压缩后加密时用的aes密钥,由如下命令生成的单行的base64字符串, head -c 32 /dev/urandom | base64 > upload_secret DEPLOY_URL发布的上传地址,脚本目录中有php写的接收端,作用是接收加密的配置解密解压后发布到内部服务器上, https://host/u
TeleTelegram机器人,它将通过简单HTTP调用发送的推送消息转换为您...
webhook2telegram:Tele一个Telegram机器人,它将通过简单HTTP调用的推送消息转换为您可以订阅的Telegram消息 webhook2电报 (以前是电报-中间人-机器人) 可将简单的JSONHTTP请求转换为Telegram推送消息,您将在智能手机,PC或任何拥有的Telegram客...
mqttwarn:订阅MQTT主题(带有通配符)和可通知的可插拔服务
关于 mqttwarn-订阅MQTT主题并通知可插拔服务。 描述 mqttwarn订阅任意数量的MQTT主题,并在可选地应用复杂的转换之后将接收到的有效负载发布到一个或多个通知服务。 它带有70多个通知处理程序插件,可用于各种通知服务,并且对进一步的贡献...
联通安卓免流
联通安卓免流
免流专用移动电信联通免费流量
来自承诺的更新:免流多线程工具 v2.0 (去除更新优化版) 这款工具的最大亮点在于扫描的速度非常之快,相信大家会喜欢的。
Menu_Sub_Menu_Template:Menu Sub菜单控制台应用程序系统。 在C ++中
Menu_Sub_Menu_Template:Menu Sub菜单控制台应用程序系统。 在C ++中
提取均值信号特征的matlab代码-CHALL_21_SUB_A1B:CHALL_21_SUB_A1B
CHALL_21_SUB_A1B-main.zip,CHALL_21_SUB_A1B-main,cre_TAB_labels.m,my_test_model.m,test_model.m,train_model.m,NEW_NET_06L.mat,my_train_model.m,extract_data_from_header.m,last_ECG_preproc.m,get_12ECG_...
MADA_DPC_sub_supfinal_.mdl_sub_dtc_brainod
MADA_DPC_sub_supfinal_.mdl_sub_dtc_brainodl_INDUCTIONGENERATOR_源码.rar.rar
sub_1.rar_1X18"SUB_sub_vhdl
sub_1 subtractor 1 bit xxxxxxxxxxxx
MADA_DPC_sub_supfinal_.mdl_sub_dtc_brainodl_INDUCTIONGENERATOR_源
MADA_DPC_sub_supfinal_.mdl_sub_dtc_brainodl_INDUCTIONGENERATOR_源码.zip
sub_circuit_test_sub_sub-circuit_proteus_
proteus project file to create sub circuit
adder_sub_struct.rar_adder_adder_sub_struct_sub_vhd_vhdl
adder sub struct by vhdl
ClashToV2:把Clash的订阅转换为一行一个分享链接
ClashToV2 把Clash的订阅转换为一行一个分享链接 使用
子转换器:在各种订阅格式之间转换的实用程序
子转换器:在各种订阅格式之间转换的实用程序
手机订阅问题
根据测试用例整理出来的测试问题.大首页与所有留学国家频道公告区,NEW的标志去掉,城市名称与第一排对齐 测试
AutoLabel:网络威胁情报自动标注系统
10:“ counter_measure”, 11:“ sub_activity”, 12:“ IP_evil”, 13:“ IP”, 14:“ domain_evil”, 15:“域”, 16:“ attack_goal”, 17:“时间”, 18:“工具”, 19:“功能”, 20:“ ...
Exploratory_data_analysis_week1:第1周的作业
Exploratory_data_analysis_week1 第1周的作业 介绍 该分配使用来自数据, 库是机器学习数据集的流行存储库。 特别是,我们将使用我在课程网站上提供的“个人家庭... Sub_metering_1 :能量子计量1号(以有功电能的瓦
Exploratory_Data_Analysis_week1:Coursera Hopkins探索性数据分析课程工作的回购(第1周)
*此文件是从rdpeng的README.md复制而来的介绍该...电压:分钟平均电压(伏特) Global_intensity :家庭全球分钟平均电流强度(以安培为单位) Sub_metering_1 :1号能量子计量表(有功电能的瓦特小时)。 它对应于厨房
博客园安卓客户端
这是一款博客园安卓客户端,能帮助喜欢用博客园的用户更快捷的使用博客员。
一个注册码的算法反编
Sub cmdReg_Click() 'N * ref: __vbaExceptHandler 'N * ref: __vbaObjSet 'N * ref: __vbaHresultCheckObj 'N * ref: __vbaFreeObj 'N * ref: __vbaObjSet 'N * ref: __vbaHresultCheckObj 'N * ref: __vbaFreeObj ...
乐曲演奏器vhdl设计
q <= sub_wire0(3 DOWNTO 0); lpm_rom_component : lpm_rom GENERIC MAP ( intended_device_family => "ACEX1K", lpm_address_control => "REGISTERED", lpm_file => "music.hex", lpm_outdata => ...
网站banner图轮播效果 js
.sub_nav{width:663px; height:25px; bottom:0px; position:absolute; color:#999999; z-index:200;} .sub_no{height:25px; float:right;} .sub_no li{display:block; width:25px; height:25px; float:left; ...
ZeroMQ-XOP:ZeroMQ XOP使Igor Pro可以使用ZeroMQ消息传递层和JSON作为消息格式通过网络进行接口
:cpp:func:zeromq_sub_add_filter :cpp:func:`zeromq_sub_connect` :cpp:func:zeromq_sub_recv :cpp:func:zeromq_sub_remove_filter 安装 视窗 退出Igor Pro 将vcredist软件包安装在“ output / ...
评论
立即下载 vip 低至0.43元/次送3个月+抽豪礼
C. php代码加密怎么解密
$key="Thisissupposedtobeasecretkey!!!";
functionkeyED($txt,$encrypt_key)
{
$encrypt_key=md5($encrypt_key);
$ctr=0;
$tmp="";
for($i=0;$i<strlen($txt);$i++){
if($ctr==strlen($encrypt_key))$ctr=0;
$tmp.=substr($txt,$i,1)^substr($encrypt_key,$ctr,1);
$ctr++;
}
return$tmp;
}
functionencrypt($txt,$key)
{
srand((double)microtime()*1000000);
$encrypt_key=md5(rand(0,32000));
$ctr=0;
$tmp="";
for($i=0;$i<strlen($txt);$i++){
if($ctr==strlen($encrypt_key))$ctr=0;
$tmp.=substr($encrypt_key,$ctr,1).
(substr($txt,$i,1)^substr($encrypt_key,$ctr,1));
$ctr++;
}
returnkeyED($tmp,$key);
}
functiondecrypt($txt,$key)
{
$txt=keyED($txt,$key);
$tmp="";
for($i=0;$i<strlen($txt);$i++){
$md5=substr($txt,$i,1);
$i++;
$tmp.=(substr($txt,$i,1)^$md5);
}
return$tmp;
}
$string="HelloWorld!!!";
//encrypt$string,andstoreitin$enc_text
$enc_text=encrypt($string,$key);
//decrypttheencryptedtext$enc_text,andstoreitin$dec_text
$dec_text=decrypt($enc_text,$key);
//加密
functionstr2hex($s)
{
$r="";
$hexes=array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
for($i=0;$i<strlen($s);$i++)=""$r.=($hexes[(ord($s{$i})>>4)].$hexes[(ord($s{$i})&0xf)]);
return$r;
}
//解密
functionhex2str($s)
{
$r="";
for($i=0;$i<strlen($s);$i=""+="2)"{
$x1=ord($s{$i});
$x1=($x1>=48&&$x1<58)?$x1-48:$x1-97+10;
$x2=ord($s{$i+1});
$x2=($x2>=48&&$x2<58)?$x2-48:$x2-97+10;
$r.=chr((($x1<<4)&0xf0)|($x2&0x0f));
}
return$r;
}
echostr2hex("山东");
echo"
";
echohex2str("c9bdb6ab");
?>