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

Reply via email to