2016-02-14 14:10 GMT+01:00 Stefano Sabatini <stefa...@gmail.com>:

> On date Saturday 2016-02-13 22:00:27 +0100, Martin Vignali encoded:
> [...]
> > From 8395ed7c66327f754e656622bacb5c2dd91d00ca Mon Sep 17 00:00:00 2001
> > From: Martin Vignali <martin.vign...@gmail.com>
> > Date: Sat, 13 Feb 2016 21:46:38 +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       |  7 +++++++
> >  libavformat/segment.c | 28 ++++++++++++++++++++++++++++
> >  2 files changed, 35 insertions(+)
> >
> > diff --git a/doc/muxers.texi b/doc/muxers.texi
> > index 2e6bb4c..21f3525 100644
> > --- a/doc/muxers.texi
> > +++ b/doc/muxers.texi
> > @@ -1017,6 +1017,13 @@ 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..fc997cc 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
> > @@ -227,6 +229,31 @@ static int segment_start(AVFormatContext *s, int
> write_header)
> >      SegmentContext *seg = s->priv_data;
> >      AVFormatContext *oc = seg->avf;
> >      int err = 0;
> > +    AVTimecode tc;
> > +    AVRational rate;
> > +    int i;
> > +
> > +    if (seg->increment_tc) {
> > +        AVDictionaryEntry *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)
> > +                        return err;
> > +                    tc.start += (int)
> av_q2d(av_mul_q(av_make_q(seg->time, 1000000 ), rate));/* increment
> timecode */
>
> > +                    char buf[AV_TIMECODE_STR_SIZE];
>
> This will create compilation warnings/failures since it's not C90
> style, put the declaration at the beginning of the block
>
> > +                    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");
> > +        }
> > +    }
> >
> >      if (write_header) {
> >          avformat_free_context(oc);
> > @@ -948,6 +975,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 },
>
> LGTM otherwise if tested, thanks.
> --
> FFmpeg = Fundamental and Fascinating Majestic Plastic Extended Guru
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


Hello,

New patch attach, i move variable declaration at the top (for
AVDictionnaryEntry too).
I also remove the return err, in case of an error occured in the
av_timecode_init_from_string function.
Instead i put an AV Log Warning, and the timecode is not modified.

Best regards

Martin
From 5e162acdc9ec4602c3263796c07ca4226b314e14 Mon Sep 17 00:00:00 2001
From: Martin Vignali <martin.vign...@gmail.com>
Date: Sun, 14 Feb 2016 15:32:27 +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       |  7 +++++++
 libavformat/segment.c | 31 +++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 2e6bb4c..21f3525 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1017,6 +1017,13 @@ 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..00680b3 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
@@ -227,6 +229,34 @@ static int segment_start(AVFormatContext *s, int write_header)
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     int err = 0;
+    AVTimecode tc;
+    AVRational rate;
+    AVDictionaryEntry *tcr;
+    char buf[AV_TIMECODE_STR_SIZE];
+    int i;
+    
+    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) av_q2d(av_mul_q(av_make_q(seg->time, 1000000 ), 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");
+        }
+    }
 
     if (write_header) {
         avformat_free_context(oc);
@@ -948,6 +978,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