[FFmpeg-devel] Fwd: Fwd: libavformat/segment : add option to increment timecode

Stefano Sabatini stefasab at gmail.com
Tue Mar 8 19:45:52 CET 2016


On date Sunday 2016-02-28 21:41:32 +0100, Martin Vignali encoded:
> 2016-02-23 20:08 GMT+01:00 Martin Vignali <martin.vignali at gmail.com>:
[...]
> 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.vignali at 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
> + at 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
> + at 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 },

This could be _TYPE_BOOL, but no need for a separate patch.

[...]

LGTM, will apply soon if I read no more comments, thanks.
-- 
FFmpeg = Fantastic & Fostering Most Purposeless Erotic Gospel


More information about the ffmpeg-devel mailing list