头像
mawen1250
核心会员
核心会员
帖子: 670
注册时间: 2011-07-24 20:33

关于DirectShowSource源滤镜相关问题的讨论

由于有人问起关于DSS的问题,所以我干脆专门写一贴整合一下我所知道的问题:

1. DSS通过的是Windows系统的DS(DirectShow)接口调用DS滤镜,所以首先它限定了Windows,无法跨平台。

2. DS环境往往很复杂(特别是在你安装了各种第三方滤镜和各种解码包的情况下),往往难以保证自己在播放某个片源时具体调用的滤镜,除非自己用Graph Studio手动写grf文件确定滤镜调用的filter graph——这无疑增加了难度和复杂度。

3. DS滤镜本身大都是为了播放设计的,所以它们从设计理念上,优先保证的必然是播放的体验(快速载入、快速seek、流畅、容错、兼容)而不是压制的正确性(准确seek、frame perfect、bit exact),具体可以表现在以下几点。

4. 视频容器有个概念是index,index顾名思义就是目录,通常放在文件头,从它可以得知视频总共有多少帧,每一帧在文件中的哪个位置。
在没有index的情况下,如果是播放的时候,通常我们是按时间来跳转,所以可以快速搜索一下PTS(时间戳),得知跳转位置;而如果是压制的时候,想要快速跳转到某一帧(按帧号搜索),就只能通过猜测,可以想到的办法是通过文件大小、码率、帧的PTS来猜测,但这无法保证准确,特别如果是VFR的话这种办法显然会很不靠谱,而DirectShowSource这个滤镜在这方面是做的不好的。
不是所有的容器都有index,例如ts、m2ts就没有index,因为他们是为流媒体设计的容器,而流媒体播放的都是片段(例如TV放送),不可能获取完整的文件,所以在设计时就不包含index。通常mkv和mp4都是有index的,但有时候也能见到没有index的mp4(比如从监控capture的视频)。以及各种raw stream都不包含index,比如h264流、h265流、m2v,它们在播放器里一般表现为无法拖动进度条(既没有index也没有PTS)。
诸如DG系、ffms2、lsmas这类源滤镜,都会预先扫一遍文件,生成一个index文件,这样就能最大程度保证跳转的准确性。
而DSS系列源滤镜,都是不会预先扫一遍文件的(有哪个播放器播放文件还会先扫一遍的?),所以在文件没有自带index的情况下,往往很难保证准确的跳转。

5. 可能有人觉得自己压制是全程线性走下来的(既不Trim也不用时域滤镜),并不需要seek,但和index相关的另一个问题是,没有index时,整个视频的总帧数是不确定的。
而AVS也好,VS也好,在一个滤镜初始化阶段,就要报告它返回的总帧数,但它在扫完整个文件以前又是不知道总帧数的,所以这就形成了矛盾……
DG系、ffms2、lsmas由于在初始化阶段就扫一遍文件生成index,所以可以报告准确的总帧数。
而DSS系,这真的只能靠猜了……所以往往结果都会有所出入,多几帧少几帧都不稀奇,等它真正跑到了最后,少的帧只有丢掉,多的那就复制最后一帧。

6. DS滤镜除了基本的解码视频以外还会干别的事,比如做个格式转换、做个后处理之类的——到底怎么做的,还得看具体调用了什么滤镜,设置的参数是什么,以及播放的上下文环境——所以无端地又增加了复杂度和不确定性,或许也有人会利用DS滤镜来做点什么处理,但这就不在这里的讨论范围之内了。
经常出现的一个问题就是,有不少视频解码器会优先转换到YUY2输出,而到了avs里想要处理、输出,又得转回YV12,这一来一去无端地就增加了转换损失。

-------------------------------------------------------------------------------

当然DSS也不全是缺点:

1. 从上文得知,mkv以及普通的mp4之类的容器是内置index的,这时候再花费额外的时间去预先扫一遍显得有些多余,所以它们用DSS是相对安全的(但你还得保证其他几点不出问题,包括调用的滤镜本身在demux、解码上是不是有问题)。
注:对于普通的mp4和mov一类的容器有更好的选择,在AVS里是LSMASHVideoSource,VS里是lsmas.LibavSMASHSource,它们利用L-SMASH做demux,也无需额外生成index。

2. 遇到其他源滤镜都无法正常工作,但DS播放环境却可以播放的文件,那也只能用DSS了。

3. 相比于其他源滤镜,DSS的解码支持相对比较万能,如果输入的文件可能是任何类型的阿猫阿狗,而只有一个源滤镜可以选择的话,DSS可能是一个比较优先选择——这也是为什么某些GUI默认会给你用DSS。

4. 我是抖M,就喜欢找麻烦的事做。

-------------------------------------------------------------------------------

具体到AVS中的DSS相关滤镜来说,我主要知道以下三个:

1. DirectShowSource,AVS自带的,已经没啥好说的了。

2. DSS2,来自Haali Splitter里的avss.dll,始终调用Haali作为demuxer,算是做了一些限制,但Haali本身并不是万能的,比如对于ts,Haali其实是很容易出问题的(如果经常用eac3to把m2ts remux成mkv就应该有所了解)。在帧数猜测方面,根据我的经验准确率还是比DSS高不少的。

3. DSS2 mod,魔改版,其核心就是强制调用它自带的LAV系列滤镜做分离和解码,所以已经和系统的DS环境没有多少关系了。并且它也加了很多prefetch、cache相关的功能,一定程度上也提高了seek的安全性,虽然还是很复杂,而且我也没搞懂怎么用,该出问题还是出问题。但总的来说它比上面两个都要好了很多。

-------------------------------------------------------------------------------

综上所述,简单说来,DSS是个大坑,里面涉及到非常复杂的相关专业知识,一般人很难驾驭,然而事实上是:

1. 对这些有一定了解的极个别人,明白去折腾它就是件吃力不讨好的事,明明有更多更好的选择,所以也根本不会去用

2. 虽然我不是很懂,但能不用就不用,DG大法好/lsmas大法好

3. 你说这些谁看得懂?我用着爽就行



总之:
DSS是非常高级的源滤镜,一般人很难用好。 - 06_taro.jpg
11. 帧数基本靠猜 跳转基本靠脸 压前钢丝球洗脸 - mawen1250评DSS.jpg
1. 你们压制都出神入化了 怎么还不用DSS? - 辣鸡.jpg
上次由 mawen1250 在 2016-07-27 12:59,总共编辑 1 次。
fch1993
帖子: 213
注册时间: 2012-06-12 11:56

Re: 关于DirectShowSource源滤镜相关问题的讨论

DSS主要还是用于偏门格式的视频解码问题。

现有的源滤镜过于依赖ffmpeg/liav的解码支持,对于很多商用格式支持不好,而很多商用格式只提供DS解码方案。

比如说RMHD格式。

而且部分冷门格式也不支持,比如说daala。

回到 “理论讨论 / Theoratical discussion”