(……能不能换个好点的标题。)
最近利用空闲时间把手头经常看的一些DVDISO都压一份观看用,结果发现这里面的小问题还不少。结果一折腾起来就没个头了。
这篇文章比较长,稍微给个简介。本文主要讲了这么几个问题(不按顺序):
- DVD的PAR处理
- Color matrix相关
- DVD压制实践:
- film DVD、hybrid DVD的压制细节
- DVD回放时FPS问题(0.1%)以及带来的章节desync问题探究
- 几款不同软件压制DVD的对比
Pixel aspect ratio(PAR)
第一个问题就是PAR。拿常见的可变宽荧幕NTSC来说,之前我都是压制的时候手动resize成848(最接近853的mod 14)×480之类的,没怎么细究过。最近想换用别人推荐的视频SAR不动,靠容器指定DAR的方式。结果用megui随便跑了一个,怎么出来的结果是…876×480?
打开megui的AVS creator一看,才发现默认的DAR是什么“ITU 16:9 NTSC (1.823169)”,而不是16:9。稍微研究了下,发现这个问题相当复杂,而且你去看ITU的Rec.是不能直接得出什么结论的——ITU是描述的analog(信号是多少xx赫兹之类的)的情况,所以到底是什么PAR其实是根据ITU的recommendation(主要是601和470,可能还有别的)推算出来的。
好在,这种问题有很多人已经研究过了,这里先提供一些链接(维基百科也可以先看看,看了下虽然没有明显错误,但是说得颇混乱):
- A Quick Guide to Digital Video Resolution and Aspect Ratio Conversions:据说是一篇经典文章了,对于如何从信号频率搞出PAR的来龙去脉写得很详细。
- Pixel Aspect Ratio – The Mossywell Web Site:另外一篇还不错的文章。
- Doom9帖子1:总结了常见的几组PAR和他们的来源。没细节,但是作为cheat sheet很好用。
简单总结下。
- NTSC的4:3的PAR应该是4320/4739,或者更准确的数字:38800/42651。这是用信号扫描时间推算出来的。如果是anamorphic widescreen(可变宽屏),那就乘以4/3变成5760/4739(更准确的数字:155200/127953)。
- 之所以是这个数字,是因为NTSC数字视频的实际视频区域(active picture)应该是710.85×486(这个数字是用标准中的analog的sample rate/time推算出来的)——这个区域应该被display为4:3或16:9。稍微算下就知道,5760/4739的PAR可以保证710.85/486的SAR正好变成16:9的DAR。
- 1.823169(8640/4739)这个数字,正是套用同样的PAR,去乘720/480这个DVD的SAR得到的DAR(
720/480*5760/4739=8640/4739)。 - 可以看到,由于DVD的720×480的宽是大于有效区域的。所以,理论上DVD视频的左右两边应该有黑边。
- 等等,那486比480多出来的那6条线呢?那6条线在制作DVD的时候直接出血掉了。实践上,可能近年制作/录制的NTSC视频来说,这6条线其实从一开始就不存在。你可以理解为把上面那个实际视频区域710.85×486按比例缩放——变成702又2/27×480就好。剩下的自然是黑边啦,所以你有时候也会见到704×480的DVD(少见),因为要完整呈现有效区域,没必要720(720/704/480这些都是16的倍数。MPEG1/2年代编码器的限制之一。要不然也不用折腾这么多了)。
- 所以,当你入手一个720×480的DVD,保证正确比例的做法是用5760/4739的PAR来encode为一个876×480的视频(875更接近,不过如果是encode一般有mod 2限制。或者直接指定DAR)。结果应该是视频内容部分是真·16:9,两边多黑边。
但是!这些都是理想情况,实践上有一个非常重要的区别。现在,许多(可以说绝大多数)新的DVD早已经是原生digital制作,也因此已经完全按照720×480无黑边制作了——也就是说,正确的播放方法不应该遵守ITU,而是直接拉成16:9播放/压制(相当于PAR=32/27)。当然,如果你发现视频左右两侧有不小的黑边,那应该考虑用ITU试试(或者简单地直接切黑边后拉到16:9)。至于4:3,似乎还是遵守ITU的比较多,毕竟都是很老的碟子。可以参考这个用户的rule of thumb。另外,据我观察播放器在playback DVD的时候都是直接16:9/4:3了事,没有用ITU resizing的。还好对播放比较新的DVD没影响。另外,不要小看这一点AR变形,如果对比观看,用对了和用错了还是相当明显的。
编辑:关于上面这段,不一定一定正确。请参见补遗文。
Color相关
这个其实和DVD没啥关系,但是到戏肉之前先垫垫场(啥)。
其实就是我前几天没事儿干观察了下手机拍摄的视频的元数据,发现居然是:
Color range : Full Color primaries : BT.601 PAL Transfer characteristics : BT.601 Matrix coefficients : BT.470 System B/G
这里的奇怪之处有:1. 居然是full range;2. 居然是PAL;3. 居然是BT.601。
前两个只是奇怪,最后一个就不太对,因为HD视频理应用BT.709。但是,如果录制的时候的转换矩阵确实是用601,至少有tag,播放的时候不会有问题。
这其实不是重点,只是因为这个,我突然好奇起来Color primaries、Transfer characteristics、Matrix coefficients这仨有啥区别,尤其是这里还出现了个我没见过的BT.470 System B/G。
Doom9这个帖子非常有帮助。不过我只是浅尝辄止,所以下面非常粗略地总结下。
- Color primaries:指定gamut的范围(三个原色[即“primaries”]的位置,白点位置)。理论上回放时只和校准(显示器)颜色有关,所以绝大部分播放器不会使用这个属性。
- Transfer characteristics:指定gamma ramp。譬如,你可以指定为linear等。几乎所有播放器都无视,直接用那个标准的nonlinear的ramp(见下文)。
- Matrix coefficients:这个是比较关键的也几乎是唯一会被播放器读取并采用的,指定了YUV和RGB的转换矩阵。
这几个属性的标准方面:
Color primaries有多种标准(维基有个表):
- BT.601 NTSC = SMPTE 170M = SMPTE C
- 老的NTSC 1953 primaries = BT.470 System M = FCC 1953
- BT.601 PAL = BT.470 System B/G
- SMPTE 240M:BT.709之前的一个HD标准,未被广泛使用
- BT.709
- BT.2020 = BT.2100
Transfer characteristics:
- BT.601 = BT.470 System B/G (PAL) = BT.470 System M (NTSC) =SMPTE 170M (NTSC) = BT.709,即:所有常见标准的gamma曲线其实都一样。
- BT.2020:根据维基百科,也一样,只不过常数精度更高
Matrix coefficients:
- BT.601 = BT.470 B/G (PAL) = SMPTE 170M (NTSC) ,至少在H264标准里是这样,即SD的都一样。写成不同的tag一般只是便于识别源是PAL还是NTSC
- BT.709
- BT.2020的没细看,八成不一样就是。
Progressive soft-telecine DVD压制
我在前文提过这种DVD,说白了就是实际是23.976p,靠加tag来soft-telecine到29.97播放。也提到实际PC播放的时候其实还是按23.976放。现在知道这种视频一般在业内叫“film”,下面也这么叫。
压制这种视频其实不是很复杂,我们以every♥ing!专辑《Colorful Shining Dream First Date♥》的DVD为例。这个DVD里收录了一个MV和Live 1的特辑,长度很长(这个后面很关键)。这个视频是纯film,用dgindex做index,显示99.99% FILM。用megui的d2v+avs+x264组合压制的话,会以23.796恒定帧率压制,出来的视频也OK。但是有问题的,也是我纠结的部分,是章节文件。
megui压制film DVD的章节错位问题
为了便于叙述,先简介一下这视频的一些基本信息。首先,这个DVD分为三个title,title0是全部播放,19章节;title1是只播放MV,1章节;title 2是只播放演唱会,18章节。我主要是在压制title 2。使用的工具是megui的OneClick encoder,但是本质就是上面的工具链,多了一部自动提取chapter封装MKV而已。
对于压出来的视频,我们记录下:帧数,时长,帧间隔。
统计帧数有多种方法,比如用mediainfo:
mediainfo --Output="Video;%FrameCount%" filename.mkv
另外,对于MKV格式,用mkvextract可以获取timecode表:
mkvextract.exe timecodes_v2 filename.mkv 0:timecodes.txt
这个相当实用,列出了每一帧的时间,用此可以推算出上面的所有需要的信息。数据的数量会比mediainfo显示的帧数多一个,相信是因为最后一个数字是最后一帧的结束时间。注意,不要用PotPlayer的OSD等方法来看帧数,那个对于VFR的视频完全不准,无法依赖(后叙)。据说用ffprobe也能抽取类似的信息,不过我试了下不是很好使没仔细研究。
这里,我这个视频的第一帧(帧0?)是从0ms开始,总帧数是115273。最后一帧的结束时间是4807844.708,也就是1:20:07.845(视频长度)。可以算下fps:
fps = 115273/[(4807844.708-0)/1000]=23.97602398
符合。我们也需要观察一下每帧的间隔。这里,每帧之间的差距都是41或者42ms。
但是问题出在chapter上,这里,这个视频的chapter是:
00:00:00.000 : en:Chapter 01 00:06:44.501 : en:Chapter 02 中略 01:29:10.006 : en:Chapter 17 01:37:49.923 : en:Chapter 18
可以看到,这最后几个chapter的开始时间根本就比视频长度还长了,肯定不对头。于是,回过头来看看DVD里的本来的chapter长啥样。手头能直接从IFO里提取chapter的工具只有megui自带的chapter creator和chapter grabber两个。megui提取的结果如下:
CHAPTER01=00:00:00.000 CHAPTER01NAME=Chapter 01 CHAPTER02=00:05:23.601 CHAPTER02NAME=Chapter 02 中略 CHAPTER17=01:11:20.009 CHAPTER17NAME=Chapter 17 CHAPTER18=01:18:15.943 CHAPTER18NAME=Chapter 18
看上去靠谱多了。这里要注意到megui这块显示“29.97”,我选成23.976,就会转换成上面那个错误的时间戳。看来,megui虽然识别出了视频是film,但是对chapter没有做正确的处理,多进行了一次不必要的29.97/23.976转换。
Chapter grabber提取出来的时间也是和megui的chapter creator一致的。但是chapter grabber似乎有点弱鸡:无法正确读取VIDEO_TS.IFO只能选VTS_01_0.IFO,而且只能打开title0。
那么,我们直接提取出这个时间戳试试。封入MKV,就会发现……时间还是不对。这次不是滞后,而是提前,但是提前的不多。
DVD回放FPS的1000/1001问题
百思不得其解之下,我直接打开DVD播放,确认了下里面的章节时间确实是最后一个为01:18:15.943没错——但是时间点在这里就是对的。仔细定睛一看:怎么总时长是01:20:03?!
和我们压制出来的视频的1:20:07.845长度对比下,相信眼尖的可以发现——两者的差距正好是24和23.976。也就是说,这种FILM的DVD,虽然vob的元数据写的清清楚楚23.976,但是在按DVD播放的时候,却是按照24fps来播放的。我试了Pot/MPV/MPC-HC/BE,全都一样。同理,如果播放title0(整个DVD),会显示1:25:21,压片出来则是1:25:26,错了5秒。我还尝试了用dgindex提取音轨,长度确实是01:25:26。
对NTSC稍微有点了解的应该知道这个1.001倍差是怎么来的,这里不赘述。但是应该和我们遇到的现象无关——既然元数据是23.976,为什么要自作多情按24放呢?我在网上搜了半天,确实有搜到一个人提到这个问题:他遇到的是标准的60fps/59.94fps(或30/29.97)的情况下,直接回放DVD和megui压制出时间不同外加chapter偏移。可见这个问题是普遍的,和film其实没关系。更重要的是,他是用物理的Sony DVD player播放出60fps的,所以可见至少我们这些软件是真实模拟了DVD碟机。
虽然知道了问题的普遍性,但是依然不清楚为什么。不过这个差距实在是太小,所以在片子短的时候根本就很难注意到。另外,似乎直接播放VOB文件也会有这样的问题,但是时间太短看不真切。
顺便一提,获取真实帧率除了上面说的timecode大法,可以利用PotPlayer开启转换滤镜后的OSD:

(不开转换滤镜没括号那个数字,看不出来。)当然有波动,所以这种方法对于区分24和23.976还是无能为力了,主要用来看是24还是30。这里可以看到,视频的元数据还是29.97,最后的输出则都垂直同步到60fps左右了。
既然知道了原因,接下来我们的处理方式就很简单了:将DVD里的chapter直接抽出来(规避上述Megui的不必要的29.97/23.976转换BUG),然后手动做一次24/23.976转换(变慢)。得到的结果chapter文件:
CHAPTER01=00:00:00.000 CHAPTER01NAME=Chapter 01 CHAPTER02=00:05:23.924 CHAPTER02NAME=Chapter 02 CHAPTER03=00:09:11.552 中略 CHAPTER17=01:11:24.293 CHAPTER17NAME=Chapter 17 CHAPTER18=01:18:20.643 CHAPTER18NAME=Chapter 18
合成到之前的MKV里(记得删除老的chapter),眼睛收货,基本完美。
其他软件对比
虽然算是搞定了,但是我还是好奇用其他软件进行转换会怎样,能自动处理好吗?
makeMKV
首先让我们来试试几个纯remux的选项。MakeMKV一直是我比较信赖的软件,而且对多title支持很好。我转了一份title02出来,帧数为115273,OK;最后一帧结束时间是4807836(=1:20:07.836)倒是稍有出入,不过换算下来fps是23.9760674依然OK。
但是MakeMKV出来的视频有个问题,就是帧间隔不一致。和之前megui压制出来的不同,其帧间隔表现为33/50/34/50……的循环序列。虽然平均值还是23.976fps,但是如果真的这样播放,岂不是会很怪?可惜,肉眼是看不出有什么区别,还是得稍后求救doom9大神。
补记:Doom9没大神救我,不过MKVToolnix的作者称此为正常现象(但是没回答我是否会影响播放的问题:()。
Chapter方面,则是
CHAPTER01=00:00:00.000 CHAPTER01NAME=Chapter 01 CHAPTER02=00:05:23.923 CHAPTER02NAME=Chapter 02 中略 CHAPTER17=01:11:24.280 CHAPTER17NAME=Chapter 17 CHAPTER18=01:18:20.629 CHAPTER18NAME=Chapter 18
虽然和我之前24/23.976转换之后的基本一致,也是准确的。但是还是有个趋势我不是很喜欢:从chapter1只错1ms到最后一个chapter错了13ms为止,两者的差距正好是个单调增,这给人的感觉是其中一个有在转换的时候浮点精度不够导致的(比如用了23.976而不是24000/1001)。还好,1个半小时的视频都只有这点差距,即使是强迫症的我也能接受。
MakeMKV还有一点,就是视频的元数据是保留了那些tag(variable即VFR后来讲):
Frame rate mode : Variable Frame rate : 23.976 FPS Scan type : Progressive Scan order : 2:3 Pulldown
所以还会被播放器识别为29.97(不影响播放)。
mkvtoolnix
另外一个remux的选项就是mkvtoolnix。由于mkvtoolnix只能傻傻地拖vob进去(倒是如果你拖VTS_01_1.VOB会自动识别后面的是append,但是注意别拖VTS_01_0.VOB进去,0是菜单那一帧),所以我们只能比较title0(全部播放)。具体就不赘述了,出来的帧数122905、最后一帧5126154(1:25:26.154)、fps=23.97606471和MakeMKV封title0完全一致。另外帧间隔不一致的问题也是一样,虽然两者的timecode并不是100%一致(大概每1秒钟就会有前后两帧各错1ms,囧):

不过我比较了下两者的元数据…
Writing library : libebml v1.3.6 + libmatroska v1.4.9 Writing library : libmakemkv v1.12.2 (1.3.5/1.4.7) win(x64-release)
……喂你这“libmakemkv”括号里的版本号很可疑啊,其实你就是用的完全一样的libebml和libmatroska来制作MKV的吧啊喂。说不定把两者版本更新为一致连上述的不一致都不存在了。
哦还有就是mkvtoolnix这么搞是没有chapter的,也不支持IFO中提取。我还顺便看了下remux出来的PCM的音轨的timecodes,是精确的30fps。
HandBrake
试完这个我们再来试试HandBrake(下称:HB)。HB也是个free(的“一键压片”工具,之前算是用过一次。虽然压制功能弱一些,但是对DVD的处理应该还是有其独到之处。
如果要和我们之前的结果进行比较,有个地方要稍微注意下,就是FPS的设定。默认的选项是peak=30fps的VFR(可变帧率),所以压出来的片子有可能会有部分非23.976的部分。最好改成CFR=same as source的方式。这里,我两种都试了,不过变量没控制好,CFR使用的编码器是x265 slow crf 18,VFR用的是x264 slow crf 18,不过根据另外一组实验,encoder的不同对结果没影响。
结果方面,两者的characteristics分别如下:
| 获取方法 | 参数 | CFR | VFR |
| Video timecodes | 开始ms | 0 | 21 |
(from mkvextract) |
结束ms | 4808053.708 | 4808085.708 |
| Diff. | 4808053.708 | 4808064.708 | |
| Frame Count | 115278 | 115273 | |
| 折算FPS | 23.97602169 | 23.97492692 | |
mediainfo |
Video dur. | 4808058 | 4808058 |
| Audio dur. | 4808054 | 4808077 | |
| General dur. | 4808054 | 4808077 | |
| Frame Count | 115278 | 115278 |
这张表里主要有以下几个奇怪之处。
- VFR那个视频,用mediainfo获取到的frame count和数time codes的结果在不一样,差了5帧。个人认为timecodes这个数据是准的,而mediainfo的结果是建立在CFR的假设下得出的。
- 其实,这个“VFR”版只有第一帧是非23.796——帧0的时间是21ms,而帧1的时间是282ms,间隔了261ms。按照23.976p的正常40-41ms间隔计算下,正好差不多可以补上那5帧的差别(这1帧顶别人6帧)。当然,由于VFR的存在,折算fps和23.976稍微有点偏差,这是正常现象。
- 可以看到,Mediainfo汇报的各种duration和timecodes报告的有细微差别。首先我不懂这个“duration”到底是简单的最后的结束时间,还是还要去除掉开始时间。但是从VFR那个可以看到,不管去不去掉21ms都对不上。即使是CFR那边也一样,反而和audio的能对上…相比之下,megui压制版用Mediainfo汇报出来的数据就完全一样。
- 可以看到,VFR版的Video是从21ms开始,同时,其audio部分则有个-21ms(相对video)的delay tag,所以audio其实是从0ms开始。个人觉得这视频不从0ms开始正是为了和音频同步而已。
另外,如果和上面其他几款软件的数据对比,会发现反而是VFR的和之前的frame count相同(115273),CFR的不同。对比时间戳的话,HB的CFR的时间戳几乎和megui的结果完全重叠,只是在最后比megui版多出来5帧(约200ms)。看了下HB的log,有这么一段(这是CFR的):
[06:16:51] reader: done. 1 scr changes [06:16:53] work: average encoding speed for job is 15.803467 fps [06:16:53] vfr: 115278 frames output, 0 dropped and 5 duped for CFR/PFR [06:16:53] vfr: lost time: 0 (0 frames) [06:16:53] vfr: gained time: 0 (0 frames) (0 not accounted for) [06:16:53] mpeg2video-decoder done: 115273 frames, 0 decoder errors [06:16:53] sync: got 115273 frames, 115157 expected [06:16:53] sync: framerate min 23.981 fps, max 29.970 fps, avg 23.976 fps
基本来说,源MPEG2那边确实只有115273帧,但是是VFR。所以,为了VFR->CFR,复制了5帧出来共计115278。至于megui那边则似乎直接没有这样操作,强行把当做CFR逐帧转了。
同理,VFR则不需要对帧的数量进行调整,直接保证帧间隔和原来的源一致就行了。这是VFR的:
[08:52:09] reader: done. 1 scr changes [08:52:10] work: average encoding speed for job is 62.888802 fps [08:52:10] vfr: 115273 frames output, 0 dropped and 0 duped for CFR/PFR [08:52:10] vfr: lost time: 0 (0 frames) [08:52:10] vfr: gained time: 0 (0 frames) (0 not accounted for) [08:52:10] mpeg2video-decoder done: 115273 frames, 0 decoder errors [08:52:10] sync: got 115273 frames, 115157 expected [08:52:10] sync: framerate min 23.981 fps, max 29.970 fps, avg 23.976 fps
哦差点忘了说,无论是CFR还是VFR,帧间隔也是正常的40/41,而不是直接remux那种奇怪的不等距的间距。
让我们来看看chapter时间,毕竟最开始我们就是在研究这个。
CFR那边是
00:00:00.250 : :Chapter 1 00:05:24.157 : :Chapter 2 中略 01:11:24.530 : :Chapter 17 01:18:20.863 : :Chapter 18
VFR那边是
00:00:00.261 : :Chapter 1 00:05:24.127 : :Chapter 2 中略 01:11:24.500 : :Chapter 17 01:18:20.832 : :Chapter 18
虽然稍有区别,但是实际时间点都是精准的。准确地说,CFR版本和megui、makeMKV提取等最后一章节的开始点是完全一致的一帧;VFR版要提前一帧。但是我感觉VFR版的更对,因为VFR正好是在转场(片尾credit的)开始的第一帧,别的都是第二帧。嘛,这种小细节并没有别人在意……
哦我还看了下HB的log,他对chapter是这么操作的
[04:15:22] scan: chap 1 c=0->0, b=188473->379436 (190964), 323600 ms [04:15:22] scan: chap 2 c=1->1, b=379437->514336 (134900), 227400 ms [04:15:22] scan: chap 3 c=2->2, b=514337->657180 (142844), 244000 ms ……
这是读取原始的。
[04:15:23] sync: first pts audio 0xa0bd is 0 [04:15:23] sync: first pts video is 19770 [04:15:23] sync: "Chapter 1" (1) at frame 1 time 19770 [04:24:26] sync: "Chapter 2" (2) at frame 7767 time 29171392 [04:31:23] sync: "Chapter 3" (3) at frame 13225 time 49659360 ……
这是写入的时候。虽然看不懂但是有个专门的category叫sync就感觉很专业!
这里感慨一句,所有的这种细枝末节,都是软件(不限于HB本身,还有各种lib等)作者一点点抠出来的啊。想写一个这种项目,尤其是比较底层、又是video这种历史包袱估计比山还高的,真是不容易。
几种压制方式的画质比较
既然片子都压出来了,我们顺便比较一下几种方式出来的画质几何,也给以后做个参考。对于这种我还会保留原盘的,其实只要画质不太差就行,所以我都是无脑slow crf 18。参与比较的有megui压出来的x264 10bit(hi10p)、x265以及handBrake压出来的x264和x265。
比较的结果比较出人意料,差别还挺大的。1:1播放(LAV+MadVR渲染,不过既然大家都一样应该算公平),细节最好的明显是x264 hi10p:

比较黄框部分,尤其是在HB的x265里,衣服的兜儿的线直接就没了……明明哪边都没有开denoise。当然你可以说x265的压缩噪声少,但是这种少法我不要啊!
这里有个奇怪之处是同样的参数为啥megui和HB的x265的区别肉眼可见。我比较了下log:
除了发现HB的版本老得快有代差以外(嗯,我承认我才发现我的HB是去年4月的旧版…)别的没啥特殊之处。不过最后出来的码率低了快10%,有点画质区别也是正常吧。
x264(hb)和megui的x264 hi10p的区别倒不算很大。体积方面(只计算视频),
HB-x264: 1.23 GB HB-x265: 844 MB megui-x264-10bit: 1.18 GB megui-x265: 952 MB
我于是在想,同样的crf参数,在x265和x264到底能否代表同样质量?但是无论如何,按理说HEVC的目的不是号称同样质量减少一半体积嘛,这点程度的体积差给我打败x264啊!
Film的反交错问题
我们已经知道了film是p,所以不用反交错。用megui压制的时候,那个自动反交错功能会根据DGIndex的汇报判断出是99.99% film所以禁用反交错。
用HB则稍微有点问题。默认的情况下,开启的是decomb滤镜。但是他这个检测感觉并不是很强壮,这是我压title2 chapter1的结果:
[06:56:15] comb detect: heavy 490 | light 1752 | uncombed 5523 | total 7765 [06:56:15] decomb: deinterlaced 490 | blended 1752 | unfiltered 5523 | total 7765
可以看到,其检测结果是有约2000多帧有heavy或light的comb,所以进行了deinterlace和blend。这显然不是我们想要的,因为理论上会降低画质。换成yadif的话没有对应的log,所以不知道是如何处理的,但是估计也差不多。所以,这里我们最好手动关闭deinterlace才行。
(不过,我稍微对比了下画质,虽然有不同但是也很难讲到底有变差多少,囧)
外一则:播放多title DVD的几个现象
在本文撰写过程中(好吧其实是半个月前),我发现各大播放器对于多title的DVD支持,尤其是进度条,都有各种谜之BUG。这里以Pot和MPC举例,其他播放器根据我的实验,也多少都有问题。播放的片还是上面那个。
问题1:直接播放VTS_01_0.IFO的问题
实话说我也没懂VIDEO_TS.IFO和VTS_01_0.IFO这俩有啥区别,总之如果直接播放VIDEO_TS.IFO,一切正常,可以在菜单里选不同的titile等。但是如果直接播放VTS_01_0.IFO,虽然内容看上去是title0(所有内容,从MV开始),但Pot里视频长度会变成奇怪的1:31:10(变长了),MPC-HC那边会变成1:20:08(也就是莫名是title2的23.976速度下的长度——不知道是不是巧合)。具体为什么我没细究,我记得之前对比了下播放的帧速也真的不太一样。
另外一个现象是拖进度条和播放到某个时间点的结果不一样。比如,在MPC里,如果你正常播放,到4:10还依然是MV(MV的长度是05:18左右);但是如果你手动拖进度条到4:10,会发现已经在Live的部分了……Pot那边虽然没这诡异的问题,但是chapter的时间点也完全不对。
问题2:直接播放VOB
这个仅限于直接播放VOB1,估计也是因为多title导致的。VOB1在MPC、mediainfo等显示duration只有09:29,这个根据体积计算就知道明显不对,Pot里显示14:28稍微靠谱些,但是实际上单独VOB1用mkvtoolnix封装下就知道真实长度应该是14:47左右。然后MPC那边又有“拖进度条和播放到某个时间点的结果不一样”的问题——again,还是多title复用视频片段的锅。所以,看DVD的时候,尤其是比较长的有多章节、多title的情况下,还是老老实实用VIDEO_TS.IFO启动,或者makeMKV封装下再看。
Hybrid DVD压制
上面说了这么多还只是纯film的视频。还有一种更恶心的:混合film和普通29.97fps interlaced视频的。这手头也有个例子:TrySail的一专《Sail Canvas》初回的DVD。不过,这次只有一个title0,两个chapter。其中chapter1是MV,是film;chapter2是花絮,是普通的29.97 interlaced,最后几秒Aniplex的logo又变回film。
Remux
这种视频,用MakeMKV remux是会自动使用VFR的方法来处理,播放时没有问题。Interlacing的问题至少我这边LAV可以实时监测并tag,给下流处理,其他解码器不清楚。
※刚发现其实有点小问题:如果你按照顺序播放,前面(根据MadVR的OSD)会标记interlacing off,后面自动变成on,正常;如果直接拖动到后半部分,也会切换成on,正常;但是你一旦你on了之后,再拖回part1,就不会off了囧,不知道是纯OSD显示BUG,还是会真的影响播放(比如对progressive的内容强行加了deinterlacing),姑且去Doom9问了。
需要注意,上面提到的各种“问题”都还在,比如MakeMKV压出来在23.976p的部分奇怪的不等间距time code;比如chapter要加1‰偏移(这次的chapter 2的开始时间,在DVD是4:30.000,用MakeMKV封装之后就会自动变成4:300.270)。
Encode
压制的话,用HandBrake处理起来是最得心应手的——可以直接压制成VFR的视频。这个也是我比较推荐的做法。chapter的处理也全自动。HB也可以选成CFR输出,我试了下如果选“same as source”会选择23.976(毕竟上来先是这个),后面的会被转换一次帧率。但是30转24的效果比较差,可以感觉到卡卡的,不推荐——即使真的想转成CFR,也用29.97吧。
补记:HB压制VFR的MKV的时候,metatag会不对(会显示CFR+一个错误的帧率,一般是原始视频的起始帧率)。虽然不影响播放,但是有强迫症的可以选择用mp4输出;然后用MKVtoolnix封装回MKV。即使你已经用MKV输出了,你也可以用ffmpeg先remux成MP4,再封装回MKV。注意几点:
- 直接重新remux MKV到MKV不行。
- MP4->MKV要用MKVtoolnix,不能用ffmpeg。Ffmpeg也会有tag写成CFR的问题(我怀疑HB用的就是ffmpeg的lib)。
- 这样操作一番还能解决一个问题,就是HB压出来的MKV的metatag还没有每个stream的bit rate的问题。
补记的补记:去HandBrake问了,原来其实不是metatag不对。其实,MKV的规范根本就没有“帧率”这个header——或者说MKV这个容器根本就没有帧率这个概念,因为具体的帧时间控制完全是靠timecodes来的。我们能Mediainfo里看到的tag纯粹是MI自己猜测的,所以没有参考性。至于为啥MP4 remux回MKV就有,那是因为原video stream本身的这类信息可以被继承下来并被MI读取到。同理,HB压出来的MKV没有bitrate也是同理——规范根本没有这个header。不过,MKVToolnix默认会自动计算bitrate(以及一些其他)并存到“tag”(一种可以往MKV添加任意自定义元数据的方法)里,所以MKVToolNix封出来的MKV一般还是能显示bitrate的。但是HB并不适用MKVToolnix来封装的,所以就欠奉了。
至于deinterlacing,由于HB这边选择不多,就用默认的decomb吧,其实我这DVD我看了下,后面的又是假interlaced(即两场同时曝光,实质progressive),所以什么都不加直接让编码器weave都没问题,也没法比较了。
megui那边就比较麻烦,据说用了AVS脚本压,就只能CFR;所以如果想压VFR,要么直接送x264,要么用AVS压完后自行搞出timecodes封装。我不是很想折腾,就试了下直接压CFR。开启auto deinterlacing的前提下,出来的结果还是没大问题的,CFR 29.97fps,23.976fps的部分会被比较正确地转换成29.97。如果不开deinterlacing,23.976p的部分会被直接telecine (2:3 pulldown) 成29.97,经典的5烂2效果我就不用说了(顺便一提用DGIndex预览记得去掉“Honor pull down flags”否则也是一样)。不过别忘了章节的时间问题,还得手动操作一下。
我也试了下用megui去直接encode MakeMKV remux的mkv,和直接用DVD压好像没啥区别,至少VFR的MKV当source看来是能处理。
哦还有一点,千万不要用megui OneClick encoder的“Don’t encode video”(remux)功能,完全狗屎,第一,他会按原始视频的平均FPS压片,出来个28.84 CFR的鬼东西,视频速度全乱了,音频也desync。其次,不知道为啥,这个remux的速度慢的出奇,甚至比一些preset下的encode还慢……
分段处理
其实还有个不错的方案是直接分割,然后两段分别用23.976 / 29.97 CFR。但是用megui按章节分割又是难死,所以还是用HB做这个吧,可以选chapter压制很便利。就是记得1点:由于第一部分和第二部分开始于同一个VOB里,所以元数据只有第一部分的,所以如果你压第二部分选CFR(same as source),会很尴尬地变成23.976fps。所以手动选一下29.97吧,或者直接上VFR,本质也会是29.97。其实推荐VFR,鬼知道手动选29.97会不会出现某些帧没对齐所以进行多余操作之类的,但是选了VFR之后元数据里的nominal FPS又会依然是23.976看着很不爽……
哦对,HB我升级了新版,发现也支持x264 hi10p了,很不错哦。
结语
写这文章的时间都能写出一篇论文了,光excel都做了7个表,用了几十G硬盘,现在什么也写不动了。总之我的结语就是DVD必须死,NTSC必须死。








