Merge commit '2889c5e16711770437f380f1bead5f72c6a0b17a'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 19 Mar 2015 10:24:00 +0000 (11:24 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 19 Mar 2015 11:09:51 +0000 (12:09 +0100)
* commit '2889c5e16711770437f380f1bead5f72c6a0b17a':
  movenc: Heuristically set the duration of the last sample in a fragment if not set

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/movenc.c
libavformat/movenc.h
tests/ref/fate/sub-movtextenc

@@@ -4093,10 -3154,38 +4093,36 @@@ static int mov_flush_fragment(AVFormatC
      if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
          return 0;
  
+     for (i = 0; i < mov->nb_streams; i++) {
+         MOVTrack *track = &mov->tracks[i];
+         if (track->entry <= 1)
+             continue;
+         // Sample durations are calculated as the diff of dts values,
+         // but for the last sample in a fragment, we don't know the dts
+         // of the first sample in the next fragment, so we have to rely
+         // on what was set as duration in the AVPacket. Not all callers
+         // set this though, so we might want to replace it with an
+         // estimate if it currently is zero.
+         if (get_cluster_duration(track, track->entry - 1) != 0)
+             continue;
+         // Use the duration (i.e. dts diff) of the second last sample for
+         // the last one. This is a wild guess (and fatal if it turns out
+         // to be too long), but probably the best we can do - having a zero
+         // duration is bad as well.
+         track->track_duration += get_cluster_duration(track, track->entry - 2);
+         if (!mov->missing_duration_warned) {
+             av_log(s, AV_LOG_WARNING,
+                    "Estimating the duration of the last packet in a "
+                    "fragment, consider setting the duration field in "
+                    "AVPacket instead.\n");
+             mov->missing_duration_warned = 1;
+         }
+     }
      if (!mov->moov_written) {
          int64_t pos = avio_tell(s->pb);
 -        int ret;
 -        AVIOContext *moov_buf;
          uint8_t *buf;
 -        int buf_size;
 +        int buf_size, moov_size;
  
          for (i = 0; i < mov->nb_streams; i++)
              if (!mov->tracks[i].entry)
@@@ -189,9 -173,8 +189,10 @@@ typedef struct MOVMuxContext 
      AVFormatContext *fc;
  
      int use_editlist;
 +    float gamma;
 +
      int frag_interleave;
+     int missing_duration_warned;
  } MOVMuxContext;
  
  #define FF_MOV_FLAG_RTP_HINT              (1 <<  0)
index 9b08b21,0000000..6efe2c0
mode 100644,000000..100644
--- /dev/null
@@@ -1,1 -1,0 +1,1 @@@
- eacd7d65ec75c5520f5108b0a885a995
++ef264064c522389d0cf267c4d6235561