欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TS流PAT、PMT、ES、PES分析及解析代码

程序员文章站 2022-03-05 12:21:05
...

TS流即是我们所熟知的传输流,其是由定长的TS包组成(188字节),包括包头和负载数据。其中包头固定为4字节,用来指明包的起始位置、负载的PID以及各种标志位;负载则由各种表及基础流组成;

PAT表给出了TS中所携带的节目数及其节目号和节目PID;
PMT表给出了一个节目的具体信息,包括流类型及PID,PAT表中的节目数决定了PMT表的个数;

ES是原始流,其经过PES打包器之后,被转换成PES包;
PES是ES流经打包而生成的数据流,只能含有一种性质的ES,如只含有视频ES或只含音频ES,PES的基本单位是PES包,由包头和负载组成;PS节目流即是由若干个PES包组成;
编码器形成单一码流的详细过程如下图所示:
TS流PAT、PMT、ES、PES分析及解析代码

以下为部分PAT和PMT表的解析(C++):

PAT表解析:

PAT::PAT(uint8_t *buffer)
    : raw_data(buffer),
      table_id(raw_data[0]),
      section_syntax_indicator(raw_data[1] >> 7),
      zero((raw_data[1] >> 6) & 0x01),
      reserved1((raw_data[1] >> 4) & 0x03),
      section_length((raw_data[1] & 0x0F) << 8 | raw_data[2]),
      transport_stream_id(raw_data[3] << 8 | raw_data[4]),
      reserved2(raw_data[5] >> 6),
      version_number((raw_data[5] >> 1) & 0x1F),
      current_next_indicator(raw_data[5] & 0x01),
      section_number(raw_data[6]),
      last_section_number(raw_data[7])
{
    if (table_id != 0x00)
    {
        throw new PatErr(PatErr::PTID);
    }
}

PMT表解析:

PMT::PMT(uint8_t *data)
      : raw_data(data),
        table_id(raw_data[0]),
        section_syntax_indicator(raw_data[1] >> 7),
        zero((raw_data[1] >> 6) & 0x01),
        reserved1((raw_data[1] >> 4) & 0x03),
        section_length((raw_data[1] & 0x0F) << 8 | raw_data[2]),
        program_number(raw_data[3] << 8 | raw_data[4]),
        reserved2(raw_data[5] >> 6),
        version_number((raw_data[5] >> 1) & 0x1F),
        current_next_indicator(raw_data[5] & 0x01),
        section_number(raw_data[6]),
        last_section_number(raw_data[7]),
        reserved3(raw_data[8] >> 5),
        PCR_PID((raw_data[8] & 0x1F) << 8 | raw_data[9]),
        reserved4(raw_data[10] >> 4),
        program_info_length((raw_data[10] & 0x0F) << 8 | raw_data[11])

{

}

PMT表中节目信息保存:

void PMT::get_stream_detail(std::vector<STREAM_INFO*> &stream_info)
{
    uint32_t idx = 12 + program_info_length;

    if (!raw_data)
    {
        return;
    }

    while (idx < section_length + 3 - 4)
    {
        STREAM_INFO *info = new STREAM_INFO(raw_data + idx);

        if (check_type(info->stream_type))
        {
            stream_info.push_back(info);
        }

        idx += 5 + info->ES_info_length;
    }
}

运行结果截图如下:
TS流PAT、PMT、ES、PES分析及解析代码

完整工程链接 http://download.csdn.net/download/visual_c_plus/10257947

以上为本人根据自身理解所写,如有错误,请指正。

注:es提取只实现了视频es的提取;码流图来源于网络,侵删。