TSヘッダのパースと後続パケットの処理
ISO13818-1とARIB STD-B10を眺めながらMpeg2-tsファイルのパースをしてみる。
TSのバイナリは188バイトを1パケットとし、パケットは全て0x47から始まる。先頭4バイトはヘッダで、後続バイトが何者なのかなどの情報が入っている。 (ISO13818-1 2.4.3.2, Table 2-2)
たとえば以下のようなパケットがあるとする:
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だ。ヘッダの定義はビット単位になっているので、このバイトをビットに開くき、仕様と照らし合わせると以下のようになる:
sync_byte | transport_error_indicator | payload_unit_start_indicator | transport_priority | PID | transport_scrambling_control | adaptation_field_control | continuity_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 |
後続バイトをパースするのにまず注目すべきなのがPID、payload_unit_start_indicator、adaptation_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-7やARIB STD-B10付属第1章1.4に定義されていて、要は電子番組表にあるような番組情報である。
payload_unit_start_indicatorは一塊の情報が複数パケットに分割されるときに、どれが先頭パケットなのかを示すためのフラグで、上の例では1だからこのパケットは先頭パケットである。ちなみにこのパケットの後続パケットは以下であって、payload_unit_start_indicatorが0であることが確認できる(2バイト目の2ビット目が0)。
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_fieldやpayloadがあるかを示すフラグで、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ビットのデータからはじまり、いろんなメタデータが入っている。
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 |
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 |
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 |
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 |