转自:http://blog.sina.com.cn/s/blog_786eaa330100rp9e.html
一、JSVM配置文件简介
配置文件的位置在JSVM\H264Extension\data 中
1.MVC.cfg是# JSVM Configuration File in AVC mode,也就是AVC的编码配置文件。毕竟JSVM是支持AVC编码的嘛。如果是研究SVC,基本上不怎么用这个配置文件。
2.encoder.cfg是最主要的JSVM配置文件,# JSVM Main Configuration File。指定输出文件名、待编码帧数、CGS或者是MGS、GOP大小、参考帧数目、基本层编码模式和运动搜索、层数、每一层的配置文件叫什么名字、环路滤波等等.不指定输入文件哦
3.layer-i.cfg是第i层的配置文件,注意:layer-i.cfg文件主要是对空域可伸缩而言,layer0就是基本层了,其他空域增强层。虽然在主配置文件encoder.cfg中,对时域、空域和质量都有设置,只是空域可伸缩的设置参数是单独拿出来的。在layer-i.cfg中,是此层的输入文件大小、输入文件名、重建文件名、输入输出帧率、QP之类的,不同的是多了:NumFGSLayers、FGSMotion、InterLayerPred和BaseQuality,分别表示细粒度可伸缩层(即质量增强层)的层数、是否在FGS层中的改善运动矢量、本层是否采用层间预测、本层基本质量层的质量级别(貌似是针对质量分层而言)。
二、如何配置出各种可分级?
1.时间可分级由GOPSize、FrameRate、FrameRateOut控制,目前只能按照二进制的那种分级。
一个GOP是包括了一个Keypicture和相邻Keypicture之间的B picture。GOP大小必须是2的倍数。因为要时域分层。所以如果在encoder.cfg中设定GOPSize=16,FrameRate=30,若分为3层,则在layer0的FrameRateout=7.5.那layer0的GOP实际上=4。layer1的FrameRateout=15,那layer1的GOP实际上是8,同样layer2的GOP就是16.
依据是JSVM9.19中的代码:
iGOPSize = (Int)floor( 0.5F + iGOPSize / (dMaximumFrameRate / (Float) (m_pcH264AVCEncoder->getCodingParameter()->getLayerParameters(0).m_dOutputFrameRate)) );
翻译成伪代码:本层实际的GOPSize=取整数(总的GOPSize/(总的FrameRate/本层的FrameRateout))
至于原理上的理解,只要看一下时间可分级的图就行了。对于时间可分级,反正高层总是包含低层的帧。
2.质量可分级由CgsSnrRefinement 控制质量分级。(CGS或MGS)
3.空间可分级:各个layer-i.cfg中的分辨率设置不一样就是空间可分级了。设置的一样就是只有质量可分级。
JSVM 目前只支持 3 个 D 层。所谓D层可以理解为空间可分级,在每一个D层里还可以根据QP的不同划分不同的Q层、根据不同帧率划分的T层。可以参考问号的blog:(D层就是指dependency_id相同的coded slice的组合)
1.layer representation:对于一幅图像,具有相同dependency_id和quality_id的所有coded slices的组合。
2. dependency representation:对于一幅图像,具有相同dependency_id的所有coded slices组合。
3. access unit:对于一幅图像,所有的dependency representation再加上相关的non-VCL NAL units。
4. scalable layer:具有相同dependency_id、quality_id和temporal_id的所有layer representation的组合。
5. dependency layer:具有相同dependency_id的scalable layer组合。
6. base layer:dependency_id、quality_id都为0的layer representation。
4.如何组合?
a.想设置有两层空间分辨率,每层又有两个质量层,那么可以:
a.1:encoder.cfg中设置输入四层,然后layer0和layer1有相同的空间分辨率和不同的QP值,layer2和layer3有相同的空间分辨率和不同的QP值。(空间可分级+CGS)。不过CGS貌似会自动控制QP。
a.2:encoder.cfg中设置输入2层,然后然后layer0和layer1有不同的空间分辨率,在每一个layer配置中都启用MGSVectorMode,设置16个系数的其中两个(和为16)。(空间可分级+MGS)
注:MGSVector是一种质量分级的方法。即表示把 16 个系数中的几个单独分成一个质量层(一个 4x4 变换块有 16 个残差系数,分层传输)。 |
实例!!!:
1.只要时间可分级
配置:encoder.cfg中,把NumLayers设成1,LayerCfg指定为layer0.cfg,FrameRate设为30,然后GOPSize=4;CgsSnrRefinement此时无效
layer0.cfg中,FrameRateIn设为30,FrameRateOut设为30;
执行:H264AVCEcoderLibTestStatic –pf encoder.cfg
实验结果:GOPSize=4,编出来有3个时间层:帧率分别为30、15、7.
实验结果:GOPSize=2,编出来有2个时间层:帧率分别为30、15
实验结果:GOPSize=1,编出来有1个时间层:帧率为30
下图是GOPSize=2的截图,采用命令BitStreamExtractorStaticxxx.264查看
2.只要空间可分级
配置:encoder.cfg中,把NumLayers设成2,LayerCfg指定为layer0.cfg和layer1.cfg,FrameRate设为15,然后GOPSize=1;CgsSnrRefinement=0,但此时无效(因为分辨率不同);
Layer1.cfg中,输入FOREMAN_352x288_30.yuv,分辨率设为352x288,FrameRateIn设为15,FrameRateOut设为15;
Layer0.cfg中,输入FOREMAN_176x144_15.yuv,分辨率设为176x144,FrameRateIn设为15,FrameRateOut设为15;
3.只要质量可分级(CGS)
配置:encoder.cfg中,把NumLayers设成2,LayerCfg指定为layer0.cfg和layer1.cfg,FrameRate设为30,然后GOPSize=1;CgsSnrRefinement=0;
Layer1.cfg中,输入FOREMAN_352x288_30.yuv,分辨率设为352x288,FrameRateIn设为30,FrameRateOut设为30;
Layer0.cfg中,输入FOREMAN_352x288_30.yuv,分辨率设为352x288,FrameRateIn设为30,FrameRateOut设为30;
实验结果:注意,CGS属于空间可分级的一种特殊形式。JSVM把它的输出结果按照空间可分级形式表示了(D层一样)。其实分辨率是一样的,但是一个QP是32,一个QP是26。(JSVM自动分配)
4.只要质量可分级(MGS)
配置:encoder.cfg中,把NumLayers设成2,LayerCfg指定为layer0.cfg和layer1.cfg,FrameRate设为30,然后GOPSize=1;CgsSnrRefinement=1;
Layer1.cfg中,输入FOREMAN_352x288_30.yuv,分辨率设为352x288,FrameRateIn设为30,FrameRateOut设为30;
Layer0.cfg中,输入FOREMAN_352x288_30.yuv,分辨率设为352x288,FrameRateIn设为30,FrameRateOut设为30;
实验结果:注意,这里与CGS不同的是D层一样,但Q层不一样,这才是JSVM眼中正统的质量可分级
注意:还有一种方式实现MGS,是用MGSVectorMode,但是没有试验成功,可能必须要混合可分级时才能用MGSVectorMode
5.混合可分级,按照前面四种自由组合即可