2016-02-23 20:08 GMT+01:00 Martin Vignali <martin.vign...@gmail.com>:
> > > 2016-02-23 19:41 GMT+01:00 Stefano Sabatini <stefa...@gmail.com>: > >> On date Friday 2016-02-19 14:04:12 +0100, Martin Vignali encoded: >> > 2016-02-15 2:35 GMT+01:00 Stefano Sabatini <stefa...@gmail.com>: >> [...] >> > > > + err = av_timecode_init_from_string(&tc, rate, >> > > tcr->value, s); >> > > > + if (err < 0) { >> > > > + av_log(s, AV_LOG_WARNING, "Could not >> increment >> > > timecode, error occured during timecode creation."); >> > > > + break; >> > > > + } >> > > >> > > > + tc.start += (int) >> > > av_q2d(av_mul_q(av_make_q(seg->time, 1000000 ), rate));/* increment >> > > timecode */ >> > > >> > > nit: 1000000_) => 1000000) >> > > >> > > Also, reading from the timecode.c code it looks like the increment >> > > must be expressed in fps units. >> > > >> > >> > Sorry don't understand what's wrong now. In my tests, the timecode >> > incrementation is correct (but maybe i missed a special case) >> >> Not necessarily a problem, assuming the fps is consistent with the >> rate. >> > > Ok, so i think there is no problem, because timecode is created with the > rate (av_timecode_init_from_string set the fps from rate.), > and the increment is made with the rate. > Both values are consistent. > > > >> >> > > Finally, you are using the segment->time, which is different from the >> > > effective segment duration. Could you set the metadata in segment_end, >> > > where the exact duration is known? >> > > >> > >> > Do you know how can i get the exact segment duration ? >> >> What about setting the metadata when you're *closing* the segment >> (e.g. in segment_end())? >> >> This way you can know the exact duration. >> -- >> >> > Ok for that, but in fact my question is more about the way to have a more > precise duration than segment->time. > > Thanks, > > Martin > > Hello, New patch attached, with the timecode incrementation inside segment_end() Use this time start_time and end_time (from SegmentListEntry) to calculate the duration of the segment. Best regards Martin
From 6aab70f629ae8b951574c27d70f06e80334a9309 Mon Sep 17 00:00:00 2001 From: Martin Vignali <martin.vign...@gmail.com> Date: Sun, 28 Feb 2016 21:36:42 +0100 Subject: [PATCH] lavf/segment: add increment timecode option for example you can split a file, keeping a continuous timecode between each segment : ffmpeg -i src.mov -timecode 10:00:00:00 -vcodec copy -f segment \ -segment_time 2 -reset_timestamps 1 -increment_tc 1 target_%03d.mov --- doc/muxers.texi | 6 ++++++ libavformat/segment.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/doc/muxers.texi b/doc/muxers.texi index 2e6bb4c..c2d26a8 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1017,6 +1017,12 @@ implementation for HLS segmentation. The segment muxer supports the following options: @table @option +@item increment_tc @var{1|0} +if set to @code{1}, increment timecode between each segment +If this is selected, the input need to have +a timecode in the first video stream. Default value is +@code{0}. + @item reference_stream @var{specifier} Set the reference stream, as specified by the string @var{specifier}. If @var{specifier} is set to @code{auto}, the reference is chosen diff --git a/libavformat/segment.c b/libavformat/segment.c index dd3b092..6335c89 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -41,6 +41,7 @@ #include "libavutil/parseutils.h" #include "libavutil/mathematics.h" #include "libavutil/time.h" +#include "libavutil/timecode.h" #include "libavutil/time_internal.h" #include "libavutil/timestamp.h" @@ -95,6 +96,7 @@ typedef struct SegmentContext { char *time_str; ///< segment duration specification string int64_t time; ///< segment duration int use_strftime; ///< flag to expand filename with strftime + int increment_tc; ///< flag to increment timecode if found char *times_str; ///< segment times specification string int64_t *times; ///< list of segment interval specification @@ -337,6 +339,12 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; int ret = 0; + AVTimecode tc; + AVRational rate; + AVDictionaryEntry *tcr; + char buf[AV_TIMECODE_STR_SIZE]; + int i; + int err; av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */ if (write_trailer) @@ -390,6 +398,29 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) seg->avf->filename, seg->segment_count); seg->segment_count++; + if (seg->increment_tc) { + tcr = av_dict_get(s->metadata, "timecode", NULL, 0); + if (tcr) { + /* search the first video stream */ + for (i = 0; i < s->nb_streams; i++) { + if (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + rate = s->streams[i]->avg_frame_rate;/* Get fps from the video stream */ + err = av_timecode_init_from_string(&tc, rate, tcr->value, s); + if (err < 0) { + av_log(s, AV_LOG_WARNING, "Could not increment timecode, error occured during timecode creation."); + break; + } + tc.start += (int)((seg->cur_entry.end_time - seg->cur_entry.start_time) * av_q2d(rate));/* increment timecode */ + av_dict_set(&s->metadata, "timecode", + av_timecode_make_string(&tc, buf, 0), 0); + break; + } + } + } else { + av_log(s, AV_LOG_WARNING, "Could not increment timecode, no timecode metadata found"); + } + } + end: ff_format_io_close(oc, &oc->pb); @@ -948,6 +979,7 @@ static const AVOption options[] = { { "segment_start_number", "set the sequence number of the first segment", OFFSET(segment_idx), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, { "segment_wrap_number", "set the number of wrap before the first segment", OFFSET(segment_idx_wrap_nb), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, { "strftime", "set filename expansion with strftime at segment creation", OFFSET(use_strftime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, + { "increment_tc", "increment timecode between each segment", OFFSET(increment_tc), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, E }, { "break_non_keyframes", "allow breaking segments on non-keyframes", OFFSET(break_non_keyframes), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E }, { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, E }, -- 1.9.3 (Apple Git-50)
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel