6 PES包格式
标准的传输流包语法如表1所述。
表1
Stream_id | '1011 1101' 标示 "private_stream_1" |
PES_packet_length |
|
data_alignment_indicator | 设为1表示subtitle分段使用PES包对齐 |
Presentation_Time_Stamp of subtitle |
|
PES_packet_data_byte | 这些字节的编码和下面的PES_data_field保持一致 |
7 subtitle的PES包数据
7.1 subtitle 的PES_data_filed语法
Syntax | Size | Type |
PES_data_field() { |
|
|
data_identifier | 8 | bslbf |
subtitle_stream_id | 8 | bslbf |
while nextbits() == '0000 1111' { |
|
|
Subtitling_segment() |
|
|
} |
|
|
end_of_PES_data_field_marker | 8 | bslbf |
} |
|
|
Data_identifier: subtitling的数据该值应该设为0x20
Subtitle_stream_id:该字段标示存储在PES中的subtitle流。Subtitling数据该值应为0x00
end_of_PES_data_field_marker: 一个8位的字段,值为: '1111 1111'.
7.2 subtitling分段的语法和语义
Subtitling流的基本语法元素是“segment”。它构成了subtitling规范中个元素的通用的格式。
Syntax | Size | Type |
Subtitling_segment() { |
|
|
sync_byte | 8 | bslbf |
segment_type | 8 | bslbf |
page_id | 16 | bslbf |
segment_length | 16 | uimsbf |
segment_data_field() |
|
|
} |
|
|
Sync_byte:值固定为'0000 1111'的8位字段,目的在于允许解码过程进行同步检测
Segment_type:该值标识了segment_data_filed包含的数据类型。表2显示了subtitling规范中定义的segment_type的值。
表2
0x10 | 页构成分段Page compostion segment |
|
0x11 | 区域构成分段 region composition segment |
|
0x12 | CLUT 定义分段 |
|
0x13 | 对象数据分段 object data segment |
|
0x40-0x7F | 供未来使用 |
|
0x80-0xEF | 私有数据 |
|
0xFF | 填充stuffing |
|
其他值 | 供未来使用 |
|
Page_id :该字段标识了subtitling_segment被包含的页。
Segment_length:该字段表示该字段后直到subtitling_segment结束的字节的数量
Segment_data_field:segment的负载。不同的分段类型语法不同。
注释:
一个subtitling显示是由最多两页的信息构成的;它们是PMT中的subtitle_descriptor中由composition_page_id和ancillary_page_id定义的。
composition_page_id标识了构成页;它至少包含了顶层数据结构的定义,即也构成分段(page_composition_segment)。这种页可能额外包含subtitling显示所需的其他段的数据。构成页中的分段可能会引用辅助页中的分段,但是它们(构成页中的分段)仅能被同一个组成页中的分段引用。
ancillary_page_id标识了一个可选的辅助页;它包含可能在不同subtitle显示中使用的分段。它不包含page_composition_segment。辅助页中的分段仅能引用该页中的分段,但是它们可以被其他(composition)页引用。因此,一个辅助页可能会包含很多不会被特殊页构成使用的分段。
7.2.1 页构成分段
Syntax | Size | Type |
page_composition_segment() { |
|
|
Sync_byte【0x0F】 | 8 | bslbf |
Segment_type【0x10】 | 8 | bslbf |
Page_id | 16 | bslbf |
Segment_length | 16 | uimsbf |
Page_time_out | 8 | uimsbf |
Page_version_number | 4 | uimsbf |
Page_state | 2 | bslbf |
reserved | 2 | bslbf |
While(processed_length < segment_length){ |
|
|
Region_id | 8 | bslbf |
reserved | 8 | bslbf |
Region_horizontal_address | 16 | uimsbf |
Region_vertical_address | 16 | uimsbf |
} |
|
|
} |
|
|
Page_time_out:以秒为单位的时间,在该时间后该page不再有效因此应该从屏幕擦除,在这之前期不应该被重新定义。Time_out计时从第一次收到page_composition_segment开始。如果有相同的版本号的相同分段再次被收到,time-out计时不应该重新计算。Time-out的目的是为了避免如果IRD碰巧丢失了page的冲定义或者删除信息而造成该page长时间存留在屏幕上的情况。IRD对time-out不需要计时的十分精确,-0/+5秒都是可以的。
Page_version_number:分段数据的版本号。该段的内容的任何变化,版本号都会增加(模16)。
Page_state:该字段表示页组合分段中和subtitling页描述相关联的内存规划的状态。Page_state的值定义在下面的表中:
表3
00 | Normal case | 页组合分段后跟着不完整的region集合 |
01 | Acquisition point | 页组合分段后跟着完整的region集合,描述当前的内存规划 |
10 | Mode change | 页组合分段后跟着regions,描述一个新的内存规划 |
11 | reserved | 保留 |
Processed_length:从该字段起包含while循环在内需要解码器处理的字节数。
Region_id: 页中唯一标识一个区域的元素。所有的region都应该按照region_vertical_address字段中的顺序排列在页组合分段中。每个region在页中都有一个唯一的ID。
region_horizontal_address: 该字段指定了region的左上角像素的水平地址。720个有效像素的最左像素的索引值为0,且像素索引从左向右递增。地址的水平地址应该小于720.
region_vertical_address: 该字段指定了region的顶行的垂直地址。720x576帧的顶行是0行,且行的索引在帧内从上到下依次增加。垂直地址的值应该小于576。
注释:
所有的像素的地址都是基于720x576扫描线的。数值和图象的长宽比无关;在16:9的显示中一个详述要比4:3的看起来宽一些。在某些情况下,对一个logo实例来说,这可能导致无法接受的变形。独立的数据可能会用来为不同的长宽比提供描述。Subtitle_descriptor表示是否一个subtitle数据流可以显示在任意的显示器上或者只能显示在特定长宽比的显示器上。
7.2.2 区域构成分段
Syntax | Size | Type |
region_composition_segment() { |
|
|
Sync_byte【0x0F】 | 8 | bslbf |
Stream_type【0x11】 | 8 | bslbf |
Page_id | 16 | bslbf |
Segment_length | 16 | uimsbf |
Region_id | 8 | uimsbf |
Region_version_number | 4 | uimsbf |
Region_fill_flag | 1 | bslbf |
reserved | 3 | bslbf |
Region_width | 16 | uimsbf |
Region_height | 16 | uimsbf |
Region_level_of_compatibility | 3 | bslbf |
Region_depth | 3 | bslbf |
reserved | 2 | bslbf |
CLUT_id | 8 | bslbf |
Region_8-bit_pixel_code | 8 | bslbf |
Region_4-bit_pixel_code | 4 | bslbf |
Region_2-bit_pixel_code | 2 | bslbf |
reserved | 2 | bslbf |
While(processed_length<segment_length){ |
|
|
Object_id | 16 | bslbf |
Object_type | 2 | bslbf |
Object_provider_flag | 2 | bslbf |
Object_horiziontal_position | 12 | uimsbf |
reserved | 4 | bslbf |
Object_vertical_position | 12 | uimsbf |
If(object_type ==0x01 or object_type == 0x02){ |
|
|
foreground_pixel_code | 8 | bslbf |
background_pixel_code | 8 | bslbf |
} |
|
|
} |
|
|
} |
|
|
Region_id: 该8位字段唯一表示了一个region,该region的信息包含在这个region构成分段中。
Region_version_number:该字段指示分段数据的版本号。该分段内容的任何变化,除了lower_level_change_flag,都会使得版本号增加(模16)。
region_fill_flag: 如果设置为1,表示region中的所有object都被设置为固定的值。
region_width:表示region的宽度,水平像素的值。该字段的值应该在1到720之前,且region_width和region_horizontal_address的和不应该超过720.
region_height:表示region的高度,垂直扫描线的值。该字段的值应该在1到576之前,且region_height和region_vertical_address的和不应该超过576.
region_level_of_compatibility: 该值表示解码器解码该region所需的CLUT的最小类型
表4
0x01 | 2比特的CLUT条目 |
0x02 | 4比特的CLUT条目 |
0x03 | 8比特的CLUT条目 |
注意:其他值保留 |
如果解码器不支持该字段指示的CLUT类型,那么这个独立region中的像素数据不应该可见,及时其他一些需要更低的CLUT类型可能会被呈现。
Region_depth:标识该region可以使用的最大的像素深度
CLUT_id:标识供该region使用的CLUT族
region_8-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的256色的像素编码
region_4-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的16色的像素编码
region_2-bit_pixel-code:标识当region_fill_flag被设置时,供给region使用的4色的像素编码
processed_length:表示
object_id:标识region中显示的一个object
object_type:标识object的类型
表5
0x00 | 基本类型,位图 |
0x01 | 基本类型,字符 |
0x02 | 组合对象,字符串 |
0x03 | 保留 |
object_provider_flag: 一个2比特的标识,表示object的来源
表6
0x00 | 来自subtitling流 |
0x01 | 来自IRD的ROM |
0x02 | 保留 |
0x03 | 保留 |
object_horizontal_position: 指定object的水平位置,单位为像素,相对于相关联的region的左边缘
object_vertical_position: 指定object的垂直位置,单位为扫描线,相对于相关联的region的顶部
foreground_pixel_code:标识定义字符的前景色的8_bit_pixel_code(CLUT 条目)
background_pixel_code:标识定义字符的背景色的8_bit_pixel_code(CLUT 条目)
注释:
只有4条目或16条目的CLUT的IRD通过在第九章中描述的方式查找前景色和背景色。
7.2.3 CLUT定义分段
Syntax | Size | Type |
CLUT_definition_segment() { |
|
|
Sync_byte【0x0f】 | 8 | bslbf |
Segment_type【0x12】 | 8 | bslbf |
Page_id | 16 | bslbf |
Segment_length | 16 | uimsbf |
CLUT-id | 8 | bslbf |
CLUT_version_number | 4 | uimsbf |
Reserved | 4 | bslbf |
while (processed_length < segment_length) { |
|
|
CLUT_entry_id | 8 | bslbf |
2-bit/entry_CLUT_flag | 1 | bslbf |
4-bit/entry_CLUT_flag | 1 | bslbf |
8-bit/entry_CLUT_flag | 1 | bslbf |
reserved | 4 | bslbf |
Full_range_flag | 1 | bslbf |
if (full_range_flag =='1') { |
|
|
Y-value | 8 | bslbf |
Cr-value | 8 | bslbf |
Cb-value | 8 | bslbf |
T-value | 8 | bslbf |
}else{ |
|
|
Y-value | 8 | bslbf |
Cr-value | 4 | bslbf |
Cb-value | 4 | bslbf |
T-value | 2 | bslbf |
} |
|
|
} |
|
|
} |
|
|
CLUT-id:唯一标识在CLUT_definition_segment中包含的CLUT组数据
CLUT_version_number:表示该分段数据的版本。该分段任何内容的修改都会引起版本号增加(模16)
Processed_length:while循环中已经被解码器处理的数据的字节数
CLUT_entry_id:指定CLUT的条目号。CLUT第一个条目号码为0。
2-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识2-bit/entry CLUT的条目
4-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识4-bit/entry CLUT的条目
8-bit/entry_CLUT_flag: 如果设置为‘1’,表示该CLUT值将被用于标识8-bit/entry CLUT的条目
full_range_flag: 如果设置为‘1’,表示Y_value,Cr_value,Cb_value和T_value字段为8比特方案。如果设置为‘0’,这些字段进包含最重要的比特位。
Y_value:该条目中CLUT的Y(亮度)输出值。Y_value值为0表示完全透明。这种情况下,Cr_value,Cb_value和T_value的值就没用用了,应该被设置为0。
Cr_value:该条目中CLUT的Cr(色调)输出值。
Cb_value:该条目中CLUT的Cb(饱和度)输出值。
注释1:
Y,Cr,Cb的含义定义在ITU-R文档中。
T_value:该条目中CLUT的透明度输出值。值为0表示不透明。最大值正1对应着完全透明。其他值的透明度为线性差值定义。
全透明通过Y_value设置为0值获得。
注释2:
将像素编码转换为Y,Cr,Cb和T值的解码器模型在第九章中描述。默认的CLUT内容在第十章中给出。
注释3:
所有的CLUT可以被重定义。不需要所有的CLUT固定为像第十章中给出的一样的默认内容。
7.2.4 对象数据分段
Sytax | Size | Type |
object_data_segment() { |
|
|
Sync_byte 【0x0F】 | 8 | blsbf |
Segment_type 【0x13】 |
|
|
Page_id |
|
|
Segment_length |
|
|
Object_id |
|
|
Object_version_number |
|
|
Object_coding_method |
|
|
Non_modifying_colour_flag |
|
|
reserved |
|
|
if (object_coding_method == '00'){ |
|
|
top_field_data_block_length |
|
|
bottom_field_data_block_length |
|
|
while(processed_length<top_field_data_block_length) |
|
|
pixel-data_sub-block() |
|
|
while(processed_length<bottom_field_data_block_length) |
|
|
pixel-data_sub-block() |
|
|
if (!wordaligned()) |
|
|
8_stuff_bits |
|
|
} |
|
|
if (object_coding_method == '01') { |
|
|
number of codes |
|
|
for (i == 1, i <= number of codes, i ++) |
|
|
character_code |
|
|
} |
|
|
} |
|
|
object_id:标识object_data_segment中的object数据
object_version_number: 表示segment数据的版本。该分段任何内容的变化,版本号都会增加(模16)
object_coding_method:指示用于object编码的方法。
表7
0x00 | 像素编码 |
0x01 | 字符串编码 |
0x02 | 保留 |
0x03 | 保留 |
non_modifying_colour_flag: 设置为‘1’的话表示CLUT条目值‘1’是一个非修改的颜色。意味着其不应该覆盖任何底层的object。
top_field_data_block_length: 表示随后顶部区域包含的data_sub-blocks的字节数。
bottom_field_data_block_length: 表示随后底部区域包含的data_sub-blocks的字节数。
processed_length:while循环中已经被解码器处理的数据的字节数
8_stuff_bits: 8填充位,应该如‘0000 0000’一样编码。
一个object的顶部区域和底部区域的像素数据子块都应该在相同的的object_data_segment中传输。如果一个segment没有携带底部区域数据,即,bottom_field_data_block_length值为“0x0000”,这时,顶部区域的数据对底部区域来说应该也是有效的。
number_of_codes:表示字符串中编码字符的数量
character_code:表示通过定义在subtitle_descriptor中的字符表的索引来标示一个字符。每个队字符表的引用被看做是一个单独的字符编码,即使最终的字符是没有空间的。例如,浮动音标就被当做独立的字符编码。
7.2.4.1 Pixel-data sub-block
Syntax | Size | Type |
pixel-data_sub-block() { |
|
|
Sync_byte【0X0F】 | 8 | bslbf |
Segment_type【】 | 8 | bslbf |
Page_id | 16 | bslbf |
Segment_length | 16 | uimsbf |
Data_type | 8 | bslbf |
if data_type =='0x10' { |
|
|
Repeat{ |
|
|
2-bit/pixel_code_string() |
|
|
}until (end of 2-bit/pixel_code_string) |
|
|
While((!bytealigned()) |
|
|
2_stuff_bits | 2 | bslbf |
} |
|
|
if data_type =='0x11' { |
|
|
Repeat{ |
|
|
4-bit/pixel_code_string() |
|
|
}until (end of 4-bit/pixel_code_string) |
|
|
While((!bytealigned()) |
|
|
4_stuff_bits | 4 | bslbf |
} |
|
|
if data_type =='0x12' { |
|
|
Repeat{ |
|
|
4-bit/pixel_code_string() |
|
|
}until (end of 4-bit/pixel_code_string) |
|
|
} |
|
|
if data_type =='0x20' |
|
|
2_to_4-bit_map-table | 16 | bslbf |
if data_type =='0x21' |
|
|
2_to_8-bit_map-table | 32 | bslbf |
if data_type =='0x22' |
|
|
4_to_8-bit_map-table | 128 | bslbf |
} |
|
|
Data_type: 标识包含在data_sub-block中的信息的类型。
表8
0x10 | 2比特像素编码串 |
0x11 | 4比特像素编码串 |
0x12 | 8比特像素编码串 |
0x20 | 2_to_4比特映射表数据 |
0x21 | 2_to_8比特映射表数据 |
0x22 | 4_to_8比特映射表数据 |
0xF0 | Object行编码结束 |
NOTE:其他值保留 |
‘0x0F’编码应该被包含在每一些列编码串之后,来表示一个object的一个扫描行。
2_to_4-bit_map-table:说明通过列出4个4比特条目如何将2bit/pixel编码映射到4bit/pixel的CLUT条目上。条目号0是第一个,3是最后一个。
2_to_8-bit_map-table:说明通过列出4个8比特条目如何将2bit/pixel编码映射到8bit/pixel的CLUT条目上。条目号0是第一个,3是最后一个。
4_to_8-bit_map-table:说明通过列出16个8比特条目如何将4bit/pixel编码映射到8bit/pixel的CLUT条目上。条目号0是第一个,15是最后一个。
2_stuff_bits: 2填充位编码为‘00’
4_stuff_bits: 4填充位编码为‘0000’
7.2.4.2 Syntax and semantics of the pixel code strings 像素编码串的语法
Syntax | Size | Type |
2-bit/pixel_code_string() { |
|
|
if (nextbits() != '00') { |
|
|
2-bit_pixel-code | 2 | bslbf |
} else { |
|
|
2-bit_zero | 2 | bslbf |
Switch_1 | 1 | bslbf |
if (switch_1 == '1') { |
|
|
run_length_3-10 | 3 | uimsbf |
2-bit_pixel-code | 2 | bslbf |
}else{ |
|
|
Switch_2 | 1 | bslbf |
if (switch_2 == '0') { |
|
|
Switch_3 | 2 | bslbf |
if (switch_3 == '10') { |
|
|
run_length_12-27 | 4 | uimsbf |
2-bit_pixel-code | 2 | bslbf |
} |
|
|
if (switch_3 == '11') { |
|
|
run_length_29-284 | 8 | uimsbf |
2-bit_pixel-code | 2 | bslbf |
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
2-bit_pixel-code: 一个2比特编码,表示一个像素的伪色彩是一个有四个条目的CLUT的一个条目号或者一个映射表的一个条目号
2-bit_zero: 即‘00’
switch_1:一个1比特开关,表示后面字段数据的含义
run_length_3-10: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.
switch_2: 一个1比特开关,如果设为‘1’,表示这个像素应该被设置为伪色彩‘00’,否则其表示后面存在数据域。
switch_3: 一个2比特开关,含义如下:
表9
00 | 2-bit/pixel_code_string的结尾 |
01 | 两个像素应该设置为伪色彩‘00’ |
10 | 接下来的6比特包含补偿编码像素数据 |
11 | 接下来的10比特包含补偿编码像素数据 |
run_length_12-27: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于12.
run_length_29-284:应该被设为下面定义的伪色彩的像素数量。该值不应该小于29.
Syntax | Size | Type |
4-bit/pixel_code_string() { |
|
|
if (nextbits() != '0000') { |
|
|
4-bit_pixel-code | 4 | bslbf |
} else { |
|
|
4-bit_zero | 4 | bslbf |
Switch_1 | 1 | bslbf |
if (switch_1 == '0') { |
|
|
if (nextbits() != '000') |
|
|
run_length_3-9 | 3 | uimsbf |
else |
|
|
end_of_string_signal | 3 | bslbf |
}else{ |
|
|
Switch_2 | 1 | bslbf |
if (switch_2 == '0') { |
|
|
run_length_4-7 | 2 | bslbf |
4-bit_pixel-code | 4 | bslbf |
}else{ |
|
|
switch_3 | 2 | bslbf |
if (switch_3 == '10') { |
|
|
run_length_9-24 | 4 | uimsbf |
4-bit_pixel-code | 4 | bslbf |
} |
|
|
if (switch_3 == '11') { |
|
|
run_length_25-280 | 8 | uimsbf |
4-bit_pixel-code | 4 | bslbf |
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
4-bit_pixel-code:一个4比特编码,表示一个像素的伪色彩是一个有四个条目的CLUT的一个条目号或者一个映射表的一个条目号
4-bit_zero: 即‘0000’
switch_1: 一个1比特开关,表示后面字段数据的含义
run_length_3-9:应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.
end_of_string_signal: 一个值为‘000’的3比特字段。该字段的出现,即nextbits() == '000'表示4-bit/pixel_code_string的结尾。
switch_2: 一个1比特开关,如果设为‘0’,表示后面的6bie包含游程编码像素数据,否则其表示后面存在数据域。
switch_3: 一个2比特开关,含义如下:
表10
00 | 1 pixel shall be set to pseudo-colour (entry) '0000' |
01 | 2 pixels shall be set to pseudo-colour (entry) '0000' |
10 | 接下来的8比特包含游程编码像素数据 |
11 | 接下来的12比特包含游程编码像素数据 |
run_length_9-24: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于9.
run_length_25-280: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于25.
Syntax | Size | Type |
8-bit/pixel_code_string() { |
|
|
if (nextbits() != '0000 0000') { |
|
|
8-bit_pixel-code | 8 | bslbf |
}else{ |
|
|
8-bit_zero | 8 | bslbf |
switch_1 | 1 | bslbf |
if switch_1 == '0' { |
|
|
if nextbits() != '000 0000' |
|
|
run_length_1-127 | 7 | uimsbf |
else |
|
|
end_of_string_signal | 7 | bslbs |
}else{ |
|
|
run_length_3-127 | 7 | uimsbf |
8-bit_pixel-code | 8 | bslbf |
} |
|
|
} |
|
|
} |
|
|
8-bit_pixel-code: 一个8比特编码,表示一个像素的伪色彩,是有256个条目的CLUT中的一个条目
8-bit_zero:即‘0000 0000’
switch_1: 一个1比特开关,表示后面字段数据的含义
run_length_1-127:应该被设为下面定义的伪色彩的像素数量 '0x00'.
end_of_string_signal:一个值为‘000 0000’的3比特字段。该字段的出现,即nextbits() == '000 0000'表示8-bit/pixel_code_string的结尾。
run_length_3-127: 应该被设为下面定义的伪色彩的像素数量。该值不应该小于3.