从JSVM到RM52j
May 16th, 2007 by sha
这两天快被程序折磨死了……
前段时间依依不舍的从JSVM程序里钻出来,被迫要求快速掌握RM52j的程序。
其实从一个复杂庞大的程序到一个比较而言相对简单些的程序里,应该很快,但是以前的jsvm中有关预测和估计的细节部分没有完全的明白彻底,再加上RM里面太多难以理解的东西,容易误导人(说实话吧,因为RM是借用人家国外人的框架,修改部分的细节,性能比不上不说,还存在bug),所以看到现在才算完全的弄明白。
弄懂后又在是否做weighting prediction的问题上纠缠了2天,感觉这一块没得做了……正打算放弃的时候被组长教导了一番,呵呵。反思一下觉得说的确实也是:首先做研究就是要沉住气、静得下心,不能做到一半就轻易的放弃;第二任何决定和结论都要用事实说话,哪块可以做?哪块不可以做?都要做大量的测试、通过比较实验结果后才能下结论。被教导一番后自己心中也是觉得挺惭愧的。于是决定好好的先做实验,起初做实验是打算在小组讨论时用实验报告来证实自己的想法的,没有想到的是测试了序列之后居然发现这块还是有研究价值的,呵呵(再次应验她说的话很有道理~心中甚是崇拜加感谢~~)于是开始查找文献,看看别人是怎么在这块做创新的,发现有关加权预测的论文不怎么多。不过说实话,这一部分也确实不怎么好做,到现在还没有找出一条比较清晰的思路来,马上周五又要小组讨论了,其实自己心里确实是像做出点东西出来的,但是为什么就是没有那种思如泉涌的感觉呢?
现在才感觉到自己底气不足呀……思路很不开阔,容易受限制。可能最根本的原因还是自己论文看少了,本来就应该是厚积薄发的过程,没有平时的积累导致现在就没有灵感。
K说我不管怎么样,现在也要硬着头皮的把事情做完。想想确实也是的,只要自己好好搞,不管最后结果怎么样,自己都会有收获的。再不能象现在后悔以前没有好好看论文一样了,以前没有好好看当时肯定也是有各种各样的原因,但是不管什么原因都是自己没有全力以赴的学习,所以现在要克服这种浮躁心理,否则永远只能后悔以前没有做好,后悔以前不应该怎样怎样……
ding
我最近也在看RM52J,感觉好难啊,以前都没有接触过CODEC的,现在是硬着头皮去看,
请问师兄:你看RM52J看了多久才把它看好啊?我越看越绝望了
~~我来回答你的问题~~~~
首先,这篇文章的作者是S(不是king),S是女生,hehe . ^_^
然后说说有关RM52j 的问题:
我不知道你是对AVS视频编解码标准有兴趣而自学的、还是你所处的实验室在做这方面的东西?你看过JSVM或者JM没有呢?
我想你应该已经学习过有关视频编码标准的书了,并且对编解码的基本原理也应该掌握得很清楚。那么此时确实应该开始看代码了,毕竟从了解算法原理到熟悉代码实现还是有很长一段路要走的。
如果你没有看过JM或是JSVM就开始研究AVS的RM或SM代码话,可能会在很多地方有疑惑……我个人建议你先看国际的标准JM,因为JM相对RM而言内容较完整一些,有些地方更容易让人理解。
由于我也不是很清楚你现在学习到哪一步了,所以能够提供的建议有限,希望能够对你有些帮助。;-P
谢谢师姐,你的建议对我非常的宝贵!呵呵
刚刚拿到了RM52j,才可是看,不过估计肯定要花很长时间的了
It is hard to hack RM series, I have to say. We have implemented a lot of global structures/variables to “realize” a techniques, which makes software mess. It is not hard to understand standard, so, read standard, and then go through the source code.
Report a bug:)
macroblock.h
line 104 :
const int BLOCK_STEP[8][2]=….
index are [partmode][n],
where partmode could be larger then 7,
which is dangerours.
avs是模仿h264的,但在宏块划分部分,avs没有细分到4个像素的级别,即没有使用8*4,4*8和4*4的划分方式,只有16*16,16*8,8*16,8*8四种。而在代码实现而言,avs为了日后的扩展(我想可能是这个目的)还是使用了和h264相同大小的数组来存贮宏块的划分方式,所以容易误导人。
下面是avs解码器macroblock.h文件对BLOCK_STEP的定义:
const int BLOCK_STEP[8][2]=
{
{0,0},{2,2},{2,1},{1,2},{1,1},{2,1},{1,2},{1,1}
};
这个里面,后面三个的值其实是是和前面重复的。那么只剩5种有效值:{0,0},{2,2},{2,1},{1,2},{1,1}。他们表示:not used/8×8/8×16/16×8/16×16
例如这样一个语句:
step_h0 = (BLOCK_STEP[IS_P8×8(currMB) ? 4 : currMB->mb_type][0]);
判断当前宏块是否使用的8*8划分方式,如果是,则step_h0=BLOCK_STEP[4][0]即=1
BLOCK_STEP[0]是未使用的,应该是为了方便代码的理解才这样做的吧,i think。
谢谢sha,
我还是认为这是BUG,
注意currMB->mb_type会等于I4MB,
I4MB在defines.h定义为9,
这会造成数组越界. 因为BLOCK_STEP的下标定义是[8][2]
读出来的数据是不确定的.
step_h0,step_V0不正确的话直接影响到后面码流的读取,
目前的CODE 在这种情况下正好读出来是无意义数(1,2),
所以没有造成跑飞.
我的版本是RM52J_R1, 不知道是否是最新的.
更正, 后面的CODE在这种模式下都不使用STEP_H0/V0,
所以还好, 最多只能算潜在BUG.
RM52J_R1 好像是avs里面普通版本(除高清和安防之外)比较稳定的版本了,呵呵,看来你研究得蛮深入的嘛。我就快要告别avs拉,确切的说是要暂时告别视频压缩编解码这一块了。因为本人马上毕业,以后的工作不做视频压缩。其实还是蛮留恋的,avs里面确实还有很多潜在的bug,等待你慢慢发掘哈,呵呵。发现了bug就给avs发信吧,俺们国家视频标准的发展和壮大就要靠你们的努力了,^_^
hehe, 向开发AVS的同行致敬!
不知道他们都在哪个论坛溜达呢?
好向他们请教哈.
SHA, 你手里最新版本是什么?
和国标一致么?
我最近是在avs-s上做的,avs-s是面向安防的视频编码标准,它的最新版本是avs_sm0.1。至于RM代码的最新版本我就不太清楚了,反正直到去年年底基本上大家还都是在RM_52J上做提案的,因为这个版本比较稳定,新版本好像也有,但是仿佛不太稳定,也就没有过多的在意。avs国标基本上完全定下来了(我指的是普通标准,非安防,也非高清),如果没有新提案进去的话,算法思想可能不会再修改了吧,所以即使有新版本,那么也应该是代码级别上的修正。RM_52J上确实存在很多bug,本来是JM的代码,为h264而制订的,而avs却在上面进行了一些修改,变成RM,所以有些地方其思想和代码不太一致,自然就会误导人。并且也一直都不断的有人在发信报告错误,但是在一般情况下,RM52J的运行是正常的。
avs有专门的网站,但是那个是拿出来忽悠人的,maybe,呵呵。至于avs内部的一些细节东东,如果你所在的实验室或工作单位是avs的会员,那么取到avs服务器的账号和密码,进去瞧瞧就一目了然了。最后,有关论坛这方面,我就不太清楚了,呵呵,因为俺们实验室总是会face-to-face的讨论,没那个多余的精力去网上论坛了。有些视频的牛人都有自己的博客,你也可以去搜搜。
好了,回答完拉~,呵呵,以上都是me的一家之言哦,可能有不准确的地方,希望对你有所帮助。
太感谢了sha,
再问个问题, macroblock.c 第1000行(巧哈)
….
currSE.value1–;
real_mb_type = currSE.value1;
if(currSE.value1mb_type = currSE.value1;
img->cod_counter–;
}
这个是B_IMG时候SKIP_MODE_FLAG为零的代码,
分析下来会把B_SKIP和B_DIRECT_16X16合成了一个结果,都是0,
后面就没法区分B_DIRECT和B_SKIP了,这个是怎么回事啊?
你说的这一块我不大清楚。就我所知,待选模式中有效的是P_SKIP和B_DIRECT。而B_SKIP模式属于B_DIRECT模式的特例,B_SKIP就是当选择B_DIRECT模式后,得到的残差系数经过变换、量化后全部都为0,那么此时的B_DIRECT即为B_SKIP。你提到“后面就没法区分B_DIRECT和B_SKIP了”,我觉得可能不需要区分吧。当解码器读一个宏块的信息时,他只需要知道此宏块是不是B_DIRECT的,而不需要知道是B_DIRECT还是B_SKIP,i think。因为如果是B_DIRECT模式的,那么解码器就知道此宏块信息里面是没有运动向量和参考索引信息传过来的,至于有没有残差信息,是不影响解码器正确读宏块信息并解码的,他只负责读,不管读出来的是不是零。
因为我对这一块不熟悉,所以不能肯定,只是自己的理解而已。^_^
谢谢SHA,
确实如此, 看下来表18的序号,
比实际C代码里的表格18的INDEX小1,
因为B_SKIP不需要编码在MB_TYPE里头,
而SKIP是通过前面MB_SKIP_RUN不等于零来实现的.
通过这个MB_SKIP_RUN跳过的MB不需要任何码流比特,
所以MB_TYPE不需要考虑SKIP模式, yeahhhh…
再问一些问题,
我用AVS网站上下载的SDK,
好像不能播放RM52J产生的AVS文件.
另外通过什么工具能将AVS网站上的测试序列文件中
的VIDEO码流分离出来, 用于测试RM52J的DECOCDE?
SDK是啥东东?俺没有用过哦……你说的“AVS网站上的测试序列文件中的VIDEO码流分离出来”俺也没有分离过哦……
“用于测试RM52J的DECOCDE”,你直接用RM52J的编码器生成一个.avs文件,然后就可以直接用解码器解呀,还需要特意去寻找.avs文件么? 你有编码器的测试序列吧?就是.yuv文件。貌似你做得东东一直都只和解码器有关哈,不用改编码器的,呵呵……
或者你告诉我AVS网站上哪里有你说的需要分离的码流可以下载的,俺去下一下帮你瞧瞧 ^_^
在这里,
http://www.avs.org.cn/fruits/
试试看怎么把STREAM1-9.AVS灌到RM52J_R1里头.