ISDBT中CC的处理疑问

一个针对日本的数字电视应用(ISDBT)里字幕处理有一些问题,规范文档庞大又复杂,读起来还以为语焉不详。接手遗留项目尝试处理字幕显示的问题,边读spec边看代码,先猜想、试图理解既有逻辑,再分析问题产生的缘由,寻找解决方案。git

文档是ARIB STD-B24 Version 5.1 Volume 1(Data Coding and Transmission Specification for Digital Broadcasting)。文档中出现的"02/0"表示0x20,"07/15"表示0x7F。ide

1. 一个data group里的多个data unit
按照规范文档定义(见文档的Table 9-1 Data group),一个字幕数据(one caption data)最多由256个data groups组成。data group结构里有6位的group id,2位的group version,8位的group link number(从0开始),8位的last group link number(标明最后一个group)。但实际上绝少见到一个data group放不下的字幕数据。目前的实现只考虑了一个data group。
在此输入图片描述测试

根据group id,group能够分为caption management group和caption statement group(见文档的Table 9-2 Correspondence to caption data and data group identification),这两类data group结构都在最后包含了若干个data unit(见文档的Table 9-3 Structure management data和Table 9-10 Caption statement data)。
在此输入图片描述 在此输入图片描述字体

观察码流发现,大部分状况一个data group里只有一个data unit,但仍是不止一次地看到同一个data group里有两个data unit。出现这种状况时,第一个data unit都是0x0C开始、包含字体大小、颜色和字符编码的数据(data unit的不一样类型参见文档的Table 9-12 Types of data unit,这里只讨论0x20,即statement body),第二个data unit都是一个TIME命令(9D 20 XX 0C,这里是十六进制表示,下同)。以前的实现假设一个data group里若是有多个data unit,每一个data unit也都是0x0C开始、包含字体大小、颜色和字符编码的数据,若是只有命令而没有字符编码数据则会被丢弃。
在此输入图片描述 在此输入图片描述this

怎么理解只有TIME命令的data unit?目前只能认为是补充前一条data unit(0x0C开始、包含字体大小、颜色和字符编码的数据)。编码

观察码流还发现另外一种情形,data group里只有一个data unit,这个data unit的数据也只有一个0x0C。前面一直没有提到0C命令,这里讨论一下。在文档的Table 7-14 Control function character set code table中能够看到,0C是清屏命令(CS),Table 7-15 C0 control set中定义为“Display area of the display screen is erased”。在以前的实现里,没有字符数据的data unit都被丢弃了。但是为何会送出一个单独的0x0C呢?在某一个码流里还看到连续两个这样的data group,只有一个data unit,里面只有一个0x0C。
在此输入图片描述code

根据0C的定义,咱们能够这样理解每个包含字符数据的data unit,0x0C开头意即清除上一条字幕,开始准备显示当前字幕。TIME命令后若是跟随0x0C(9D 20 XX 0C),意即presentation了duration的时间后清除(TIME命令的分析见下文)。单独的一个0x0C是否是意味着,没有要显示的字幕,但也要清除上一条字幕呢?目前只能这样去实现了。orm

2. caption management group中是否有DC
经过解析DMF(display mode)来判断DMF以后是否有一个单字节的DC(display condition designation)(见文档的Table 9-3 Structure management data),文档的Table 9-5 Display mode和Table 9-6 Designation of display condition解释了DMF和DC,可仍是没看懂DC。观察码流,DMF的值老是10(十进制),按照规范文档定义,DMF等于十二、13或14时,后一个字节是DC。视频

3. TIME命令
按照文档“ARIB STD-B24 Version 5.1 Volume 1”的解释,9D是TIME命令(见文档的Table 7-14 Control function character set code table),在Table 7-16 C1 control set中定义了三种状况,观察测试用的一些码流,状况(1)最多见,即"TIME 02/0 P2",状况(5)"TIME 02/8 P2"和状况(6)"TIME 02/9"很少见,这里只分析状况(1)。三种状况的解释请见下面的注释代码段。队列

"TIME 02/0 P2"的命令模式意味着遇到9D 20 XX这个模式,取出XX的低6位做为P2,P2设置字幕显示的duration时间,单位是0.1秒,取值范围是从0x40到0x7F。

观察实际的码流,最多见到的命令模式是9D 20 XX 0C。也比较好理解,即当前字幕显示P2/10.0秒以后清屏。以前的实现把0C做为该模式之必要。

但是,在某一个码流里发现这样的状况:9D 20 7F 9D 20 7F 9D 20 7F 9D 20 44 0C。按照以前的处理逻辑,第一组9D 20的P2后不是0C,因而放弃把9D看成TIME命令来处理,跳过9D,继续解析20和7F(20会被做为空格处理,7F本是删除,这里忽略不做处理),直到最后一个9D,能找到那个0C,才会把44取出来计算P2,而计算出来的duration时间是0.4秒。

这很奇怪,0.4秒的presentation时间让人几乎没法看清,这字幕就没有意义了。规范文档里没有提到连续屡次送来TIME 02/0命令该如何解析。连续几天没有想出因此然,忽然有一天在反复阅读规范文档时想到,会不会是累加。由于P2的取值范围是0x40到0x7F,0x7F表示6.3秒,若是须要表达大于6.3秒的duration时间,岂不是须要累加表示。若是是这样,连续的9D 20命令模式中除最后一个外,前面的P2都应该是7F,这须要观察更多码流文件来验证,如今不具有这个条件。若是这样理解,咱们发现的这个状况中,duration时间应该是19.3秒。

<!-- lang: cpp -->
     	/* TIME, Table 7-15 C0 control set
    (1) Wait for process: TIME 02/0 P2
	Processing of code as of this code is stopped for set duration by parameter
	P2. Parameter P2 is in the range of 04/0 to 07/15 and set by binary of 6 bit
	from b6 to b1. (b7 and b8 are not used.) Designating time should be 0.1 sec.
    (5) Time control mode(TMD): TIME 02/8 P2
       TIME 02/8 04/0: Free
       TIME 02/8 04/1: Real
       TIME 02/8 04/2: Offset
       TIME 02/8 04/3: Unique
    (6) Presentation start time(STM), Playback time(DTM), Offset time(OTM),
       Performance time(PTM), Display end time(ETM):
       TIME P P11-P1i I1 P21-P2j I2 P31-P3k I3 P41-P4m I F
		P = 02/9 I = 02/0 I1-I3 = 03/11
		P11-P1i = 03/0-03/9 (decimal)time
		P21-P2j = 03/0-03/9 (decimal)minute
		P31-P3k = 03/0-03/9 (decimal)second
		P41-P4m = 03/0-03/9 (decimal)millisecond
		F = 04/0 STM, DTM
			04/1 OTM
			04/2 PTM
			04/3 ETM
       At performance time, I3, P41 --- P4m is not sent out.*/

4. 多行显示字幕
字符编码数据中若是遇到0x0D,认为是要换行,多数码流里用0D命令来显示人物对话,譬如电影电视剧中AB两人的对话,通常0D先后的字幕还会用不一样的颜色显示。

还有一种状况须要换行,即根据data unit中的字体大小设定、或者应用自己的设置,视频画面的宽度不够在一行里显示全部字符,须要作截断换行处理。以前的实现对字幕显示位置作了限制,只能显示两行字幕,因而当第一行字幕(0xOD前)须要截断换行时,本该显示的第二行(0x0D)字幕就没法显示了。目前调整为放宽限制至三行。若是0x0D先后的字符数据都有点长、须要截断换行,0x0D后的字幕将会被截断,只能部分显示。

5. 清除字幕的判断条件
字幕显示的时间能够用音视频同步的参考时钟来和视频同步,字幕数据也来自PES包,有本身的pts(presentation time stamp)。可是因为未知缘由,咱们获取到字幕数据时,其pts已经落后于参考时钟。也就是说,老是晚一步贴字幕。这个问题还没有解决。

目前的处理逻辑是,获取到字幕数据,转成图片,肯定往视频帧上贴图的位置,放到队列里,渲染视频帧时若是字幕队列里有内容(read index),取出来比较其pts和参考时钟,该显示了就贴图,而后看该字幕是否有上文提到的duration信息(9D 20 XX),若是有,将其pts加上duration后和参考时钟比较,若是过时就清除。

仅仅这样还不够,若是当前字幕没有duration信息怎么办?观察码流发现,不少场景字幕不带有duration信息,咱们猜想认为,这种状况下是要依赖下一条将要显示的字幕到了该显示的时间来取代当前字幕,至关于为其清屏(每条字幕都是0C开头)。所以,不带有duration信息的字幕将一直显示,直到其下一条字幕须要显示了。

这种场景的典型例子就是一人或多人不停地说话,后一条字幕替换前一条。如此猜想,也包含这样一个假定,若是这样集中的说话或对话结束了,接下来无人说话或者干脆插播广告,最后一条字幕是必定会带有duration信息的。若是没有,这条字幕将一直显示着。以前咱们的实现常常错误地丢弃了duration信息,就出现这样的问题,补丁方案是对没有duration信息的字幕,赋默认值3秒。如今去掉了这个补丁,由于它会影响下一条字幕的显示。

这又带来一个问题,若是当前字幕的duration时间比较长,譬若有10秒,而期间下一条字幕的pts已经到了该显示的时间。谁的优先级高?目前的实现是当前字幕的duration优先级高。

前面提到过,有单独的data unit,而且只有一个0x0C,而这个0x0C也有pts,这又意味着什么?目前的实现是清屏(即贴这个空字幕)时间要看0x0C的pts,而不是接受到0x0C马上清屏。

相关文章
相关标签/搜索