[转贴]JM阐述

2024-06-18 22:38
文章标签 阐述 转贴 jm

本文主要是介绍[转贴]JM阐述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文转自:http://www.360doc.com/content/09/1109/10/230402_8657319.shtml#

由于DPB中间的参考帧的MV都是以4X4块为单位,现在以8X8块作Direct mode模式,所以必须对子块的MV作合并,
JM采用的东西是如下图的方式:
x o | o x
o o | o o
- - - - -
o o | o o
x o | o x
每8X8块取外角上的4X4块的MV.
算法如下:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
b8Mode是帧间预测中对8X8块的再次细分,称为亚宏块级模式,划分定在表格b8_mode_table中
const int  b8_mode_table[6]  = {0, 4, 5, 6, 7};
其中0是8X8 Direct模式,只对B帧,4,8X8,5,8X4,6,4X8,7,4X4,以上5中模式在宏块级中统称为P8X8模式,这个可以在码流TRACE文件中可以应证。

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

264标准中可以对宏块级语法元素按照重要的等级进行分区,可以分为分区A,B,C,
这个数据分区可以根据数组映射获得264时如何处理分区得.涉及到3个数组.
typedef enum  
{
  SE_HEADER,
  SE_PTYPE,
  SE_MBTYPE,
  SE_REFFRAME,
  SE_INTRAPREDMODE,
  SE_MVD,
  SE_CBP_INTRA,
  SE_LUM_DC_INTRA,
  SE_CHR_DC_INTRA,
  SE_LUM_AC_INTRA,
  SE_CHR_AC_INTRA,
  SE_CBP_INTER,
  SE_LUM_DC_INTER,
  SE_CHR_DC_INTER,
  SE_LUM_AC_INTER,
  SE_CHR_AC_INTER,
  SE_DELTA_QUANT_INTER,
  SE_DELTA_QUANT_INTRA,
  SE_BFRAME,
  SE_EOS,
  SE_MAX_ELEMENTS  //!< number of maximum syntax elements
} SE_type;         // substituting the definitions in elements.h
以上定义了264宏块级编码要用到的语法元素,当然不是所有的宏块编码都有以上元素,根据帧内,帧间,实际编码过程中,等有所不同。
关于以上的元素具体含义,参考JM或标准可以获得,不过有些元素似乎在JM中并没有利用到,比如SE_EOS,不知道最新版如何?

int assignSE2partition_NoDP[SE_MAX_ELEMENTS] =
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int assignSE2partition_DP[SE_MAX_ELEMENTS] =
   0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0 } ;
上面元素0,代表DPA,1代表DPB,2代表DPC,可以看出来假如没有定义数据分区得话:所有的语法元素都是DPA,
定义了数据分区,那么帧内系数是分区B,帧间系数是分区C,其他的元素都是分区A.可以看得出来,遭遇信道丢包时,
光有DPB或DPC,没有DPA是无法解出码流的,假如没有DPB,DPC的话,还可以根据DPA的元素获得近似值。
那么JM是如何实现宏块级数据分区管理的呢,这个由Slice里面的datapartition数组管理,第一个成员为DPA,
第二个为DPB,第三个为DPC,可以根据语法元素切换输出到A,B,C中.

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
把编码方式切换到CAVLC,其实在foreman测试序列,个人觉得CABAC,CAVLC编码压缩效率差别不大
SNR更是差不多,但是CAVLC要简单很多。
经过一个晚上的艰苦战斗,初步得出结论,SKIP模式对B,P帧而言,DIRECT模式只对B而言,
个人觉得DIRECT模式,SKIP模式,这种说法有些让人困惑。
下面讲B帧的DIRECT,SKIP模式:
DIRECT,SKIP,模式相同的是,他们的宏块类型都是0,运动向量残差都为0,因为MVD可以通过临块预测方式得到
但是SKIP模式的cbp为0,也就是没有残差传输,它是双向预测,参考帧在LIST0,LIST1中的
序号也是根据临块的参考帧情况获得(注意不一定序号非的是0),所以连参考帧都不用传输.,
SKIP模式有更严格的要求,CBP为0,也就是没有残差系数,达到最大的压缩效率。
再讲P帧的SKIP模式,但前象预测,参考帧为LIST0中序号为0帧,无参考帧编码,CBP为0,无残差系数编码.
她们的分块模式为0,都是16X16.
但是在CAVLC中,SKIP模式,对SKIP宏块没有任何实际编码码流,解码器是如何识别这个宏块存在的,
大家打开TRACE文件,可以看到为一个SKIP或者连续几个SKIP宏块结束后,接着下一个非SKIP宏块,
一开始就有一个语法元素,mb_skip_run有一个值,这个元素采用Exp-Golomb编码,这个值的意思就是前面有多少个SKIP块,这就是264码流
巧妙的解决方案,当遇到这个元素非0的时候,就自动往前面做SKIP宏块填充,.
@34679 mb_skip_run                                                   1 (  0)  
@34680 mb_type (P_SLICE) ( 4, 1) =                               010 (  1)  
@34683 mvd_l0 (0) =  -6  (org_mv -10 pred_mv  -4)              0001101 ( -6)  
@34690 mvd_l0 (1) =    (org_mv   0 pred_mv   0)                    1 (  0)  
@34691 mvd_l0 (0) = -11  (org_mv -20 pred_mv  -9)            000010111 (-11)  
@34700 mvd_l0 (1) =    (org_mv   9 pred_mv   2)              0001110 (  7)  
@34707 CBP ( 4, 1) =                                               1 (  0)  

