您的位置:首页 > 其它

FFMpeg之 Mpeg2TS解析

2016-05-11 23:03 274 查看
TS流是由一个又一个的188(或204)字节的ts小包组成:4字节的头和184字节的数据.

4B的头:
typedef struct
{
unsigned sync_byte:8;/*8 bits的同步字节,0x47,传送包标识符*/
unsigned transport_error_indicator:1;/*1 bit的错误指示信息,1表示当前Packet至少有1bit的传输错误,0表示所有数据都正确*/
unsigned payload_unit_start_indicator:1;/*负载单元开始标志,请参考ISO13818-1了解该标志作用,置0,表示ts包不是pes,置1,有效净荷以pes包的第一个字节开始*/
unsigned transport_priority:1;/*1 bit的传输优先级标志,1表示高优先级,0表示低优先级*/
unsigned PID:13;/*13 bits的Packet ID号码,唯一的号码对应不同的包,都是什么类型下面会列出*/
unsigned transport_scrambling_control:2;/*2 bits的加密标志,00表示没有加密,其他表示已被加密*/
unsigned adaptation_field_control:2;/* 2 bits的附加区域控制,请参考ISO13818-1了解该标志作用*/
unsigned continuity_counter:4;/*4 bits的包递增计数器*/
}PACKET_HEADER;




在数据区域就可以存放psi或音视频数据.

PSI(program specific information)

SI(service information)

实现解复用需要PAT PMT SDT

CA需要CAT

EPG需要NIT EIT TDT TOT


PAT(Program Association Table)节目关联表

在pat中可以看到这里只有一个节目,而在pmt中可以看到这个节目更为详细的信息





table_id:8 bits,标志本表格的类型,应该是0x00

section_syntax_indicator:1 bit,段语法标志,应该是'1'

'0':固定的'0',这是为了防止和ISO13818Video流格式中的控制字冲突而设置的.

Reserved:保留的2bits,保留位一般都是'0'

section_length:12bits的段大小,单位是Bytes.

transport_stream_id:16bits的当前流ID,DVB内唯一.(事实上很多都是自定义的TS ID)

version_number:5bits版本号码,标注当前节目的版本.这是个非常有用的参数,当检测到这个字段改变时,说明TS流中的节目已经变化了,程序必须重新搜索节目.

current_next_indicator:1bit:当前还是未来使用标志符,一般情况下为'0'

section_number:8bits当前段号码

last_section_number:8bits最后段号码(section_number和last_section_number的功能是当PAT内容>184字节时,PAT表会分成多个段(sections),解复用程序必须在全部接收完成后再进行PAT的分析)


PMT(Program Map Table)节目映射表



table_id:8bits的ID,应该是0x02

section_syntax_indicator:1bit的段语法标志,应该是'1'

'0':固定是'0',如果不是说明数据有错.

reserved:2bits保留位,应该是'00'

section_length:16bits段长度,从program_number开始,到CRC_32(包含)的字节总数.

program_number:16bits的频道号码,表示当前的PMT关联到的频道.换句话就是说,当前描述的是program_number频道的信息.

reserved:2bits保留位,应该是'00'

version_number:版本号码,如果PMT内容有更新,则version_number会递增1通知解复用程序需要重新接收节目信息,否则version_number是固定不变的.

current_next_indicator:当前未来标志符,一般是0

section_number:当前段号码

last_section_number:最后段号码,含义和PAT中的对应字段相同,请参考PAT部分.

reserved:3bits保留位,一般是'000'.

PCR_PID:13bits的PCR PID,具体请参考ISO13818-1,解复用程序不使用该参数.

reserved:4bits保留位,一般是'0000'

program_info_length:节目信息长度(之后的是N个描述符结构,一般可以忽略掉,这个字段就代表描述符总的长度,单位是Bytes)

紧接着就是频道内部包含的节目类型和对应的PID号码了.

stream_type:8bits流类型,标志是Video还是Audio还是其他数据.

reserved:3 bits保留位.

elementary_PID:13bits对应的数据PID号码(如果stream_type是Video,那么这个PID就是Video PID,如果stream_type标志是Audio,那么这个PID就是Audio PID)

reserved:4 bits保留位.

ES_info_length:和program_info_length类似的信息长度(其后是N2个描述符号)

CRC_32:32bits段末尾是本段的CRC校验值,一般忽略.


SDT(Service description section)服务描述段

table_id:8bits的ID,可以是0x42,表示描述的是当前流的信息,也可以是0x46,表示是其他流的信息(EPG使用此参数)

section_syntax_indicator:段语法标志,一般是'1'

reserved_future_used:2bits保留未来使用

reserved:1bit保留位,防止控制字冲突,一般是'0',也有可能是'1'

section_length:12bits的段长度,单位是Bytes,从transport_stream_id开始,到CRC_32结束(包含)

transport_stream_id:16bits当前描述的流ID

reserved:2bits保留位

version_number:5bits的版本号码,如果数据更新则此字段递增1

current_next_indicator:当前未来标志,一般是'0',表示当前马上使用.

original_netword_id:16bits的原始网络ID号

reserved_future_use:8bits保留未来使用位

接下来是N个节目信息的循环:

service_id:16 bits的服务器ID,实际上就是PMT段中的program_number.

reserved_future_used:6bits保留未来使用位

EIT_schedule_flag:1bit的EIT信息,1表示当前流实现了该节目的EIT传送

EIT_present_following_flag:1bits的EIT信息,1表示当前流实现了该节目的EIT传送

running_status:3bits的运行状态信息:1-还未播放 2-几分钟后马上开始,3-被暂停播出,4-正在播放,其他---保留

free_CA_mode:1bits的加密信息,'1'表示该节目被加密.

紧 接着的是描述符,一般是Service descriptor,分析此描述符可以获取servive_id指定的节目的节目名称.具体格式请参考 EN300468中的Service descriptor部分.分析完毕,则节目名称和节目号码已经联系起来了.机顶盒程序就可以用这些节目名称代替 PID让用户选择,从而实现比较友好的用户界面!

  

机顶盒先调整高频头到一个固定的频率(如498MHZ),如果此频率有数字信号,则COFDM芯片(如MT352)会自动把TS流数据传送给MPEG- 2 decoder.MPEG-2 decoder先进行数据的同步,也就是等待完整的Packet的到来.然后循环查找是否出现PID== 0x0000的Packet,如果出现了,则马上进入分析PAT的处理,获取了所有的PMT的PID.接着循环查找是否出现PMT,如果发现了,则自动进 入PMT分析,获取该频段所有的频道数据并保存.只要我们处理了PMT,那么我们就可以获取频道中所有的PID信息,例如当前频道包含多少个Video,共多少个Audio,和其他数据,还能知道每种数据对应的PID分别是什么.这样如果我们要选择其中一个Video和Audio收看,那么只需要把要收看的节目的Video

PID和Audio PID保存起来,在处理Packet的时候进行过滤即可实现.

如果没有发现PAT或者没有发现PMT,说明该频段没有信号,进入下一个频率扫描.

从以上描述可以看出,机顶盒搜索频率是随机发生的,要使每次机顶盒都能搜索到信号,则要求TS流每隔一段时间就发送一次PAT和PMT.事实上DVB传输系统就是这么做的.因此无论何时接入终端系统,系统都能马上搜索到节目并正确解复用实现播放.不仅仅如此,其他数据也都是交替传送的.比如第一个Packet可能是PAT,第二个Packet可能是PMT,而第三个Packet可能是Video 1,第四个Packet可能是Video 2,

只要系统传输速度足够快(就是称之为"码率"的东东),实现实时播放是没有任何问题的.

到这里虽然实现了解复用,但可以看出,使用的PID都是枯燥的数字,如果调台要用户自己输入数字那可是太麻烦了,而且还容易输入错误,操作非常不直观,即使做成一个菜单让用户选择也是非常的呆板.针对这个问题,DVB系统提出了一个SDT表格,该表格标志一个节目的名称,并且能和PMT中的PID联系起来,这样用户就可以通过直接选择节目名称来选择节目了.

转载:http://www.xuebuyuan.com/1489591.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: