0%

CRI Sofdec 数据结构分析

本文最初完成于2021/07/15,原使用MediaWiki语言写就。

本文记录对CRI Sofdec格式的数据流之结构的分析结果。

除不明数据段之外的所有结构已分析完成。

CRI Sofdec简述

CRI Sofdec格式为CRI Middleware公司开发的视频中间件格式,典型扩展名为SFD。当前CRI Middleware已停止支持该格式。

该格式的数据结构为一种MPEG-1系统层(定义于ISO/IEC 11172-1)的变体。其中至少有一路MPEG-1/2视频流,可能有至少一路SFA(CRI ADX的一种变体)/AIX流,在有SFA流的同时可能有至少一路AC-3流。

CRI Sofdec结构

CRI Sofdec数据流(下简称SFD)内部有多个符合ISO/IEC 11172-1的2.4.3.2节定义的包。每个包的大小均为0x800。

其中,第00-03个包标示了SFD的各种信息,之后的包为经多路复用的音视频流。

以下所提到的各涉及原始MPEG-1结构的数据字段名均由ISO/IEC 11172所定义。

信息包组

信息包组即指SFD内部的第00-03个包(较旧版本的SFD可能缺少第03个包)。

下面列出这些包的结构。

第00个包(音频流声明包)(若无音频流,则该包不存在)

偏址 信息
0x0000 包头
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 系统头
1
2
3
4
5
6
7
8
9
10
11
12
13
system_header_start_code = default ('00 00 01 BB'[hex])
header_length = [default]
rate_bound = [mux_rate]
audio_bound = [default]
flxed_flag = '1'
CSPS_flag = '0'
system_audio_lock_flag = '0'
system_video_lock_flag = '0'
video_bound = '0 0000'
reserved_byte = default ('1111 1111')
stream_id = [default]
STD_buffer_bound_scale = '0'
STD_buffer_size_bound = '0 0000 0000 0100'
偏址 信息
0x001B + 3 * audio_bound 分组头
1
2
3
4
5
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = 'BE'[hex] (填充流)
packet_length = [default]
'0000 1111'
填充流数据(长度[packet_length])。全为 'FF'[hex] 。结束于0x07FF。

第01个包(视频流声明包)

偏址 信息
0x0000 包头
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 系统头
1
2
3
4
5
6
7
8
9
10
11
12
13
system_header_start_code = default ('00 00 01 BB'[hex])
header_length = [default]
rate_bound = [mux_rate]
audio_bound = '0000 00'
flxed_flag = '1'
CSPS_flag = '0'
system_audio_lock_flag = '0'
system_video_lock_flag = '0'
video_bound = [default]
reserved_byte = default ('1111 1111')
stream_id = [default]
STD_buffer_bound_scale = '1'
STD_buffer_size_bound = '0 0000 0010 1110'
偏址 信息
0x001B + 3 * video_bound 分组头
1
2
3
4
5
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = 'BE'[hex] (填充流)
packet_length = [default]
'0000 1111'
填充流数据(长度[packet_length])。全为 'FF'[hex] 。结束于0x07FF。

第02个包(Sofdec信息包)[版本1]

偏址 信息
未声明 填充字段。全为'00'[hex]。
0x0000 包头(长度12)
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 分组头(长度6)
1
2
3
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = 'BF'[hex] (private_stream_2, 私用流)
packet_length = [default] ( 典型值:'07 EE'[hex] )
偏址 信息
0x0020 流类型标记?长度24。恒定值。
1
2
'53 6F 66 64 65 63 53 74 72 65 61 6D 20 20 20 20 20 20 20 20 20 20 20 20'[hex]
= [SofdecStream ]
偏址 信息
0x0038 版本标记。长度8。
0x0040 SFD文件名及生成时间。
1
2
3
0x00:生成文件名。长度8。不足以空格('20'[hex])填充。
0x08:'2E 73 66 64'[hex] (".sfd")
0x0C:生成时间。长度12。YYYYMMDDhhmm。
偏址 信息
0x0060 多路复用器内部ID。长度32。示例:
1
2
3
4
'53 46 4D 20 56 65 72 2E 32 2E 32 35 20 32 30 30 34 2D 30 37 2D 32 31 20 43 52 49 2D 4D 57 20 20'[hex]
= [SFM Ver.2.25 2004-07-21 CRI-MW ]
'53 6F 66 64 65 63 20 43 52 41 46 54 2F 47 55 49 20 56 65 72 2E 31 2E 37 34 00 00 00 00 00 00 00'[hex]
= [Sofdec CRAFT/GUI Ver.1.74]
偏址 信息
0x0080 - 0x008F 不明数据段。
0x00B0 - 0x00CF 不明数据段。
0x0180 原始I/O记录。每长度64记述一条文件信息。
1
2
3
4
0x00:文件名。长度8。
0x08:后缀名。长度4。
0x0C:生成时间。长度12。YYYYMMDDhhmm。
0x18:不明数据段。

第02个包(Sofdec信息包)[版本2]

