libdvbpsi 源代码学习(一)

时间:2022-11-11 16:30:26

    libdvbpsi是VLC里的一个轻便的用来实现MPEG-2 TS流解析和编码的开源库,可以解析的PSI/SI表有:PAT,PMT,NIT,CAT,SDT,EIT,TOT, 可以解析大部分的描述子。

 

下载:http://www.videolan.org/developers/libdvbpsi.html

详细文档(API,文件,结构体说明等):http://www.videolan.org/developers/libdvbpsi/doc/doxygen/html/index.html

 

以 libdvbpsi-0.1.7/examplesdecode_pat.c 为例子,说明libdvbpsi的大概框架:

 

1、dvbpsi_handle h_dvbpsi = dvbpsi_AttachPAT(DumpPAT, NULL);

    指定数据输出的回调函数,并创建一个decoder句柄,同时在这里面指定了私有的decoder(h_dvbpsi->p_private_decoder),和收集section的回调函数(h_dvbpsi->pf_callback = &dvbpsi_GatherPATSections;)。

 

2、dvbpsi_PushPacket(h_dvbpsi, data);

    这个函数是libdvbpsi里核心的一个函数,用来实现段(section)到包(packet)的映射,得到一个完整的section后,通过回调函数把这个section送到私有的decoder(h_dvbpsi->p_private_decoder)挂载上去,直到找到TS流中子表中所有section。

 

    它处理每一个PID为0x0000(PAT_PID)的包,这个函数先是对packet做一些判断,比如同步码,连续计数,调整字段(有的话直接跳过),然后构建填充h_dvbpsi->p_current_section, 当h_dvbpsi->p_current_section填充完成后,进入回调函数h_dvbpsi->pf_callback。

 

    h_dvbpsi->pf_callback这个回调按照我的理解,有点像C++中的虚函数,有各种Override版本,以实现不同的功能。在解析PAT时在dvbpsi_AttachPAT(DumpPAT, NULL)中已经指定了这个回调函数:dvbpsi_GatherPATSections()。这个函数先判断h_dvbpsi->p_current_section是否有效,比如table_id字段是不是PAT表的TID等等,之后通过version number和section number等字段判断是否挂载到h_dvbpsi->p_private_decoder上。如果h_dvbpsi->p_private_decoder已经收集到所有section,则调用解析函数dvbpsi_DecodePATSections()从section中解析出PAT信息。紧接着调用h_dvbpsi->p_private_decoder的回调函数(DumpPAT),输出PAT信息。

   

3、dvbpsi_DetachPAT(h_dvbpsi)

    释放内存。

 

    这是libdvbpsi解析TS流的一个大概的框架,由于PAT子表一般只有一个,像SDT,EIT等有多个子表时,h_dvbpsi->pf_callback就不能直接进行收集section了,必须先dvbpsi_Demux(),把section送到合适的子表decoder(dvbpsi_demux_subdec_t)中去收集。