diff --git a/libavformat/segment.c b/libavformat/segment.c index bdb3a51369..23d68fde70 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -71,6 +71,7 @@ typedef struct { int nb_times; ///< number of elments in the times array char *time_delta_str; ///< approximation value duration used for the segment times int64_t time_delta; + int individual_header_trailer; /**< Set by a private option. */ int has_video; double start_time, end_time; } SegmentContext; @@ -115,18 +116,19 @@ static int segment_mux_init(AVFormatContext *s) return 0; } - -static int segment_start(AVFormatContext *s) +static int segment_start(AVFormatContext *s, int write_header) { SegmentContext *c = s->priv_data; AVFormatContext *oc = c->avf; int err = 0; - avformat_free_context(oc); - c->avf = NULL; - if ((err = segment_mux_init(s)) < 0) - return err; - oc = c->avf; + if (write_header) { + avformat_free_context(oc); + c->avf = NULL; + if ((err = segment_mux_init(s)) < 0) + return err; + oc = c->avf; + } if (c->segment_idx_wrap) c->segment_idx %= c->segment_idx_wrap; @@ -142,8 +144,10 @@ static int segment_start(AVFormatContext *s) &s->interrupt_callback, NULL)) < 0) return err; - if ((err = avformat_write_header(oc, NULL)) < 0) - return err; + if (write_header) { + if ((err = avformat_write_header(oc, NULL)) < 0) + return err; + } return 0; } @@ -188,13 +192,14 @@ static void segment_list_close(AVFormatContext *s) avio_close(seg->list_pb); } -static int segment_end(AVFormatContext *s) +static int segment_end(AVFormatContext *s, int write_trailer) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; int ret = 0; - ret = av_write_trailer(oc); + if (write_trailer) + ret = av_write_trailer(oc); if (ret < 0) av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n", @@ -413,7 +418,12 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_DEBUG, "Next segment starts with packet stream:%d pts:%"PRId64" pts_time:%f\n", pkt->stream_index, pkt->pts, pkt->pts * av_q2d(st->time_base)); - if ((ret = segment_end(s)) < 0 || (ret = segment_start(s)) < 0) + ret = segment_end(s, seg->individual_header_trailer); + + if (!ret) + ret = segment_start(s, seg->individual_header_trailer); + + if (ret) goto fail; oc = seg->avf; @@ -440,7 +450,7 @@ static int seg_write_trailer(struct AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - int ret = segment_end(s); + int ret = segment_end(s, 1); if (seg->list) segment_list_close(s); @@ -471,6 +481,7 @@ static const AVOption options[] = { { "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(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, + { "individual_header_trailer", "write header/trailer to each segment", OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, { NULL }, };