aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoakim Plate <elupus@ecce.se>2013-12-14 14:55:13 +0100
committerJoakim Plate <elupus@ecce.se>2013-12-15 15:48:36 +0100
commit4153310f31a29a3462969785be118c95a2d12f3e (patch)
treebb3343675142281a4bce8484daf9e5e60dd16cb4 /lib
parentd929efd05bd4c4c690131e5644617d2ac32e8d73 (diff)
mpegts: stop analyzing when pmt for all programs have been found
This disables NOHEADER after finding PMT for all programs to avoid find_stream_info always exhausting probe size for mpegts. This is very important for live streams since read speed will be limited. rtsp, udp and any protocol streaming a live mpegts will have dramatically faster startup time. Note, lack of codec parameters for streams can still cause the full probe size to be exhausted.
Diffstat (limited to 'lib')
-rw-r--r--lib/ffmpeg/libavformat/mpegts.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/lib/ffmpeg/libavformat/mpegts.c b/lib/ffmpeg/libavformat/mpegts.c
index 9b9c47ef85..1ae699bcdc 100644
--- a/lib/ffmpeg/libavformat/mpegts.c
+++ b/lib/ffmpeg/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 {
@@ -186,6 +189,17 @@ typedef struct PESContext {
extern AVInputFormat ff_mpegts_demuxer;
+static struct Program * get_program(MpegTSContext *ts, unsigned int programid)
+{
+ int i;
+ for(i=0; i<ts->nb_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;
@@ -206,8 +220,10 @@ static void clear_program(MpegTSContext *ts, unsigned int programid)
clear_avprogram(ts, programid);
for(i=0; i<ts->nb_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)
@@ -226,19 +242,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; i<ts->nb_prg; i++) {
- if(ts->prg[i].id == programid) {
- p = &ts->prg[i];
- break;
- }
- }
+ struct Program *p = get_program(ts, programid);
if(!p)
return;
@@ -247,6 +257,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;
@@ -1531,6 +1550,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;
@@ -1847,6 +1868,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; i<ts->nb_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;
// Note: The position here points actually behind the current packet.