Browse code

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>

Martin Storsjö authored on 2012/03/20 02:31:15
Showing 3 changed files
... ...
@@ -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) {
... ...
@@ -149,6 +149,7 @@ typedef struct MOVMuxContext {
149 149
 
150 150
     int fragments;
151 151
     int max_fragment_duration;
152
+    int min_fragment_duration;
152 153
     int max_fragment_size;
153 154
     int ism_lookahead;
154 155
     AVIOContext *mdat_buf;