MPEG-2 TSファイル処理 -TSパケットのダンプ-

# はじめに
最近MPEG-2 TSのデータを使用することがあるので、メモがわりにいろいろと記していこうかと思います。規格に精通した人間ではないので、記事中に間違い等あるかもしれませんが、ご容赦ください。また、ご指摘頂けると助かります。

記事ではMPEG-2 TSの解析について実際に動くプログラムを載せていきます。ソースはGitHub上に公開します。

https://github.com/sagesagesagesagesage

基本的にC言語のコードとなります。

# MPEG-2 TSについて
地上デジタル放送、BS/CS放送ではMPEG-2システムのMPEG-2 TS（トランスポートストリーム）を使用して放送データを配信しています。それに対し、DVDはMPEG-2 PSを使用しています。
本記事では先のMPEG-2 TSを対象にします。

MPEG-2 TSはWikipediaによるとISO/IEC 13818-1、ITU-T勧告H.222.0で標準化されているらしいです。詳細ついてはそちらをご参照ください。

また、以下のページが大変参考になります。

[デジタル映像の「アーカイブ&デリバリー」に関する技術情報サイト](http://www.mpeg.co.jp/index.html)
[VIDEO-ITを取り巻く市場と技術](http://www.mpeg.co.jp/libraries/video_it/index.html)

# とりあえずダンプしてみる
MPEG-2 TSはトランスポートパケット（TSパケット）という、188バイトで固定長のパケットで構成されています。（188バイト以外、例えば204バイトのパケットもありますが、本記事では取り扱いません。）パケットの先頭は必ず0x47のSync byteで始まります。

そこで、TSファイルから188バイト単位でTSパケットを読み込み、Sync byteを確認してTSパケットであればカンマ区切りで画面に表示します。

```
static	bool			ts_dump( const char* ts_file )
{
	FILE*		ifp = NULL;
	
	uint8_t		i;
	uint8_t		ts_buffer[ TS_PACKET_SIZE ];		// TS_PACKET_SIZEは188
	
	bool		result = false;
	
	ifp = fopen( ts_file, "rb" );
	if( ifp ){
		while( TS_PACKET_SIZE == fread( ts_buffer, 1, sizeof( ts_buffer ), ifp ) ){
			if( TS_SYNC_BYTE != ts_buffer[ 0 ] ){
				continue;
			}
			
			for( i = 0 ; i < TS_PACKET_SIZE ; i++ ){
				printf( "%02X,", ts_buffer[ i ] );
			}
			printf( "\n" );
		}
		
		fclose( ifp );
		result = true;
	}else{
		perror( "Input file open." );
	}

	return result;
}
```

実行結果
```
47,01,00,1E,83,0B,55,16,10,F3,2C,50,C9,35,98,08,1F,91,02,07,DE,A4,05,10,20,7D,F4,08,1F,8A,03,98,AB,BA,07,E4,37,98,00,AD,2A,80,16,E3,C4,C0,3A,EA,89,81,B2,08,B7,47,DF,C1,0D,B4,3B,F3,02,5B,38,0E,1B,11,31,19,34,B4,7E,DC,67,C0,F6,E2,E4,35,AE,E0,B6,4C,DB,A0,74,04,1C,01,EA,17,00,62,19,00,11,94,13,00,25,0C,23,56,A0,40,FC,73,E0,40,FC,C2,4C,08,1F,72,85,C0,81,F8,68,09,BA,D4,08,1F,9F,A0,40,FD,0D,02,07,E4,68,10,3F,1E,EE,81,D6,0A,24,00,9D,0A,80,62,49,80,31,42,E0,18,A2,AD,C3,7A,68,25,64,60,7C,E8,9A,49,89,A9,01,46,91,26,E8,7D,7F,F9,3A,00,76,49,88,60,39,BB,A1,04,98,03,23,E2,
47,01,00,1F,A4,55,B8,80,EC,27,64,84,79,E2,EF,D5,BB,04,14,EF,FE,99,29,86,C5,FB,AA,4A,82,C3,0F,8B,FA,4E,CF,06,9D,47,FB,4B,18,D5,B1,69,61,A3,DB,19,9A,86,0C,30,D1,F4,32,B5,51,9F,18,61,A3,96,AB,2F,95,6B,A3,34,66,CC,F6,8F,C4,E3,40,0F,9B,86,29,F3,86,F6,CD,1A,5B,7A,9A,19,71,A3,FC,DD,49,C8,D9,94,E6,FA,7C,29,B1,F1,48,0D,99,C1,6C,B4,AF,06,8F,F3,ED,57,4A,DC,F3,9B,D9,8A,D0,03,E1,CD,C7,76,80,55,8D,9B,57,72,96,36,3D,B7,04,B1,E4,16,B5,66,77,10,9F,A2,02,92,20,C3,83,EE,81,A5,50,EE,47,02,CD,77,51,A0,CE,99,42,F9,64,4C,6C,BD,78,CC,EA,AE,B5,E5,00,00,00,01,1F,42,3F,85,3D,49,2D,18,
47,1F,FF,1F,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,
- 以下略 -
```

先頭のSync byte が0x47で始まっていることが分かります。

# おわりに
188バイト単位でTSパケットの取得ができたので、次はTSパケットヘッダの解析をしたいと思います。