X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpegts.c;h=39b1b5d552644688e3c94cc306e71d38e79888ec;hb=74a9c92840d3494393938874c1cdd5bdb95cc918;hp=d67c63a4de20480d351c7d089467e923241cdefa;hpb=8e70fdab3614a5ef709d60b67c6729c3eca93c21;p=ffmpeg diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index d67c63a4de2..39b1b5d5526 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -90,6 +90,9 @@ struct Program { unsigned int id; //program id/service id unsigned int nb_pids; unsigned int pids[MAX_PIDS_PER_PROGRAM]; + + /** have we found pmt for this program */ + int pmt_found; }; struct MpegTSContext { @@ -142,6 +145,8 @@ struct MpegTSContext { static const AVOption mpegtsraw_options[] = { {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, + {"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT, + {.i64 = 0}, 0, 0, AV_OPT_FLAG_METADATA }, { NULL }, }; @@ -155,6 +160,8 @@ static const AVClass mpegtsraw_class = { static const AVOption mpegts_options[] = { {"fix_teletext_pts", "Try to fix pts values of dvb teletext streams.", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, + {"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT, + {.i64 = 0}, 0, 0, AV_OPT_FLAG_METADATA }, { NULL }, }; @@ -205,6 +212,17 @@ typedef struct PESContext { extern AVInputFormat ff_mpegts_demuxer; +static struct Program * get_program(MpegTSContext *ts, unsigned int programid) +{ + int i; + for(i=0; inb_prg; i++) { + if(ts->prg[i].id == programid) { + return &ts->prg[i]; + } + } + return NULL; +} + static void clear_avprogram(MpegTSContext *ts, unsigned int programid) { AVProgram *prg = NULL; @@ -225,8 +243,10 @@ static void clear_program(MpegTSContext *ts, unsigned int programid) clear_avprogram(ts, programid); for(i=0; inb_prg; i++) - if(ts->prg[i].id == programid) + if(ts->prg[i].id == programid) { ts->prg[i].nb_pids = 0; + ts->prg[i].pmt_found = 0; + } } static void clear_programs(MpegTSContext *ts) @@ -245,19 +265,13 @@ static void add_pat_entry(MpegTSContext *ts, unsigned int programid) p = &ts->prg[ts->nb_prg]; p->id = programid; p->nb_pids = 0; + p->pmt_found = 0; ts->nb_prg++; } static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid) { - int i; - struct Program *p = NULL; - for(i=0; inb_prg; i++) { - if(ts->prg[i].id == programid) { - p = &ts->prg[i]; - break; - } - } + struct Program *p = get_program(ts, programid); if(!p) return; @@ -266,6 +280,15 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned i p->pids[p->nb_pids++] = pid; } +static void set_pmt_found(MpegTSContext *ts, unsigned int programid) +{ + struct Program *p = get_program(ts, programid); + if(!p) + return; + + p->pmt_found = 1; +} + static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int pid) { int i; @@ -1233,6 +1256,11 @@ static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) descr->sl.timestamp_res = avio_rb32(&d->pb); avio_rb32(&d->pb); descr->sl.timestamp_len = avio_r8(&d->pb); + if (descr->sl.timestamp_len > 64) { + avpriv_request_sample(NULL, "timestamp_len > 64"); + descr->sl.timestamp_len = 64; + return AVERROR_PATCHWELCOME; + } descr->sl.ocr_len = avio_r8(&d->pb); descr->sl.au_len = avio_r8(&d->pb); descr->sl.inst_bitrate_len = avio_r8(&d->pb); @@ -1590,6 +1618,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!ts->stream->nb_streams) ts->stop_parse = 2; + set_pmt_found(ts, h->id); + for(;;) { st = 0; pes = NULL; @@ -1912,6 +1942,21 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet) p, p_end - p, 0); } } + + // stop find_stream_info from waiting for more streams + // when all programs have received a PMT + if( ts->stream->ctx_flags & AVFMTCTX_NOHEADER) { + int i; + for(i=0; inb_prg; i++) { + if (!ts->prg[i].pmt_found) + break; + } + if (i == ts->nb_prg && ts->nb_prg > 0) { + av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n"); + ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER; + } + } + } else { int ret; int64_t pcr = -1;