[FFmpeg-devel] [PATCH] ffmpeg: add otsoffset option

Stefano Sabatini stefasab at gmail.com
Thu Jan 23 18:47:36 CET 2014


This option is useful to add a given offset to the output. Since it works
at the muxing level, it doesn't need transcoding.

This is slightly more convenient to use than -itsoffset, since it only
works with -copyts, while the new option allows to set the absolute
offset when -copyts is not selected.

TODO: mention the option in Changelog
---
 doc/ffmpeg.texi | 12 ++++++++++++
 ffmpeg.c        | 19 +++++++++++++------
 ffmpeg.h        |  3 ++-
 ffmpeg_opt.c    |  4 ++++
 4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index fb7a198..ff7a08e 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -316,6 +316,18 @@ The offset is added to the timestamps of the input files. Specifying
 a positive offset means that the corresponding streams are delayed by
 the time duration specified in @var{offset}.
 
+ at item -otsoffset @var{offset} (@emph{input})
+Set the output time offset.
+
+ at var{offset} must be a time duration specification,
+see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
+
+The offset is added to the timestamps of the output files, before
+being sent to the muxer.
+
+Specifying a positive offset means that the corresponding streams are
+delayed bt the time duration specified in @var{offset}.
+
 @item -timestamp @var{date} (@emph{output})
 Set the recording timestamp in the container.
 
diff --git a/ffmpeg.c b/ffmpeg.c
index aacf938..0685ff5 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -561,6 +561,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
 {
     AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
     AVCodecContext          *avctx = ost->st->codec;
+    OutputFile *of = output_files[ost->file_index];
     int ret;
 
     if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
@@ -644,14 +645,20 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
 
     pkt->stream_index = ost->index;
 
+    if (pkt->dts != AV_NOPTS_VALUE)
+        pkt->dts += av_rescale_q(of->ts_offset, AV_TIME_BASE_Q, ost->st->time_base);
+    if (pkt->pts != AV_NOPTS_VALUE)
+        pkt->pts += av_rescale_q(of->ts_offset, AV_TIME_BASE_Q, ost->st->time_base);
+
     if (debug_ts) {
         av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
-                "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
-                av_get_media_type_string(ost->st->codec->codec_type),
-                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
-                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
-                pkt->size
-              );
+               "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s size:%d\n",
+               av_get_media_type_string(ost->st->codec->codec_type),
+               av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
+               av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
+               av_ts2str(of->ts_offset),
+               av_ts2timestr(of->ts_offset, &AV_TIME_BASE_Q),
+               pkt->size);
     }
 
     ret = av_interleaved_write_frame(s, pkt);
diff --git a/ffmpeg.h b/ffmpeg.h
index 00f7a2a..542215e 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -119,6 +119,7 @@ typedef struct OptionsContext {
     int        nb_hwaccel_devices;
 
     /* output options */
+    int64_t output_ts_offset;
     StreamMap *stream_maps;
     int     nb_stream_maps;
     AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */
@@ -421,7 +422,7 @@ typedef struct OutputFile {
     int64_t recording_time;  ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
     int64_t start_time;      ///< start time in microseconds == AV_TIME_BASE units
     uint64_t limit_filesize; /* filesize limit expressed in bytes */
-
+    int64_t ts_offset;       ///< TS offset in AV_TIME_BASE unit to apply to output timestamps
     int shortest;
 } OutputFile;
 
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 4e0dc47..824e90d 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1689,6 +1689,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
     of->ost_index      = nb_output_streams;
     of->recording_time = o->recording_time;
     of->start_time     = o->start_time;
+    of->ts_offset      = o->output_ts_offset;
     of->limit_filesize = o->limit_filesize;
     of->shortest       = o->shortest;
     av_dict_copy(&of->opts, o->g->format_opts, 0);
@@ -2710,6 +2711,9 @@ const OptionDef options[] = {
     { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
         "set the input ts offset", "time_off" },
+    { "otsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
+                        OPT_EXPERT | OPT_OUTPUT,                      { .off = OFFSET(output_ts_offset) },
+        "set the output ts offset", "time_off" },
     { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC |
                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(ts_scale) },
         "set the input ts scale", "scale" },
-- 
1.8.1.2



More information about the ffmpeg-devel mailing list