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:
parent
ccfa8aa26f
commit
39f5a5462c
@ -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[] = {
|
|||||||
{ "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) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user