[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