aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mpegts.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-05-31 02:56:15 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-05-31 02:56:15 +0000
commit8430f3ecb8d8012c03cd80cc455bacd59b473509 (patch)
treef745987f886a69dea68003daf69ae1855cbfaedd /libavformat/mpegts.c
parent40b0872a56d2177de8d305bf4f3fa34255b723aa (diff)
downloadffmpeg-8430f3ecb8d8012c03cd80cc455bacd59b473509.tar.gz
rework stream type and codec identification
Originally committed as revision 19003 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpegts.c')
-rw-r--r--libavformat/mpegts.c160
1 files changed, 81 insertions, 79 deletions
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index a6e87c19cf..5f94c2a6d1 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -42,7 +42,7 @@
typedef struct PESContext PESContext;
static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type);
-static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code);
+static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code, uint32_t prog_reg_desc, uint32_t reg_desc);
enum MpegTSFilterType {
MPEGTS_PES,
@@ -496,8 +496,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
int desc_list_len, desc_len, desc_tag;
int comp_page = 0, anc_page = 0; /* initialize to kill warnings */
char language[4] = {0}; /* initialize to kill warnings */
- int has_hdmv_descr = 0;
- int has_dirac_descr = 0;
+ uint32_t prog_reg_desc = 0; /* registration descriptor */
uint32_t reg_desc = 0; /* registration descriptor */
#ifdef DEBUG
@@ -536,10 +535,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
break;
program_info_length -= len + 2;
if(tag == REGISTRATION_DESCRIPTOR && len >= 4) {
- reg_desc = bytestream_get_le32(&p);
+ prog_reg_desc = bytestream_get_le32(&p);
len -= 4;
- if(reg_desc == AV_RL32("HDMV"))
- has_hdmv_descr = 1;
}
p += len;
}
@@ -547,6 +544,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (p >= p_end)
return;
for(;;) {
+ reg_desc = 0;
language[0] = 0;
st = 0;
stream_type = get8(&p, p_end);
@@ -587,7 +585,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
switch(desc_tag) {
case DVB_SUBT_DESCID:
if (stream_type == STREAM_TYPE_PRIVATE_DATA)
- stream_type = STREAM_TYPE_SUBTITLE_DVB;
+ stream_type = STREAM_TYPE_SUBTITLE_DVB; // demuxer internal
language[0] = get8(&p, desc_end);
language[1] = get8(&p, desc_end);
@@ -606,10 +604,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
break;
case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */
reg_desc = bytestream_get_le32(&p);
- if(reg_desc == AV_RL32("drac"))
- has_dirac_descr = 1;
- else if(reg_desc == AV_RL32("AC-3"))
- stream_type = STREAM_TYPE_AUDIO_AC3;
break;
default:
break;
@@ -629,7 +623,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
if (pes)
- st = new_pes_av_stream(pes, 0);
+ st = new_pes_av_stream(pes, 0, prog_reg_desc, reg_desc);
}
add_pid_to_pmt(ts, h->id, pid);
@@ -933,78 +927,86 @@ static int mpegts_push_data(MpegTSFilter *filter,
return 0;
}
-static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code)
-{
- AVStream *st;
- enum CodecID codec_id;
+typedef struct {
+ uint32_t stream_type;
enum CodecType codec_type;
+ enum CodecID codec_id;
+} StreamType;
+
+static const StreamType ISO_types[] = {
+ { 0x01, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO },
+ { 0x02, CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO },
+ { 0x03, CODEC_TYPE_AUDIO, CODEC_ID_MP3 },
+ { 0x04, CODEC_TYPE_AUDIO, CODEC_ID_MP3 },
+ { 0x0f, CODEC_TYPE_AUDIO, CODEC_ID_AAC },
+ { 0x10, CODEC_TYPE_VIDEO, CODEC_ID_MPEG4 },
+ { 0x1b, CODEC_TYPE_VIDEO, CODEC_ID_H264 },
+ { 0xd1, CODEC_TYPE_VIDEO, CODEC_ID_DIRAC },
+ { 0xea, CODEC_TYPE_VIDEO, CODEC_ID_VC1 },
+ { 0 },
+};
- switch(pes->stream_type){
- case STREAM_TYPE_AUDIO_MPEG1:
- case STREAM_TYPE_AUDIO_MPEG2:
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_MP3;
- break;
- case STREAM_TYPE_VIDEO_MPEG1:
- case STREAM_TYPE_VIDEO_MPEG2:
- codec_type = CODEC_TYPE_VIDEO;
- codec_id = CODEC_ID_MPEG2VIDEO;
- break;
- case STREAM_TYPE_VIDEO_MPEG4:
- codec_type = CODEC_TYPE_VIDEO;
- codec_id = CODEC_ID_MPEG4;
- break;
- case STREAM_TYPE_VIDEO_H264:
- codec_type = CODEC_TYPE_VIDEO;
- codec_id = CODEC_ID_H264;
- break;
- case STREAM_TYPE_VIDEO_VC1:
- codec_type = CODEC_TYPE_VIDEO;
- codec_id = CODEC_ID_VC1;
- break;
- case STREAM_TYPE_VIDEO_DIRAC:
- codec_type = CODEC_TYPE_VIDEO;
- codec_id = CODEC_ID_DIRAC;
- break;
- case STREAM_TYPE_AUDIO_AAC:
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_AAC;
- break;
- case STREAM_TYPE_AUDIO_AC3:
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_AC3;
- break;
- case STREAM_TYPE_AUDIO_DTS:
- case STREAM_TYPE_AUDIO_HDMV_DTS:
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_DTS;
- break;
- case STREAM_TYPE_SUBTITLE_DVB:
- codec_type = CODEC_TYPE_SUBTITLE;
- codec_id = CODEC_ID_DVB_SUBTITLE;
- break;
- default:
- if (code >= 0x1c0 && code <= 0x1df) {
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_MP2;
- } else if (code == 0x1bd) {
- codec_type = CODEC_TYPE_AUDIO;
- codec_id = CODEC_ID_AC3;
- } else {
- codec_type = CODEC_TYPE_DATA;
- codec_id = CODEC_ID_PROBE;
+static const StreamType HDMV_types[] = {
+ { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
+ { 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
+ { 0 },
+};
+
+/* ATSC ? */
+static const StreamType MISC_types[] = {
+ { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
+ { 0x8a, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
+ { STREAM_TYPE_SUBTITLE_DVB, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, // demuxer internal
+ { 0 },
+};
+
+static const StreamType REGD_types[] = {
+ { MKTAG('d','r','a','c'), CODEC_TYPE_VIDEO, CODEC_ID_DIRAC },
+ { MKTAG('A','C','-','3'), CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
+ { 0 },
+};
+
+static void mpegts_find_stream_type(AVStream *st,
+ uint32_t stream_type, const StreamType *types)
+{
+ for (; types->stream_type; types++) {
+ if (stream_type == types->stream_type) {
+ st->codec->codec_type = types->codec_type;
+ st->codec->codec_id = types->codec_id;
+ return;
}
- break;
}
- st = av_new_stream(pes->stream, pes->pid);
- if (st) {
- av_set_pts_info(st, 33, 1, 90000);
- st->priv_data = pes;
- st->codec->codec_type = codec_type;
- st->codec->codec_id = codec_id;
- st->need_parsing = AVSTREAM_PARSE_FULL;
- pes->st = st;
+}
+
+static AVStream *new_pes_av_stream(PESContext *pes, uint32_t code,
+ uint32_t prog_reg_desc, uint32_t reg_desc)
+{
+ AVStream *st = av_new_stream(pes->stream, pes->pid);
+
+ if (!st)
+ return NULL;
+
+ av_set_pts_info(st, 33, 1, 90000);
+ st->priv_data = pes;
+ st->codec->codec_type = CODEC_TYPE_DATA;
+ st->codec->codec_id = CODEC_ID_PROBE;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ pes->st = st;
+
+ dprintf(pes->stream, "stream_type=%x prog_reg_desc=%.4s reg_desc=%.4s\n",
+ pes->stream_type, (char*)&prog_reg_desc, (char*)&reg_desc);
+
+ if (pes->stream_type == 0x06) { // private data carrying pes data
+ mpegts_find_stream_type(st, reg_desc, REGD_types);
+ } else {
+ mpegts_find_stream_type(st, pes->stream_type, ISO_types);
+ if (prog_reg_desc == AV_RL32("HDMV") &&
+ st->codec->codec_id == CODEC_ID_PROBE)
+ mpegts_find_stream_type(st, pes->stream_type, HDMV_types);
+ if (st->codec->codec_id == CODEC_ID_PROBE)
+ mpegts_find_stream_type(st, pes->stream_type, MISC_types);
}
+
return st;
}