[FFmpeg-devel] [PATCH] libavformat/segment.c cut at clocktime

Stefano Sabatini stefasab at gmail.com
Fri Jul 4 17:27:30 CEST 2014


On date Friday 2014-07-04 15:12:12 +0200, Deti Fliegl encoded:
> Signed-off-by: Deti fliegl <fliegl at baycom.de>
> ---
>  doc/muxers.texi       |  7 +++++++
>  libavformat/segment.c | 29 +++++++++++++++++++++++++++--
>  2 files changed, 34 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index da7f186..fa18b1d 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -879,6 +879,13 @@ Note that splitting may not be accurate, unless you
> force the
>  reference stream key-frames at the given time. See the introductory
>  notice and the examples below.
> 

> + at item segment_atclocktime @var{atclocktime}
> +Setting @var{atclocktime} to "1" tells the segmenter to split at regular
> +clock time. Default value is "0". The @var{time} value specified in
> + at option{segment_time} is used for setting the length of the segment. For
> +example with @option{segment_time} set to "900" this makes it possible to
> +create files at 12:00 o'clock, 12:15, 12:30, etc.

Consistency edit:

@item segment_atclocktime @var{1|0}
If set to 1 split at regular clock time intervals starting from 00:00
o'clock. The @var{time} value specified in @option{segment_time} is
used for setting the length of the splitting interval.

For example with @option{segment_time} set to "900" this makes it possible
to create files at 12:00 o'clock, 12:15, 12:30, etc.

Default value is 0.

>  @item segment_time_delta @var{delta}
>  Specify the accuracy time when selecting the start time for a
>  segment, expressed as a duration specification. Default value is "0".
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index fe84f27..1fee55b 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -27,6 +27,8 @@
>  /* #define DEBUG */
> 
>  #include <float.h>
> +#include <time.h>
> +#include <sys/time.h>
> 
>  #include "avformat.h"
>  #include "internal.h"
> @@ -73,6 +75,11 @@ typedef struct {
>      char *list;            ///< filename for the segment list file
>      int   list_flags;      ///< flags affecting list generation
>      int   list_size;       ///< number of entries for the segment list file

> +
> +    int *use_clocktime;    ///< flag to cut segments at regular clock time

again, this should be int use_clocktime (note the "*")

> +    int64_t last_val;      ///< remember last time for wrap around
> detection

uh mangled patch, possibly send the patch as an attachment

> +    int64_t last_cut;      ///< remember last cut
> +
>      char *entry_prefix;    ///< prefix to add to list entry filenames
>      ListType list_type;    ///< set the list type
>      AVIOContext *list_pb;  ///< list file put-byte context
> @@ -668,6 +675,11 @@ static int seg_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>      int64_t end_pts = INT64_MAX, offset;
>      int start_frame = INT_MAX;
>      int ret;
> +    struct tm *ti;
> +    struct timeval now;

> +    int64_t usecs; // to prevent integer overflow this value is only
> usecs/10

why do you think there is an integer overflow here?

> +    int64_t wrapped_val;
> +    int cut_pending = 0;
> 
>      if (seg->times) {
>          end_pts = seg->segment_count < seg->nb_times ?
> @@ -676,7 +688,19 @@ static int seg_write_packet(AVFormatContext *s,
> AVPacket *pkt)
>          start_frame = seg->segment_count <= seg->nb_frames ?
>              seg->frames[seg->segment_count] : INT_MAX;
>      } else {
> -        end_pts = seg->time * (seg->segment_count+1);
> +        if (seg->use_clocktime) {
> +            gettimeofday(&now, NULL);
> +            ti = localtime(&now.tv_sec);

Ideally, use localtime_r since this is not thread-safe, see the
ifdeffery as used in other parts of the code, for example
libavcodec/jacobsubdec.c.

> +            usecs = (ti->tm_hour*3600 + ti->tm_min*60 + ti->tm_sec) *
> 100000 + now.tv_usec/10;

Why do you think there is an integer overflow here?

The maximum value you can get here is 24 * 3600 * 1000000 - 1 which is
far below the maximum positive value stored in an int64_t (2^63-1).

> +            wrapped_val = usecs % (seg->time / 10);
> +            if (seg->last_cut != usecs && wrapped_val < seg->last_val) {
> +                cut_pending = 1;
> +                seg->last_cut = usecs;
> +            }
> +            seg->last_val = wrapped_val;
> +        } else {
> +            end_pts = seg->time * (seg->segment_count+1);
> +        }
>      }

[...]
-- 
FFmpeg = Frightening Funny Mastodontic Problematic Extravagant Gnome


More information about the ffmpeg-devel mailing list