首页 > 技术宅区 > [笔记]低码率H.264视频心得

[笔记]低码率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 技术宅区 , , ,

  1. 2010年2月8日21:13 | #1

    这个是压缩视频大小的教材么?果然很专业,我一般就用几个格式相互转换的傻瓜型工具…

    [回复]

  2. SwanSong
    2010年2月9日00:32 | #2

    关于锐化和低码率的关系的说明让我有不少收获

    降噪我都用FFT3DGPU,觉得dfttest好像慢很多

    [回复]

    Aki 回复:

    fft3dgpu/filter在某些texture比较重的画面上有奇怪的效果,所以我一般用都是2pass
    这种实写的话觉得随便抹抹就行了,所以直接用默认参数的dfttest
    速度一直不是我考虑的问题,我家的Q9550压这个CIF的东西单pass的速度也不会超过20fps

    [回复]

  3. 2010年2月10日02:39 | #3

    先回LS:dfttest的多线程支持比fft3dfilter好很多(ncpu开到core数,dfttest在我的i7上比fft3dfilter快多了,但在本本上速度差不多);当然只要你显卡还行的话,dfttest比fft3dgpu还是慢的(不过,在我的i7+9800GT上,fft3dgpu优势并不是很明显,或许是9800GT还不够强吧)。

    不过我倒觉得默认参数的dfttest很强啊,默认我记得是1.7吧,应该是比较强的降噪了。秋月姐姐如果只是想随便打打的话我觉得RemoveGrain+Repair这种就够了……

    顺便一提,faac在64k码率上应一塌糊涂才对啊……我以前给VOD做的时候都是用NDAAC或者CTAAC的。64k即使Lame也能干掉faac。再一提,faac的q=0.25应该不是64k(我印象中大概是q=50吧),倒是NDAAC的q=0.25是64k……

    [回复]

    ssnake 回复:

    @ssnake, 第二段 默认->默认sigma

    [回复]

    admin 回复:

    广告这种东西一塌糊涂就行了-.-
    dfttest我觉得同样sigma下比fft3d系列要弱,所以就用了。

    [回复]

    ssnake 回复:

    @admin, 弱降噪在我的理解里是dfttest的sigma=1.0以下= =

    顺便为啥验证码永远是FIREHOOH。。

    [回复]

    admin 回复:

    custom spam keyword而已 完全是自己输入的pseudorandom序列

  1. 本文目前尚无任何 trackbacks 和 pingbacks.

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Switch to our mobile site