Commit 8430f3ec authored by Baptiste Coudurier's avatar Baptiste Coudurier

rework stream type and codec identification

Originally committed as revision 19003 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 40b0872a
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
typedef struct PESContext PESContext; typedef struct PESContext PESContext;
static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type); 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 { enum MpegTSFilterType {
MPEGTS_PES, MPEGTS_PES,
...@@ -496,8 +496,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len ...@@ -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 desc_list_len, desc_len, desc_tag;
int comp_page = 0, anc_page = 0; /* initialize to kill warnings */ int comp_page = 0, anc_page = 0; /* initialize to kill warnings */
char language[4] = {0}; /* initialize to kill warnings */ char language[4] = {0}; /* initialize to kill warnings */
int has_hdmv_descr = 0; uint32_t prog_reg_desc = 0; /* registration descriptor */
int has_dirac_descr = 0;
uint32_t reg_desc = 0; /* registration descriptor */ uint32_t reg_desc = 0; /* registration descriptor */
#ifdef DEBUG #ifdef DEBUG
...@@ -536,10 +535,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len ...@@ -536,10 +535,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
break; break;
program_info_length -= len + 2; program_info_length -= len + 2;
if(tag == REGISTRATION_DESCRIPTOR && len >= 4) { if(tag == REGISTRATION_DESCRIPTOR && len >= 4) {
reg_desc = bytestream_get_le32(&p); prog_reg_desc = bytestream_get_le32(&p);
len -= 4; len -= 4;
if(reg_desc == AV_RL32("HDMV"))
has_hdmv_descr = 1;
} }
p += len; p += len;
} }
...@@ -547,6 +544,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len ...@@ -547,6 +544,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
if (p >= p_end) if (p >= p_end)
return; return;
for(;;) { for(;;) {
reg_desc = 0;
language[0] = 0; language[0] = 0;
st = 0; st = 0;
stream_type = get8(&p, p_end); stream_type = get8(&p, p_end);
...@@ -587,7 +585,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len ...@@ -587,7 +585,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
switch(desc_tag) { switch(desc_tag) {
case DVB_SUBT_DESCID: case DVB_SUBT_DESCID:
if (stream_type == STREAM_TYPE_PRIVATE_DATA) 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[0] = get8(&p, desc_end);
language[1] = 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 ...@@ -606,10 +604,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
break; break;
case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */ case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */
reg_desc = bytestream_get_le32(&p); 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; break;
default: default:
break; break;
...@@ -629,7 +623,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len ...@@ -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 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); pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
if (pes) 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); add_pid_to_pmt(ts, h->id, pid);
...@@ -933,78 +927,86 @@ static int mpegts_push_data(MpegTSFilter *filter, ...@@ -933,78 +927,86 @@ static int mpegts_push_data(MpegTSFilter *filter,
return 0; return 0;
} }
static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code) typedef struct {
{ uint32_t stream_type;
AVStream *st;
enum CodecID codec_id;
enum CodecType codec_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){ static const StreamType HDMV_types[] = {
case STREAM_TYPE_AUDIO_MPEG1: { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
case STREAM_TYPE_AUDIO_MPEG2: { 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
codec_type = CODEC_TYPE_AUDIO; { 0 },
codec_id = CODEC_ID_MP3; };
break;
case STREAM_TYPE_VIDEO_MPEG1: /* ATSC ? */
case STREAM_TYPE_VIDEO_MPEG2: static const StreamType MISC_types[] = {
codec_type = CODEC_TYPE_VIDEO; { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
codec_id = CODEC_ID_MPEG2VIDEO; { 0x8a, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
break; { STREAM_TYPE_SUBTITLE_DVB, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, // demuxer internal
case STREAM_TYPE_VIDEO_MPEG4: { 0 },
codec_type = CODEC_TYPE_VIDEO; };
codec_id = CODEC_ID_MPEG4;
break; static const StreamType REGD_types[] = {
case STREAM_TYPE_VIDEO_H264: { MKTAG('d','r','a','c'), CODEC_TYPE_VIDEO, CODEC_ID_DIRAC },
codec_type = CODEC_TYPE_VIDEO; { MKTAG('A','C','-','3'), CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
codec_id = CODEC_ID_H264; { 0 },
break; };
case STREAM_TYPE_VIDEO_VC1:
codec_type = CODEC_TYPE_VIDEO; static void mpegts_find_stream_type(AVStream *st,
codec_id = CODEC_ID_VC1; uint32_t stream_type, const StreamType *types)
break; {
case STREAM_TYPE_VIDEO_DIRAC: for (; types->stream_type; types++) {
codec_type = CODEC_TYPE_VIDEO; if (stream_type == types->stream_type) {
codec_id = CODEC_ID_DIRAC; st->codec->codec_type = types->codec_type;
break; st->codec->codec_id = types->codec_id;
case STREAM_TYPE_AUDIO_AAC: return;
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;
} }
break;
} }
st = av_new_stream(pes->stream, pes->pid); }
if (st) {
av_set_pts_info(st, 33, 1, 90000); static AVStream *new_pes_av_stream(PESContext *pes, uint32_t code,
st->priv_data = pes; uint32_t prog_reg_desc, uint32_t reg_desc)
st->codec->codec_type = codec_type; {
st->codec->codec_id = codec_id; AVStream *st = av_new_stream(pes->stream, pes->pid);
st->need_parsing = AVSTREAM_PARSE_FULL;
pes->st = st; 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; return st;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment