TSヘッダのパースと後続パケットの処理

ISO13818-1ARIB STD-B10を眺めながらMpeg2-tsファイルのパースをしてみる。

TSのバイナリは188バイトを1パケットとし、パケットは全て0x47から始まる。先頭4バイトはヘッダで、後続バイトが何者なのかなどの情報が入っている。 (ISO13818-1 2.4.3.2, Table 2-2)

たとえば以下のようなパケットがあるとする:

図1 TSパケットの例
47 40 12 18 00 4F F0 CC 01 26 FF 01 01 43 11 00
04 01 4F 44 4D DA 15 17 25 00 00 05 00 10 B1 4D
78 6A 70 6E 10 AA A6 C1 CE 3F 40 4D 4D 1B 24 2A
3B 1B 7D FA D6 63 30 61 42 58 A8 CE 35 28 40 61
21 22 32 46 49 7E F2 3C 7D 47 3C B9 EB 41 30 CB
E4 EB B3 C8 C8 CF 1B 7E BF 1B 7D E4 E9 BA CB 3C
7D 47 3C B9 EB C8 33 32 43 6E AC 49 7E F2 39 53
E9 B7 C6 B7 DE A6 B3 C8 E2 21 26 21 26 21 26 40
35 B7 A4 32 46 49 7E 3C 7D 47 3C 4A 7D 4B 21 F2
3E 52 32 70 B7 DE B9 21 23 50 06 F1 03 00 6A 70
6E 54 06 22 FF 2F FF 84 FF C1 02 A4 01 C4 11 F2
03 10 0F FF 6F 6A 70 6E 25 39 25 46

ヘッダは先頭の4バイトなので、このパケットの場合は47 40 12 18だ。ヘッダの定義はビット単位になっているので、このバイトをビットに開くき、仕様と照らし合わせると以下のようになる:

表1 図1のヘッダを定義と対照させたもの
sync_bytetransport_error_indicatorpayload_unit_start_indicatortransport_priorityPIDtransport_scrambling_controladaptation_field_controlcontinuity_counter
8 bit 1 bit 1 bit 1 bit 13 bit 2 bit 2 bit 4 bit
01000111 0 1 0 00000 00010010 00 01 1000

後続バイトをパースするのにまず注目すべきなのがPIDpayload_unit_start_indicatoradaptation_field_control、それにcontinuity_counterの4つである。

PIDは後続バイトが何を表現しているのかを表しているもので、標準的なのがISO13818-1 2.4.3.3, Table 2-3、国内における詳細な定義がARIB STD-B10第1部第5章5.1 表5-1にある。上の例では0x0012なので、ARIB STD-B10第1部第5章5.1 表5-1よりEIT(Event Information Table)である。EITが何者なのかはARIB STD-B10第2部第5章5.2.7 表5-7ARIB STD-B10付属第1章1.4に定義されていて、要は電子番組表にあるような番組情報である。

payload_unit_start_indicatorは一塊の情報が複数パケットに分割されるときに、どれが先頭パケットなのかを示すためのフラグで、上の例では1だからこのパケットは先頭パケットである。ちなみにこのパケットの後続パケットは以下であって、payload_unit_start_indicatorが0であることが確認できる(2バイト目の2ビット目が0)。

図2 図1の後続パケット
47 00 12 19 25 6C 25 2A C7 0E 00 08 30 05 01 13
6A 70 6E 00 6A 70 6E 00 D0 F1 B5 8C FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF

adaptation_field_controlは後続パケットにadaptation_fieldpayloadがあるかを示すフラグで、payloadはPIDによって定義された実際のデータ、adaptation_fieldはそれに先立って他のデータを定義したりスタッフィングに使われたりしている。adaptation_field_controlは2ビットで、上1ビットが立っている場合はadaptation_fieldがあり、下1ビットが立っている場合はpayloadがあることを表す。表1の例では01なので、adaptation_fieldはなく、ヘッダに続いて直ちにpayloadが始まる。

