Mercurial > libavformat.hg
comparison mpegts.c @ 4978:deaa9053dc97 libavformat
rework stream type and codec identification
author | bcoudurier |
---|---|
date | Sun, 31 May 2009 02:56:15 +0000 |
parents | 586df9be38ad |
children | c6796179d3fa |
comparison
equal
deleted
inserted
replaced
4977:586df9be38ad | 4978:deaa9053dc97 |
---|---|
40 #define MAX_PES_PAYLOAD 200*1024 | 40 #define MAX_PES_PAYLOAD 200*1024 |
41 | 41 |
42 typedef struct PESContext PESContext; | 42 typedef struct PESContext PESContext; |
43 | 43 |
44 static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type); | 44 static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type); |
45 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code); | 45 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code, uint32_t prog_reg_desc, uint32_t reg_desc); |
46 | 46 |
47 enum MpegTSFilterType { | 47 enum MpegTSFilterType { |
48 MPEGTS_PES, | 48 MPEGTS_PES, |
49 MPEGTS_SECTION, | 49 MPEGTS_SECTION, |
50 }; | 50 }; |
494 const uint8_t *p, *p_end, *desc_list_end, *desc_end; | 494 const uint8_t *p, *p_end, *desc_list_end, *desc_end; |
495 int program_info_length, pcr_pid, pid, stream_type; | 495 int program_info_length, pcr_pid, pid, stream_type; |
496 int desc_list_len, desc_len, desc_tag; | 496 int desc_list_len, desc_len, desc_tag; |
497 int comp_page = 0, anc_page = 0; /* initialize to kill warnings */ | 497 int comp_page = 0, anc_page = 0; /* initialize to kill warnings */ |
498 char language[4] = {0}; /* initialize to kill warnings */ | 498 char language[4] = {0}; /* initialize to kill warnings */ |
499 int has_hdmv_descr = 0; | 499 uint32_t prog_reg_desc = 0; /* registration descriptor */ |
500 int has_dirac_descr = 0; | |
501 uint32_t reg_desc = 0; /* registration descriptor */ | 500 uint32_t reg_desc = 0; /* registration descriptor */ |
502 | 501 |
503 #ifdef DEBUG | 502 #ifdef DEBUG |
504 dprintf(ts->stream, "PMT: len %i\n", section_len); | 503 dprintf(ts->stream, "PMT: len %i\n", section_len); |
505 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); | 504 av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); |
534 if(len > program_info_length - 2) | 533 if(len > program_info_length - 2) |
535 //something else is broken, exit the program_descriptors_loop | 534 //something else is broken, exit the program_descriptors_loop |
536 break; | 535 break; |
537 program_info_length -= len + 2; | 536 program_info_length -= len + 2; |
538 if(tag == REGISTRATION_DESCRIPTOR && len >= 4) { | 537 if(tag == REGISTRATION_DESCRIPTOR && len >= 4) { |
539 reg_desc = bytestream_get_le32(&p); | 538 prog_reg_desc = bytestream_get_le32(&p); |
540 len -= 4; | 539 len -= 4; |
541 if(reg_desc == AV_RL32("HDMV")) | |
542 has_hdmv_descr = 1; | |
543 } | 540 } |
544 p += len; | 541 p += len; |
545 } | 542 } |
546 p += program_info_length; | 543 p += program_info_length; |
547 if (p >= p_end) | 544 if (p >= p_end) |
548 return; | 545 return; |
549 for(;;) { | 546 for(;;) { |
547 reg_desc = 0; | |
550 language[0] = 0; | 548 language[0] = 0; |
551 st = 0; | 549 st = 0; |
552 stream_type = get8(&p, p_end); | 550 stream_type = get8(&p, p_end); |
553 if (stream_type < 0) | 551 if (stream_type < 0) |
554 break; | 552 break; |
585 desc_tag, desc_len); | 583 desc_tag, desc_len); |
586 | 584 |
587 switch(desc_tag) { | 585 switch(desc_tag) { |
588 case DVB_SUBT_DESCID: | 586 case DVB_SUBT_DESCID: |
589 if (stream_type == STREAM_TYPE_PRIVATE_DATA) | 587 if (stream_type == STREAM_TYPE_PRIVATE_DATA) |
590 stream_type = STREAM_TYPE_SUBTITLE_DVB; | 588 stream_type = STREAM_TYPE_SUBTITLE_DVB; // demuxer internal |
591 | 589 |
592 language[0] = get8(&p, desc_end); | 590 language[0] = get8(&p, desc_end); |
593 language[1] = get8(&p, desc_end); | 591 language[1] = get8(&p, desc_end); |
594 language[2] = get8(&p, desc_end); | 592 language[2] = get8(&p, desc_end); |
595 language[3] = 0; | 593 language[3] = 0; |
604 language[2] = get8(&p, desc_end); | 602 language[2] = get8(&p, desc_end); |
605 language[3] = 0; | 603 language[3] = 0; |
606 break; | 604 break; |
607 case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */ | 605 case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */ |
608 reg_desc = bytestream_get_le32(&p); | 606 reg_desc = bytestream_get_le32(&p); |
609 if(reg_desc == AV_RL32("drac")) | |
610 has_dirac_descr = 1; | |
611 else if(reg_desc == AV_RL32("AC-3")) | |
612 stream_type = STREAM_TYPE_AUDIO_AC3; | |
613 break; | 607 break; |
614 default: | 608 default: |
615 break; | 609 break; |
616 } | 610 } |
617 p = desc_end; | 611 p = desc_end; |
627 st= pes->st; | 621 st= pes->st; |
628 } else { | 622 } else { |
629 if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably | 623 if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably |
630 pes = add_pes_stream(ts, pid, pcr_pid, stream_type); | 624 pes = add_pes_stream(ts, pid, pcr_pid, stream_type); |
631 if (pes) | 625 if (pes) |
632 st = new_pes_av_stream(pes, 0); | 626 st = new_pes_av_stream(pes, 0, prog_reg_desc, reg_desc); |
633 } | 627 } |
634 | 628 |
635 add_pid_to_pmt(ts, h->id, pid); | 629 add_pid_to_pmt(ts, h->id, pid); |
636 | 630 |
637 if(st) { | 631 if(st) { |
931 } | 925 } |
932 | 926 |
933 return 0; | 927 return 0; |
934 } | 928 } |
935 | 929 |
936 static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code) | 930 typedef struct { |
937 { | 931 uint32_t stream_type; |
938 AVStream *st; | 932 enum CodecType codec_type; |
939 enum CodecID codec_id; | 933 enum CodecID codec_id; |
940 enum CodecType codec_type; | 934 } StreamType; |
941 | 935 |
942 switch(pes->stream_type){ | 936 static const StreamType ISO_types[] = { |
943 case STREAM_TYPE_AUDIO_MPEG1: | 937 { 0x01, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO }, |
944 case STREAM_TYPE_AUDIO_MPEG2: | 938 { 0x02, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO }, |
945 codec_type = CODEC_TYPE_AUDIO; | 939 { 0x03, CODEC_TYPE_AUDIO, CODEC_ID_MP3 }, |
946 codec_id = CODEC_ID_MP3; | 940 { 0x04, CODEC_TYPE_AUDIO, CODEC_ID_MP3 }, |
947 break; | 941 { 0x0f, CODEC_TYPE_AUDIO, CODEC_ID_AAC }, |
948 case STREAM_TYPE_VIDEO_MPEG1: | 942 { 0x10, CODEC_TYPE_VIDEO, CODEC_ID_MPEG4 }, |
949 case STREAM_TYPE_VIDEO_MPEG2: | 943 { 0x1b, CODEC_TYPE_VIDEO, CODEC_ID_H264 }, |
950 codec_type = CODEC_TYPE_VIDEO; | 944 { 0xd1, CODEC_TYPE_VIDEO, CODEC_ID_DIRAC }, |
951 codec_id = CODEC_ID_MPEG2VIDEO; | 945 { 0xea, CODEC_TYPE_VIDEO, CODEC_ID_VC1 }, |
952 break; | 946 { 0 }, |
953 case STREAM_TYPE_VIDEO_MPEG4: | 947 }; |
954 codec_type = CODEC_TYPE_VIDEO; | 948 |
955 codec_id = CODEC_ID_MPEG4; | 949 static const StreamType HDMV_types[] = { |
956 break; | 950 { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, |
957 case STREAM_TYPE_VIDEO_H264: | 951 { 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS }, |
958 codec_type = CODEC_TYPE_VIDEO; | 952 { 0 }, |
959 codec_id = CODEC_ID_H264; | 953 }; |
960 break; | 954 |
961 case STREAM_TYPE_VIDEO_VC1: | 955 /* ATSC ? */ |
962 codec_type = CODEC_TYPE_VIDEO; | 956 static const StreamType MISC_types[] = { |
963 codec_id = CODEC_ID_VC1; | 957 { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, |
964 break; | 958 { 0x8a, CODEC_TYPE_AUDIO, CODEC_ID_DTS }, |
965 case STREAM_TYPE_VIDEO_DIRAC: | 959 { STREAM_TYPE_SUBTITLE_DVB, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, // demuxer internal |
966 codec_type = CODEC_TYPE_VIDEO; | 960 { 0 }, |
967 codec_id = CODEC_ID_DIRAC; | 961 }; |
968 break; | 962 |
969 case STREAM_TYPE_AUDIO_AAC: | 963 static const StreamType REGD_types[] = { |
970 codec_type = CODEC_TYPE_AUDIO; | 964 { MKTAG('d','r','a','c'), CODEC_TYPE_VIDEO, CODEC_ID_DIRAC }, |
971 codec_id = CODEC_ID_AAC; | 965 { MKTAG('A','C','-','3'), CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, |
972 break; | 966 { 0 }, |
973 case STREAM_TYPE_AUDIO_AC3: | 967 }; |
974 codec_type = CODEC_TYPE_AUDIO; | 968 |
975 codec_id = CODEC_ID_AC3; | 969 static void mpegts_find_stream_type(AVStream *st, |
976 break; | 970 uint32_t stream_type, const StreamType *types) |
977 case STREAM_TYPE_AUDIO_DTS: | 971 { |
978 case STREAM_TYPE_AUDIO_HDMV_DTS: | 972 for (; types->stream_type; types++) { |
979 codec_type = CODEC_TYPE_AUDIO; | 973 if (stream_type == types->stream_type) { |
980 codec_id = CODEC_ID_DTS; | 974 st->codec->codec_type = types->codec_type; |
981 break; | 975 st->codec->codec_id = types->codec_id; |
982 case STREAM_TYPE_SUBTITLE_DVB: | 976 return; |
983 codec_type = CODEC_TYPE_SUBTITLE; | 977 } |
984 codec_id = CODEC_ID_DVB_SUBTITLE; | 978 } |
985 break; | 979 } |
986 default: | 980 |
987 if (code >= 0x1c0 && code <= 0x1df) { | 981 static AVStream *new_pes_av_stream(PESContext *pes, uint32_t code, |
988 codec_type = CODEC_TYPE_AUDIO; | 982 uint32_t prog_reg_desc, uint32_t reg_desc) |
989 codec_id = CODEC_ID_MP2; | 983 { |
990 } else if (code == 0x1bd) { | 984 AVStream *st = av_new_stream(pes->stream, pes->pid); |
991 codec_type = CODEC_TYPE_AUDIO; | 985 |
992 codec_id = CODEC_ID_AC3; | 986 if (!st) |
993 } else { | 987 return NULL; |
994 codec_type = CODEC_TYPE_DATA; | 988 |
995 codec_id = CODEC_ID_PROBE; | 989 av_set_pts_info(st, 33, 1, 90000); |
996 } | 990 st->priv_data = pes; |
997 break; | 991 st->codec->codec_type = CODEC_TYPE_DATA; |
998 } | 992 st->codec->codec_id = CODEC_ID_PROBE; |
999 st = av_new_stream(pes->stream, pes->pid); | 993 st->need_parsing = AVSTREAM_PARSE_FULL; |
1000 if (st) { | 994 pes->st = st; |
1001 av_set_pts_info(st, 33, 1, 90000); | 995 |
1002 st->priv_data = pes; | 996 dprintf(pes->stream, "stream_type=%x prog_reg_desc=%.4s reg_desc=%.4s\n", |
1003 st->codec->codec_type = codec_type; | 997 pes->stream_type, (char*)&prog_reg_desc, (char*)®_desc); |
1004 st->codec->codec_id = codec_id; | 998 |
1005 st->need_parsing = AVSTREAM_PARSE_FULL; | 999 if (pes->stream_type == 0x06) { // private data carrying pes data |
1006 pes->st = st; | 1000 mpegts_find_stream_type(st, reg_desc, REGD_types); |
1007 } | 1001 } else { |
1002 mpegts_find_stream_type(st, pes->stream_type, ISO_types); | |
1003 if (prog_reg_desc == AV_RL32("HDMV") && | |
1004 st->codec->codec_id == CODEC_ID_PROBE) | |
1005 mpegts_find_stream_type(st, pes->stream_type, HDMV_types); | |
1006 if (st->codec->codec_id == CODEC_ID_PROBE) | |
1007 mpegts_find_stream_type(st, pes->stream_type, MISC_types); | |
1008 } | |
1009 | |
1008 return st; | 1010 return st; |
1009 } | 1011 } |
1010 | 1012 |
1011 | 1013 |
1012 static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type) | 1014 static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type) |