[FFmpeg-devel] [PATCH] libavformat/segment.c cut at clocktime
Stefano Sabatini
stefasab at gmail.com
Thu Jul 3 20:09:03 CEST 2014
On date Thursday 2014-07-03 13:19:04 +0200, Deti Fliegl encoded:
> Hello,
>
> this patch allows the segmenter to cut a segment aligned to normal
> clocktime. For example it is possible to get a new segment every 15
> minutes at 12:00, 12:15, 12:30, 12:45, ... with this simple syntax:
>
> ffmpeg -i http://stream.example.org -f segment -segment_time 900
> -segment_atclocktime 1 -c copy -map 0 output%02d.mp3
>
> The code is designed to start counting at midnight and it cuts at this
> condition:
>
> if(!(seconds_since_midnight % segment_time_in_seconds)) {
> ...
> }
>
> We use this feature for logging live signals.
>
> Deti
> diff --git a/libavformat/segment.c b/libavformat/segment.c
Please send a git-format patch complete with author info. Also please
update doc/muxers.texi segment documentation.
> index fe84f27..c1c315e 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -38,6 +38,7 @@
> #include "libavutil/parseutils.h"
> #include "libavutil/mathematics.h"
> #include "libavutil/timestamp.h"
> +#include "libavutil/time.h"
>
> typedef struct SegmentListEntry {
> int index;
> @@ -73,6 +74,9 @@ 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; ///< cut segments at regular clock time
int use_clocktime; ??
> + int cut_pending; ///< cut at clocktime pending
> + int 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 +672,9 @@ 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;
> + time_t now;
> + int secs;
this could be double (in the not very likely but not impossible case
the user wants to cut at second fragments).
>
> if (seg->times) {
> end_pts = seg->segment_count < seg->nb_times ?
> @@ -676,7 +683,17 @@ 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) {
nit: if_(
> + now = time(NULL);
> + ti = localtime(&now);
> + secs=ti->tm_hour*3600+ti->tm_min*60+ti->tm_sec;
> + if(seg->last_cut != secs && !(secs % (seg->time/1000000))) {
> + seg->cut_pending = 1;
> + seg->last_cut = secs;
> + }
> + } 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,10 +703,11 @@ 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 ||
> + (seg->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))) {
> + seg->cut_pending = 0;
> if ((ret = segment_end(s, seg->individual_header_trailer, 0)) < 0)
> goto fail;
>
> @@ -795,6 +813,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 },
--
FFmpeg = Fascinating and Frenzy Merciful Proud Elastic God
More information about the ffmpeg-devel
mailing list