#!/Perl/bin/perl
# TSファイル中のエレメンタリPIDとストリーム形式種別を適当に出力してみるテスト

binmode(STDIN);
binmode(STDOUT);

%stream_id_table=(
0x01, "ISO/IEC 11172-2映像",
0x02, "ITU-T勧告H.262|ISO/IEC 13818-2映像またはISO/IEC 11172-2制約パラメータ映像ストリーム",
0x03, "ISO/IEC 11172-3音声",
0x04, "ISO/IEC 13818-3音声",
0x05, "ITU-T勧告H.222.0|ISO/IEC 13818-1プライベートセクション",
0x06, "プライベートデータを収容したITU-T勧告H.222.0|ISO/IEC 13818-1 PESパケット",
0x07, "ISO/IEC 13522 MHEG",
0x08, "ITU-T勧告H.222.0|ISO/IEC 13818-1付属書A DSM-CC",
0x09, "ITU-T勧告H.222.1",
0x0A, "ISO/IEC 13818-6（タイプA）",
0x0B, "ISO/IEC 13818-6（タイプB）",
0x0C, "ISO/IEC 13818-6（タイプC）",
0x0D, "ISO/IEC 13818-6（タイプD）",
0x0E, "上記勧告以外でITU-T勧告H.222.0|ISO/IEC 13818-1で規定されるデータタイプ",
0x0F, "ISO/IEC 13818-7音声（ADTSトランスポート構\造）",
0x10, "ISO/IEC 14496-2 映像",
0x11, "ISO/IEC 14496-3 音声（ISO/IEC 14496-3 / AMD 1で規定されるLATM トランスポート構\造）",
0x12, "PES パケットで伝送されるISO/IEC 14496-1 SL パケット化ストリーム又はフレックスマックスストリーム",
0x13, "ISO/IEC 14496 セクションで伝送されるISO/IEC14496-1 SL パケット化ストリーム又はフレックスマックスストリーム",
0x14, "ISO/IEC 13818-6 同期ダウンロードプロトコル",
0x15, "PES パケットで伝送されるメタデータ",
0x16, "メタデータセクションで伝送されるメタデータ",
0x17, "ISO/IEC 13818-6 データカルーセルで伝送されるメタデータ",
0x18, "ISO/IEC 13818-6 オブジェクトカルーセルで伝送されるメタデータ",
0x19, "ISO/IEC 13818-6 同期ダウンロードプロトコルで伝送されるメタデータ",
0x1A, "IPMP ストリーム（ISO/IEC 13818-11 で規定されるMPEG-2 IPMP）",
0x1B, "ITU-T 勧告H.264|ISO/IEC 14496-10 映像で規定されるAVC 映像ストリーム",
0x1C, "ISO/IEC 14496-3 音声（DST、ALS、SLS など何ら追加のトランスポート構\造を使用しないもの）",
0x1D, "ISO/IEC 14496-17 テキスト",
0x1E, "ISO/IEC 23002-3 で規定される補助映像ストリーム",
0x1F, "ITU-T 勧告H.264|ISO/IEC 14496-10 映像の付録Gで規定される一つ以上のプロファイルに準拠するAVC 映像ストリームのSVC 映像サブビットストリーム",
0x20, "ITU-T 勧告H.264|ISO/IEC 14496-10 映像の付録Hで規定される一つ以上のプロファイルに準拠するAVC 映像ストリームのMVC 映像サブビットストリーム",
0x7F, "IPMPストリーム"
);


$status = 0;
while(not eof(STDIN)){

	read(STDIN, $ts_data, 188);

	$pid = substr($ts_data, 1, 2);
#	printf STDOUT "status=%d PID=0x%04.4x\n", $status, hex(unpack("H*", $pid)) & 0x00001FFF;

	if ($status == 0) {
		#PAT RECORD
		if ((hex(unpack("H*", $pid)) & 0x00001FFF) == 0x0000) {
			$status = 1;

			$section_len = hex(unpack("H*", substr($ts_data, 6, 2))) & 0x0000FFF;
#			printf STDOUT "LEN=%d ", $section_len;
			$pmt_count = ($section_len - 5 - 4) / 4;
#			printf STDOUT "COUNT=%d ", $pmt_count;

			$program_cnt = 0;
			for ($i = 0; $i < $pmt_count; $i++) {
#				printf STDOUT "(ID=0x%s) ", unpack("H*", substr($ts_data, 4 + 9 + $i * 4, 2));
				$id = hex(unpack("H*", substr($ts_data, 4 + 9 + $i * 4, 2))) & 0x1FFF;
				next if ($id == 0x0000);
				$pmt_id[$program_cnt++] = hex(unpack("H*", substr($ts_data, 4 + 9 + $i * 4 + 2, 2))) & 0x1FFF;
				printf STDOUT "PMT ID=0x%04.4x ", $pmt_id[$program_cnt - 1];
			}
			printf STDOUT "\n";
		}
	} elsif  ($status == 1) {
		#PMT RECORD
		if ((hex(unpack("H*", $pid)) & 0x00001FFF) == $pmt_id[0]) {
			$status = 2;

			$section_len = hex(unpack("H*", substr($ts_data, 6, 2))) & 0x0000FFF;
#			printf STDOUT "LEN=%d ", $section_len;

			$start_point = 4 + 8;
			while($next_point < $section_len) {
#				printf STDOUT "start_point=%03.3d ", $start_point;

				$temp = hex(unpack("H*", substr($ts_data, $start_point, 4)));
#				printf STDOUT "start_point_data=0x%08.8x ", $temp;

				$stream_id = hex(unpack("H*", substr($ts_data, $start_point, 1)));
#				printf STDOUT "STREAM ID=0x%02.2x ", $stream_id;

#				$program_id = hex(unpack("H*", substr($ts_data, $start_point + 1, 2)));
#				printf STDOUT "PROGRAM ID=0x%04.4x ", $program_id;

				$program_id = hex(unpack("H*", substr($ts_data, $start_point + 1, 2))) & 0x1FFF;
#				printf STDOUT "PROGRAM ID=0x%04.4x ", $program_id;

				$program_len = hex(unpack("H*", substr($ts_data, $start_point + 3, 2))) & 0x0FFF;
#				printf STDOUT "PROGRAM LEN=%04.4d ", $program_len;

				$next_point = $start_point + 3 + 2 + $program_len; 
#				$temp = hex(unpack("H*", substr($ts_data, $next_point, 4)));
#				printf STDOUT "next_point_data=0x%08.8x ", $temp;

				if ($stream_id != 0x00) {
					printf STDOUT "STREAM ID=0x%02.2x PROGRAM ID=0x%04.4x %s\n", $stream_id, $program_id, $stream_id_table{$stream_id};
				}
				$start_point = $next_point;
			}
			last;
		}
	}
}

close(STDIN);
close(STDOUT);
