Commit 39f5a546 authored by Martin Storsjö's avatar Martin Storsjö

movenc: Add a min_frag_duration option

The other fragmentation options (frag_duration, frag_size and
frag_keyframe) are combined with OR, cutting fragments at the
first of the conditions being fulfilled.
Signed-off-by: 's avatarMartin Storsjö <martin@martin.st>
parent ccfa8aa2
...@@ -172,8 +172,15 @@ Allow the caller to manually choose when to cut fragments, by ...@@ -172,8 +172,15 @@ Allow the caller to manually choose when to cut fragments, by
calling @code{av_write_frame(ctx, NULL)} to write a fragment with calling @code{av_write_frame(ctx, NULL)} to write a fragment with
the packets written so far. (This is only useful with other the packets written so far. (This is only useful with other
applications integrating libavformat, not from @command{avconv}.) applications integrating libavformat, not from @command{avconv}.)
@item -min_frag_duration @var{duration}
Don't create fragments that are shorter than @var{duration} microseconds long.
@end table @end table
If more than one condition is specified, fragments are cut when
one of the specified conditions is fulfilled. The exception to this is
@code{-min_frag_duration}, which has to be fulfilled for any of the other
conditions to apply.
Additionally, the way the output file is written can be adjusted Additionally, the way the output file is written can be adjusted
through a few other options: through a few other options:
......
...@@ -56,6 +56,7 @@ static const AVOption options[] = { ...@@ -56,6 +56,7 @@ static const AVOption options[] = {
{ "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}, { "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},
{ "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
{ "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
{ NULL }, { NULL },
...@@ -2831,21 +2832,25 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt) ...@@ -2831,21 +2832,25 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
unsigned int samples_in_chunk = 0; unsigned int samples_in_chunk = 0;
int size= pkt->size; int size= pkt->size;
uint8_t *reformatted_data = NULL; uint8_t *reformatted_data = NULL;
int64_t frag_duration = 0;
if (!s->pb->seekable && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV)) if (!s->pb->seekable && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV))
return 0; /* Can't handle that */ return 0; /* Can't handle that */
if (!size) return 0; /* Discard 0 sized packets */ if (!size) return 0; /* Discard 0 sized packets */
if ((mov->max_fragment_duration && trk->entry && if (trk->entry)
av_rescale_q(pkt->dts - trk->cluster[0].dts, frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
s->streams[pkt->stream_index]->time_base, s->streams[pkt->stream_index]->time_base,
AV_TIME_BASE_Q) >= mov->max_fragment_duration) || AV_TIME_BASE_Q);
if ((mov->max_fragment_duration &&
frag_duration >= mov->max_fragment_duration) ||
(mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) || (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
(mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME && (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
enc->codec_type == AVMEDIA_TYPE_VIDEO && enc->codec_type == AVMEDIA_TYPE_VIDEO &&
trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) { trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) {
mov_flush_fragment(s); if (frag_duration >= mov->min_fragment_duration)
mov_flush_fragment(s);
} }
if (mov->flags & FF_MOV_FLAG_FRAGMENT) { if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
......
...@@ -149,6 +149,7 @@ typedef struct MOVMuxContext { ...@@ -149,6 +149,7 @@ typedef struct MOVMuxContext {
int fragments; int fragments;
int max_fragment_duration; int max_fragment_duration;
int min_fragment_duration;
int max_fragment_size; int max_fragment_size;
int ism_lookahead; int ism_lookahead;
AVIOContext *mdat_buf; AVIOContext *mdat_buf;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment