This permits some interesting segmenting techniques with formats like Matroska, where you can concatenate the header and segments [N, nb_segments) and get a working file that starts at segment N's start time. --- libavformat/segment.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/libavformat/segment.c b/libavformat/segment.c index b623bb6..b84b2df 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -105,6 +105,7 @@ typedef struct SegmentContext { int64_t time_delta; int individual_header_trailer; /**< Set by a private option. */ int write_header_trailer; /**< Set by a private option. */ + char *header_filename; ///< filename to write the output header to int reset_timestamps; ///< reset timestamps at the begin of each segment int64_t initial_offset; ///< initial timestamps offset, expressed in microseconds @@ -594,6 +595,11 @@ static int seg_write_header(AVFormatContext *s) if (!seg->write_header_trailer) seg->individual_header_trailer = 0; + if (seg->header_filename) { + seg->write_header_trailer = 1; + seg->individual_header_trailer = 0; + } + if (!!seg->time_str + !!seg->times_str + !!seg->frames_str > 1) { av_log(s, AV_LOG_ERROR, "segment_time, segment_times, and segment_frames options " @@ -670,7 +676,7 @@ static int seg_write_header(AVFormatContext *s) goto fail; if (seg->write_header_trailer) { - if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, + if ((ret = avio_open2(&oc->pb, seg->header_filename ? seg->header_filename : oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename); goto fail; @@ -706,8 +712,13 @@ static int seg_write_header(AVFormatContext *s) if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0) s->avoid_negative_ts = 1; - if (!seg->write_header_trailer) { - close_null_ctxp(&oc->pb); + if (!seg->write_header_trailer || seg->header_filename) { + if (seg->header_filename) { + av_write_frame(oc, NULL); + avio_closep(&oc->pb); + } else { + close_null_ctxp(&oc->pb); + } if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) goto fail; @@ -880,6 +891,7 @@ static const AVOption options[] = { { "segment_format", "set container format used for the segments", OFFSET(format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_format_options", "set list of options for the container format used for the segments", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_list", "set the segment list filename", OFFSET(list), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, + { "segment_header_filename", "write a single file containing the header", OFFSET(header_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E }, { "segment_list_flags","set flags affecting segment list generation", OFFSET(list_flags), AV_OPT_TYPE_FLAGS, {.i64 = SEGMENT_LIST_FLAG_CACHE }, 0, UINT_MAX, E, "list_flags"}, { "cache", "allow list caching", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_CACHE }, INT_MIN, INT_MAX, E, "list_flags"}, -- 2.3.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel