#include #include // ################################################## // # // ################################################## #define TS_HEADER_LENGTH 4 void dump_ts_packet(char *buf){ int i, j; for(i = 0; i < 5; i = i + 1){ // line printf(" %02d: ", i); for(j = 0; j < 16; j = j + 1){ printf("%02x ", (buf[i*16 + j] & 0xff)); } printf("\n"); } } int main(int argc, char* argv[]){ FILE *fp_in; unsigned int c; unsigned int pid; unsigned int PAT_section_length; unsigned int PMT_section_length; unsigned int PMT_program_info_length; struct PMT{ unsigned int program_number; unsigned int program_map_PID; }; struct COMPONENT{ unsigned int stream_type; char stream_type_char[32]; unsigned int elementary_PID; unsigned int ES_info_length; char descripter[128]; }; struct PMT pmt[10]; struct COMPONENT component[10]; int count = 0; // パケット数のカウンタ char buf[188]; int i; int detect_PAT_count = 0; // PATに書かれているPMTの数 int detect_component_count = 0; // PMTに書かれているコンポーネントの数 int p; if(( fp_in = fopen(argv[1], "rb")) == NULL){ return -1; } // ################### // ##### 最初の同期バイトを探す ##### // ################### while(1){ c = fgetc(fp_in); if(c == 0x47){ break; } } fseek(fp_in, -1, SEEK_CUR); // ################### // ##### 188バイト単位に読み出す ##### // ################### while(1){ if(fread(buf, 1, 188, fp_in) < 1){ break; } // ##### TSパケットヘッダからPIDを取得 ##### pid = ((((char)buf[0+1] & 0xff) << 8 | (buf[1+1] & 0xff)) & 0x1fff); printf("%04d(0x%04x): 0x%04x", count, count*188, pid); if(pid == 0){ // ################### // ##### PAT解析 ##### // ################### printf(" PAT\n"); p = TS_HEADER_LENGTH + 2; PAT_section_length = ((buf[p] & 0xff) << 8 | (buf[p+ 1] & 0xff)) & 0x0fff; printf(" PAT_section_length : %d\n", PAT_section_length); detect_PAT_count = 0; while(p < TS_HEADER_LENGTH + PAT_section_length - 4){ pmt[detect_PAT_count].program_number = ((buf[p + 7] & 0xff) << 8 | (buf[p + 8] & 0xff)); pmt[detect_PAT_count].program_map_PID = ((buf[p + 9] & 0xff) << 8 | (buf[p + 10] & 0xff)) & 0x1fff; printf(" program_number:0x%04x(%03d), program_map_PID(PMT):0x%04x\n", pmt[detect_PAT_count].program_number, pmt[detect_PAT_count].program_number, pmt[detect_PAT_count].program_map_PID); p = p + 4; detect_PAT_count = detect_PAT_count + 1; } } else if(detect_PAT_count != 0){ // ################### // ##### PMT解析 ##### // ################### for(i = 0; i < detect_PAT_count; i = i + 1){ if(pid == pmt[i].program_map_PID){ printf(" PMT(0x%04x)\n", pmt[i].program_map_PID); PMT_section_length = ((buf[TS_HEADER_LENGTH + 1 + 1] & 0xff) << 8 | (buf[TS_HEADER_LENGTH+ 2 + 1] & 0xff)) & 0x0fff; PMT_program_info_length = ((buf[TS_HEADER_LENGTH + 10 + 1] & 0xff) << 8 | (buf[TS_HEADER_LENGTH+ 11 + 1] & 0xff)) & 0x0fff; printf(" PMT_section_length:0x%04x(%d), PMT_program_info_length:0x%04x(%d)\n", PMT_section_length, PMT_section_length, PMT_program_info_length, PMT_program_info_length); // ################### // ##### コンポーネント情報取得 ##### // ################### detect_component_count = 0; p = TS_HEADER_LENGTH + 12 + PMT_program_info_length + 1; while(p < TS_HEADER_LENGTH + PMT_section_length - 4){ component[detect_component_count].stream_type = buf[p] & 0xff; // printf(" stream_type:0x%02x\n", component[detect_component_count].stream_type); switch(component[detect_component_count].stream_type){ // TR-B14 case 0x01: printf(" stream_type:0x%02x:MPEG1 VIDEO\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "MPEG1 VIDEO"); break; case 0x02: printf(" stream_type:0x%02x:MPEG2 VIDEO\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "MPEG2 VIDEO"); break; case 0x06: printf(" stream_type:0x%02x:字幕・文字スーパー\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "字幕・文字スーパー"); break; case 0x0d: printf(" stream_type:0x%02x:データカルーセル\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "データカルーセル"); break; case 0x0f: printf(" stream_type:0x%02x:MPEG2 AAC\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "MPEG2 AAC"); break; case 0x1b: printf(" stream_type:0x%02x:H.264ワンセグ\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "H.264ワンセグ"); break; default: printf(" stream_type:0x%02x:不明\n", component[detect_component_count].stream_type); strcpy(component[detect_component_count].stream_type_char, "不明"); break; } component[detect_component_count].elementary_PID = (((buf[p+1] & 0xff) << 8) | (buf[p+2] & 0xff)) & 0x1fff; printf(" elementary_PID:0x%04x\n", component[detect_component_count].elementary_PID); component[detect_component_count].ES_info_length = (((buf[p+3] & 0xff) << 8 ) | (buf[p+4] & 0xff)) & 0x0fff; printf(" ES_info_length:0x%04x\n", component[detect_component_count].ES_info_length); p = p + 5 + component[detect_component_count].ES_info_length; detect_component_count = detect_component_count + 1; } } } } printf("\n"); count = count + 1; } fclose(fp_in); return 0; }