Let pmt override stream info when encoutered later in the ts file.

Do not set codec id based on pes start code, this is unreliable.
Fix gazeta-20090408-1456-aa.ts

Originally committed as revision 20474 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Baptiste Coudurier 2009-11-08 03:17:08 +00:00
parent 187bc061e4
commit b3f9f7a333

View file

@ -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);
enum MpegTSFilterType { enum MpegTSFilterType {
MPEGTS_PES, MPEGTS_PES,
@ -553,22 +553,20 @@ static void mpegts_find_stream_type(AVStream *st,
} }
} }
static AVStream *new_pes_av_stream(PESContext *pes, uint32_t prog_reg_desc, uint32_t code) static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
uint32_t stream_type, uint32_t prog_reg_desc)
{ {
AVStream *st = av_new_stream(pes->stream, pes->pid);
if (!st)
return NULL;
av_set_pts_info(st, 33, 1, 90000); av_set_pts_info(st, 33, 1, 90000);
st->priv_data = pes; st->priv_data = pes;
st->codec->codec_type = CODEC_TYPE_DATA; st->codec->codec_type = CODEC_TYPE_DATA;
st->codec->codec_id = CODEC_ID_NONE; st->codec->codec_id = CODEC_ID_NONE;
st->need_parsing = AVSTREAM_PARSE_FULL; st->need_parsing = AVSTREAM_PARSE_FULL;
pes->st = st; pes->st = st;
pes->stream_type = stream_type;
dprintf(pes->stream, "stream_type=%x pid=%x prog_reg_desc=%.4s\n", av_log(pes->stream, AV_LOG_DEBUG,
pes->stream_type, pes->pid, (char*)&prog_reg_desc); "stream=%d stream_type=%x pid=%x prog_reg_desc=%.4s\n",
st->index, pes->stream_type, pes->pid, (char*)&prog_reg_desc);
st->codec->codec_tag = pes->stream_type; st->codec->codec_tag = pes->stream_type;
@ -583,13 +581,13 @@ static AVStream *new_pes_av_stream(PESContext *pes, uint32_t prog_reg_desc, uint
// priv_data cannot be shared between streams // priv_data cannot be shared between streams
PESContext *sub_pes = av_malloc(sizeof(*sub_pes)); PESContext *sub_pes = av_malloc(sizeof(*sub_pes));
if (!sub_pes) if (!sub_pes)
return NULL; return AVERROR(ENOMEM);
memcpy(sub_pes, pes, sizeof(*sub_pes)); memcpy(sub_pes, pes, sizeof(*sub_pes));
sub_st = av_new_stream(pes->stream, pes->pid); sub_st = av_new_stream(pes->stream, pes->pid);
if (!sub_st) { if (!sub_st) {
av_free(sub_pes); av_free(sub_pes);
return NULL; return AVERROR(ENOMEM);
} }
av_set_pts_info(sub_st, 33, 1, 90000); av_set_pts_info(sub_st, 33, 1, 90000);
@ -603,18 +601,7 @@ static AVStream *new_pes_av_stream(PESContext *pes, uint32_t prog_reg_desc, uint
if (st->codec->codec_id == CODEC_ID_NONE) if (st->codec->codec_id == CODEC_ID_NONE)
mpegts_find_stream_type(st, pes->stream_type, MISC_types); mpegts_find_stream_type(st, pes->stream_type, MISC_types);
/* stream was not present in PMT, guess based on PES start code */ return 0;
if (st->codec->codec_id == CODEC_ID_NONE) {
if (code >= 0x1c0 && code <= 0x1df) {
st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MP2;
} else if (code == 0x1bd) {
st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_AC3;
}
}
return st;
} }
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
@ -694,14 +681,17 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
st = pes->st; st = pes->st;
} else { } else {
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);
if (pes) if (pes)
st = new_pes_av_stream(pes, prog_reg_desc, 0); st = av_new_stream(pes->stream, pes->pid);
} }
if (!st) if (!st)
return; return;
if (!pes->stream_type)
mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
add_pid_to_pmt(ts, h->id, pid); add_pid_to_pmt(ts, h->id, pid);
av_program_add_stream_index(ts->stream, h->id, st->index); av_program_add_stream_index(ts->stream, h->id, st->index);
@ -983,10 +973,12 @@ static int mpegts_push_data(MpegTSFilter *filter,
goto skip; goto skip;
/* stream not present in PMT */ /* stream not present in PMT */
if (!pes->st) if (!pes->st) {
pes->st = new_pes_av_stream(pes, 0, code); pes->st = av_new_stream(ts->stream, pes->pid);
if (!pes->st) if (!pes->st)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
mpegts_set_stream_info(pes->st, pes, 0, 0);
}
pes->total_size = AV_RB16(pes->header + 4); pes->total_size = AV_RB16(pes->header + 4);
/* NOTE: a zero total size means the PES size is /* NOTE: a zero total size means the PES size is
@ -1110,7 +1102,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
return 0; return 0;
} }
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)
{ {
MpegTSFilter *tss; MpegTSFilter *tss;
PESContext *pes; PESContext *pes;
@ -1123,7 +1115,6 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int s
pes->stream = ts->stream; pes->stream = ts->stream;
pes->pid = pid; pes->pid = pid;
pes->pcr_pid = pcr_pid; pes->pcr_pid = pcr_pid;
pes->stream_type = stream_type;
pes->state = MPEGTS_SKIP; pes->state = MPEGTS_SKIP;
pes->pts = AV_NOPTS_VALUE; pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE; pes->dts = AV_NOPTS_VALUE;
@ -1150,7 +1141,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
is_start = packet[1] & 0x40; is_start = packet[1] & 0x40;
tss = ts->pids[pid]; tss = ts->pids[pid];
if (ts->auto_guess && tss == NULL && is_start) { if (ts->auto_guess && tss == NULL && is_start) {
add_pes_stream(ts, pid, -1, 0); add_pes_stream(ts, pid, -1);
tss = ts->pids[pid]; tss = ts->pids[pid];
} }
if (!tss) if (!tss)