From d3a2a614bf51129731aab7e12ea2a13ed1729b0c Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Wed, 15 Aug 2012 22:12:11 +0200 Subject: [PATCH] lavf/segment: fix bogus segment index rewrapping logic Decouple segment index wrapping and segment count logic. The counter should not be reset since it detects the segment increasing timeframe. --- libavformat/segment.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libavformat/segment.c b/libavformat/segment.c index f945e73423..001620225b 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -42,14 +42,15 @@ typedef enum { typedef struct { const AVClass *class; /**< Class for private options. */ - int number; + int segment_idx; ///< index of the segment file to write, starting from 0 + int segment_idx_wrap; ///< number after which the index wraps + int segment_count; ///< number of segment files already written AVFormatContext *avf; char *format; ///< format to use for output segment files char *list; ///< filename for the segment list file int list_size; ///< number of entries for the segment list file ListType list_type; ///< set the list type AVIOContext *list_pb; ///< list file put-byte context - int wrap; ///< number after which the index wraps char *time_str; ///< segment duration specification string int64_t time; ///< segment duration char *times_str; ///< segment times specification string @@ -67,14 +68,15 @@ static int segment_start(AVFormatContext *s) AVFormatContext *oc = seg->avf; int err = 0; - if (seg->wrap) - seg->number %= seg->wrap; + if (seg->segment_idx_wrap) + seg->segment_idx %= seg->segment_idx_wrap; if (av_get_frame_filename(oc->filename, sizeof(oc->filename), - s->filename, seg->number++) < 0) { + s->filename, seg->segment_idx++) < 0) { av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename); return AVERROR(EINVAL); } + seg->segment_count++; if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) @@ -121,7 +123,7 @@ static int segment_end(AVFormatContext *s) oc->filename); if (seg->list) { - if (seg->list_size && !(seg->number % seg->list_size)) { + if (seg->list_size && !(seg->segment_count % seg->list_size)) { avio_close(seg->list_pb); if ((ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) @@ -204,7 +206,7 @@ static int seg_write_header(AVFormatContext *s) AVFormatContext *oc; int ret, i; - seg->number = 0; + seg->segment_count = 0; if (seg->time_str && seg->times_str) { av_log(s, AV_LOG_ERROR, @@ -274,10 +276,11 @@ static int seg_write_header(AVFormatContext *s) oc->nb_streams = s->nb_streams; if (av_get_frame_filename(oc->filename, sizeof(oc->filename), - s->filename, seg->number++) < 0) { + s->filename, seg->segment_idx++) < 0) { ret = AVERROR(EINVAL); goto fail; } + seg->segment_count++; if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) @@ -310,9 +313,10 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) int ret; if (seg->times) { - end_pts = seg->number <= seg->nb_times ? seg->times[seg->number-1] : INT64_MAX; + end_pts = seg->segment_count <= seg->nb_times ? + seg->times[seg->segment_count-1] : INT64_MAX; } else { - end_pts = seg->time * seg->number; + end_pts = seg->time * seg->segment_count; } /* if the segment has video, start a new segment *only* with a key video frame */ @@ -375,7 +379,7 @@ static const AVOption options[] = { { "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_str), AV_OPT_TYPE_STRING, {.str = "0"}, 0, 0, E }, { "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E }, - { "segment_wrap", "set number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, E }, + { "segment_wrap", "set number after which the index wraps", OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, E }, { NULL }, };