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*)&reg_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)