VCD杂谈

沈天珩
(本页面创建于2024年9月16日)

目录

§0 前言
§1 扇区
 1.1 检错码与纠错码
 1.2 扇区地址
§2 刻录软件
§3 轨道
§4 文件系统
 4.1 主卷描述符
 4.2 必要文件
§5 PBC详解
 5.1 INFO.VCD
 5.2 ENTRIES.VCD
 5.3 LOT(_X).VCD
 5.4 PSD(_X).VCD
 5.5 Segment
§6 番外篇
 6.1 如何添加音频轨道
 6.2 “大容量”VCD
§7 尾声
参考文献




§0 前言

  写在前面:本文为随笔,非一般意义上的“技术文档”,因此可能存在一些非正式、口语化的表述以及一些个人的主观看法。如果只是不喜欢语言风格的话请绕道走。如果文中有技术相关的错误欢迎指出。

  VCD(Video Compact Disc),即诞生于上世纪末、流行于上世纪末至本世纪初的一种影音光盘,其存储介质与CD(音乐光盘)相同。随着DVD、BD的普及,VCD早在十多年前就开始渐渐退出历史舞台了,时至今日几乎已经销声匿迹了;但其仍存在一定的研究价值。最近整理了一下家中的老光盘,勾起了一些年轻时的回忆。早教时期就看过各种各样的光盘;2014年开始“玩儿”光盘烧录,摆弄各式各样的刻录软件进行DIY,但只是表面工夫,知其然不知其所以然;自从2017年制作出符合规格的标准VCD2.0之后几乎没再碰过光盘。而一转眼很多年过去了,对计算机技术有了更高层次的认识,便借着这次机会对VCD的内部深入地展开了探究。

  本文主要探究VCD2.0,着重探究它的灵魂所在——PBC(PlayBack Control)部分。行文中不可避免地会涉及一些其它格式的光盘相关的内容,但一般不会展开细说,如果在阅读本文时遇到障碍,请自行查阅相关标准。文中也会通过举例等方式较为直观地解释标准中存在的一些较为晦涩的词句,方便读者理解。


§1 扇区

  在各个社交平台上VCD相关的话题下见到不少人会疑惑,为什么VCD里面的文件复制出来大小比文件资源管理器里面显示的数据大了很多?例如,一盘最常见的标注为80min/700MB的CD-R光盘,若“刚好刻满”,它在文件资源管理器里面会显示为703.125MB,但里面的文件实际上会达到807.4951171875MB。这是因为,文件资源管理器中显示的数据量是把VCD盘当成数据光盘理解了。

  实际上,一个扇区有2352字节,而一般地,利用CD盘烧录数据光盘时,其采用一种被称为Mode1的模式存储数据,其中只有2048字节为用户数据,其余字节会记录扇区地址、检错码、纠错码等信息,因此一张标注为80min/700MB的光盘若烧录为数据光盘,它能够存下的有效信息真的只有703.125MB,其余均为冗余信息[1]。然而,VCD盘并不采用Mode1来存储数据,而是采用Mode2。Mode2在最初的标准中规定可以存放2336字节作为用户数据,在随后被称为CD-XA的扩展标准中,Mode2被细分出了Form1和Form2,VCD盘的首个数据轨道采用Form1,每个扇区的有效信息为2048字节;其余轨道采用Form2,每个扇区的有效信息为2324字节[2]。如此一来,VCD盘能存放的实际有效数据显然显著高于标注量。

