From b613ff5e930cb216ce97c79a561336e9de683b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 20 Jan 2012 19:29:33 +0200 Subject: [PATCH] movenc: Allow the caller to decide on fragmentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/movenc.c | 28 ++++++++++++++++++++-------- libavformat/movenc.h | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index bcf755abc7..29ba129372 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -48,6 +48,7 @@ static const AVOption options[] = { { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, @@ -2366,7 +2367,7 @@ static int mov_flush_fragment(AVFormatContext *s) return 0; } -int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) +static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt) { MOVMuxContext *mov = s->priv_data; AVIOContext *pb = s->pb; @@ -2504,6 +2505,16 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + if (!pkt) { + mov_flush_fragment(s); + return 1; + } else { + return mov_write_packet_internal(s, pkt); + } +} + // QuickTime chapters involve an additional text track with the chapter names // as samples, and a tref pointing from the other tracks to the chapter one. static void mov_create_chapter_track(AVFormatContext *s, int tracknum) @@ -2685,7 +2696,8 @@ static int mov_write_header(AVFormatContext *s) * enabled. */ if (mov->max_fragment_duration || mov->max_fragment_size || mov->flags & (FF_MOV_FLAG_EMPTY_MOOV | - FF_MOV_FLAG_FRAG_KEYFRAME)) + FF_MOV_FLAG_FRAG_KEYFRAME | + FF_MOV_FLAG_FRAG_CUSTOM)) mov->flags |= FF_MOV_FLAG_FRAGMENT; if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV)) @@ -2794,7 +2806,7 @@ AVOutputFormat ff_mov_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0}, .priv_class = &mov_muxer_class, }; @@ -2811,7 +2823,7 @@ AVOutputFormat ff_tgp_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0}, .priv_class = &tgp_muxer_class, }; @@ -2833,7 +2845,7 @@ AVOutputFormat ff_mp4_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0}, .priv_class = &mp4_muxer_class, }; @@ -2854,7 +2866,7 @@ AVOutputFormat ff_psp_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0}, .priv_class = &psp_muxer_class, }; @@ -2871,7 +2883,7 @@ AVOutputFormat ff_tg2_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0}, .priv_class = &tg2_muxer_class, }; @@ -2889,7 +2901,7 @@ AVOutputFormat ff_ipod_muxer = { .write_header = mov_write_header, .write_packet = ff_mov_write_packet, .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, + .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0}, .priv_class = &ipod_muxer_class, }; diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 4cc61b3a7d..892324948e 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -144,6 +144,7 @@ typedef struct MOVMuxContext { #define FF_MOV_FLAG_EMPTY_MOOV 4 #define FF_MOV_FLAG_FRAG_KEYFRAME 8 #define FF_MOV_FLAG_SEPARATE_MOOF 16 +#define FF_MOV_FLAG_FRAG_CUSTOM 32 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);