*********** Pic: 2 (I/P) MB: 16 Slice: 0 **********


*********** Pic: 2 (I/P) MB: 17 Slice: 0 **********


*********** Pic: 2 (I/P) MB: 18 Slice: 0 **********

@34708 mb_skip_run                                                 011 (  2)  
@34711 mb_type (P_SLICE) ( 7, 1) =                             00101 (  4)  
上面表示18号宏块前面有2个SKIP宏块,解码器然后可以自动填充。
其实本来解决这个问题,可以用更少的时间来解决这个问题,但是,JM97对TRACE文件输出,有一个bug,
导致,输出的TRACE混乱错误,无法理解,浪费了大量的时间,花了几个小时才找出解决这个bug,该bug位于
writeSyntaxElement2Buf_Fixed函数中,这个地方需要注释掉TRACE输出。
int writeSyntaxElement2Buf_Fixed(SyntaxElement *se, Bitstream* this_streamBuffer )
{

  writeUVLC2buffer(se, this_streamBuffer );

#if TRACE
// if(se->type <= 1)
//  trace2out (se);
#endif
  return (se->len);
}
其实上面两句是留给MBHEADER输出的,因为它不用参加RDO rate计算
个人觉得JM对TRACE文件的输出管理还有些问题,有待修改,不知道在新的JM版本中有没有修正这个bug.
这个也算是解决这个问题的副产品.

另外CABAC对贷这个问题好像不一样,有时间可以在研究这个问题

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
求象素的灰度.....
#define MAX_LEN (1000*3)
unsigned char RGB[MAX_LEN]={2,2,2,4,5,6,7,8,9,0};
unsigned int mulData[7] = {313524,615514,119538};
__int64 mask1 = 0xFFFFFFFF00000000;
__int64 mask2 = 0x00000000FFFF0000;
__int64 mask3 = 0x000000000000FFFF;

