以为我自己的经验来说,编码器开发和优化过程中的不一致主要包括:CABAC 状态不一致、编解码不一致、debug/release 不一致、多次运行不一致。本文主要总结编码器多次运行不一致问题及解决方案。
多次运行不一致一般来说经常出现在多线程中。可能的原因是某些状态没有初始化,导致在多线程的时候每次运行拿到的值不一样;也可能是一个线程用到了另外一个还没有执行完的线程,导致拿到了空的或者错误的值。
多线程/单线程不一致
通常设置多线程时会保证单线程和多线程的结果时一致的,有时候更改某些代码后会出现多线程和单线程的结果不一致,如果多线程运行每次出现的结果是一样的,只是和单线程的结果不一样,那这是比较好解决的一个问题。
首先对多线程和单线程分别进行编码,尽量关闭deblock和sao。然后把多线程和单线程的码流使用码流分析仪打开,或者用VTM打开dtrace的宏解码再用YUView打开。这个目的是为了找到第一个出现不一致的块,同时可以确定两个不同的块选择的模式,找到第一个不同的块后后面就好办了,就不停的打log,来确定最初问题出现的地方,修掉就可以了。
多线程多次运行不一致
多线程多次运行不一致比较难的一点是难以复现,很难出现重复的编码结果,这就会导致我们无法方便定位问题的原因。所以需要通过几种方法来将不一致的可能情况给缩小,让不一致的结果尽量在一个结果上出现频率较高。我们先使用单线程编码一遍来得到一个anchor的编码结果。然后可以尝试以下办法:
一种方法是尽量关闭编码工具,现尝试把编码工具关闭之后是否还有不一致的情况。如果没有了,就去定位具体是哪个编码工具导致的。如果还有不一致,那就看出现不一致的结果复现的概率大不大,如果一个结果出现的概率比较大,这样就可以方便定位了。
定位方法和多线程/单线程不一致的方法一样,就不断的打log来找到问题所在的地方,但是要保证多线程编码的结果是一样的,比如多线程编出来码率是34.56kb的结果概率比较大,那只有在这个结果下的log才有意义,其他结果是没有意义的。
如果不一致的结果仍然难以复现,第二种方法就是尽量减少编码帧数。比如5帧10帧这种,先看看是不是可以稳定浮现。如果不行,可以随便将一个不一致的结果和anchor对比,找到编码顺序第一个不一样的帧的poc值,在编码时就编这么多帧,然后不断的缩小帧数,直到可以一种编码结果可以多次出现,然后按照上面的方法定位即可。
目前我遇到的问题基本上可以用这两个方法解决,这是我自己的解决方案,可能还有其它更好的方案。