1.1 检错码与纠错码

  检错码(EDC,Error Detection Code)和纠错码(ECC,Error Correction Code)看似与VCD的PBC部分无关。然而,若想真正深入探究PBC,不可避免地需要直接对相关文件进行字节层面的编辑。CD盘的检错码与纠错码十分强大,若只是修改了一个字节便草草保存,检错码与纠错码只会以为是这个字节出错了,从而在读盘时会发挥其能力将它“篡改”回来。因此我们在编辑了文件之后,我们需要同时对相关扇区的检错码与纠错码进行修正。在VCD本身的规范(白皮书)中,只提到了计算检错码与纠错码时和Mode1的差异,例如从哪一个字节开始取,到哪一个字节结束等,但其核心逻辑与Mode1相同[3]

  我们先来看检错码。在ECMA-130中提到,检错码使用一个32次多项式(x¹⁶+x¹⁵+x²+1)(x¹⁶+x²+x+1)进行循环冗余校验[1]。把一个扇区中特定范围的字节逐字节反向取出后在末尾补上32个二进制位0,将其视为多项式后对其取模——其实就是在每一个二进制位都模二同余的前提下模0x18001801B,得到的余式再反向一次即为检错码,占用4个字节,置于待检验的范围正后方。对于Mode2而言,Form1需要取自0x10起至0x817的2056个字节;Form2需要取自0x10起至0x92B的2332个字节。

  这里举一个例子来辅助理解一下“逐字节反向取出”,例如我们有一段十六进制的数据0x12345678,先拆分为四个字节0x12、0x34、0x56、0x78,随后对每个字节的二进制位进行反向,例如0x12写成二进制即为00010010,反向之后为01001000,写成十六进制即0x48,因此我们反向取出得到的四个字节为0x48、0x2C、0x6A、0x1E,即最后参与模运算的数据为0x482C6A1E;又比如,若最后计算出余式为0x482C6A1E,那么检错码即为0x12345678。

  我们注意到,Form2的检验范围为0x10至0x92B,因此检错码被放置于0x92C至0x92F,这就已经把一个扇区用完了,显然Form2是没有纠错码的——放不下了。实际上,在CD-XA标准中也提到,Form2末尾的检错码并不是必选项,如果不想要检错码,直接将该扇区的0x92C至0x92F写为0x00000000即可[2]。因为即使检错码检查出了有错误字节的存在,它的长度也不足以检查出错误的位置,更遑论修正;而且,VCD盘中Form2的扇区——即视频轨道中,少量数据的错误并不会引起致命问题,即无论图像或是音频中出现极小的噪点或极短的噪声,都不会对观感和听感造成本质上的影响。这与音乐光盘类似,音乐光盘存储数据时既非Mode1也非Mode2,而是采用一种被称为CD-DA的模式,每个扇区的2352个字节全部用来记录音频的采样数据,连文件头都没有——因为比特率在规范中是被定死的,更没有检错码和纠错码。

  然而,Form1的检验范围为0x10至0x817,检错码被放置于0x818至0x81B,距离扇区末尾还有276个字节的空间,这里正是用来存放纠错码的。VCD盘中有且仅有首个数据轨道采用Form1,里面存放了许多关键信息,例如上面提到的PBC的规则设定,一旦错了一个字节就会引起不小的麻烦,因此我们寄希望于纠错码能把错误修正,免于影响正常播放。按照标准,纠错码的检验范围为0xC至0x81B,共2064字节,但需要将0xC至0xF的4个字节无脑视为0x00000000之后再参与运算。

  纠错码分为P纠错码和Q纠错码两段,这样能够精准定位错误的位置并将其修正。将这2064字节按顺序排列成一个24行43列的矩阵,矩阵的每个元素包含两个字节,则P纠错码对每一列分别计算后将数据置于第25至26行;Q检错码需要对每条左上-右下方向的对角线分别计算,对角线上位于第一列的元素在哪一行就将数据置于哪一行的第44至45列。对于每一次取出的数据(即P纠错码的“一列”,Q纠错码的“一条对角线”),我们需要分奇偶字节分别计算,奇字节的结果置于对应元素的奇字节,偶字节的结果置于对应元素的偶字节。举例说明,假设我们有0x1234、0x5678这两个数据,那么0x12和0x56一起参与运算,设得到的结果为0x9A;0x34和0x78一起参与运算,设得到的结果为0xBC,则最终结果为0x9ABC。奇字节与偶字节互不干扰。我们需要在GF(2⁸)上进行运算,生成多项式为P(x)=x⁸+x⁴+x³+x²+1,即0x11D;生成元为α=2。假设我们取出的某一列的24个奇字节分别为s₀,s₁,...,s₂₃,第25至26行的计算结果分别为s₂₄,s₂₅,则我们需要保证在GF(2⁸)上同时满足s₀+s₁+...+s₂₃≡s₂₄+s₂₅(mod 0x11D)及α²⁵s₀+α²⁴s₁+...+α²s₂₃≡αs₂₄+s₂₅(mod 0x11D),解方程即可。Q纠错码相较于P纠错码虽然取数据的方式不同,但逻辑相同,因而略过。

  以下是一段模拟Form1的检错码与纠错码计算的程序,以十六进制输入0x10至0x817的2056个字节,按下计算键即可自动生成检错码及纠错码共280个字节:
检错码/纠错码为:

  以下是一段模拟Form2的检错码计算的程序,以十六进制输入0x10至0x92B的2332个字节,按下计算键即可自动生成检错码共4个字节:
检错码为:

  至此,即使读者仍不明白检错码与纠错码的计算原理,也能通过程序直接计算出检错码与纠错码便于修改数据。

1.2 扇区地址

  在ECMA-130标准中规定,无论是Mode1还是Mode2,每个扇区自0xC起至0xE的3个字节用于存放扇区地址。而字节0xF则用于标明其属于哪一种模式,Mode1即0x01,Mode2即0x02。这3个字节在十六进制模式下以十进制数码分别记录分钟、秒、扇区(即mm:ss:ff),其中1秒=75扇区,例如12分34秒56扇区就存作0x123456,并不需要进行十进制与十六进制的转换,所见即所得。这也是为什么纠错码在参与运算前要把0xC至0xF的4个字节先归零,因为我们不希望同样的有效数据被置于不同的扇区时会得出不同的纠错码。在后文中,凡是提到扇区地址,皆以mm:ss:ff的形式表达。

  理论上,扇区地址可从00:00:00开始,至99:59:74结束;实际上,VCD要求前150个扇区留空,即自00:00:00至00:01:74均不存在数据[3],因此bin格式的VCD映像文件往往直接从00:02:00开始记录数据;而结束扇区的最大地址则由光盘本身容量决定,例如常见的标注为80min/700MB的CD-R光盘,可安全地使用79:59:74及之前的所有扇区——若强行在80:00:00及之后的扇区写入数据,大概率这些数据会无法读取,甚至导致光盘报废。符合标准的12厘米CD-R光盘有63min、74min、80min、90min及99min五种规格,以74min与80min最为常见。时至今日,90min与99min的“大容量CD-R”︁只有二手平台还存在少量卖家,厂商早已停产。

  写这一段是想告诉读者在直接进行字节层面的编辑时如何快速定位。另外我们需要注意的是,首先我们不应该对标注扇区地址的3个字节做任何的改动,其次如果想要把多个轨道交换位置,或删去中间的部分轨道时,我们不可以直接对映像文件分割再合并,因为这样会导致扇区地址不按升序排列,造成定位错误。


