DVB開發之重點掌握

一、PSI/SI都採用表的形式來存儲相關信息,一般一個表又包含子表,段,描述子等元素構成。網絡

    (1)表(Table)oop

    表最初由MPEG-2標準定義的一種存儲信息的結構,一般由一個或者多個子表(Sub_table)組成,不一樣的表經過表的標識(table_id)進行區分,例如PMT的table_id=0x02,NIT的table_id=0x40;code

    (2)段(Section)視頻

    段用於完成PSI/SI信息到傳輸流包的映射,表或者子表一般由一個或者多個段組成,一個表容許被分紅很少於256個段,每一個段攜帶表的一部分;ip

    Section段的通用結構以下:開發

    (3)描述子(Descriptor)io

    描述子也叫作描述符,語意上比較完整的語法結構,用於提供特定的信息。全部描述子都是一個8位標識的「descripor_tag」開始後面緊跟一個8位的數表示描述子數據區的字節長度,從描述子第三個字節開始的數據則是各個描述子的具體內容。table

    其語法結構以下:ast

    

二、NIT表:class

    網絡信息表(NIT)
    包含經過一個網絡傳輸的TS流的物理結構有關的信息,以及網絡自身有關信息,如:網絡基本信息:網絡標識、網絡名稱、網絡多語言名稱、連接信息 。TS流信息:TS流標識、傳輸系統描述、頻率列表、業務列表;

    NIT表語法結構:

    NIT表C代碼,解析了通用表頭部分信息:

static void ParseNIT_SectionHead(TS_NIT *pstTS_NIT, unsigned char *pucSectionBuffer)
{
 int iNetworkDescriptorLen = 0;
 int iNIT_Length = 0;
 pstTS_NIT->table_id = pucSectionBuffer[0];
 pstTS_NIT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
 pstTS_NIT->reserved_future_use_1 = (pucSectionBuffer[1] >> 6) & 0x01;
 pstTS_NIT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x03;
 pstTS_NIT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
 pstTS_NIT->network_id = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
 pstTS_NIT->reserved_2 = pucSectionBuffer[5] >> 6;
 pstTS_NIT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
 pstTS_NIT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
 pstTS_NIT->section_number = pucSectionBuffer[6];
 pstTS_NIT->last_section_number = pucSectionBuffer[7];
 pstTS_NIT->reserved_future_use_2 = pucSectionBuffer[8] >> 4;
 pstTS_NIT->network_descriptors_length = ((pucSectionBuffer[8] & 0x0F) << 8) | pucSectionBuffer[9];
 iNetworkDescriptorLen = pstTS_NIT->network_descriptors_length;
 memcpy(pstTS_NIT->network_descriptor, pucSectionBuffer + 10, iNetworkDescriptorLen);
 pstTS_NIT->reserved_future_use_2 = pucSectionBuffer[10 + iNetworkDescriptorLen] >> 4;
 pstTS_NIT->transport_stream_loop_length = ((pucSectionBuffer[10 + iNetworkDescriptorLen] & 0x0F) << 8)
         | pucSectionBuffer[10 + iNetworkDescriptorLen + 1];
 iNIT_Length = pstTS_NIT->section_length + 3;
 pstTS_NIT->CRC_32 = (pucSectionBuffer[iNIT_Length - 4] << 24) | (pucSectionBuffer[iNIT_Length - 3] << 16)
         | (pucSectionBuffer[iNIT_Length - 2] << 8) | pucSectionBuffer[iNIT_Length - 1];
}

三、PAT表:

    節目關聯表(PAT)

    關聯了節目編號(Program Number)與PMT所使用的PID以及給出NIT所用PID,它是PSI信息的根目錄,只要找到PID爲0的表,機頂盒就能獲知PMT的PID,從而找到PMT表。

    節目關聯表語法結構

    PAT表C代碼解析數據,只解析Section頭:

static void ParsePAT_SectionHead(TS_PAT *pstTS_PAT, unsigned char *pucSectionBuffer)
{
 int iPAT_Length = 0;
 pstTS_PAT->table_id = pucSectionBuffer[0];
 pstTS_PAT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
 pstTS_PAT->zero = (pucSectionBuffer[1] >> 6) & 0x1;
 pstTS_PAT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x3;
 pstTS_PAT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
 pstTS_PAT->transport_stream_id = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
 pstTS_PAT->reserved_2 = pucSectionBuffer[5] >> 6;
 pstTS_PAT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
 pstTS_PAT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
 pstTS_PAT->section_number = pucSectionBuffer[6];
 pstTS_PAT->last_section_number = pucSectionBuffer[7];
 iPAT_Length = 3 + pstTS_PAT->section_length;
 pstTS_PAT->CRC_32 = (pucSectionBuffer[iPAT_Length - 4] << 24) | (pucSectionBuffer[iPAT_Length - 3] << 16)
         | (pucSectionBuffer[iPAT_Length - 2] << 8) | pucSectionBuffer[iPAT_Length - 1];
}

   

 四、PMT表:

    節目映射表(PMT)

    描述了組成當前傳輸流的某個節目的視頻流,音頻流,數據流信息和PID以及該節目參考時鐘PRC的PID,經過PMT表機頂盒能夠從傳輸流中提取出組成該節目的基本流,並予以解碼重放,一個PMT表對應一個傳輸流中的一個節目。

節目映射表語法結構:

    PMT表C語言解析表頭數據信息:

static void ParsePMT_SectionHead(TS_PMT *pstTS_PMT, unsigned char *pucSectionBuffer)
{
 int iPMT_Length = 0;
 pstTS_PMT->table_id = pucSectionBuffer[0];
 pstTS_PMT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
 pstTS_PMT->zero = (pucSectionBuffer[1] >> 6) & 0x01;
 pstTS_PMT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x03;
 pstTS_PMT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
 pstTS_PMT->program_number = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
 pstTS_PMT->reserved_2 = pucSectionBuffer[5] >> 6;
 pstTS_PMT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
 pstTS_PMT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
 pstTS_PMT->section_number = pucSectionBuffer[6];
 pstTS_PMT->last_section_number = pucSectionBuffer[7];
 pstTS_PMT->reserved_3 = pucSectionBuffer[8] >> 5;
 pstTS_PMT->PCR_PID = ((pucSectionBuffer[8] << 8) | pucSectionBuffer[9]) & 0x1FFF;
 pstTS_PMT->reserved_4 = pucSectionBuffer[10] >> 4;
 pstTS_PMT->program_info_length = ((pucSectionBuffer[10] & 0x0F) << 8) | pucSectionBuffer[11];
 if (0 != pstTS_PMT->program_info_length)
 {
  memcpy(pstTS_PMT->program_info_descriptor, pucSectionBuffer + 12, pstTS_PMT->program_info_length);
 }
 iPMT_Length = pstTS_PMT->section_length + 3;
 pstTS_PMT->CRC_32 = (pucSectionBuffer[iPMT_Length - 4] << 24) | (pucSectionBuffer[iPMT_Length - 3] << 16)
         | (pucSectionBuffer[iPMT_Length - 2] << 8) | pucSectionBuffer[iPMT_Length - 1];
}

    固然不止這些表,這些僅僅只是羅列出了DVB開發中常見的幾種表!

相關文章
相關標籤/搜索