数字电视中TS包解码函数 (二)

2014-11-24 02:57:07 · 作者: · 浏览: 5
payload_pos; //有效载荷长度
while(i_available > 0)
{
if(i_available >= h_dvbpsi->i_need)
{
/* 有足够的字节存储头部或整个段的信息 */
memcpy(p_section->p_payload_end, p_payload_pos, h_dvbpsi->i_need);
p_payload_pos += h_dvbpsi->i_need;
p_section->p_payload_end += h_dvbpsi->i_need;
i_available -= h_dvbpsi->i_need;
if(!h_dvbpsi->b_complete_header)
{
/* Header is complete */
h_dvbpsi->b_complete_header = 1;
/* Compute p_section->i_length and update h_dvbpsi->i_need */
//不懂
h_dvbpsi->i_need = p_section->i_length = ((uint16_t)(p_section->p_data[1] & 0xf)) << 8 | p_section->p_data[2]; //从第12个比特位到第24个比特位为长度批示段
/* 检查段是否超过最大长度 */
if(h_dvbpsi->i_need > h_dvbpsi->i_section_max_size - 3) //包头3个字节
{
DVBPSI_ERROR("PSI decoder", "PSI section too long");
dvbpsi_DeletePSISections(p_section);
h_dvbpsi->p_current_section = NULL;
/* 如果还有新段没有分析,则继续*/
if(p_new_pos)
{
h_dvbpsi->p_current_section
= p_section
= dvbpsi_NewPSISection(h_dvbpsi->i_section_max_size);
p_payload_pos = p_new_pos;
p_new_pos = NULL;
h_dvbpsi->i_need = 3;
h_dvbpsi->b_complete_header = 0;
i_available = 188 + p_data - p_payload_pos;
}
else
{
i_available = 0;
}
}
}
else
{
/* PSI section is complete */
p_section->b_syntax_indicator = p_section->p_data[1] & 0x80; //读段语法标志 位
p_section->b_private_indicator = p_section->p_data[1] & 0x40; //固定的'0',这是为了防止和ISO13818Video流格式中的控制字冲突而设置的
/* 如果存在CRC校验数据,则更新p_payload_end指针 */
if(p_section->b_syntax_indicator)
p_section->p_payload_end -= 4;
if(dvbpsi_ValidPSISection(p_section)) /*调用函数对数据进行CRC校验*/
{
/* 数据无误 */
p_section->i_table_id = p_section->p_data[0]; //从第一个字节读取表ID,0x00为PAT,0x02为PMT
if(p_section->b_syntax_indicator)
{
p_section->i_extension = (p_section->p_data[3] << 8)
| p_section->p_data[4]; //16bits的当前流ID,DVB内唯一.(事实上很多都是自定义的TS ID)
p_section->i_version = (p_section->p_data[5] & 0x3e) >> 1; //43到47的5bits为版本号码,标注当前节目的版本.这是个非常有用的参数,当检测到这个字段改变时,说明TS流中的节目已经变化了,程序必须重新搜索节目
p_section->b_current_next = p_section->p_data[5] & 0x1; //第48比特位,当前还是未来使用标志符,一般情况下为'0'
p_section->i_number = p_section->p_data[6]; //当前段号码
p_section->i_last_number = p_section->p_data[7]; //最后段号码(section_