任务六
利用之前编写的函数,从码流中解析EIT表,主要是获取对应的service_id和EPG标题,时间段等。
相关知识
简述
EIT表按照时间顺序提供每一个业务所包含的事件信息,是事件信息表的简称,它是EPG中绝大部分信息的携带者。我们看电视的时候,节目预告之类的内容,就是通过这个表来获取的。另外,EIT主要的信息是通过插入的描述符来实现的。根据table_id的不同,一共分为四类EIT表
传输流 | 信息 | table_id |
---|---|---|
当前TS流 | 当前/后续事件信息 | 0x4E |
其他TS流 | 当前/后续事件信息 | 0x4F |
当前TS流 | 事件时间信息 | 0x50-0x5F |
其他TS流 | 事件时间信息 | 0x60-0x6F |
相同的EIT子表具有相同的transport和original_stream_id
EIT表结构
在这里,需要重点关注的字段有
start_time:表示这个事件的开始时间是什么
duration:表示事件持续的时间,可以计算出结束时间
running:运行状态
Short event descriptor的结构
在这个描述子中,我们重点关注的字段有
ISO_639_language_code:语言代码,说明后续文本字段的语言
event_name_char:事件名称字符
text_char:文本字符,对事件的简单描述
对 EIT schedule的解释
EIT schedule用来发送大量的event信息,也就是EPG的节目单。EIT schedule 被分成16个table_id来传送,0x50-0x5F代表的是当前流的schedule,0x60-0x6F代表的是其他流的schedule,也就是说一个节目最多可以用16个字表来发送节目预告,这16个EIT是按照时间顺序排列的。
注意下,在EIT子表中引入了节(segment)的概念,刚开始接触的时候有点模糊,知道是什么,但不知道为什么,在这里简单解释是什么。
在普通的子表中分段使用段(section),每个子表语法结构中都有个8bit字段的last_section_number,用来表示一个子表由多少个段来组成。由字长我们可以看出,一个子表最多有256个段。而EIT中在子表和段中插入了一个节的层次。关于节有如下约定:
- 一个EIT子表被分成32个节
- 每个节最多有8个段
- 一个EIT子表最多有256个段
- 每个节所包含的时间信息最长不能超过3个小时
- 如果在节中小于8个段在使用,就需要 靠字段segment_ last_section_ number 标识节中有哪些有效的段。EIT 中传送的字段segment last section_number 值算法为s0+n-1。这里s0的值是节中的第一个段号,n表示该节中段的个数。举个例子:如果某个EIT子表中第二个节只包含2个段,那么在这2个段中字段segment_last_section_number的值就是:8 + 2 -1 = 9
- 节中包含所有的段,那么字段segment_last_section_number值算法为s0+7
- 如果节中包含所有的段是空段,那么字段segment_last_section_number值算法为s0+0
- EIT Table_id=0x50(或 者0x60)的第一个节包含着今天00:00-02:59:59 UTC时间的三个小时的事件信息,第二个节包含了03:00:00 and 05:59:59 UTC时间的三个小时的事件信息,依次类推下去,一个子表最多能包含4天的事件信息;
根据以上,我想就可以解释为什么在EIT ACTUAL SCHEDULE中section number的跨度为8的原因了
EIT表解析
1-流程图
2-数据结构定义
typedef struct program_time
{
int hour;
int minute;
int second;
}PROGRAM_TIME;
typedef struct event_node
{
unsigned short event_id;
unsigned char start_time[START_TIME_LEN];
unsigned char duration[DURATION_LEN];
unsigned char running_status :3;
unsigned char *event_name;
unsigned char *text;
struct event_node *next;
}EVENT_NODE;
typedef struct eit_info_node
{
unsigned short service_id;
unsigned short transport_stream_id;
unsigned short original_network_id;
struct event_node *event_link_head;
struct eit_info_node *next;
}EIT_INFO;
typedef int(*EIT_TAG_CHECK)(unsigned char tag);
3-相关代码
/*****************************************************************************
* Function Name: eit_tag_check_callback
* Description : check the eit tag type whether we want
* Parameters : unsigned char tag
* Returns : static int
* return 1 we want
* return 0 we don't
*****************************************************************************/
static int eit_tag_check_callback(unsigned char tag)
{
if(SHORT_EVENT_DESCRIPTOR_TAG == tag)
{
return 1;
}
return 0;
}
/*****************************************************************************
* Function Name: get_short_descriptor_message
* Description : get the short event descriptor message
* Parameters : SECTION *eit_actual_section
* unsigned int *eit_descriptors_read_position
* unsigned int eit_descriptors_end_position
* EVENT_NODE *new_event_node
* EIT_TAG_CHECK eit_tag_check
* Returns : static void
*****************************************************************************/
static void get_short_descriptor_messa