ffmpeg: add patch to stop find_stream info when all pmt's are found
authorJoakim Plate <elupus@ecce.se>
Sun, 15 Dec 2013 14:49:55 +0000 (15:49 +0100)
committerJoakim Plate <elupus@ecce.se>
Sun, 15 Dec 2013 14:49:55 +0000 (15:49 +0100)
lib/ffmpeg/patches/0060-mpegts-stop-analyzing-when-pmt-for-all-programs-have.patch [new file with mode: 0644]

diff --git a/lib/ffmpeg/patches/0060-mpegts-stop-analyzing-when-pmt-for-all-programs-have.patch b/lib/ffmpeg/patches/0060-mpegts-stop-analyzing-when-pmt-for-all-programs-have.patch
new file mode 100644 (file)
index 0000000..ed23469
--- /dev/null
@@ -0,0 +1,135 @@
+From 120e44f817d73572d14a3db4af24a3d517aaacd8 Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@ecce.se>
+Date: Sat, 14 Dec 2013 14:55:13 +0100
+Subject: [PATCH 1/1] 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.
+---
+ libavformat/mpegts.c | 54 +++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 45 insertions(+), 9 deletions(-)
+
+diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
+index d67c63a..fa92fb7 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 {
+@@ -205,6 +208,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;
+@@ -225,8 +239,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)
+@@ -245,19 +261,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;
+@@ -266,6 +276,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;
+@@ -1590,6 +1609,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 +1933,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;
+         int64_t pcr = -1;
+-- 
+1.8.2
+