[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
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 = ¶ms; 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*)©_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; }
participants (1)
-
gkovacs