[FFmpeg-devel] [PATCH 1/2] avformat: Optimize av_find_program_from_stream() so it is O(1) instead of O(streams*programs)

Michael Niedermayer michaelni at gmx.at
Sat Feb 14 04:04:45 CET 2015


Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavformat/avformat.h |    5 +++++
 libavformat/mpegts.c   |    3 +++
 libavformat/utils.c    |   10 ++++++++++
 3 files changed, 18 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 3007f81..3dbbaca 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1111,6 +1111,11 @@ typedef struct AVStream {
      * - decoding: Set by libavformat to calculate sample_aspect_ratio internally
      */
     AVRational display_aspect_ratio;
+
+    /**
+     * Internal data for optimizig finding AVPrograms
+     */
+    int program_index;
 } AVStream;
 
 AVRational av_stream_get_r_frame_rate(const AVStream *s);
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index afda648..0d7eb65 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -263,6 +263,9 @@ static void clear_avprogram(MpegTSContext *ts, unsigned int programid)
         }
     if (!prg)
         return;
+    for (i = 0; i<prg->nb_stream_indexes; i++) {
+        ts->stream->streams[prg->stream_index[i]]->program_index = INT_MAX;
+    }
     prg->nb_stream_indexes = 0;
 }
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 917f8ce..fb79ecd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3455,6 +3455,12 @@ AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int
 {
     int i, j;
 
+    i = ic->streams[s]->program_index;
+    if (i<INT_MAX && !last) {
+        av_assert0(i<ic->nb_programs);
+        return ic->programs[i];
+    }
+
     for (i = 0; i < ic->nb_programs; i++) {
         if (ic->programs[i] == last) {
             last = NULL;
@@ -3707,6 +3713,7 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
     st->info->fps_last_dts  = AV_NOPTS_VALUE;
 
     st->inject_global_side_data = s->internal->inject_global_side_data;
+    st->program_index = INT_MAX;
 
     s->streams[s->nb_streams++] = st;
     return st;
@@ -3774,6 +3781,7 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
 {
     int i, j;
     AVProgram *program = NULL;
+    AVStream *st = ac->streams[idx];
     void *tmp;
 
     if (idx >= ac->nb_streams) {
@@ -3794,6 +3802,8 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
             return;
         program->stream_index = tmp;
         program->stream_index[program->nb_stream_indexes++] = idx;
+        st->program_index = FFMIN(st->program_index, i);
+
         return;
     }
 }
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list