Merge commit '847bf5988fec1d3e65c1d8cf0cdb8caf0cfd0c1b'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 3 Jan 2015 02:13:16 +0000 (03:13 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 3 Jan 2015 02:13:16 +0000 (03:13 +0100)
* commit '847bf5988fec1d3e65c1d8cf0cdb8caf0cfd0c1b':
  movenc: Add an option for delaying writing the moov with empty_moov

Conflicts:
libavformat/movenc.c
libavformat/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/movenc.c
libavformat/movenc.h
libavformat/version.h

@@@ -66,8 -61,9 +66,9 @@@ static const AVOption options[] = 
      { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+     { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
 -    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
 +    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
      { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
      { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
      { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
@@@ -3861,12 -3117,25 +3875,22 @@@ static int mov_flush_fragment(AVFormatC
          if (i < mov->nb_streams)
              return 0;
  
 -        if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
 -            return ret;
 -        mov_write_moov_tag(moov_buf, mov, s);
 -        buf_size = ffio_close_null_buf(moov_buf);
 +        moov_size = get_moov_size(s);
          for (i = 0; i < mov->nb_streams; i++)
 -            mov->tracks[i].data_offset = pos + buf_size + 8;
 +            mov->tracks[i].data_offset = pos + moov_size + 8;
  
+         if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
+             mov_write_identification(s->pb, s);
          mov_write_moov_tag(s->pb, mov, s);
  
+         if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
+             if (mov->flags & FF_MOV_FLAG_FASTSTART)
+                 mov->reserved_moov_pos = avio_tell(s->pb);
+             avio_flush(s->pb);
+             mov->fragments++;
+             return 0;
+         }
          buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
          mov->mdat_buf = NULL;
          avio_wb32(s->pb, buf_size + 8);
@@@ -3959,24 -3241,9 +3996,24 @@@ int ff_mov_write_packet(AVFormatContex
      int size = pkt->size, ret = 0;
      uint8_t *reformatted_data = NULL;
  
 +    if (trk->entry) {
 +        int64_t duration = pkt->dts - trk->cluster[trk->entry - 1].dts;
 +        if (duration < 0 || duration > INT_MAX) {
 +            av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" / timestamp: %"PRId64" is out of range for mov/mp4 format\n",
 +                duration, pkt->dts
 +            );
 +
 +            pkt->dts = trk->cluster[trk->entry - 1].dts + 1;
 +            pkt->pts = AV_NOPTS_VALUE;
 +        }
 +        if (pkt->duration < 0) {
 +            av_log(s, AV_LOG_ERROR, "Application provided duration: %d is invalid\n", pkt->duration);
 +            return AVERROR(EINVAL);
 +        }
 +    }
      if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
          int ret;
-         if (mov->fragments > 0) {
+         if (mov->fragments > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
              if (!trk->mdat_buf) {
                  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
                      return ret;
              trk->frag_start   = pkt->dts;
              trk->start_dts    = 0;
              trk->frag_discont = 0;
-         } else if (pkt->dts && mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
+         } else if (mov->fragments >= 1)
              av_log(s, AV_LOG_WARNING,
-                    "Track %d starts with a nonzero dts %"PRId64". This "
-                    "currently isn't handled correctly in combination with "
-                    "empty_moov.\n", pkt->stream_index, pkt->dts);
+                    "Track %d starts with a nonzero dts %"PRId64", while the moov "
+                    "already has been written. Set the delay_moov flag to handle "
+                    "this case.\n",
+                    pkt->stream_index, pkt->dts);
      }
      trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
 +    trk->last_sample_is_subtitle_end = 0;
  
      if (pkt->pts == AV_NOPTS_VALUE) {
          av_log(s, AV_LOG_WARNING, "pts has no value\n");
@@@ -4582,9 -3674,9 +4620,12 @@@ static int mov_write_header(AVFormatCon
          else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
      }
  
 +    if (s->flags & AVFMT_FLAG_BITEXACT)
 +        mov->exact = 1;
 +
+     if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
+         mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
      /* Set the FRAGMENT flag if any of the fragmentation methods are
       * enabled. */
      if (mov->max_fragment_duration || mov->max_fragment_size ||
          return AVERROR(EINVAL);
      }
  
-     if ((ret = mov_write_identification(pb, s)) < 0)
-         return ret;
 -
+     if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
+         if ((ret = mov_write_identification(pb, s)) < 0)
+             return ret;
+     }
  
      mov->nb_streams = s->nb_streams;
      if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
Simple merge
@@@ -30,8 -30,8 +30,8 @@@
  #include "libavutil/version.h"
  
  #define LIBAVFORMAT_VERSION_MAJOR 56
- #define LIBAVFORMAT_VERSION_MINOR  16
- #define LIBAVFORMAT_VERSION_MICRO 102
 -#define LIBAVFORMAT_VERSION_MINOR 11
 -#define LIBAVFORMAT_VERSION_MICRO  0
++#define LIBAVFORMAT_VERSION_MINOR  17
++#define LIBAVFORMAT_VERSION_MICRO 100
  
  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                 LIBAVFORMAT_VERSION_MINOR, \