[FFmpeg-soc] [soc]: r4843 - in concat: ffmpeg.c.diff libavformat/concatgen.c libavformat/m3u.c libavformat/playlist.c libavformat/playlist.h libavformat/pls.c libavformat/xspf.c

gkovacs subversion at mplayerhq.hu
Thu Jul 30 23:28:02 CEST 2009


Author: gkovacs
Date: Thu Jul 30 23:28:01 2009
New Revision: 4843

Log:
now storing time offsets for each stream to simplify implementing seeking between files

Modified:
   concat/ffmpeg.c.diff
   concat/libavformat/concatgen.c
   concat/libavformat/m3u.c
   concat/libavformat/playlist.c
   concat/libavformat/playlist.h
   concat/libavformat/pls.c
   concat/libavformat/xspf.c

Modified: concat/ffmpeg.c.diff
==============================================================================
--- concat/ffmpeg.c.diff	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/ffmpeg.c.diff	Thu Jul 30 23:28:01 2009	(r4843)
@@ -1,5 +1,5 @@
 diff --git a/ffmpeg.c b/ffmpeg.c
-index 22bfed8..921943f 100644
+index 22bfed8..fe39b2d 100644
 --- a/ffmpeg.c
 +++ b/ffmpeg.c
 @@ -70,6 +70,8 @@
@@ -93,7 +93,7 @@ index 22bfed8..921943f 100644
      AVFormatContext *ic;
      AVFormatParameters params, *ap = &params;
      int err, i, ret, rfps, rfps_base;
-@@ -2859,6 +2884,43 @@ static void opt_input_file(const char *filename)
+@@ -2859,6 +2884,45 @@ static void opt_input_file(const char *filename)
      using_stdin |= !strncmp(filename, "pipe:", 5) ||
                      !strcmp(filename, "/dev/stdin");
  
@@ -106,7 +106,8 @@ index 22bfed8..921943f 100644
 +            ic->nb_streams = 2;
 +            ic->iformat = ff_concat_alloc_demuxer();
 +            ff_playlist_set_context(ic, playlist_ctx);
-+            ff_playlist_populate_context(ic);
++            ff_playlist_populate_context(playlist_ctx, playlist_ctx->pe_curidx);
++            ff_playlist_set_streams(ic);
 +            nb_input_files = 1;
 +            input_files[0] = ic;
 +            goto configcodecs;
@@ -128,7 +129,8 @@ index 22bfed8..921943f 100644
 +        ic->nb_streams = 2;
 +        ic->iformat = ff_concat_alloc_demuxer();
 +        ff_playlist_set_context(ic, playlist_ctx);
-+        ff_playlist_populate_context(ic);
++        ff_playlist_populate_context(playlist_ctx, playlist_ctx->pe_curidx);
++        ff_playlist_set_streams(ic);
 +        nb_input_files = 1;
 +        input_files[0] = ic;
 +        goto configcodecs;
@@ -137,7 +139,7 @@ index 22bfed8..921943f 100644
      /* get default parameters from command line */
      ic = avformat_alloc_context();
  
-@@ -2925,6 +2987,8 @@ static void opt_input_file(const char *filename)
+@@ -2925,6 +2989,8 @@ static void opt_input_file(const char *filename)
          start_time = 0;
      }
  
@@ -146,7 +148,7 @@ index 22bfed8..921943f 100644
      /* update the current parameters so that they match the one of the input stream */
      for(i=0;i<ic->nb_streams;i++) {
          AVCodecContext *enc = ic->streams[i]->codec;
-@@ -3000,6 +3064,8 @@ static void opt_input_file(const char *filename)
+@@ -3000,6 +3066,8 @@ static void opt_input_file(const char *filename)
          dump_format(ic, nb_input_files, filename, 0);
  
      nb_input_files++;
@@ -155,7 +157,7 @@ index 22bfed8..921943f 100644
      file_iformat = NULL;
      file_oformat = NULL;
  
-@@ -3874,6 +3940,7 @@ static const OptionDef options[] = {
+@@ -3874,6 +3942,7 @@ static const OptionDef options[] = {
      { "programid", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&opt_programid}, "desired program number", "" },
      { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" },
      { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)&copy_initial_nonkeyframes}, "copy initial non-keyframes" },

Modified: concat/libavformat/concatgen.c
==============================================================================
--- concat/libavformat/concatgen.c	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/concatgen.c	Thu Jul 30 23:28:01 2009	(r4843)
@@ -50,11 +50,10 @@ int ff_concatgen_read_packet(AVFormatCon
         }
         if (ret >= 0) {
             if (pkt) {
-                int64_t time_offset;
-                time_offset = av_rescale_q(ctx->time_offset, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);
-                av_log(ic, AV_LOG_DEBUG, "%s conv stream time from %ld to %d/%d is %ld\n", ic->iformat->name, ctx->time_offset, ic->streams[stream_index]->time_base.num, ic->streams[stream_index]->time_base.den, time_offset);
                 // TODO changing either dts or pts leads to timing issues on h264
-                pkt->dts += time_offset;
+                pkt->dts += av_rescale_q(ff_playlist_time_offset(ctx->durations, ctx->pe_curidx),
+                                         AV_TIME_BASE_Q,
+                                         ic->streams[stream_index]->time_base);
                 if (!ic->streams[pkt->stream_index]->codec->has_b_frames)
                     pkt->pts = pkt->dts + 1;
             }
@@ -64,9 +63,10 @@ int ff_concatgen_read_packet(AVFormatCon
             // TODO switch from AVERROR_EOF to AVERROR_EOS
             // -32 AVERROR_EOF for avi, -51 for ogg
                 av_log(ic, AV_LOG_DEBUG, "Switching stream %d to %d\n", stream_index, ctx->pe_curidx+1);
-                ctx->time_offset += av_rescale_q(ic->cur_st->duration, ic->cur_st->time_base, AV_TIME_BASE_Q);
-                if (!ctx->icl[++ctx->pe_curidx])
-                    ff_playlist_populate_context(s);
+                ctx->durations[ctx->pe_curidx] = av_rescale_q(ic->cur_st->duration, ic->cur_st->time_base, AV_TIME_BASE_Q);
+                ctx->pe_curidx = ff_playlist_stream_index_from_time(ctx, ff_playlist_time_offset(ctx->durations, ctx->pe_curidx));
+                ff_playlist_populate_context(ctx, ctx->pe_curidx);
+                ff_playlist_set_streams(s);
                 have_switched_streams = 1;
                 continue;
             } else {

Modified: concat/libavformat/m3u.c
==============================================================================
--- concat/libavformat/m3u.c	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/m3u.c	Thu Jul 30 23:28:01 2009	(r4843)
@@ -83,7 +83,8 @@ static int m3u_read_header(AVFormatConte
     PlaylistContext *ctx = av_mallocz(sizeof(*ctx));
     m3u_list_files(s->pb, ctx, s->filename);
     s->priv_data = ctx;
-    ff_playlist_populate_context(s);
+    ff_playlist_populate_context(ctx, ctx->pe_curidx);
+    ff_playlist_set_streams(s);
     return 0;
 }
 

Modified: concat/libavformat/playlist.c
==============================================================================
--- concat/libavformat/playlist.c	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/playlist.c	Thu Jul 30 23:28:01 2009	(r4843)
@@ -47,15 +47,19 @@ AVFormatContext *ff_playlist_alloc_forma
     return ic;
 }
 
-void ff_playlist_populate_context(AVFormatContext *s)
+void ff_playlist_populate_context(PlaylistContext *ctx, int pe_curidx)
+{
+    ctx->icl = av_realloc(ctx->icl, sizeof(*(ctx->icl)) * (pe_curidx+2));
+    ctx->icl[pe_curidx+1] = NULL;
+    ctx->icl[pe_curidx] = ff_playlist_alloc_formatcontext(ctx->flist[pe_curidx]);
+}
+
+void ff_playlist_set_streams(AVFormatContext *s)
 {
     int i;
     AVFormatContext *ic;
     PlaylistContext *ctx = s->priv_data;
-    ctx->icl = av_realloc(ctx->icl, sizeof(*(ctx->icl)) * (ctx->pe_curidx+2));
-    ctx->icl[ctx->pe_curidx+1] = NULL;
-    ic = ctx->icl[ctx->pe_curidx] = ff_playlist_alloc_formatcontext(ctx->flist[ctx->pe_curidx]);
-    ic->iformat->read_header(ic, 0);
+    ic = ctx->icl[ctx->pe_curidx];
     s->nb_streams = ic->nb_streams;
     for (i = 0; i < ic->nb_streams; ++i)
         s->streams[i] = ic->streams[i];
@@ -137,6 +141,8 @@ void ff_playlist_add_path(PlaylistContex
     ctx->flist = av_realloc(ctx->flist, sizeof(*(ctx->flist)) * (++ctx->pelist_size+1));
     ctx->flist[ctx->pelist_size] = NULL;
     ctx->flist[ctx->pelist_size-1] = itempath;
+    ctx->durations = av_realloc(ctx->durations, sizeof(*(ctx->durations)) * (ctx->pelist_size+1));
+    ctx->durations[ctx->pelist_size] = NULL;
 }
 
 // converts list of mixed absolute and relative paths into all absolute paths
@@ -156,3 +162,26 @@ void ff_playlist_relative_paths(char **f
             flist[i] = fullfpath;
     }
 }
+
+int64_t ff_playlist_time_offset(int64_t *durations, int pe_curidx)
+{
+    int i;
+    int64_t total = 0;
+    for (i = 0; i < pe_curidx; ++i) {
+        total += durations[i];
+    }
+    return total;
+}
+
+int ff_playlist_stream_index_from_time(PlaylistContext *ctx, int64_t pts)
+{
+    int i;
+    int64_t total;
+    i = total = 0;
+    while (pts >= total) {
+        if (i >= ctx->pelist_size)
+            break;
+        total += ctx->durations[i++];
+    }
+    return i;
+}

Modified: concat/libavformat/playlist.h
==============================================================================
--- concat/libavformat/playlist.h	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/playlist.h	Thu Jul 30 23:28:01 2009	(r4843)
@@ -46,7 +46,7 @@ typedef struct PlaylistContext {
     AVFormatContext **icl; /**< List of FormatContext for each playlist items */
     int pelist_size; /**< Number of PlayElem stored in pelist */
     int pe_curidx; /**< Index of the PlayElem that packets are being read from */
-    int64_t time_offset; /**< Time offset, in 10^-6 seconds, for all multimedia streams */
+    int64_t *durations; /**< Durations, in 10^-6 seconds, for each playlist item */
 } PlaylistContext;
 
 /** @fn int ff_playlist_alloc_playelem(PlayElem* pe)
@@ -59,7 +59,9 @@ AVFormatContext *ff_playlist_alloc_forma
  *  @brief Opens the current PlayElem from the PlaylistContext.
  *  @param s AVFormatContext of the concat-type demuxer, which contains the PlaylistContext.
  */
-void ff_playlist_populate_context(AVFormatContext *s);
+void ff_playlist_populate_context(PlaylistContext *ctx, int pe_curidx);
+
+void ff_playlist_set_streams(AVFormatContext *s);
 
 /** @fn PlaylistContext* ff_playlist_get_context(AVFormatContext *ic)
  *  @brief Returns PlaylistContext continaed within a concat-type demuxer.
@@ -115,4 +117,8 @@ PlaylistContext *ff_playlist_from_encode
  */
 void ff_playlist_add_path(PlaylistContext *ctx, char *itempath);
 
+int64_t ff_playlist_time_offset(int64_t *durations, int pe_curidx);
+
+int ff_playlist_stream_index_from_time(PlaylistContext *ctx, int64_t pts);
+
 #endif /* AVFORMAT_PLAYLIST_H */

Modified: concat/libavformat/pls.c
==============================================================================
--- concat/libavformat/pls.c	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/pls.c	Thu Jul 30 23:28:01 2009	(r4843)
@@ -110,7 +110,8 @@ static int pls_read_header(AVFormatConte
         return AVERROR_EOF;
     }
     s->priv_data = ctx;
-    ff_playlist_populate_context(s);
+    ff_playlist_populate_context(ctx, ctx->pe_curidx);
+    ff_playlist_set_streams(s);
     return 0;
 }
 

Modified: concat/libavformat/xspf.c
==============================================================================
--- concat/libavformat/xspf.c	Thu Jul 30 12:20:39 2009	(r4842)
+++ concat/libavformat/xspf.c	Thu Jul 30 23:28:01 2009	(r4843)
@@ -111,7 +111,8 @@ static int xspf_read_header(AVFormatCont
         return AVERROR_EOF;
     }
     s->priv_data = ctx;
-    ff_playlist_populate_context(s);
+    ff_playlist_populate_context(ctx, ctx->pe_curidx);
+    ff_playlist_set_streams(s);
     return 0;
 }
 


More information about the FFmpeg-soc mailing list