From c864c3968acce9cc96631ebbd362cbc207eddfbd Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Tue, 2 Oct 2012 23:59:35 +0200 Subject: segment: Add an option for omitting the first header and final trailer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows writing totally bare segments, without any header/trailer included anywhere. Signed-off-by: Martin Storsjö --- libavformat/segment.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'libavformat/segment.c') diff --git a/libavformat/segment.c b/libavformat/segment.c index fb5a22e6bc..1e928a7ebf 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -41,6 +41,7 @@ typedef struct { int size; /**< Set by a private option. */ int wrap; /**< Set by a private option. */ int individual_header_trailer; /**< Set by a private option. */ + int write_header_trailer; /**< Set by a private option. */ int64_t offset_time; int64_t recording_time; int has_video; @@ -119,6 +120,26 @@ static int segment_end(AVFormatContext *oc, int write_trailer) return ret; } +static int open_null_ctx(AVIOContext **ctx) +{ + int buf_size = 32768; + uint8_t *buf = av_malloc(buf_size); + if (!buf) + return AVERROR(ENOMEM); + *ctx = avio_alloc_context(buf, buf_size, AVIO_FLAG_WRITE, NULL, NULL, NULL, NULL); + if (!*ctx) { + av_free(buf); + return AVERROR(ENOMEM); + } + return 0; +} + +static void close_null_ctx(AVIOContext *pb) +{ + av_free(pb->buffer); + av_free(pb); +} + static int seg_write_header(AVFormatContext *s) { SegmentContext *seg = s->priv_data; @@ -128,6 +149,8 @@ static int seg_write_header(AVFormatContext *s) seg->number = 0; seg->offset_time = 0; seg->recording_time = seg->time * 1000000; + if (!seg->write_header_trailer) + seg->individual_header_trailer = 0; if (seg->list) if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE, @@ -166,15 +189,27 @@ static int seg_write_header(AVFormatContext *s) goto fail; } - if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) - goto fail; + if (seg->write_header_trailer) { + if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL)) < 0) + goto fail; + } else { + if ((ret = open_null_ctx(&oc->pb)) < 0) + goto fail; + } if ((ret = avformat_write_header(oc, NULL)) < 0) { avio_close(oc->pb); goto fail; } + if (!seg->write_header_trailer) { + close_null_ctx(oc->pb); + if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL)) < 0) + goto fail; + } + if (seg->list) { avio_printf(seg->pb, "%s\n", oc->filename); avio_flush(seg->pb); @@ -244,7 +279,15 @@ static int seg_write_trailer(struct AVFormatContext *s) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; - int ret = segment_end(oc); + int ret; + if (!seg->write_header_trailer) { + ret = segment_end(oc, 0); + open_null_ctx(&oc->pb); + av_write_trailer(oc); + close_null_ctx(oc->pb); + } else { + ret = segment_end(oc, 1); + } if (seg->list) avio_close(seg->pb); avformat_free_context(oc); @@ -260,6 +303,7 @@ static const AVOption options[] = { { "segment_list_size", "maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E }, { "segment_wrap", "number after which the index wraps", OFFSET(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 }, + { "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, { NULL }, }; -- cgit v1.2.3