§2 刻录软件

  网络上倒是不乏各式各样号称能够烧录VCD的软件,实际上真正能做出符合规范的VCD的软件少之又少。例如“光盘刻录大师”系列的软件,它在各种视频音频的格式转换、裁剪、合并等功能方面确实非常不错,也能够制作出符合标准的音乐光盘和数据光盘——这两种类型的光盘的烧录其实Windows本身就自带。然而在制作VCD时,它并没有严格按照视频码率1150kbps、音频码率224kbps的要求,使得80min规格的CD-R实际能存放近3小时的视频——这也被称为KVCD,总之不是标准VCD,在一些较老的影碟机上无法正确读取;即使是较新的影碟机,它在时间显示上也会有问题,可能实际播放了3秒的视频,机器上才前进了1秒——因为码率被压缩了。另一个弊端是它根本无法制作带有菜单的VCD,这使得做出来的所谓VCD2.0与VCD1.1没有本质区别。而菜单是PBC中非常重要的一环,连菜单都不支持,显然也不支持PBC的其它“奇技淫巧”。

  比较专业一些的刻录软件例如Nero,它确实支持VCD带有菜单,也能够把码率转换成符合要求的数值,但它仅仅是有菜单,并不能进行其它类型的播放控制,用现在的流行语说就是,“支持了PBC但没完全支持”。但是我们也不是说就此因噎废食,Nero有一个好处就是它可以支持“超刻”。对于90min及99min的CD-R而言,它在硬件上确实支持烧录这些时长,但是刻录机通常只会告诉你光驱内的光盘可用时间只有80分钟——这个时候需要打开“超刻”功能,并使用Disc At Once烧录模式,才能真正意义上将80:00:00及以后的有效扇区利用起来。多数刻录软件是不支持这个功能的。当然,如果在光驱内放入了一盘80min规格的CD-R,又打开了超刻功能想要烧录到90:00:00,那结果必然是上文中提到过的,后面的数据无法读取甚至光盘报废。

  在这里,我们一般选用德国Roxio公司的VideoPack软件进行带有完整PBC功能的标准VCD2.0的制作。但是这个软件有个缺陷,它常常无法读取出光驱的存在,使得无法直接烧录光盘。我们需要将其保存为cda格式的光盘映像文件,再通过UltraISO转换为bin/cue格式(注:bin文件即为最终写入光盘的数据,而cue文件指示了轨道信息,后文会提及,这两个文件缺一不可,需要互相配合工作),最后再用Nero对转换后的光盘映像进行烧录——当然,如果bin文件的大小小于807.4951171875MB,即总数据量在79:59:74之内,我们也可以直接跳过转换的步骤,直接用UltraISO将cda格式的映像文件烧录至光盘。用Nero的目的是为了方便“超刻”。

  另外需要注意的是,即便软件支持“超刻”,光盘规格也是“大容量”的,也有可能因为光驱本身的原因导致烧录失败。因为烧录时需要光驱进行寻轨,才能将数据写入正确的物理位置,如果寻轨能力较弱,无法检测到光盘外圈实际存在的有效扇区,仍然会导致数据无法读取甚至光盘报废。Nero带有超刻测试功能,利用它可以测试出在当前的光驱的前提条件下当前的光盘最多可以烧录多少数据。


§3 轨道

  所谓“轨道”,就约等于我们在影碟机上播放时的那个“曲目编号”。一张CD盘,无论被烧录为音乐光盘也好,VCD也罢,又甚至是混合类型的光盘,都离不开轨道信息。轨道信息被存放于TOC区域的Q通道中,这与那些2352字节的程序区扇区无关,是另外的一块儿物理区域。CD盘上最多支持99个轨道,下文中统称轨道1至轨道99。每一个轨道又可以有100个索引,但如今几乎已经不可见能够支持读取索引信息的影碟机或光驱,并且VCD也不需要索引,因此本文中略过。如需在轨道中间进行切分并对其应用一些特殊的播放控制,我们完全可以利用PBC以达到目的,具体在后文中会讲到。

  打开一个cue文件,我们可以观察到如下格式的信息:

  TRACK 01 MODE2/2352
INDEX 01 00:00:00
这是一个典型的VCD盘的cue文件的部分内容。其中,TRACK即为轨道,第一行表示轨道1采用Mode2;INDEX表示索引,第二行表示轨道1的第1个索引位置在00:02:00处——如前文中所述,VCD要求前150个扇区留空,而bin文件直接省略了这150个扇区,因此实际为00:02:00的扇区相对于bin文件而言确实是“首个”扇区,即00:00:00。cue文件中的索引位置指向的是bin文件,而不是VCD的扇区地址,我们需要时刻注意这个2秒的偏移,在之后分析ENTRIES.VCD文件时也会用到。

  在标准的VCD盘中,轨道1是一个数据轨道,采用Mode2-Form1存储一些关键文件,这些关键文件,尤其是与PBC强相关的部分,会在后文中详细叙述;后续的轨道一般均为视频轨道,采用Mode2-Form2存储视频码率为1150kbps、音频码率为224kbps、帧率为25(PAL制式)或29.97(NTSC制式)、分辨率为352*288(PAL制式)或352*240(NTSC制式)、声道为双声道(立体声)、包长(packet length)为2324字节的MPEG-1文件。当然,标准VCD也允许在视频轨道之后添加音频轨道,存储模式为CD-DA(即相当于音乐光盘),但是音频轨道不得出现在视频轨道之前——我暂时还没有测试过把音频轨道放在视频轨道之前会发生什么,但我的直觉告诉我无论是影碟机还是电脑,应该都能够正确读取内容,只是这样不符合VCD的标准,也就不细究了。对于音频轨道而言,我们不能在cue文件中写MODE2/2352,而是要写AUDIO。

  在电脑上播放VCD盘时,我们一般看不到“曲目编号”——能支持PBC的VCD播放器都寥寥无几,这里我们一般选择Roxio的VideoDisc Player,用VideoPack制作出的映像里面已经自带了这个软件及其对应的autorun文件,烧录完成之后哪怕去其它没有安装过VideoPack的电脑上也可以直接自动打开一同被烧录进光盘的VideoDisc Player进行播放;在影碟机上播放VCD盘时,我们看到的“曲目编号”为轨道编号减去1——播放音乐光盘时,“曲目编号”即为轨道编号,要留意这个差异。

  下文中,提及在电脑上播放VCD盘时,默认使用VideoDisc Player进行播放。


§4 文件系统

  VCD盘中的文件系统采用ISO 9600。然而,为了使影碟机方便读取数据,轨道1中的一些关键文件被置于固定的扇区之中——这也是为什么我们不可以直接用映像编辑软件去修改/增加/删减VCD盘的映像文件,因为这会直接导致这些关键文件被重新安放到其它位置,致使影碟机无法读盘。光盘根目录的信息置于哪里并没有硬性规定,不过VideoPack制作出的映像都会置于00:08:00(LBA=450)。从这个扇区出发我们可以一层层看到各个文件夹或文件被置于哪个扇区(占用多个扇区的文件则标出首个扇区,必须占用一段连续的扇区,不得跳跃)、每个文件占用了多少个扇区,至此整个文件系统便有了。

4.1 主卷描述符

  主卷描述符并没有对应的文件,但它是VCD中必不可缺的数据,位于00:02:16(LBA=16)处,占用1个扇区。详细结构可以参考ECMA-119[4],这里只挑其中的一些重点来讲。

  自0x18起(注意,Mode2-Form1的用户数据自0x18至0x817,后文不再重复),40个字节为系统标识符:

0x01X: // // // // // // // // 01 43 44 30 30 31 01 00
0x02X: 43 44 2D 52 54 4F 53 20 43 44 2D 42 52 49 44 47
0x03X: 45 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
其中,0x4344303031即为ASCII编码下的“CD001”︁;0x43442D52544F532043442D425249444745即为ASCII编码下的“CD-RTOS CD-BRIDGE”︁。这些数据不可以修改。

  自0x40起,32个字节为卷标识符,通俗地讲,也可以认为是光盘的名称,因为它会显示在文件资源管理器中。不足部分以空格(0x20)补足。据这篇文章[5]所说,许多VCD的卷标识符都会被命名为一串无意义的字符串,例如空白、下划线或“VolumeLabel”︁等。那我们就以“VolumeLabel”︁为例,看一下这32个字节会是什么。首先把这个字符串转换为ASCII编码:0x566F6C756D654C6162656C,于是我们就得到了:

0x04X: 56 6F 6C 75 6D 65 4C 61 62 65 6C 20 20 20 20 20
0x05X: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
当然,在这里我仍然推荐给光盘起一个有辨识度的名字,尤其是当你将许多光盘映像同时加载到虚拟光驱时,有一个好名字绝对能帮你快速辨别谁是谁。需注意,若打开映像文件直接进行字节层面的编辑,则编辑完之后要重新计算检错码与纠错码并一同修改。以下不再重复提醒。

  自0x68起,8个字节用于表示自00:04:00起至光盘末尾一共有多少个扇区,先以小端序记录一遍,再用大端序重复记录一遍以防数据损坏。例如一张光盘共300000个扇区,减去00:04:00之前共300个扇区,则剩下299700个扇区。由于299700=0x492B4,因此这8个字节为:

0x06X: // // // // // // // // B4 92 04 00 00 04 92 B4

  自0xB6起,8个字节用于表示文件系统根目录信息所在的LBA,同样先以小端序记录一遍,再用大端序重复记录一遍。前文中出现过LBA但未作解释,这里顺便解释一下。bin文件记录的首个扇区(通常为00:02:00)的LBA值为0,之后每一个扇区递增1。我们仍以VideoPack制作出的映像为例,根目录信息被置于00:08:00,而00:08:00相较于00:02:00经过了(8-2)×75=450个扇区,因此LBA=450。由于450=0x1C2,因此这8个字节为:

0x0BX: // // // // // // C2 01 00 00 00 00 01 C2 // //

  自0xC6起,7个字节用于表示根目录的修改时间。这7个字节分别表示:年-1900、月、日、时、分、秒、时区(以带符号整数存储15分钟的倍数,范围自-48至+52)。例如北京时间(GMT+8:00)2024年9月16日8时整,则这7个字节的十进制表示分别为124、9、16、8、0、0、32(因为8小时是15分钟的32倍),将其转换为十六进制可知这7个字节为:

0x0CX: // // // // // // 7C 09 10 08 00 00 20 // // //

  在这之后还有一些例如应用标识符、CD-XA识别签名等,这些数据都不可以随便修改,在此略过。

4.2 必要文件

  在根目录下,MPEGAV文件夹与VCD文件夹是必须存在的,前者用于存放所有视频轨道对应的文件,后者用于存放INFO.VCD与ENTRIES.VCD这两个必需的文件以及LOT.VCD与PSD.VCD这两个非必需但与PBC密切相关的文件。这四个以VCD为扩展名的文件非常重要,会在下文中详细讲解,并且它们必须被置于固定的扇区之中。还有两个非必需但也与PBC密切相关的文件夹,分别名为SEGMENT、EXT。其它非必需且与PBC无关的文件夹,例如CDDA、KARAOKE等,在本文中就直接略过了。另外,AUTORUN.INF(即autorun文件)与VCD_PLAY.EXE(即上文中所述的VideoDisc Player)显然也是非必需的,但推荐留在根目录下方便光盘在电脑上播放。


§5 PBC详解

  终于来到本文的核心部分了!相比VCD1.1,VCD2.0最大的特色便是引入了PBC,它是VCD2.0的灵魂所在。绝大多数用到了PBC的VCD盘中,只是把PBC作为菜单去使用,但PBC的功能非常强大,远不止菜单这么微不足道。PBC用得好的话,它能够很大程度上实现和用户的互动,例如广东锦声音像制品有限公司出的《小星星猜谜语》系列VCD,在每个谜语念完几遍之后都会出现两个选项,此时你可以用遥控器上的1和2来进行选择,如果选对了会跳转到“你选择的答案是正确的”的轨道,然后自动播放下一个谜语;如果选错了会跳转到“你选择的答案不对,再重新看一遍吧”的轨道,然后自动返回这个谜语。甚至于,只要你愿意,完全可以制作出在影碟机上播放(此处默认PBC为开启状态)和在电脑上播放时效果截然不同的VCD盘。

5.1 INFO.VCD

  INFO.VCD是VCD盘的必需文件之一,在文件系统中存放于VCD文件夹下,且必须固定于00:04:00扇区,占用1个扇区。数据显然是放在这个扇区的0x18至0x817范围内的,但对文件本身而言我们仍然把这2048个字节称为0x0至0x7FF。后文中对每一个特定的文件都使用文件本身的偏移量来指代字节,而非任何一个扇区内的偏移量。这样在通过WinHex等程序打开并修改文件时方便定位。若需直接打开bin文件编辑,请手动计算额外的24字节偏移量。INFO.VCD内存储了VCD盘的基础信息,如下表所示:

起讫偏移量大小该范围内所存放内容

  其实这些信息在VCD标准[3]中都已经说得很详细了,即使不知道去哪里下载标准,搜到这篇文章[5]也并不难。但是这些都是英文版本的,而写这篇随笔的其中一个重要目的便是提供一个中文版本的参考。

5.2 ENTRIES.VCD

  ENTRIES.VCD是VCD盘的必需文件之一,在文件系统中存放于VCD文件夹下,且必须固定于00:04:01扇区,占用1个扇区。ENTRIES.VCD内存储了所有进入点(entry)的信息。通常情况下,自轨道2起,每个轨道的起始扇区为一个必需的进入点;但若有需要,在轨道内部亦可插入其它非必需的进入点将轨道切分成多段,其作用与轨道中的索引位置类似,然而,如今几乎已经不可见能够支持读取索引信息的影碟机或光驱,但VCD盘中轨道内部的进入点仍然可以正常读取。例如广东福光影音发展有限公司出的淘气包系列百科全书VCD就用到了轨道内部的进入点便于定位。文件内各字节所代表的含义如下表所示:

起讫偏移量大小该范围内所存放内容

  实际上,如果不需要在轨道内部插入额外的进入点,ENTRIES.VCD甚至乱写都无所谓。为什么会这么说呢?在电脑上播放的时候,播放软件只会根据文件系统本身来定位轨道,即MPEGAV文件夹下的AVSEQnn.DAT文件(nn表示一个十进制两位数,最小为01,最大为98,加一即为轨道编号);而在影碟机上播放时,轨道信息会直接从Q通道中的数据读取,也就是本文第3章的内容,这与是否打开PBC播放也没有任何关系。只有当PSD.VCD文件引用了某个进入点编号时这份文件才会有用武之地,而如果没有在轨道内部插入额外的进入点,换言之所有进入点都是轨道的起始点,那在PSD.VCD中又有什么必要引用进入点编号而不是直接引用轨道编号呢?在这里我想说的是,如果想要做出一盘真正标准的VCD,那仍然建议按照标准认真准备这些数据;而如果只是出于某些目的去修改光盘映像,无所谓是否标准,“能放就行”的话,不去理睬这份文件可以减少一些工作量。

5.3 LOT(_X).VCD

  LOT.VCD与LOT_X.VCD是VCD盘的非必需文件,但是是支持PBC的必需文件,在文件系统中分别存放于VCD文件夹、EXT文件夹下。前者与PSD.VCD互相作用,供影碟机使用,因此必须固定其扇区位置,为00:04:02扇区至00:04:33扇区,共计占用32个扇区;后者与PSD_X.VCD相互作用,供电脑使用,无需固定其扇区位置,只要文件系统中的路径正确且大小为64KB(即Mode2-Form1的32个扇区)即可,但由VideoPack制作出的映像通常会将其置于00:11:29扇区至00:11:60扇区。由于这两个文件功能相似,结构相同,因此在这里合起来一块儿说。

  这两个文件的结构比较简单。前两个字节为保留区域,无信息,均为0x00。自第3个字节开始,每两个字节代表一个列表ID的值,以十六进制存储整数,不得重复(可以看成一个双射,把列表ID与十六进制整数建立关联),且建议递增。也就是说列表ID最多可以有32767个。特殊地,如果值为0xFFFF,则表示对应的列表ID不存在或不被允许用户接触。列表ID需通过PSD(_X).VCD进行调用,常规情况下一个视频(即一个轨道或一个Segment播放项目)对应一个列表ID,但有时根据不同的条件,同一个视频播放完之后会跳转到不同的视频,例如前文中提到过的《小星星猜谜语》系列,任何一个谜语选了错误选项都会跳转到同一个视频,但放完这个视频之后会跳转回原来的谜语,这样的情况就需要给同一个视频对应多个列表ID,然后对不同的列表ID进行针对性的不同设置了。

5.4 PSD(_X).VCD

  可以说,PBC是本文的重中之重,而PSD(_X).VCD又是PBC的重中之重了。

  PSD.VCD与PSD_X.VCD是VCD盘的非必需文件,但是是支持PBC的必需文件,在文件系统中分别存放于VCD文件夹、EXT文件夹下。前者与LOT.VCD互相作用,供影碟机使用,因此必须固定其扇区位置,自00:04:34扇区起,占用扇区数量由文件大小决定,最大不超过256个扇区,而文件大小已由INFO.VCD中给出(因此如果修改PSD.VCD时改变了文件大小请一定同时修改INFO.VCD);后者与LOT_X.VCD相互作用,供电脑使用,无需固定其扇区位置,也无需在另外的文件中指示出它的大小,只要文件系统中的路径正确即可,但由VideoPack制作出的映像通常会将其置于自00:06:50扇区起的一段连续空间内。

  这两个文件并没有“文件头”,数据直接从头开始存放。文件中按顺序存储各个播放列表相关的信息——或者说,程序代码,而每一个播放列表对应的数据量必须是8个字节的整数倍,不足部分以0x00补足。一个播放列表可以是任意个视频轨道(完整或片段)、任意个音频轨道、任意个Segmemt的有序组合,不过通常仅为一个视频轨道。由于每个播放列表所含的数据量有长有短,我们没法说第多少个播放列表对应的数据一定从第多少字节开始,因此本节的表格中的偏移量仅指一个播放列表的数据。对于一个普通的播放列表而言,各字节所代表的含义如下表所示:

起讫偏移量大小该范围内所存放内容

  这里我曾经有过一个非常不理解的点,既然在LOT(_X).VCD中被要求列表ID的值不得重复,也就是说每一个列表ID都和一个唯一的值互相绑定了,那么这个值存在的意义是什么?为什么不直接在“上一曲”、“下一曲”等功能处引用列表ID,而要绕一个大弯去引用对应的值?后来发现,这个值正对应着PSD(_X).VCD中这个列表ID相关的数据从文件的第多少字节开始。它们成正比例关系,值的8倍即为起始处的偏移量,这样一来,就方便了程序直接按照偏移量读取对应的播放列表的数据,而不需要再对整个LOT(_X).VCD扫描一遍并反向查找某个值对应哪一个列表ID了——而这个“8”,是否似曾相识?对,是在INFO.VCD的偏移量0x33处定义过的,同时前文中所说的必须保证每一个播放列表对应的数据量是8个字节的整数倍也是来源于此。当然,即使VCD标准中要求它必须为8,似乎理论上也可以是其它的数值——否则还有什么特意去定义的必要呢?但不过仍然不建议轻易修改。

  对于一个带有选单的播放列表(这类播放列表只会出现在PSD.VCD中供影碟机使用)而言,各字节所代表的含义如下表所示:

起讫偏移量大小该范围内所存放内容

  对于一个带有扩展选单的播放列表(这类播放列表只会出现在PSD_X.VCD中供电脑使用)而言,各字节所代表的含义如下表所示:

起讫偏移量大小该范围内所存放内容

  最后,需要在文件结尾处加上8个字节:0x1F00000000000000,表示PSD(_X).VCD结束。至此,PBC的核心部分便完成了。看到这里是不是还有一点点儿疑问,上文中多次提到的Segment究竟是个什么呢?莫急,且看下一节。

