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>
... | ... |
@@ -172,8 +172,15 @@ Allow the caller to manually choose when to cut fragments, by |
172 | 172 |
calling @code{av_write_frame(ctx, NULL)} to write a fragment with |
173 | 173 |
the packets written so far. (This is only useful with other |
174 | 174 |
applications integrating libavformat, not from @command{avconv}.) |
175 |
+@item -min_frag_duration @var{duration} |
|
176 |
+Don't create fragments that are shorter than @var{duration} microseconds long. |
|
175 | 177 |
@end table |
176 | 178 |
|
179 |
+If more than one condition is specified, fragments are cut when |
|
180 |
+one of the specified conditions is fulfilled. The exception to this is |
|
181 |
+@code{-min_frag_duration}, which has to be fulfilled for any of the other |
|
182 |
+conditions to apply. |
|
183 |
+ |
|
177 | 184 |
Additionally, the way the output file is written can be adjusted |
178 | 185 |
through a few other options: |
179 | 186 |
|
... | ... |
@@ -56,6 +56,7 @@ static const AVOption options[] = { |
56 | 56 |
{ "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}, |
57 | 57 |
{ "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}, |
58 | 58 |
{ "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, |
59 |
+ { "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}, |
|
59 | 60 |
{ "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, |
60 | 61 |
{ "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}, |
61 | 62 |
{ NULL }, |
... | ... |
@@ -2831,21 +2832,25 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt) |
2831 | 2831 |
unsigned int samples_in_chunk = 0; |
2832 | 2832 |
int size= pkt->size; |
2833 | 2833 |
uint8_t *reformatted_data = NULL; |
2834 |
+ int64_t frag_duration = 0; |
|
2834 | 2835 |
|
2835 | 2836 |
if (!s->pb->seekable && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV)) |
2836 | 2837 |
return 0; /* Can't handle that */ |
2837 | 2838 |
|
2838 | 2839 |
if (!size) return 0; /* Discard 0 sized packets */ |
2839 | 2840 |
|
2840 |
- if ((mov->max_fragment_duration && trk->entry && |
|
2841 |
- av_rescale_q(pkt->dts - trk->cluster[0].dts, |
|
2842 |
- s->streams[pkt->stream_index]->time_base, |
|
2843 |
- AV_TIME_BASE_Q) >= mov->max_fragment_duration) || |
|
2841 |
+ if (trk->entry) |
|
2842 |
+ frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts, |
|
2843 |
+ s->streams[pkt->stream_index]->time_base, |
|
2844 |
+ AV_TIME_BASE_Q); |
|
2845 |
+ if ((mov->max_fragment_duration && |
|
2846 |
+ frag_duration >= mov->max_fragment_duration) || |
|
2844 | 2847 |
(mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) || |
2845 | 2848 |
(mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME && |
2846 | 2849 |
enc->codec_type == AVMEDIA_TYPE_VIDEO && |
2847 | 2850 |
trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) { |
2848 |
- mov_flush_fragment(s); |
|
2851 |
+ if (frag_duration >= mov->min_fragment_duration) |
|
2852 |
+ mov_flush_fragment(s); |
|
2849 | 2853 |
} |
2850 | 2854 |
|
2851 | 2855 |
if (mov->flags & FF_MOV_FLAG_FRAGMENT) { |