int main(int argc, char* argv[])
{
    char gray = 0;
unsigned int Y=(((RGB[0]*mulData[0]))+((RGB[1]*mulData[1]))+((RGB[2]*mulData[2])))>>20;
_asm{
pxor mm7,mm7
pxor mm6,mm6
mov ecx,0
sloop: movd mm0,[mulData+ecx*4]
punpcklwd mm0,mm7
mov al,[RGB+ecx]
and eax,0X000000FF
movd mm1,eax
movd mm2,eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;
punpckldq mm1,mm2
movq mm4,mm1
movq mm5,mm0
punpcklwd mm4,mm1
punpcklbw mm5,mm7
pmullw mm4,mm5
;;;;;;;;;;;;;;;;;;;;;;;;;;;
pmullw mm1,mm0
pand mm1,mask1
movq mm0,mm4
pand mm0,mask2
pand mm4,mask3
psrlq mm0,8
paddd mm1,mm0
paddd mm1,mm4
movq mm3,mm1
pand mm3,mask1
psrlq mm3,16
paddd mm1,mm3
paddd mm6,mm1
inc ecx
cmp ecx,3
jl sloop
psrld mm6,20
movd eax,mm6
mov gray,al
emms
}
return 0;
}

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
H.264对帧场编码问题支持的比较完整,因为曾经有人问我,在h.264码流中,是否有判别帧场编码的元素。
我当时对H.264如果认定码流帧场编码不太了解,更别说是宏块级帧场编码了。其实H.264对帧场编码有两种级别,分为
帧级和宏块级.帧级是对整个帧一开始就分为top field,bottom field.对两个field分别进行ME,MC,mode decision等.
而宏块级Field编码,就不一样了。曾经在流媒体网站H.264分块看到有一牛人对宏块级Field编码的解释,我感到疑惑,
但当时修行不够,说不出所以然,现在把那段话贴在这里:
jamie80:
"
当 MbaffFrameFlag = 1 & currMb->mb_field 时,偶数行放在宏块的上半部分(16x8)来编码,而奇数行位于下半部分来编码。
如果当前宏块的mb_field为0(帧编码)而左邻居宏块的mb_field为1(场编码),这样其左邻居像素就可以属于不同的4x4块,
至少左邻居奇数行的像素和偶数行的像素肯定不属于同一个4x4块,所以我们需要对它们区别对待。
(MB Adaptive Frame/Field给H.264带来不少麻烦)
我的答案是一个宏块级field编码,是这样子的,JM里面给出解释的是Field MB pair,场宏块对。也就是a couple of Field
没有单独存在的一个Field宏块,只有Field MB pair.上面一个是Top field MB(两个MB的偶数行),下面一个是Bottom MB
(两个宏块的奇数行),宏块序号上下是连续的,这个和一般的编号方式不同,上面一个是偶数,下面一个是奇数.
而不是象上面那段话那样,只有半个宏块的问题.
对此,我们做出解释,现在我们研究函数void dpb_split_field(FrameStore *fs),该函数完成的任务是对即将送入DPB的重建帧
进行帧场分解,解出top,bottom field,对顶底场进行1/4象素插值,复制场参数,分解运动向量,参考帧序号,参考帧id等。
宏块级帧场自适应模式需要对宏块对进行场模式和帧模式分别编码,计算她们的RDCOST,选其中最少的RDCOST作为编码方式,所以
自适应方式做最佳编码是付出了计算复杂度大大增加的代价。同样帧级帧场自适应方式需要帧编码,和场编码分别进行,
计算RDCOST最少值作为最佳编码,同样付出计算复杂度.
  回到文章开始时候提出的问题,码流中是否有标志指示后面访问单元(Access Unit)的帧场编码方式,答案是肯定的,在一个
SPS(sequence parameter set)中能找到frame_mbs_only_flag标志,该标志显示是否帧编码,如果为0,那么还有一个参数
mb_adaptive_frame_field_flag,下面对配置参数和以上两个元素的关系进行说明
PicInterlace代表帧级隔行扫描,MbInterlace代表宏块级隔行扫描
PicInterlace             =      # Picture AFF    (0: frame coding, 1: field coding, 2:adaptive frame/field coding)
MbInterlace                   # Macroblock AFF (0: frame coding, 1: field coding, 2:adaptive frame/field coding)
交叉位置(frame_mbs_only_flag, mb_adaptive_frame_field_flag),N/A为不需要该元素

             \PicInterlace
MbInterlace \

0

1

2

0

(1,N/A)

(0,0)

(0,0)

1

(0,1)

(0,1)

(0,1)

2

(0,1)

(0,1)

(0,1)


这篇关于[转贴]JM阐述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073256

相关文章

过滤器:自清洗过滤器工作原理及特点阐述

一、自清洗过滤器的原理描述   当水从进水口进入并从外向里进入粗滤网(粗滤网的设置根据水质情况而定),较粗的杂质被过滤后再进入细滤网,较小的杂质被拦截在细过滤内壁,过滤后的干净水从出水口流出,当滤筒内壁的杂质越积越多时,自清洗过滤器进出口的压差达到预设值或达到清洗时间或手动预制时,过滤器将开始自清洗过程,整个自清洗过程包含两个步骤:打开位于自清洗过滤器上的自动排污阀;外部的双向电机带动吸吮扫

过滤器:自清洗过滤器工作原理及技术特点阐述

一、自清洗过滤器的原理描述   当水从进水口进入并从外向里进入粗滤网(粗滤网的设置根据水质情况而定),较粗的杂质被过滤后再进入细滤网,较小的杂质被拦截在细过滤内壁,过滤后的干净水从出水口流出,当滤筒内壁的杂质越积越多时,自清洗过滤器进出口的压差达到预设值或达到清洗时间或手动预制时,过滤器将开始自清洗过程,整个自清洗过程包含两个步骤:打开位于自清洗过滤器上的自动排污阀;外部的双向电机带动吸吮扫

5000字阐述云原生消息中间件Apache Pulsar的核心特性和设计概览

点击上方蓝色字体,选择“设为星标” 回复”面试“获取更多惊喜 Apache Pulsar 是 Apache 软件基金会顶级项目,自称是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架构设计,支持多租户、持久化存储、多机房跨区域数据复制,具有强一致性、高吞吐、低延时及高可扩展性等流数据存储特性。 Pulsar 是一个用于服务器到服务器的消息系统,具有多租户

香港一带一路研究院国际事务研究中心副主任陈景才阐述香港在一带一路建设及区块链金融领域的关键作用

2024年8月28日,香港金管局举行Ensemble项目沙盒(以下简称沙盒)启动仪式,并宣布首阶段试验将涵盖四大代币化资产用例主题,标志着金融业在代币化技术的实际应用进程中迈出重要一步。香港一带一路研究院国际事务研究中心副主任陈景才,在接受媒体采访时,深入分析了香港在一带一路建设及区块链金融领域所展现的巨大潜力和独特作用。   陈景才指出,香港凭借其得天独厚的地理位置、成熟的金融市场

阐述ArrayList、Vector、LinkedList的存储性能和特性

http://www.cnblogs.com/jiangyi-uestc/p/5682699.html【转】  ArrayList 和Vector他们底层的实现都是一样的,都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。       Vector中的方法由于添

牛津大学发布首篇《Transformer多模态学习》综述论文,23页pdf涵盖310篇文献全面阐述MMT的理论与应用

【导读】Transformer是当下流行的模型。牛津大学等学者发布首篇《Transformer多模态学习》综述论文,23页pdf涵盖310篇文献全面阐述MMT的理论与应用。 Transformer是一种很有前途的神经网络学习器,在各种机器学习任务中都取得了很大的成功。随着近年来多模态应用和大数据的普及,基于Transformer 的多模态学习已成为人工智能研究的热点。本文介绍了面向多模态数据

Java底层堆内存、GC等知识点阐述

Java底层 堆(年轻代与老年代知识点)年轻代(新生区) 堆堆≠伊甸园堆(含有三个区域:伊甸园和两个幸存者)为什么是两个幸存者,一个幸存者存在不就可以嘛?原因分析分析总结 老年代 堆GC种类垃圾回收什么是垃圾回收为什么需要垃圾回收回收器新生代垃圾回收器老年代垃圾回收器JDK1.8默认的垃圾回收器,以下为jdk1.8说明 springboot GC垃圾回收器使用示例 堆(年轻代与老

阐述一下Golang中defer的原理

基本用法 在Go语言中,defer关键字用于在函数返回前执行一段代码或调用一个清理函数。这对于处理文件关闭、解锁或者返回一些资源到资源池等操作非常有用。 其基本用法如下所示: package mainimport "fmt"func main() {example()}func example() {defer fmt.Println("world")fmt.Println("hello"

从复用性角度阐述中台建设

目录 复用性中台定义深思中台建设产品线形态何时演变中台能力落地中台 业务中台架构总结 技术学习永不止步,最近也是看了很多关于架构设计相关的专栏,慢慢总结出来一部分知识,代入自己的思考与理解,以及结合并反思自己之前公司的架构设计经验,发现很多方法论适用场景,也希望能够解决小伙伴们的一些疑惑以及感谢大佬们也给我指点迷津,站在巨人的肩膀上成长~ 复用性 首先谈一下复用性的理解: 复

JM代码分析(一)

原文转自:http://blog.csdn.net/tanxuan231/article/details/44887073 入门视频采集与处理(学会分析YUV数据) http://blog.csdn.net/vblittleboy/article/details/10945439 核心编码函数研究 如果选择的是帧内模式,则预测值由当前帧已经编码重建的宏块(没有经过去块效应滤