continuity_counterはパケットが欠落していないかの確認のために用いられるもので、同じPIDのパケットが来るたびに1ずつインクリメントされ、0x0Fまで達したら次は0x00に戻る。そのため、15パケット以上一度に欠落した場合は判断ができないが、それ以外の場合はこの数字が飛んでないか確認することでパケットの欠落がないことを判断できる。図1と図2の第4バイトの下4ビットを見れば、確かに0x08と0x09で、欠落がないことがわかる。

payloadにはISO13818-1 2.4.3.6で定義されているPES(Packetized Elementary Stream)パケットとISO13818-1 2.4.4で定義されているPSI(Program Specific Information)セクションがある。前者はpayloadが0x000001から始まり、たぶん動画とか音声とかの実データが入っている。後者はPointer_field(ISO13818-1 2.4.4.1)という8ビットのデータからはじまり、いろんなメタデータが入っている。

図3 adaptation_fieldがスタッフィングに使われている例
47 01 40 37 3F 00 FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF 34 66 D8 08 6A E7 24 A1 28 F9 07 89
57 01 65 9A 48 3B 9E AC 90 24 AB C6 0F 93 94 58
DD 91 F2 4E 4A 1C F7 01 16 B2 CA 26 36 E5 A4 9A
30 24 0C 38 EC 78 55 6C 80 F1 A1 E0 72 14 41 32
D9 82 A9 48 2C A4 16 53 1F 53 03 3A 84 8C 1B FF
91 8D F7 54 C1 D4 C7 CE 72 A6 AA 45 EA 62 6A 61
65 75 20 F2 B9 48 1C A6 46 52 1B 39 C9 A4 F0 C1
A8 19 92 72 D6 38 D8 00 00 00 00 00
図4 adaptation_fieldのみでpayloadがないパケット
47 01 11 20 B7 10 D2 2D 74 82 80 F9 FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF
図5 PESパケットの例
7 41 40 16 00 00 01 E0 00 00 85 80 13 2D 91 6D
DF 69 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00 00 01 00 00 5F FF FB B8 00 00 01 B5 87 57 5B
9C 00 00 00 00 00 01 01 5A DA 9D 48 8D 3E FB 49
ED 6C 81 3E E8 49 46 24 80 98 5B 24 07 8A 8B 58
0F 15 53 7B 23 6A A1 34 90 6C 0C 29 83 31 80 11
C6 CE 95 65 61 9D 2C 85 1E BE 64 8C B7 F9 6B E6
10 47 C1 A4 94 88 9A B6 60 A0 68 4F 56 02 43 00
06 B6 92 DB 00 F1 16 5E 42 D7 B0 87 09 1C 60 AB
21 F2 B1 E3 11 6A 6C 7B EA D1 87 23 18 19 97 CA
01 59 2E 01 B8 68 60 71 74 51 48 91 91 85 68 B0
B0 2D 35 69 99 28 0C 2C 35 18 58 6F
図6 PSIパケットの例 (図1の再掲)
47 40 12 18 00 4F F0 CC 01 26 FF 01 01 43 11 00
04 01 4F 44 4D DA 15 17 25 00 00 05 00 10 B1 4D
78 6A 70 6E 10 AA A6 C1 CE 3F 40 4D 4D 1B 24 2A
3B 1B 7D FA D6 63 30 61 42 58 A8 CE 35 28 40 61
21 22 32 46 49 7E F2 3C 7D 47 3C B9 EB 41 30 CB
E4 EB B3 C8 C8 CF 1B 7E BF 1B 7D E4 E9 BA CB 3C
7D 47 3C B9 EB C8 33 32 43 6E AC 49 7E F2 39 53
E9 B7 C6 B7 DE A6 B3 C8 E2 21 26 21 26 21 26 40
35 B7 A4 32 46 49 7E 3C 7D 47 3C 4A 7D 4B 21 F2
3E 52 32 70 B7 DE B9 21 23 50 06 F1 03 00 6A 70
6E 54 06 22 FF 2F FF 84 FF C1 02 A4 01 C4 11 F2
03 10 0F FF 6F 6A 70 6E 25 39 25 46