虾虾那个图片我也找不到具体在片段的哪儿,就随便找个交错来说吧.首先是用AU通过m2v解码得到的图象,以此为参考,如下图
[AU_m2v]
然后我们用dgdecoder直接载入
- mpeg2source("VTS_01_1.demuxed.m2v.d2v")
效果如下
[mpeg2source]
由上可见,在交错的地方,是以Y方向上每4个象素为一组,与m2v解码的不同
接着加上一句ConvertToYUY2(),转为YUY2,如图
[mpeg2source_convYUY]
如果仅以此来视之,大概会觉得dg的解码确实有很严重的错误.但如果我们使用dg所提供的一个参数来自行upsample的话,如图
- mpeg2source("VTS_01_1.demuxed.m2v.d2v",upconv=1)
[mpeg2source_conv1]
我们可以意外地发现,这下显示的图象和m2v解码出来的是一致的了.
那么,是否可以认为,dg的YUY2解码是没问题的,而它的YV12解码就有问题呢?我们仍旧让dg解码为YV12(相当于upconv=0),然后对converttoYUY加上interlace参数
- ConvertToYUY2(interlaced=true)
然后再来看:
[mpeg2source_convYUY_interlace]
可见这样得到的图象仍旧和m2v一致.所以我们可以得出结论,dg的解码应该是没有问题的,问题只能出在别处,并且应该是upsample的问题
那么,这个问题是avs的么?从表面上看似乎是,这不给加了个interlace的参数结果就不一样了吗?但如果我们首先利用dg进行upsample,然后再将其转回成YV12,又是什么结果呢?
- mpeg2source("VTS_01_1.demuxed.m2v.d2v",upconv=1)
- ConvertToYV12()
[mpeg2source_conv1_convYV]
可见这画面又不一样.这可是转化成progress的YV12的,但仍然与m2v画面不一致.可是又与dg直接解码YV12也不一样.可见问题是不出在avs里.或者仅就dg直接解码YV12显示出错这点,和dg本身及avs都没有关系.
所以我推测,这应该是YV12解码器自身的问题.因为YV12的avs脚本要在VDM里显示,必须有vfw的解码器来支持.我这里的是helixYV12这个解码器.而由此可以看出,这个解码器缺省是按progress来实现YV12->YUY的upsample,所以让它直接解码会出现第二张图的错误.而dg自己upsample到YUY后,因为本身是按interlace取样又是由ATI YUY Plane解码,所以才会显示正确.
我们可以来验证这一点.首先,upsample成正确的YUY色彩,用avs2avi压制,编码分别选helixYV12和ffdshow中的huffYUV,然后用VDM直接读入它们的avi,图象如下
[mpeg2source_conv1_helix]
[mpeg2source_conv1_huff]
从中可以看到,helix虽然在色彩分布上和m2v解码相似,但色彩本身已经发生了偏移.而huff则干脆类似于dg的upconv=1又使用了ConvertToYV12的样子.
其实不只是helix,ffdshow也是如此.我这里使用另一个交错图象,直接压成x264,然后directshowsource读取.当ffdshow中的output中钩有YV12时,图象如下
[x264_ffd_yv]
当将YV12的钩去掉以后,则显示成了
[x264_ffd_yuy]
这也说明,象x264这样的编码器,如果读进的是YV12的话,根本就是直接压制掉,不会在此过程中出现chorma类的错误.有错也是再解码的问题.这也许正是全程YV12的意义所在.至于xvid之类的会如何,我没试过,不过推想大概也差不多是这样.
然而,知道这点并没有多大用途.我们更关心的是,这对filter是否会产生什么影响?
答案其实是:不会.因为在YV12下,avs的filter一般是走场来处理的.而我们把上述画面拆成场来看的话,则根本没有什么区别:
- mpeg2source("VTS_01_1.demuxed.m2v.d2v",upconv=0)
- SeparateFields()
- mpeg2source("VTS_01_1.demuxed.m2v.d2v",upconv=1)
- SeparateFields()
以下,左图是upconv=0的,右图是upconv=1的
IVTC就不说了,虾虾那个片段我已经试过,用decomb完全没问题(有有问题的么?截给我看看).我们下面再来试试deinterlacer.首先使用FieldDeinterlace(),如下图
[conv=0]
[conv=1]
[conv=0_deinterlace_convYUY]
从中可以看到,起码在边缘处,YV12和YUY2基本上没有区别.虽然有个别色块两者有差异,但将deinterlace出来的画面再ConvertToYUY2一下,就跟直接conv=1彻底没有区别了.
然后是TDeint(type=1)
[conv=0]
[conv=1]
[conv=0_deinterlace_convYUY]
这下三者干脆没有区别.
所以即使是全程走YV12,也可以放心大胆地用下去.想想也是,若非如此,当年marcFD怎敢提出如此设想?2.5版出了这么多年,要有问题早出了.
我下面换用钢炼一个SP来更深入地说明一些问题.在这里,通用的一个代码组是
- LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\DGDecode.dll")
- Mpeg2Source("H:\HAGAREN_PREMIUM\sp1\sp1.d2v",upconv=0)
- FieldHint(ovr="sp1.d2v.fh.txt")
- #ConvertToYUY2(interlaced=true)
- #ConvertToYV12(interlaced=true)
其中fieldhint是一个IVTC插件
下面首先是dg解码成YV12并做IVTC:
[conv=0]
然后是dg解码成YUY2并做IVTC
[conv=1]
然后是dg解码成YV12,并让conventtoYUY打开interlace选项
[conv=0_convYUY_interlace]
接着是dg解码成YUY2并通过ConvertToYV12打开interlace选项,转回成YV12格式
[conv=1_convYV_interlace]
下面仍是dg解码成YUY2,但通过ConvertToYV12关闭interlace选项,转回成YV12格式
[conv=1_convYV]
最后一个是dg解码成YV12,通过ConvertToYV12打开interlace选项转成YUY,然后通过ConvertToYV12关闭interlace选项,转回成YV12格式
[conv=0_convYUY_interlace_convYV]
然后我再附送一张AU做出来的图
从上面我们可以看到,AU做出的IVTC,和前四种情况是几乎完全一样的(当然象素值会有一些波动,但你要考虑到这是各种up/down sample所产生的不可避免的误差,也就睁只眼闭只眼吧.反正肉眼基本上是看不出来的.啥?汝能看出来?容老夫六体投地一个).但后两种情况就比较特殊了.从感情上将我们可能会觉得,既然都到了YUY空间了,那应该是progress的了吧,在转回去,还有必要开interlace么?不是说这正是解码器的问题么?转回去转成progress的YV12,解码不就正确了么?
但遗憾的是,它就是有问题.我们可以回忆一下,helix压出来的,不正是有色彩偏移的东西么?不管这是什么机理,总之我们了解这一点就足够了:如果片源是interlace型的,并且upsample做了interlace处理,downsample时请务必也同样开启这个选项.当然如果先前没有开,后面就也不需要开了.否则又错得一塌糊涂了.
同时这里提一个有趣的细节:第一种情况和第四种情况,不光画面一样,其实截出来的图片,CRC也是一样的.
本来讲到这里,这个问题也应该说得差不多.不过这也是一个avs流研究问题的范畴.我想把这个问题简单延伸一下,分析(或者说推测)一下虾虾遇到的究竟是什么问题.
首先再明确一遍,之所以会出现虾虾认为的问题,就是因为他在AU中看到的是YUY2所解码出来的图象,而在avs中看到的是YV12解码出来的图象.这点很重要.
下面我把钢炼的avs脚本语句顺序调整一下:
- Mpeg2Source("H:\HAGAREN_PREMIUM\sp1\sp1.d2v",upconv=0)
- ConvertToYUY2()
- FieldHint(ovr="sp1.d2v.fh.txt")
接着我们再看,问题来了:
当然你会说这还不简单,没开interlace选项呗.但如果把ConvertToYUY2语句放在fieldhint下就没这问题.这是什么缘故呢?我们把它拆成场来看一下就知道了.上边为dg upconv=1,下边为先转YUY再IVTC
从中我们可以看到,这场里的象素本身就已经是错的.可见如果先做色彩空间转换并且使用了错误的取样方式,那么就会出现采取出了错误的chorma值,并用这样的错值覆盖回画面.换言之,这样弄出来的东西,本身画面就已经错掉了,再IVTC当然不会正确.出现残影云云也是应有之义.
说句可能是题外话,这种情况,按马沙同志的话讲,就是所谓的ICP(Interlace Chorma Problem).其实ICP也是一种CUE,只不过CUE是二维的,而ICP仅仅存在于Y方向,也仅仅存在于YV12的upsample上(DVD厂商啊,请汝等早日换用high profile吧!)
回到虾虾那几张图中来讨论.第三张图没错,是因为那和开了conv=2一样,是DG自己做了upsample(顺便说一句,DG的upsample就是jackei的代码,当然不会错了).第五张图没错是因为m2v已经做了YV12->YUY的upsample.第六张图居然没错在我看来有点匪夷所思,也许是交错不够凶猛没看出来?第七张图没错理由同上,第八张图有错理由同样同上: progress的RGB转回成interlace的YV12,没错才怪.
而第二张图有错,就跟我上面说的那些有关系了.当avs为YV12格式时,avsinp这个插件的upsample看来也和解码器出同一个毛病,走了progress路线,并且相当于彻底更改毁损了画面.无论汝等在AU里怎么折腾,都不可能改回来的.
综上所述我们可以总结这么几个制作原则:
1,在avs中,能全程走YV12是就全程走.
2,优先做IVTC和deinterlace.这两样做完了,就无所谓interlace不interlace了
3,尽量不要在IVTC前做色彩空间的转换.想用YUY尽量使用DG的upconv参数来做.色彩空间转换语句前后要一致,用了interlace就都要用,没用就都别用
4,用AU读取avs,请尽量先把avs转化为YUY格式
最后,感谢虾虾挖了这么个坑,让我等有机会深入思考一下.以前光是浑浑噩噩地全程跑YV12,虽然听AU流的人提到过这些问题但并没有系统思考过.希望虾虾再接再厉,为我们挖出更多更好的坑