Merge commit 'f8ef91ff3d6bb83d601d816ef9368f911021c64b'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 22 Aug 2013 11:37:16 +0000 (13:37 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 22 Aug 2013 11:37:16 +0000 (13:37 +0200)
* commit 'f8ef91ff3d6bb83d601d816ef9368f911021c64b':
  movenc: add faststart option for web streaming

Conflicts:
doc/muxers.texi
libavformat/movenc.c
libavformat/movenc.h

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

diff --cc doc/muxers.texi
@@@ -451,11 -240,9 +451,11 @@@ pair for each track, making it easier t
  
  This option is implicitly set when writing ismv (Smooth Streaming) files.
  @item -movflags faststart
- Run a second pass moving the moov atom on top of the file. This
- operation can take a while, and will not work in various situations such
+ Run a second pass moving the index (moov atom) to the beginning of the file.
This operation can take a while, and will not work in various situations such
  as fragmented output, thus it is not enabled by default.
 +@item -movflags rtphint
 +Add RTP hinting tracks to the output file.
  @end table
  
  Smooth Streaming content can be pushed in real time to a publishing
@@@ -52,9 -51,9 +52,9 @@@ static const AVOption options[] = 
      { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
-     { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+     { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, 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},
@@@ -74,6 -71,6 +74,8 @@@ static const AVClass flavor ## _muxer_c
      .version    = LIBAVUTIL_VERSION_INT,\
  };
  
++static int get_moov_size(AVFormatContext *s);
++
  //FIXME support 64 bit variant with wide placeholders
  static int64_t update_size(AVIOContext *pb, int64_t pos)
  {
@@@ -3535,14 -3030,9 +3522,15 @@@ static int mov_write_header(AVFormatCon
  
      /* faststart: moov at the beginning of the file, if supported */
      if (mov->flags & FF_MOV_FLAG_FASTSTART) {
-         if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+         if ((mov->flags & FF_MOV_FLAG_FRAGMENT) ||
+             (s->flags & AVFMT_FLAG_CUSTOM_IO))
              mov->flags &= ~FF_MOV_FLAG_FASTSTART;
 +        else
 +            mov->reserved_moov_size = -1;
 +    }
 +
 +    if (!supports_edts(mov) && s->avoid_negative_ts < 0) {
 +        s->avoid_negative_ts = 1;
      }
  
      /* Non-seekable output is ok if using fragmentation. If ism_lookahead
                        FF_MOV_FLAG_FRAGMENT;
      }
  
-     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
 +    if (mov->reserved_moov_size){
 +        mov->reserved_moov_pos= avio_tell(pb);
 +        if (mov->reserved_moov_size > 0)
 +            avio_skip(pb, mov->reserved_moov_size);
 +    }
 +
+     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+         if (mov->flags & FF_MOV_FLAG_FASTSTART)
+             mov->reserved_moov_pos = avio_tell(pb);
          mov_write_mdat_tag(pb, mov);
+     }
  
      if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
          mov->time = ff_iso8601_to_unix_time(t->value);
@@@ -3942,10 -3362,10 +3948,10 @@@ static int mov_write_trailer(AVFormatCo
              ffio_wfourcc(pb, "mdat");
              avio_wb64(pb, mov->mdat_size + 16);
          }
 -        avio_seek(pb, moov_pos, SEEK_SET);
 +        avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
  
-         if (mov->reserved_moov_size == -1) {
-             av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n");
+         if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+             av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
              res = shift_data(s);
              if (res == 0) {
                  avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
@@@ -156,9 -146,6 +156,7 @@@ typedef struct MOVMuxContext 
  
      int flags;
      int rtp_flags;
-     int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
-     int64_t reserved_moov_pos;
 +
      int iods_skip;
      int iods_video_profile;
      int iods_audio_profile;
      int ism_lookahead;
      AVIOContext *mdat_buf;
  
 +    int use_editlist;
 +    int video_track_timescale;
++
++    int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
+     int64_t reserved_moov_pos;
  } MOVMuxContext;
  
  #define FF_MOV_FLAG_RTP_HINT 1