5.5 Segment

  Segment,若一定要翻译那可能是“段”——然而,即使这么翻译了,也容易让人摸不着头脑,因此不如直接用英文原词称呼之,也方便了与英文资料的对照。

  Segment播放项目通常也是MPEG-1视频——按标准也可以是以MPEG-1编码的纯音频,但几乎不会有人在VCD的Segment里面放纯音频。在文件系统中,所有Segment播放项目都被存放于SEGMENT文件夹下,其统一命名格式为ITEMnnnn.DAT,其中nnnn是一个四位整数,最小为0001,最大为1980。这些文件位于轨道1之中(通常在轨道末尾处),但很特殊地,它们并不以Mode2-Form1模式存储,而是和各个视频轨道一样以Mode2-Form2模式存储。Segment中的视频除了允许普通的动画外也允许定格画面,而定格画面允许更高的分辨率,为704*576(PAL制式)或704*480(NTSC制式)——当然,也允许普通的分辨率,即352*288(PAL制式)或352*240(NTSC制式)。

  在用VideoPack制作VCD时,只有拖入的图片才会最终生成到Segment之中,变为定格画面;拖入的任何视频文件最终都会变成一个独立的视频轨道。也就是说,如果你想把手中已有的视频放到Segment中去,不能直接用VideoPack制作,但你可以选择在用VideoPack制作出的映像文件的基础上进行修改——如果你对文件系统熟悉的话,因为这需要改很多数据。市面上有不少VCD会把片头动画放到Segment中,这大概率是音像制品公司有自己的一套独立的制作VCD的软件所为,我不是也不曾是、以后也大概率不会是音像制品公司的人,因此我是了解不到真正的内幕了。

  在INFO.VCD中,我们已经定义了首个Segment扇区的扇区地址;而如上所述,Segment最多有1980个。并且,每一个Segment固定地必须占用150个扇区,即相当于2秒的视频。一个播放项目可以横跨连续的多个Segment。然而,即使其最后一部分不足2秒,下一个播放项目也必须从下一个Segment开始存放,即一个Segment中不能存放多个播放项目(或其部分)。例如ITEM0001.DAT有27秒,那么它就需要独自占用14个Segment,若存在下一个播放项目,则其文件名就需要是ITEM0015.DAT——而不是ITEM0002.DAT,因为2至14都已经被占用了。

  通常我们不会在Segment中放入正片,只会放入一些诸如片头、版权页、菜单、提醒事项等等较短的内容。除非是高分辨率的定格画面,否则将视频存放于Segment中与将其存放于单独的轨道内在实际播放效果上并不会有什么不同。


§6 番外篇

  这里放一些和本文的主题弱相关的内容供有兴趣的读者们参考。

6.1 如何添加音频轨道

  上文中提到,在VCD盘的末尾处是可以以CD-DA模式存放纯音频轨道的,音质等同于音乐CD。然而,这时候就可能有人会问了,VideoPack做不出这类VCD,那应该怎么做呢?的确,在VideoPack制作VCD时若在某个轨道中仅拖入音频文件而不放入图片(即无法合成有画面的视频),点击生成映像文件会提示你无法将空白元素写入光盘。这时候,我们还是需要从字节层面直接下手。

  首先,我们用VideoPack把视频部分的映像做出来,然后根据需求按上文中所叙述的进行一些修改;随后我们将所需的音频文件按顺序制作成音乐CD的光盘映像——用任何一个支持制作音乐CD的刻录软件都可以,因为CD-DA的参数都是写死的,不同软件之间基本上也不会有什么差异。当然,我们还是要注意,视频部分和音频部分加起来不要超过光盘容量了,不然光有映像也没法写入到光盘中;轨道数更是不能超过99,否则连合法的映像都没法做。这时候,我们只要用命令行把两个bin文件合并,然后手动合并cue文件——即手动计算每个音频轨道的起始扇区,把数据加在原VCD盘映像文件的cue文件之后。注意VCD相关的轨道的模式均为“MODE2/2352”︁,而音频轨道的模式要写成“AUDIO”︁,不能弄错,否则刻录软件一定会错误识别轨道模式导致最终烧录出的光盘无法播放最后这些音频轨道,甚至直接无法读取映像文件。

  按以上所说的做出的混合模式CD,其视频部分和音频部分几乎可以说是互相分离的,因为打开PBC时只能播放视频部分——其实可以进一步修改LOT.VCD与PSD.VCD把音频轨道纳入PBC范围之内,影碟机是支持的;但是不要试图去修改LOT_X.VCD与PSD_X.VCD来把音频轨道纳入PBC范围之内,因为VideoDisc Player根本不支持读取那些轨道,这样会让软件直接崩溃。在电脑上似乎只能分开播放。虽然VCD的标准支持加入音频轨道,但目前似乎找不到合适的软件在支持PBC的前提下同时能够正确读取音频轨道,如果有发现比VideoDisc Player更好的软件,欢迎留言告知。

