DVB字幕解码
TS流解析
當調諧器選定頻點之后,此時本地的接收器能夠源源不斷地接收到TS碼流,在這些碼流中,包含了視頻信息、音頻信息以及各種輔助信息,我們所要做的就是從這些信息中找到所承載的字幕信息,并進行解碼。
TS流的復用與解復用:
在數字電視系統的前端,所有的數據(視頻,音頻以及PSI/SI信息)都會被復用器復用成TS流,從而進行傳送,示意圖如下:
機頂盒等接收設備接收到的就是這樣被復用的一個個包,需要解復用器進行解復用。解復用的意義就在于可以將TS流中類型相同的包存入相同的緩存中,分別處理,這樣就可以將視頻、音頻以及其他業務信息的數據區分隔開來。
TS流拼接成PES包
在接收器接收到TS流之后,首先需要等待數據的同步,即完整的數據包的到來。首先需要查找PID為0x0的包,這是PAT(節目映射表),每個TS流中有一個,每隔0.5s重復。在PAT表中,定義了當下TS流中的所有節目,是PSI的根節點,要查找節目必須從PAT表開始查找,其主要包含頻道號碼和每一個頻道對應的PMT的PID。當選定節目后,按照上述PID找到對應的PMT。
PMT是節目映射表,其中包含了當前頻道中所有的video數據的PID,所有的audio數據的PID,以及和當前頻道關聯在一起的其他數據的PID。從PMT中,我們可以找到字幕數據流所對應的PID,可以根據此PID拼接成一個完整的PES包。
TS包由包頭跟有效載荷組成,其中包頭4個字節,有效載荷184個字節,一共188個字節,其結構如下所示:
如前文所述,根據PMT中給定的PID找到字幕數據對應的TS包。其中,同步字節是固定的8bit字段,其值為0x47;有效載荷單元起始指示符為1bit標志,當傳輸流包有效載荷包含PES包數據時,置1指示此傳輸流包的有效載荷應隨著PES包的首字節開始,0指示此傳輸流包中無任何PES包開始,通過此標志,我們可以判斷一個PES包是否已經存儲完整;自適應段為2bit字段,指示此包頭是否跟隨自適應字段或有效載荷,當為01時指示無自適應段,僅有效載荷,為10時僅有自適應段,無有效載荷,11時為自適應段后跟隨有效載荷。如果存在自適應段,則連續計數器字段后8個bit指示自適應段長度。如果沒有自適應段只有有效載荷,則包頭之后的184個字節就是有效載荷,存入緩存中;如果有自適應段,則使用184減去自適應段長度即可得到有效載荷的長度,將其存入緩存中。直到下一個PES包頭到達,說明此PES包已完整。
PES包解析
字幕段數據的獲取
PES包的完整結構見下圖:
包起始碼前綴是固定的24比特碼,值為0x1;流id指示基本流的類型和編號,對字幕流來說,流id應為0xbd;PES包長度是一個16bit的字段,指示PES包中跟隨該字段最后字節的字節數,0值指示PES包長度既未指定,也未限定并且僅在這樣的PES包中才被允許;PES頭數據長度指示在此PES包頭中包含的由任選字段和任意填充字節所占據的字節總數;PTS指示了顯示時間與解碼時間的關系。在獲取PES包長度和PES頭數據長度后即可得到PES數據域中的數據,即字幕的相關數據。
字幕段數據的解析
上述得到的字幕數據段結構如下所示:
對字幕數據來說,data_identifier為固定的8bit字段,為0x20;subtitle_stream_id是在PES包中指示字幕流,固定為0x00,之后就是字幕的數據段;最后是8bit的PES數據結束的標志位,固定為0xff。字幕數據段的結構如下:
開始是8bit的同步字節,固定為0x0f,通過此同步字節可用來驗證傳輸信息有沒有丟失;之后是8bit的segment_type,代表傳輸的字幕數據的類型;隨后是2個字節的page_id,用來指示字幕服務的類型,通過page_id可用來區分此字幕頁是composition page還是ancillary page。Ancillary page代表由多個字幕服務共享的數據,例如logo或者字符符號。segment_length是2個字節的字段,指示該字段后直到字幕段結束的字節的數量,之后就是字幕數據段的數據。
字幕數據段較為常用的是四種類型:頁組成段、區域組成段、CLUT定義段以及對象數據段。頁組成段攜帶一個包含0個或者多個region的清單,這個清單定義了頁組成段定義的顯示中可見的region的集合,這個可見清單在PTS定義的時間變得可用,解碼器的顯示將立即從之前存在的可見區域的集合切換到最新定義的集合,在頁組成段之后可能會跟著0或多個區域組成段,但頁組成段的region清單可能跟這些區域組成段的集合有很大的不同。一個完整的區域組成段集合將隨著標志有“modechange”或“acquisition point”狀態的頁組成段出現,這是引入region并為其分配內存的過程,區域組成段攜帶有關region位置和區域屬性的信息,例如水平和垂直分辨率、背景色、區域的像素深度、CLUT的id、包含對象的列表以及對象在區域中的位置。CLUT定義段代表將要有CLUT的更改,也就是顏色的改變。對象數據段包含了一個對象的相關數據,即字幕對應的字符或者像素編碼。
頁組成段結構如上圖所示,部分解釋如下:
- page_time_out:以s為單位的時間,在該時間后該頁面不再有效,應當從屏幕上擦除此頁面,這是為了防止因為錯誤導致該頁面長期停留在屏幕上的情況發生;
- page_state:該字段表示頁組合分段中和subtitle頁描述相關聯的內存規劃的狀態,相關值的定義如下:
normal case代表頁組合分段后跟著不完整的region集合,將要更改其中的字幕元素,acquisition point表示頁組合分段后跟著完整的region集合,描述當前的內存規劃,即將更新頁面, mode change表示頁組合分段后跟著的regions,描述一個新的內存規劃,需要更新頁面。 - region_id:頁中唯一標識一個區域的元素,所有的region都應該按照region_vertical_address字段中的順序排列在頁組合分段中。
- region_horizontal_address:指定了region左上角像素的水平地址。
- region_vertical_address:指定了region頂行的垂直地址。
區域組成段結構如上圖所示,部分解釋如下:
- region_id:唯一標識了一個region。
- region_fill_flag:如果設置為1,代表該區域將使用此段中region_n-bit_pixel_code字段中定義的背景色填充。
- region_width:表示region的寬度。
- region_height:表示region的高度。
- region_level_of_compatibility:表示解碼器解碼該region所需的CLUT的最小類型。
- region_depth:該region可以使用的最大像素深度。
- CLUT_id:標識CLUT的唯一標識。
- region_8-bit_pixel_code:當region_fill_flag被設置后,該region使用的256色的像素編碼。
- region_4-bit_pixel_code:當region_fill_flag被設置后,該region使用的16色的像素編碼。
- region_2-bit_pixel_code:當region_fill_flag被設置后,該region使用的4色的像素編碼。
- object_id:標識區域中顯示的一個對象。
- object_type:標識對象的類型,設置為0x00代表位圖,0x01代表字符,0x02代表字符串,0x03保留。
- object_provider_flag:2bit的標識,標識object的來源。
- object_horizontal_position:指定對象的水平位置,單位為像素,相對于區域的左邊緣。
- object_vertical_position:指定對象的垂直位置,單位為掃描線,相對于區域的頂部。
- foreground_pixel_code:標識定義字符的前景色的8_bit_pixel_code。
- background_pixel_code:標識定義字符的背景色的8_bit_pixel_code。
CLUT定義段的結構如上所示,部分解釋如下:
- CLUT_id:標識頁中包含在CLUT定義段域中的CLUT族。
- CLUT_entry_id:指定CLUT的條目號,CLTU的條目號從0開始。
- 2-bit/entry_CLUT_flag:如果設置為1,代表該CLUT值將被用于標識2-bit/entry CLUT的條目。
- 4-bit/entry_CLUT_flag:如果設置為1,代表該CLUT值將被用于標識4-bit/entry CLUT的條目。
- 8-bit/entry_CLUT_flag:如果設置為1,代表該CLUT值將被用于標識8-bit/entry CLUT的條目。
- full_range_flag:如果設置為1,標識Y-value、Cr-value、Cb-value和T-value字段為8bit方案,如果設置為0,這些字段僅包含最重要的比特位。
- Y-value:代表該條目中CLUT的Y輸出值。
- Cr-value:代表該條目中CLUT的Cr輸出值。
- Cb-value:代表該條目中的CLUT的Cb輸出值。
- T-value:代表該條目中的透明度輸出值。
對象數據段的結構如上圖,部分解釋如下:
- object_id:標識object_data_segment中的object數據。
- object_coding_method:標識用于object編碼的方法,0x00代表像素編碼,0x01代表字符串編碼,0x02保留,0x03保留。
- non_modifying_colour_flag:設置為1代表CLUT條目值‘1’是一個非修改的顏色,意味著其不應該覆蓋任何底層的object。
- top_field_data_block_length:表示隨后頂部區域包含的pixel-data_sub-block的字節數。
- bottom_field_data_block_length:表示隨后底部區域包含的pixel-data_sub-block的字節數。
- number_of_codes:表示字符串中編碼字符的數量。
總結
- 上一篇: 软件工程专业英语专用名词翻译
- 下一篇: Python爬虫——selenium爬取