aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2012-10-02 23:59:35 +0200
committerMartin Storsjö <martin@martin.st>2012-10-04 13:52:09 +0300
commitc864c3968acce9cc96631ebbd362cbc207eddfbd (patch)
tree0d09fca45f2b197d8634498b0d14d0c07ac33da8
parenta854362b40f0e458db5a1fb0d2612a5702ee0ace (diff)
downloadffmpeg-c864c3968acce9cc96631ebbd362cbc207eddfbd.tar.gz
segment: Add an option for omitting the first header and final trailer
This allows writing totally bare segments, without any header/trailer included anywhere. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/segment.c52
1 files changed, 48 insertions, 4 deletions
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 },
};