1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

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: Martin Storsjö <martin@martin.st>
This commit is contained in:
Martin Storsjö 2012-03-19 19:31:15 +02:00
parent ccfa8aa26f
commit 39f5a5462c
3 changed files with 18 additions and 5 deletions

View File

@ -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:

View File

@ -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)
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) {

View File

@ -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;