偏址 信息
未声明 填充字段。全为'00'[hex]。
0x0000 包头(长度12)
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 分组头(长度6)
1
2
3
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = 'BF'[hex] (private_stream_2, 私用流)
packet_length = [default] ( 典型值:'07 EE'[hex] )
偏址 信息
0x0020 流类型标记?长度24。恒定值。
1
2
'53 6F 66 64 65 63 53 74 72 65 61 6D 32 20 20 20 20 20 20 20 20 20 20 20'[hex]
= [SofdecStream2 ]
偏址 信息
0x0038 版本标记。长度8。
0x0040 多路复用器内部ID。长度32。
其他部分 不明数据段。

第03个包(起始地址:0x00001800,源信息包(暂称))

可确认SFM 1.61版本即有此包。记述子流的一些参数?疑似供官方播放器使用。

多路复用流包组

多路复用流包即指SFD内部信息包组以后的所有包。

这些包的顺序可能是以分组头中 'decoding_time_stamp' 字段(若不存在,则为 'persentation_time_stamp' 字段)的升序排列。没有该字段的包和后一个包捆绑排列。

下面列出这些包的结构。

音频流子包结构

偏址 信息
0x0000 包头。
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 分组头。
1
2
3
4
5
6
7
8
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = [default]
packet_length = [default] ( 典型值:'07 E7'[hex] )
'01'
STD_buffer_scale = 0
STD_buffer_size = '00000 00000100'
'0010'
presentation_time_stamp = default
偏址 信息
0x0019 包数据。结束于0x07F8。
0x07F9 补偿填充流(长度7)。'00 00 01 BE 00 01 0F'[hex]。

视频流子包结构

偏址 信息
0x0000 包头。
1
2
3
pack_start_code = default ('00 00 01 BA'[hex])
system_clock_refence = [default]
mux_rate = default
偏址 信息
0x000C 分组头。

当本组数据中第一个picture_head为 I/P图(帧)的head时:

1
2
3
4
5
6
7
8
9
10
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = [default]
packet_length = [default] ( 典型值:'07 EE'[hex] )
'01'
STD_buffer_scale = 1
STD_buffer_size = '00000 00101110'
'0011'
presentation_time_stamp = default
'0001'
decoding_time_stamp = default

当本组数据中第一个picture_head为 B图(帧)的head时:

1
2
3
4
5
6
7
8
9
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = [default] ( 典型值:'E0'[hex] )
packet_length = [default] ( 典型值:'07 EE'[hex] )
stuffing_byte ( '1111 1111' ) × 5
'01'
STD_buffer_scale = default ( '1', 对于视频流 )
STD_buffer_size = '00000 00101110'
'0010'
presentation_time_stamp = default

当本组中不存在picture_head时:

1
2
3
4
5
6
7
8
packet_start_codec_prefix = default ('00 00 01'[hex])
stream_id = [default] ( 典型值:'E0'[hex] )
packet_length = [default] ( 典型值:'07 EE'[hex] )
stuffing_byte ( '1111 1111' ) × 9
'01'
STD_buffer_scale = default ( '1', 对于视频流 )
STD_buffer_size = '00000 00101110'
'0000 1111'
偏址 信息
0x001E 包数据。结束于0x07FF。

对于每个子流的最后一个子包,在这个包的后部应当添加一个填充流分组以保持各包0x800对齐。

对于SFD的最后一个包,在这个包的后部应当添加一个以 '00 00 01 B9'[hex]
开始且其他位均为 'FF'[hex] 的,长度为0x800的数据块。

数据计算

system_clock_refence字段计算时,system_clock_frequency值应稍大于90000。

mux_rate/rate_bound字段的计算公式:1 + 0x40F38 * m1v数 + 0x471 * AC3数 + 所有SFA的basic_rate和。

其中,对于双声道SFA,其basic_rate = 1097 / 48000 * 采样率;对于采样率24000的单声道SFA,其basic_rate = 322。

音频流presentation_time_stamp字段的计算公式:该音频流包序号 * 该音频流时基。

对于AC3音频流,其时基为0xCA8;对于SFA音频流,其时基为322,560,000 / (采样率 * 声道数) 。

视频流decoding_time_stamp字段的计算公式:该包中第一个picture_head所指的图(帧)在整个视频流中的序号(位流顺序)* 该视频流时基。

视频流presentation_time_stamp字段的计算公式:该包中第一个picture_head所指的图(帧)在整个视频流中的序号(演播顺序)* 该视频流时基。

关于视频流中图(帧)的位流顺序与演播顺序的差异请参看 ISO/IEC 11172-2:1993 的D2.3节。

视频流的时基为 90000 / 该视频流的图速率(帧率)。

其他

SFA音频流与一般的ADX文件的差异:其空白填充段结束标志 ‘(c)CRI’ 在0x11A~0x11F处。

Sofdec格式文件中的AIX流一般以遵循 “Dobly Digital AIX” 的方式排布子流。

依据本文的Sofdec混流器实现已基本完成。

参考标准

ISO/IEC 11172-1:1993

GB/T 17191.1-1997 (idt ISO/IEC 11172-1:1993)

ISO/IEC 11172-1:1993/Cor.1:1996

ISO/IEC 11172-1:1993/Cor.2:1999

GB/T 17191.2-1997 (idt ISO/IEC 11172-2:1993)