VCD 技术规范与标准演进(一):VCD 白皮书标准、CD-XA 扇区与 MPEG-1 封装
当时,家庭影音领域正处于从模拟磁带向数字光盘过渡的阶段。当时消费级视频介质主要由模拟制式的 VHS(Video Home System)统治,其水平清晰度约为 240 线;高端专业市场则使用 30 厘米直径的 LaserDisc(LD),水平清晰度达 420 线,但制造成本高昂且机械结构复杂。
1982 年索尼与飞利浦推出 CD-DA(红皮书音频 CD),确立了 12 厘米光盘的物理制造标准与 16-bit / 44.1kHz 数字音频规范。随后的核心工程问题,在于如何在物理参数受限的标准 12 厘米 CD 介质上容纳运动视频。
1993 年,飞利浦、索尼、松下与 JVC 联合发布了 Video CD 白皮书标准(VCD 1.0),并在随后升级为 1.1 版本。本文解析该规范的底层物理结构、扇区载荷计算以及 MPEG-1 码流封装。
1. 飞利浦 Rainbow Books(彩虹书)规范体系
飞利浦与其合作厂商通过不同颜色的封面区分光盘存储格式,统称为 Rainbow Books:
| 规范代号 | 封面颜色 | 发布年份 | 核心物理与逻辑定义 |
|---|---|---|---|
| Red Book | 红皮书 | 1980/1982 | CD-DA 音频格式,16-bit 44.1kHz 立体声,每秒 75 个扇区 |
| Yellow Book | 黄皮书 | 1983 | CD-ROM 数据盘,定义 Mode 1(含两层纠错)与 Mode 2 扇区 |
| Green Book | 绿皮书 | 1986 | CD-i 交互式多媒体光盘,依赖专用 OS-9 硬件系统 |
| Orange Book | 橙皮书 | 1990 | 可刻录光盘规范,定义 CD-R、CD-RW 写入模式 |
| White Book | 白皮书 | 1993 | Video CD 规范,基于 CD-ROM XA Mode 2 Form 2 存储 MPEG-1 流 |
| Blue Book | 蓝皮书 | 1995 | Enhanced Music CD (CD-Extra),混合音频轨与数据轨 |
| Scarlet Book | 绯红书 | 1999 | Super Audio CD (SACD),采用 1-bit DSD 编码 |
白皮书的工程目标是将当时定稿的 MPEG-1 视音频流适配到单速(1x)CD-ROM 驱动器上,同时保证单张光盘具备约 74 分钟的连续回放时长。
2. CD-ROM XA Mode 2 Form 2 扇区结构与吞吐计算
标准 CD-ROM 数据盘(Yellow Book Mode 1)每个物理扇区总长为 2352 字节,内部包含了较为冗长的纠错码:
- 同步字段(Sync):12 字节
- 头部字段(Header):4 字节
- 用户数据(User Data):2048 字节
- 检错码(EDC):4 字节
- 填充字段(Intermediate):8 字节
- P 校验与 Q 校验(Reed-Solomon ECC):276 字节
在 1x 驱动器转速下,物理读取速率固定为每秒 75 扇区:
如果按 Mode 1 存放视频,1.2 Mbps 的带宽不足以在保证运动画质的同时容纳立体声音频。为此,VCD 白皮书引入了 CD-ROM XA(Extended Architecture)Mode 2 Form 2 扇区格式。
+---------------------------------------------------------------------------------------+
| Sync | Header | Sub-header | User Data (Audio / Video Payload) | EDC Checksum |
| 12B | 4B | 8B | 2324B | 4B |
+---------------------------------------------------------------------------------------+
|<- - - - - - - - - - - - - - - - - Total: 2352 Bytes - - - - - - - - - - - - - - - - ->|
2.1 扇区字段解析
- Sync(12 字节):固定同步码,十六进制为
00 FF FF FF FF FF FF FF FF FF FF 00,供硬件时钟提取扇区边界; - Header(4 字节):包含分(Minute)、秒(Second)、帧(Frame)的 BCD 格式时间码,以及扇区模式字节(Mode 2 标记为
0x02); - Sub-header(8 字节):包含文件号(File Number)、通道号(Channel Number)、子模式(Submode)与编码信息(Coding Information),各占 1 字节并重复一次以作冗余校验。
Submode 字节的位定义直接控制解复用器的硬件流路由:
| 位偏移 | 字段名 | 取值与作用 |
|---|---|---|
| bit 7 | EOR | End of Record 标志 |
| bit 6 | Video | 置 1 表示该扇区载荷为视频数据 |
| bit 5 | Audio | 置 1 表示该扇区载荷为音频数据 |
| bit 4 | Data | 置 1 表示该扇区载荷为常规计算机数据 |
| bit 3 | Trigger | 硬件中断触发标记 |
| bit 2 | Form | 0 = Form 1(2048 字节数据 + ECC);1 = Form 2(2324 字节载荷,无 ECC) |
| bit 1 | RT | Real-Time 实时流标记 |
| bit 0 | EOF | End of File 文件结束标志 |
- User Data(2324 字节):剥除 ECC 校验后,扇区净有效载荷扩大至 2324 字节;
- EDC Checksum(4 字节):基于 32 位多项式生成的 CRC 检错校验码。
2.2 物理带宽与容量推导
在 Form 2 格式下,单速驱动器的净数据吞吐量提升至:
在 74 分钟的标准光盘容量预算下,可寻址物理扇区总数约为 333,000 个():
通过舍弃针对离散数字文件所必需的第二层 Reed-Solomon 纠错,VCD 在物理层释放了约 13.5% 的空间。连续视音频流对突发误码具备容忍度,偶发的单比特翻转仅会产生单宏块视觉噪点,不会导致整个解码流水线中断。
3. MPEG-1 视音频码流预算与 SIF 参数规格
Mode 2 Form 2 的物理净载荷上限为 1,394,400 bps。白皮书对 MPEG-1 视频与音频给出了严格约束;两条流和 MPEG 系统层包头、填充包共同占用这条物理通道。下面的数字适合作为码率预算理解,而不是每一个扇区都按固定比例分配的“带宽切片”:
- MPEG-1 视频流(Video):固定为 1,152,000 bps(1152 kbps);
- MPEG-1 Audio Layer II 音频流(Audio):固定为 224,000 bps(224 kbps),44.1 kHz 立体声采样;
- 系统包开销与时间戳(System Header & SCR/PTS/DTS):占用约 18,400 bps。
3.1 SIF 画面规格定义
MPEG-1(ISO/IEC 11172-2)采用标准交换格式(Standard Interchange Format,SIF),将电视广播信号的分辨率在水平和垂直方向分别缩减一半:
| 规格参数 | PAL 制式 | NTSC 制式 |
|---|---|---|
| 画面尺寸 (像素) | 352 × 288 | 352 × 240 |
| 显示纵横比 (DAR) | 4:3 | 4:3 |
| 帧率 (fps) | 25.0 fps | 29.97 fps (30000/1001) |
| 扫描方式 | 逐行扫描 (Progressive) | 逐行扫描 (Progressive) |
| 色度抽样格式 | YUV 4:2:0 平面格式 | YUV 4:2:0 平面格式 |
| 典型 GOP 结构 | (IBBPBBPBBPBB) |
电视原始信号在编码前先做垂直去隔行与水平滤波降采样。YUV 4:2:0 平面格式下,每个像素平均只占用 1.5 字节未压缩数据。以 PAL 制式为例,未经压缩的原始视频数据率为:
通过离散余弦变换(DCT)、自适应量化与运动补偿,MPEG-1 编码器实现了约 26.4:1 的压缩比,将码流控制在 1152 kbps。
4. AVSEQ01.DAT 的 RIFF CD-XA 容器封装
光盘中的主视频文件存放于 MPEGAV/ 目录下,文件命名遵循 AVSEQ01.DAT、AVSEQ02.DAT 等规则。
在 ISO 9660 文件系统层面直接读取 .DAT 文件时,操作系统看到的文件并不是裸 .mpg 文件。它使用了一种 44 字节的伪 RIFF CD-XA 容器头封装:
#pragma pack(push, 1)
struct RiffCdxaHeader {
char riff_magic[4]; // "RIFF" (0x46464952)
uint32_t riff_size; // 文件总长度 - 8
char cdxa_magic[4]; // "CDXA" (0x41584443)
char fmt_magic[4]; // "fmt " (0x20746D66)
uint32_t fmt_size; // 固定为 0x00000010 (16 字节)
uint8_t raw_attributes[16]; // CD-XA 轨道属性描述
char data_magic[4]; // "data" (0x61746164)
uint32_t data_size; // 音视频数据载荷总长度
};
#pragma pack(pop)
这种封装具有明显的历史背景:在当时的 Windows 3.1 和 Windows 95 环境下,通用多媒体系统(MCI,Media Control Interface)并不允许普通应用程序直接向 ATAPI/SCSI 机芯下发低层扇区读取指令。通过在数据流起始处放置 44 字节的 RIFF....CDXAfmt 头部,微软与飞利浦为该文件赋予了合法的多媒体容器身份;系统底层的 CD-XA 驱动(如 mciavi.drv 或后来的 DirectShow 滤镜)据此识别出该文件映射的是物理 Mode 2 Form 2 扇区流,进而通知硬件以 2352 字节定长格式抓取扇区数据。
在 44 字节头之后,数据区排列着连续的 2352 字节物理扇区映像。每个扇区内:
- 偏移行
0x00..0x17:24 字节扇区头部(Sync + Header + Sub-header); - 偏移行
0x18..0x92B:2324 字节纯净 MPEG-1 System Pack 数据; - 偏移行
0x92C..0x92F:4 字节 EDC 校验码。
4.1 原始光盘扇区与 AVSEQxx.DAT 文件封装的层次差异
在工程实现中,必须严格区分两个不同的数据层次:
- 直接读取物理光盘或 raw image(如 BIN/CUE、物理机芯): 此时播放器直接处理 CD-ROM XA Mode 2 Form 2 的 2352 字节原始物理扇区。每个扇区包含 24 字节同步与子头(Sync 12B + Header 4B + Sub-header 8B)、2324 字节 MPEG 净荷与 4 字节 EDC 校验。解复用器需要按 2352 字节定长步进并剥离头尾。
- 操作系统通过 ISO 9660 文件系统访问
AVSEQxx.DAT: 操作系统暴露出的.DAT文件属于文件层抽象。通常它是在数据起始处放置了 44 字节的伪 RIFF CD-XA 容器头,用于向早期多媒体扩展声明轨道属性。而在某些虚拟光驱或转换工具中,它甚至可能已经被底层过滤为剥除扇区头的纯字节流。
因此,播放引擎在设计底层读取管道时,需要根据输入源是“原始物理扇区流”还是“已挂载文件系统的容器流”采取不同的分流策略。
此外,在解复用 MPEG-1 Program Stream 时还存在流标识(Stream ID)的细节差异:常规连续视频轨道(如 AVSEQxx.DAT)中的视频流 ID 固定为标准定义的 0xE0;但正如后续分析 VCD 2.0 静止画面时所见,/SEGMENT/ 中的独立静止画会采用 0xE1 或 0xE2。通用解码管道若只监听 0xE0,将无法正常显示这些画面,需要在解复用层实现统一的映射转换。
本文配套播放器目前走的是挂载文件流路径:它从已挂载卷或已解压目录读取 .DAT 文件,识别 RIFF / CDXA 头后按 2352 字节步进取出 2324 字节载荷;遇到已经是 Program Stream 的输入则直接透传。它没有把 BIN/CUE、ISO 或物理设备作为原始扇区输入,也没有在这一层重算 EDC。这是有意识的兼容性边界,不应与白皮书定义的完整物理读取流程混为一谈。
5. ENTRIES.VCD:物理入口点与时间码换算
VCD 1.0 仅支持单一视频流从头至尾线性播放。1993 年底发布的 VCD 1.1 规范在 VCD/ 目录下增加了 ENTRIES.VCD 文件,用于记录章节入口点。
ENTRIES.VCD 占用一个 2048 字节的数据扇区。白皮书规范定义的头部字节布局如下:
#[repr(C, packed)]
pub struct EntriesVcdHeader {
pub id: [u8; 8], // 固定为 "ENTRYVCD"
pub version: u8, // 0x01 表示 VCD 1.1, 0x02 表示 VCD 2.0
pub system_profile: u8, // 系统配置文件标记 (System Profile Tag,通常为 0x00)
pub entry_count: u16, // 已定义的有效入口点总数 (大端序,最大通常为 500)
}
#[repr(C, packed)]
pub struct EntryRecord {
pub track_number: u8, // 轨道号 (Track 2..99)
pub minute_bcd: u8, // 分钟 (BCD 编码)
pub second_bcd: u8, // 秒钟 (BCD 编码)
pub frame_bcd: u8, // 帧号 (BCD 编码, 0..74)
}
时间码使用 BCD(Binary-Coded Decimal)格式存储。例如时间码为 14 分 28 秒 52 帧,在文件中的三个字节存储为 0x14 0x28 0x52。
将 BCD 时间码换算为绝对扇区逻辑块地址(LBA)的计算公式如下:
fn bcd_to_u8(val: u8) -> u32 {
((val >> 4) * 10 + (val & 0x0F)) as u32
}
fn msf_to_lba(minute_bcd: u8, second_bcd: u8, frame_bcd: u8) -> Option<u32> {
let m = bcd_to_u8(minute_bcd);
let s = bcd_to_u8(second_bcd);
let f = bcd_to_u8(frame_bcd);
// 1 分钟 = 60 秒,1 秒 = 75 帧;绝对 MSF 的 00:02:00 对应 LBA 0。
// 小于该值不是可换算的用户数据 LBA。
((m * 60 + s) * 75 + f).checked_sub(150)
}
这里的 mm:ss:ff 是光盘地址,换算为 LBA 时必须先确认它是包含 2 秒引导偏移的绝对 MSF。播放器当前保留并展示解析后的 MSF 和秒数,未把 ENTRIES.VCD 直接用于底层 LBA 寻道;上面的函数用于解释这两种地址体系的关系。
通过入口点对照表,播放机可以快速定位曲目或章节。一个 MPEG 音视频轨至少要有一个入口点,轨内还可以加入额外入口点,因而卡拉 OK 光盘也能把较长轨道拆成可直选的片段。
6. 小结与演进瓶颈
VCD 1.0 与 1.1 的整套系统定义紧凑:通过 CD-ROM XA Mode 2 Form 2 最大化扇区载荷,配合 MPEG-1 SIF 恒定码率压缩,在 1.4 Mbps 带宽内完成了视频回放。
然而,VCD 1.1 的交互能力受限:
- 缺少屏幕选单机制,用户必须借助纸质印刷歌本输入曲目序号;
- SIF 352 × 288 的分辨率在显示密集文本目录时边缘模糊;
- 播放流程固定,不支持条件跳转或多级分支。
为了解决图形界面与交互逻辑的缺失,1995 年公布的 VCD 2.0 白皮书规范引入了 Playback Control(PBC)机制。下一篇文章将分析 LOT.VCD 与 PSD.VCD 的二进制结构及有限状态机调度。