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

Deti Fliegl deti at fliegl.de
Fri Jul 4 15:12:12 CEST 2014


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.
+
 @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
+    int64_t last_val;      ///< remember last time for wrap around
detection
+    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
+    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);
+            usecs = (ti->tm_hour*3600 + ti->tm_min*60 + ti->tm_sec) *
100000 + now.tv_usec/10;
+            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);
+        }
     }

     av_dlog(s, "packet stream:%d pts:%s pts_time:%s is_key:%d frame:%d\n",
@@ -686,7 +710,7 @@ static int seg_write_packet(AVFormatContext *s,
AVPacket *pkt)

     if (pkt->stream_index == seg->reference_stream_index &&
         pkt->flags & AV_PKT_FLAG_KEY &&
-        (seg->frame_count >= start_frame ||
+        (cut_pending || seg->frame_count >= start_frame ||
          (pkt->pts != AV_NOPTS_VALUE &&
           av_compare_ts(pkt->pts, st->time_base,
                         end_pts-seg->time_delta, AV_TIME_BASE_Q) >= 0))) {
@@ -795,6 +819,7 @@ static const AVOption options[] = {
     { "m3u8", "M3U8 format",     0, AV_OPT_TYPE_CONST,
{.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E, "list_type" },
     { "hls", "Apple HTTP Live Streaming compatible", 0,
AV_OPT_TYPE_CONST, {.i64=LIST_TYPE_M3U8 }, INT_MIN, INT_MAX, E,
"list_type" },

+    { "segment_atclocktime",      "set segment to be cut at clocktime",
 OFFSET(use_clocktime), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E},
     { "segment_time",      "set segment duration",
  OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
     { "segment_time_delta","set approximation value used for the
segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0,
0, E },
     { "segment_times",     "set segment split time points",
  OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
-- 
1.9.1



More information about the ffmpeg-devel mailing list