存档

文章标签 ‘FLV’

[笔记]低码率H.264视频心得

2010年2月8日

86那接了点私活,大体上就是帮某些有需求的客户做些适合于streaming的视频。由于Target platform是flash v10搭载的电脑,于是那个老掉牙恶心死人的VP6/7就被我直接pass了,由于有文件大小的要求这个问题最终演化成了一个低码率H.264视频的实践问题。由于组里的480p双兼容mp4也算是典型的低码率应用,所以略作些整理吧。对我而言,perferred的toolchain是avisynth+x264+ffmpeg,当然我不用ffmpeg编码,只是拿来mux flv而已。

首先来看Video部分,avisynth+x264的黄金搭档也正是我最熟悉的两个工具。考虑到处理的视频大多都是实写(PAL),因此avisynth中只需要稍微做点降噪,再来点锐化就好了。我选择的方案是dfttest+LSFmod,dfttest用默认参数轻轻一抹,LSFmod的参数上也尽量做到柔和即可。此处值得注意的是由于最终目标码率很低(<250k@CIF),因此任何锐化(High Emphasis)的操作都可能会导致最终产品的画面布满玻璃渣,所以锐化滤镜的选择和参数的使用需要特别注意。我的LSFmod里strength只用了55。
源滤镜是处理这种千奇百怪视频的重要绊脚石,好在有ffmpegsource2这种通吃滤镜,什么VFR我才不管呢,反正都是PAL的实写,统统喂给它就能搞定了。只是要注意有时候源是yuv444的,所以出现奇数分辨率也一点都不奇怪了。

下面来看x264的参数,我的理念是在bitrate budgets下获得最好的(主观)质量,因此基本的rc方案毫无疑问的使用了1pass CRF+2pass Bitrate的方法。这样既能控制最终码率,又不至于被码率限死而影响质量。好在这个任务没有对播放端的解码延迟有什么要求,于是可以尽情的用些容易导致latency的参数了。
在确定rc方案之后,下面就是挑出一些参数来做优化了。我把参数的优化分成五个部分:ME、降码率、除块、帧类型、兼容性。
//顺便一说,我用的--crf 20的1pass。

首先是me,由于低码率的限制,精确的me(与之相对是更小的误差值)是必不可少的,相反在码率很充足的情况下me的精确性到来的不是那么重要了。我使用的是--me tesa --subme 10 --trellis 2 --merange 48的方案,tesa保证了尽可能精确的ME,subme 10保证了子块预测/细化时的准确性,merange 48相对于CIF来说也足够大了。

其次是码率的控制,开大mbtree的lookahead和降低qcomp数值是一个好方法,我是用的是--rc-lookahead 100 --qcomp 0.5的配置。有人可能会提到aq-mode 2,但我实际的感觉,aq-mode 2在这种极低的码率环境下会出现恼人的mosaic effect,所以aq-mode还是坚持使用mode 1,strength=1.0的默认设置吧。

然后是除块的参数,在前面avisynth的参数选择上我就说了锐化参数必须小心,x264里关于锐化/除块的参数有二,psy-rd和deblock。psy-rd的strength越高,玻璃渣就越明显(低码率下),deblock的负值则被认为有助于恢复锐利的线条和texture。所以对我这种环境,两者的效果都应该降低。我选择的是--psy-rd 0.2:0 --deblock 1:1的配置。

最后是帧类型和兼容性,这两个分类间相互的依赖性比较大,因此联合起来考虑。对流媒体而言,考虑到分辨率的大小,--profile main --level 3.0的设置足矣。ref 3和bframes 8则完全是个人喜好,如果要ep的话bframes 16也是可以的。--partitions b8x8,p8x8,i4x4,i8x8也是个人喜好,而且在level=3.0时这也就等于all了,我没有考虑把i8x8排除在外,因为target platform是标准终端因此没有必要。
vbv-bufsize和maxrate完全是为了限制1pass crf可能的飚码率问题,我定在了1600和1200。keyint和min-keyint则是一如既往的fps*10和1的配置。

1pass完整参数如下:
x264 –profile main –level 3.0 –pass 1 –crf 20 –stats “proc.stats” –min-keyint 1 –keyint 250 –ref 3 –bframes 8 –b-adapt 2 –direct auto –partitions none –no-fast-pskip –no-dct-decimate –vbv-bufsize 1600 –vbv-maxrate 1200 –rc-lookahead 100 –qcomp 0.5 –psy-rd 0.2:0 –deblock 1:1 –me tesa –merange 48 –subme 10 –trellis 2 –sar 1:1 –thread-input –threads 6 -o NUL proc.avs

2pass的完整参数如下:
x264 --profile main --level 3.0 --pass 2 --bitrate 340 --stats "proc.stats" --min-keyint 1 --keyint 250 --ref 3 --bframes 8 --b-adapt 2 --direct auto --partitions b8x8,p8x8,i8x8,i4x4 --no-fast-pskip --no-dct-decimate --vbv-bufsize 1600 --vbv-maxrate 1200 --rc-lookahead 100 --qcomp 0.5 --psy-rd 0.2:0 --deblock 1:1 --me tesa --merange 48 --subme 10 --trellis 2 --sar 1:1 --thread-input --threads 6 -o proc.264 proc.avs

在x264 rev.1376下实际跑的结果,crf 20的1pass在上述参数下基本码率不会超过400k,于是2pass的bitrate模式限制就比较宽松了。基本*0.75就能得到适合的2pass码率。

音频:
音频部分用ffmpeg处理,通用格式就是
ffmpeg -i somefile.ext -acodec libfaac -ab 64k oputfile.aac
有时ffmpeg的编译没有开启外部libfaac.dll的支持,解决方法要不就自己configure然后make要不就去找其他人编译的带libfaac支持的binary咯。
另外此处用的是average bitrate模式,也可以用-q这种质量模式,目标64kbps的音频q的数大约是0.25。

Mux:
继续ffmpeg:
ffmpeg -i somefile.mp4 -vcodec copy -acodec copy oputfile.flv

于是就大功告成了。

admin 技术宅区 , , ,

Switch to our mobile site