6.2 “大容量”VCD

  市面上曾出现过一些号称“大容量”的VCD。尤其是在VCD向DVD过渡的年代,一种被叫作DVCD的东西在国内短暂地火了一阵——或许对于本世纪初的人而言应该都不陌生。

  DVCD全称Double Video Compact Disc。它的名字并不是来源于DVD(即Digital Video Disc)和VCD(即Video Compact Disc)的“缝合”。所谓的Double,即双倍,意在表明它的容量能达到普通VCD的两倍之多——其实光盘本身的最大容量肯定是不到普通CD光盘的两倍的,即使按63min规格来计算两倍,那也得有126min,这都快赶上索尼曾生产过的130min规格的DDCD了。索尼的DDCD-R和DDCD-RW只有索尼自家某个特定型号的机器能够烧录和播放,如果DVCD和它如此相似,它没有道理能在一般的VCD影碟机或DVD影碟机上播放。DVCD中实际一般只有80多分钟或90多分钟的影片。然而,那个年代许多VCD都只刻有不到一个小时的实际内容,40多分钟的也不少见,甚至有30多分钟的,毕竟多刻一些也是一张,少刻一些也是一张,把总数同样多的内容分到更多张光盘上,为了赚钱不少厂家都会这么做。这么一对比就真的有“两倍”了。本质上DVCD在软件层面还是符合VCD规范的,而硬件层面不过就是把数据几乎写满了的90min或99min规格的CD光盘罢了。换了个名字看起来变得“高大上”了一些,仅此而已。

  而刚提到的索尼的DDCD,全称Double Density Compact Disc,这是真的把最大容量双倍了,能记录多达1.3GB的数据。但普通的光驱都无法读取这种光盘,它并没有掀起多大的风浪。

  另外一种“大容量”就是在软件层面都不符合VCD规范的VCD了,它是通过压缩视频的质量来达到放入总时长更久的视频的目的的,也称KVCD。前文中提及过的一款刻录软件“光盘刻录大师”就会用这种压缩的方式来制作VCD。如果对画质或音质的要求不是那么高的话,只要影碟机支持,放总归是能放的。不过在时间显示上就会变得些许奇怪,毕竟影碟机多半还是会按照扇区地址来计算时间信息。

  有人牺牲画质或音质来追求长时间,那么相反地,就一定也会有人牺牲时间来追求高画质或高音质,这就有了SVCD的雏形。与DVCD几乎同一时期,在国内短暂地流行过一种被称为CVD的光盘——全称China Video Disc,对,你没看错,中国影音光盘。它出现的时候并不符合任何一个当年现有的彩虹书规范,并且需要在专门对CVD做过支持的影碟机上才能播放,普通的VCD机并不支持。除CVD外还有HQVCD等为了高画质或高音质而昙花一现过的非标准影音光盘,而再后来几大业界巨头就取了这几种光盘的最大公倍数,制定了SVCD的标准。一张标准的SVCD的时长通常只有一张标准的VCD的时长的一半。现如今能支持播放SVCD的影碟机都能支持CVD与HQVCD的播放,当然也支持前面所说的KVCD。

  不过自从DVD甚至BD流行起来之后,画质与音质也大幅提高了,视频的总时间也大幅延长了,各类VCD昔日的辉煌也终将成为历史。


§7 尾声

  我对VCD成为历史这件事儿本身并没有什么过多的想法,科学技术的进步已经把很多东西都变成历史了。新一辈可能常常难以理解一些“历史遗留现象”,比如为什么许多软件的保存图标是一张软盘的样子——哦不,他们也许都没有“软盘”这个概念;比如为什么手机上的电话图标是一个像C字形一样的弯弯的东西,按号码又为什么被称为“拨”号;又比如,拍照的时候按下屏幕上的按钮为什么会发出“咔嚓”的快门提示音——等一下,“快门”又是什么?但是,对一些已经或将要消失在历史长河中的东西,了解的人越来越少,资料也越来越难找,总会有一些为博人眼球的混淆是非者会添油加醋地进行一些伪科普,而恰巧大家在这方面的知识几乎空白,于是不少人就会先入为主地去被动接受一些错误的概念而不自知,到后来越传越离谱。可是如果试图对他们的不实言论加以指正吧,又常常会被无知者的口水淹没。这是我十分不希望看到的。怀着一种无奈的心情写下这篇技术随笔,也是希望能够在中文互联网上多留下一份参考资料,尽自己的一份力做好真正的科普——我也没有十足的信心说我的文章里所有的内容都是百分百正确的,就像我自己也在文中提到过自己曾经有过一些错误的理解,或许在这篇文章的细节处仍然会有,这不好说。但首先,我能保证大方向上不会有问题,问题要有也只会是一些细节问题,其次,如果有人发现问题并联系我,我也一定会在查证相关资料后积极作出回应。我坚信,端正的态度是做好科普的必要条件。

  在文章的最后,我也想分享一下我在求知过程中做得最满意、最成功的一个系列的VCD的映像文件,篇幅原因另起一个页面,可以跳转,希望能给同样想深入探究VCD的朋友们一些帮助与启发。

  本文允许在注明出处的前提下随意转载。未注明出处而盗用的,一经发现,必将以法律途径解决。




参考文献

[1]ECMA. Data interchange on read-only 120 mm optical data disks (CD-ROM)[S], 1996-06

[2]Philips, Sony. System Description CD-ROM XA[S], 1991-05

[3]JVC, Matsushita, Philips, Sony. Video CD Specification Version 2.0[S], 1994-07

[4]ECMA. Volume and File Structure of CDROM for Information Interchange[S], 2019-06

[5]CDROM Video CDs (VCD)[DB/OL]. https://psx-spx.consoledev.net/cdromvideocdsvcd/