Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 26 Jan 2012 00:52:29 +0000 (01:52 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 26 Jan 2012 01:23:56 +0000 (02:23 +0100)
* qatar/master: (22 commits)
  wma: Clip WMA1 and WMA2 frame length to 11 bits.
  movenc: Don't require frame_size to be set for modes other than mov
  doc: Update APIchanges with info on muxer flushing
  movenc: Reindent a block
  tools: Remove some unnecessary #undefs.
  rv20: prevent calling ff_h263_decode_mba() with unset height/width
  tools: K&R reformatting cosmetics
  Ignore generated aviocat and ismindex tools.
  build: Automatically include architecture-specific library Makefile snippets.
  indeo5: prevent null pointer dereference on broken files
  pktdumper: Use usleep instead of sleep
  cosmetics: Remove some unnecessary block braces.
  Drop unnecessary prefix from *sink* variable and struct names.
  Add a tool for creating smooth streaming manifests
  movdec: Calculate an average bit rate for fragmented streams, too
  movenc: Write the sample rate instead of time scale in the stsd atom
  movenc: Add a separate ismv/isma (smooth streaming) muxer
  movenc: Allow the caller to decide on fragmentation
  libavformat: Add a flag for muxers that support write_packet(NULL) for flushing
  movenc: Add support for writing fragmented mov files
  ...

Conflicts:
Changelog
cmdutils.c
cmdutils.h
doc/APIchanges
ffmpeg.c
ffplay.c
libavfilter/Makefile
libavformat/Makefile
libavformat/avformat.h
libavformat/movenc.c
libavformat/movenc.h
libavformat/version.h
tools/graph2dot.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
30 files changed:
1  2 
.gitignore
Changelog
Makefile
doc/APIchanges
ffmpeg.c
ffplay.c
libavcodec/Makefile
libavcodec/indeo5.c
libavcodec/motion_est.c
libavcodec/rv10.c
libavcodec/wma.c
libavcodec/x86/dsputil_mmx.c
libavfilter/Makefile
libavfilter/vf_hflip.c
libavformat/Makefile
libavformat/allformats.c
libavformat/avformat.h
libavformat/isom.h
libavformat/mov.c
libavformat/movenc.c
libavformat/movenc.h
libavformat/utils.c
libavformat/version.h
libswscale/ppc/swscale_altivec.c
tools/graph2dot.c
tools/lavfi-showfiltfmts.c
tools/pktdumper.c
tools/probetest.c
tools/qt-faststart.c
tools/trasher.c

diff --cc .gitignore
Simple merge
diff --cc Changelog
+++ b/Changelog
@@@ -1,44 -1,34 +1,45 @@@
  Entries are sorted chronologically from oldest to youngest within each release,
  releases are sorted from youngest to oldest.
  
 -version <next>:
 -
 -- XWD encoder and decoder
 -- Support for fragmentation in the mov/mp4 muxer
 +version next:
 +- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
 +- SBaGen (SBG) binaural beats script demuxer
 +- OpenMG Audio muxer
 +- Timecode extraction in DV and MOV
 +- thumbnail video filter
 +- XML output in ffprobe
 +- asplit audio filter
 +- tinterlace video filter
 +- astreamsync audio filter
 +- amerge audio filter
+ - ISMV (Smooth Streaming) muxer
 -
 -
 -version 0.8:
 -
  - GSM audio parser
  - SMJPEG muxer
 -
 -
 -version 0.8_beta2:
 -
 +- XWD encoder and decoder
  - Automatic thread count based on detection number of (available) CPU cores
 -- Deprecate libpostproc. If desired, the switch --enable-postproc will
 -  enable it but it may be removed in a later Libav release.
 +- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder
 +- ffprobe -show_error option
 +- Avid 1:1 10-bit RGB Packer codec
 +- v308 Quicktime Uncompressed 4:4:4 encoder and decoder
 +- yuv4 libquicktime packed 4:2:0 encoder and decoder
 +- ffprobe -show_frames option
 +- silencedetect audio filter
 +- ffprobe -show_program_version, -show_library_versions, -show_versions options
  - rv34: frame-level multi-threading
  - optimized iMDCT transform on x86 using SSE for for mpegaudiodec
 +- Improved PGS subtitle decoder
 +- dumpgraph option to lavfi device
 +- r210 and r10k encoders
  
  
 -version 0.8_beta1:
 +version 0.9:
  
 +- openal input device added
 +- boxblur filter added
  - BWF muxer
  - Flash Screen Video 2 decoder
 -- ffplay/ffprobe/ffserver renamed to avplay/avprobe/avserver
 -- ffmpeg deprecated, added avconv, which is almost the same for now, except
 +- lavfi input device added
 +- added avconv, which is almost the same for now, except
  for a few incompatible changes in the options, which will hopefully make them
  easier to use. The changes are:
      * The options placement is now strictly enforced! While in theory the
diff --cc Makefile
Simple merge
diff --cc doc/APIchanges
@@@ -13,9 -13,12 +13,15 @@@ libavutil:   2011-04-1
  
  API changes, most recent first:
  
 +2012-01-24 - xxxxxxx - lavfi 2.60.100
 +  Add avfilter_graph_dump.
 +
+ 2012-01-25 - lavf 53.22.0
+   f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible
+           buffered data within a muxer. Added AVFMT_ALLOW_FLUSH for
+           muxers supporting it (av_write_frame makes sure it is called
+           only for muxers with this flag).
  2012-01-15 - lavc 53.34.0
    New audio encoding API:
    b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio
diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -629,15 -570,8 +629,17 @@@ static int configure_video_filters(Inpu
                                         "src", args, NULL, ost->graph);
      if (ret < 0)
          return ret;
 -    ret = avfilter_graph_create_filter(&ost->output_video_filter, &sink,
 -                                       "out", NULL, &sink_ctx, ost->graph);
++
 +#if FF_API_OLD_VSINK_API
 +    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
 +                                       "out", NULL, pix_fmts, ost->graph);
 +#else
 +    buffersink_params->pixel_fmts = pix_fmts;
 +    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
 +                                       "out", NULL, buffersink_params, ost->graph);
 +#endif
 +    av_freep(&buffersink_params);
++
      if (ret < 0)
          return ret;
      last_filter = ost->input_video_filter;
diff --cc ffplay.c
+++ b/ffplay.c
@@@ -1745,16 -1714,8 +1745,17 @@@ static int configure_video_filters(AVFi
      if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
                                              NULL, is, graph)) < 0)
          return ret;
 -    if ((ret = avfilter_graph_create_filter(&filt_out, &sink, "out",
 -                                            NULL, &sink_ctx, graph)) < 0)
++
 +#if FF_API_OLD_VSINK_API
 +    ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
 +                                       NULL, pix_fmts, graph);
 +#else
 +    buffersink_params->pixel_fmts = pix_fmts;
 +    ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
 +                                       NULL, buffersink_params, graph);
 +#endif
 +    av_freep(&buffersink_params);
 +    if (ret < 0)
          return ret;
  
      if (vfilters) {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -103,71 -67,8 +103,68 @@@ OBJS-$(CONFIG_NULLSRC_FILTER
  OBJS-$(CONFIG_RGBTESTSRC_FILTER)             += vsrc_testsrc.o
  OBJS-$(CONFIG_TESTSRC_FILTER)                += vsrc_testsrc.o
  
 +OBJS-$(CONFIG_BUFFERSINK_FILTER)             += sink_buffer.o
  OBJS-$(CONFIG_NULLSINK_FILTER)               += vsink_nullsink.o
  
 -DIRS = x86
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/mp_image.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/img_format.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_2xsai.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_decimate.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_denoise3d.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_detc.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_dint.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_divtc.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_down3dright.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_dsize.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq2.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_field.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fil.o
 +#OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_filmdint.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fixpts.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_framestep.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fspp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_geq.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_harddup.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_hqdn3d.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_hue.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_il.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ilpack.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ivtc.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_kerndeint.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_mcdeint.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_mirror.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_noise.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ow.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_palette.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_perspective.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_phase.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_pp7.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_pullup.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_qp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_rectangle.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_remove_logo.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_rotate.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_sab.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_screenshot.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_smartblur.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_softpulldown.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_softskip.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_spp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_stereo3d.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_swapuv.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_telecine.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_tile.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_tinterlace.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_unsharp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_uspp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_yuvcsp.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_yvu9.o
 +OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/pullup.o
 +
 +
- -include $(SRC_PATH)/$(SUBDIR)$(ARCH)/Makefile
 +DIRS = x86 libmpcodecs
 +
 +TESTPROGS = formats
  
  TOOLS = graph2dot lavfi-showfiltfmts
Simple merge
@@@ -373,5 -351,9 +373,5 @@@ OBJS-$(CONFIG_TLS_PROTOCOL
  OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
  
  SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
 -
 -EXAMPLES  = metadata output
  TESTPROGS = seek
- TOOLS     = aviocat pktdumper probetest
+ TOOLS     = aviocat ismindex pktdumper probetest
 -
 -$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale
Simple merge
@@@ -380,9 -380,7 +380,10 @@@ typedef struct AVFormatParameters 
  #define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
  #define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
  #define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
+ #define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
 +#define AVFMT_TS_NONSTRICT  0x8000000 /**< Format does not require strictly
 +                                           increasing timestamps, but they must
 +                                           still be monotonic */
  
  /**
   * @addtogroup lavf_encoding
@@@ -411,12 -416,13 +419,12 @@@ typedef struct AVOutputFormat 
      /**
       * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE,
       * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,
-      * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS
+      * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH
       */
      int flags;
 -    /**
 -     * Currently only used to set pixel format if not YUV420P.
 -     */
 -    int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
 +
 +    void *dummy;
 +
      int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,
                               AVPacket *in, int flush);
  
Simple merge
@@@ -2713,15 -2576,19 +2716,25 @@@ static int mov_read_header(AVFormatCont
      }
      av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
  
 -    if (pb->seekable && mov->chapter_track > 0)
 -        mov_read_chapters(s);
 +    if (pb->seekable) {
 +        int i;
 +        if (mov->chapter_track > 0)
 +            mov_read_chapters(s);
 +        for (i = 0; i < s->nb_streams; i++)
 +            if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd"))
 +                mov_read_timecode_track(s, s->streams[i]);
 +    }
  
+     if (mov->trex_data) {
+         int i;
+         for (i = 0; i < s->nb_streams; i++) {
+             AVStream *st = s->streams[i];
+             MOVStreamContext *sc = st->priv_data;
+             if (st->duration)
+                 st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
+         }
+     }
      return 0;
  }
  
  static const AVOption options[] = {
      { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
      { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
-     { "frag_size", "maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
-     { "frag_duration", "maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
 +    { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
+     { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+     { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+     { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.dbl = 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, {.dbl = FF_MOV_FLAG_FRAG_CUSTOM}, 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, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
 +    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
      { "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},
      { "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},
+     { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+     { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+     { "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},
      { NULL },
  };
  
@@@ -499,24 -484,15 +502,24 @@@ static int mov_write_audio_tag(AVIOCont
          avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
          avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
          avio_wb32(pb, track->sampleSize);
 -        avio_wb32(pb, track->audio_vbr ? track->enc->frame_size : 1);
 +        avio_wb32(pb, track->enc->frame_size);
      } else {
 -        /* reserved for mp4/3gp */
 -        avio_wb16(pb, 2);
 -        avio_wb16(pb, 16);
 -        avio_wb16(pb, 0);
 +        if (track->mode == MODE_MOV) {
 +            avio_wb16(pb, track->enc->channels);
 +            if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
 +                track->enc->codec_id == CODEC_ID_PCM_S8)
 +                avio_wb16(pb, 8); /* bits per sample */
 +            else
 +                avio_wb16(pb, 16);
 +            avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
 +        } else { /* reserved for mp4/3gp */
 +            avio_wb16(pb, 2);
 +            avio_wb16(pb, 16);
 +            avio_wb16(pb, 0);
 +        }
  
          avio_wb16(pb, 0); /* packet size (= 0) */
-         avio_wb16(pb, track->timescale); /* Time scale */
+         avio_wb16(pb, track->enc->sample_rate);
          avio_wb16(pb, 0); /* Reserved */
      }
  
@@@ -1451,8 -1422,11 +1457,8 @@@ static int mov_write_trak_tag(AVIOConte
      avio_wb32(pb, 0); /* size */
      ffio_wfourcc(pb, "trak");
      mov_write_tkhd_tag(pb, track, st);
-     if(!mov->fragments) // EDTS with fragments is tricky as we dont know the duration when its written
 -    if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||
 -        (track->entry && track->cluster[0].dts)) {
 -        if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
 -            mov_write_edts_tag(pb, track);  // PSP Movies require edts box
 -    }
++    if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) // EDTS with fragments is tricky as we dont know the duration when its written
 +        mov_write_edts_tag(pb, track);  // PSP Movies and several other cases require edts box
      if (track->tref_tag)
          mov_write_tref_tag(pb, track);
      mov_write_mdia_tag(pb, track);
@@@ -1940,62 -1872,6 +1904,27 @@@ static int mov_write_uuidusmt_tag(AVIOC
      return 0;
  }
  
- static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
- {
-     int64_t pos = avio_tell(pb);
-     avio_wb32(pb, 0); /* size */
-     ffio_wfourcc(pb, "trex");
-     avio_w8(pb, 0);
-     avio_wb24(pb, 0);
-     avio_wb32(pb, track->trackID);
-     avio_wb32(pb, 1); // stsd_id
-     avio_wb32(pb, 1); // duration
-     track->trex_size= track->entry ? track->cluster[FFMIN(1, track->entry-1)].size : 1;
-     avio_wb32(pb, track->trex_size);
-     track->trex_flags= st->codec->codec_type != AVMEDIA_TYPE_VIDEO ?  0x02000000 : 0x01010000;
-     avio_wb32(pb, track->trex_flags);
-     return updateSize(pb, pos);
- }
- static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov,
-                               AVFormatContext *s)
- {
-     int i;
-     int64_t pos = avio_tell(pb);
-     avio_wb32(pb, 0); /* size placeholder*/
-     ffio_wfourcc(pb, "mvex");
-     for (i=0; i<mov->nb_streams; i++) {
-         if(mov->tracks[i].entry > 0) {
-             mov_write_trex_tag(pb, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
-         }
-     }
-     return updateSize(pb, pos);
- }
 +static void build_chunks(MOVTrack *trk)
 +{
 +    int i;
 +    MOVIentry *chunk= &trk->cluster[0];
 +    uint64_t chunkSize = chunk->size;
 +    chunk->chunkNum= 1;
 +    trk->chunkCount= 1;
 +    for(i=1; i<trk->entry; i++){
 +        if(chunk->pos + chunkSize == trk->cluster[i].pos &&
 +            chunkSize + trk->cluster[i].size < (1<<20)){
 +            chunkSize             += trk->cluster[i].size;
 +            chunk->samplesInChunk += trk->cluster[i].entries;
 +        }else{
 +            trk->cluster[i].chunkNum = chunk->chunkNum+1;
 +            chunk=&trk->cluster[i];
 +            chunkSize = chunk->size;
 +            trk->chunkCount++;
 +        }
 +    }
 +}
 +
  static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
                                AVFormatContext *s)
  {
@@@ -2346,15 -2534,6 +2592,10 @@@ static int mov_write_packet_internal(AV
          } else {
              size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
          }
-     } else if (mov->frag_seq_num>0){
-         trk->cluster[trk->entry].data = av_malloc(size);
-         if (!trk->cluster[trk->entry].data)
-             return AVERROR(ENOMEM);
-         memcpy(trk->cluster[trk->entry].data, pkt->data, size);
 +    } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 &&
 +               (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
 +        av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
 +        return -1;
      } else {
          avio_write(pb, pkt->data, size);
      }
          memcpy(trk->vosData, pkt->data, size);
      }
  
-     trk->cluster[trk->entry].pos = avio_tell(pb) - (mov->frag_seq_num==0 ? size : 0);
+     if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
 -        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
++        trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
+         if (!trk->cluster)
+             return -1;
+     }
+     trk->cluster[trk->entry].pos = avio_tell(pb) - size;
      trk->cluster[trk->entry].samplesInChunk = samplesInChunk;
 +    trk->cluster[trk->entry].chunkNum = 0;
      trk->cluster[trk->entry].size = size;
      trk->cluster[trk->entry].entries = samplesInChunk;
      trk->cluster[trk->entry].dts = pkt->dts;
@@@ -2579,16 -2780,40 +2843,45 @@@ static int mov_write_header(AVFormatCon
          }
          if (!track->height)
              track->height = st->codec->height;
+         /* The ism specific timescale isn't mandatory, but is assumed by
+          * some tools, such as mp4split. */
+         if (mov->mode == MODE_ISM)
+             track->timescale = 10000000;
  
          avpriv_set_pts_info(st, 64, 1, track->timescale);
+         /* copy extradata if it exists */
+         if (st->codec->extradata_size) {
+             track->vosLen  = st->codec->extradata_size;
+             track->vosData = av_malloc(track->vosLen);
+             memcpy(track->vosData, st->codec->extradata, track->vosLen);
+         }
+     }
+     if (mov->mode == MODE_ISM) {
+         /* If no fragmentation options have been set, set a default. */
+         if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
+                             FF_MOV_FLAG_FRAG_CUSTOM)) &&
+             !mov->max_fragment_duration && !mov->max_fragment_size)
+             mov->max_fragment_duration = 5000000;
+         mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF;
      }
  
-     mov_write_mdat_tag(pb, mov);
 +    if(mov->reserved_moov_size){
 +        mov->reserved_moov_pos= avio_tell(pb);
 +        avio_skip(pb, mov->reserved_moov_size);
 +    }
 +
+     /* Set the FRAGMENT flag if any of the fragmentation methods are
+      * enabled. */
+     if (mov->max_fragment_duration || mov->max_fragment_size ||
+         mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
+                       FF_MOV_FLAG_FRAG_KEYFRAME |
+                       FF_MOV_FLAG_FRAG_CUSTOM))
+         mov->flags |= FF_MOV_FLAG_FRAGMENT;
+     if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV))
+         mov_write_mdat_tag(pb, mov);
  
  #if FF_API_TIMESTAMP
      if (s->timestamp)
@@@ -2631,45 -2862,28 +2930,40 @@@ static int mov_write_trailer(AVFormatCo
  
      int64_t moov_pos = avio_tell(pb);
  
-     /* Write size of mdat tag */
-     if (mov->mdat_size+8 <= UINT32_MAX) {
-         avio_seek(pb, mov->mdat_pos, SEEK_SET);
-         avio_wb32(pb, mov->mdat_size+8);
-     } else {
-         /* overwrite 'wide' placeholder atom */
-         avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
-         avio_wb32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */
-         ffio_wfourcc(pb, "mdat");
-         avio_wb64(pb, mov->mdat_size+16);
-     }
-     avio_seek(pb, mov->reserved_moov_size ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
+     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+         /* Write size of mdat tag */
+         if (mov->mdat_size + 8 <= UINT32_MAX) {
+             avio_seek(pb, mov->mdat_pos, SEEK_SET);
+             avio_wb32(pb, mov->mdat_size + 8);
+         } else {
+             /* overwrite 'wide' placeholder atom */
+             avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
+             /* special value: real atom size will be 64 bit value after
+              * tag field */
+             avio_wb32(pb, 1);
+             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 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
  
-     mov_write_moov_tag(pb, mov, s);
-     if(mov->reserved_moov_size){
-         int64_t size=  mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
-         if(size < 8){
-             av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
-             return -1;
+         mov_write_moov_tag(pb, mov, s);
++        if(mov->reserved_moov_size){
++            int64_t size=  mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
++            if(size < 8){
++                av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
++                return -1;
++            }
++            avio_wb32(pb, size);
++            ffio_wfourcc(pb, "free");
++            for(i=0; i<size; i++)
++                avio_w8(pb, 0);
++            avio_seek(pb, moov_pos, SEEK_SET);
 +        }
-         avio_wb32(pb, size);
-         ffio_wfourcc(pb, "free");
-         for(i=0; i<size; i++)
-             avio_w8(pb, 0);
-         avio_seek(pb, moov_pos, SEEK_SET);
+     } else {
+         mov_flush_fragment(s);
+         mov_write_mfra_tag(pb, mov);
      }
  
-     return 0;
- }
- static int mov_write_trailer(AVFormatContext *s)
- {
-     MOVMuxContext *mov = s->priv_data;
-     AVIOContext *pb = s->pb;
-     int res = 0;
-     int i;
-     flush_cluster_buffer(s);
      if (mov->chapter_track)
          av_freep(&mov->tracks[mov->chapter_track].enc);
  
  #define MODE_MOV  0x02
  #define MODE_3GP  0x04
  #define MODE_PSP  0x08 // example working PSP command line:
 -// avconv -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
 +// ffmpeg -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
  #define MODE_3G2  0x10
  #define MODE_IPOD 0x20
+ #define MODE_ISM  0x40
  
  typedef struct MOVIentry {
      uint64_t     pos;
@@@ -119,13 -134,6 +136,9 @@@ typedef struct MOVMuxContext 
  
      int flags;
      int rtp_flags;
-     int max_fragment_duration;
-     int max_fragment_size;
 +    int reserved_moov_size;
 +    int64_t reserved_moov_pos;
 +
      int iods_skip;
      int iods_video_profile;
      int iods_audio_profile;
Simple merge
@@@ -30,8 -30,8 +30,8 @@@
  #include "libavutil/avutil.h"
  
  #define LIBAVFORMAT_VERSION_MAJOR 53
- #define LIBAVFORMAT_VERSION_MINOR 30
 -#define LIBAVFORMAT_VERSION_MINOR 23
 -#define LIBAVFORMAT_VERSION_MICRO  0
++#define LIBAVFORMAT_VERSION_MINOR 31
 +#define LIBAVFORMAT_VERSION_MICRO 100
  
  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                 LIBAVFORMAT_VERSION_MINOR, \
Simple merge
@@@ -67,18 -67,22 +67,23 @@@ static void print_digraph(FILE *outfile
                           dst_filter_ctx->name,
                           dst_filter_ctx->filter->name);
  
-                 fprintf(outfile, "\"%s\" -> \"%s\"", filter_ctx_label, dst_filter_ctx_label);
+                 fprintf(outfile, "\"%s\" -> \"%s\"",
+                         filter_ctx_label, dst_filter_ctx_label);
                  if (link->type == AVMEDIA_TYPE_VIDEO) {
-                     fprintf(outfile, " [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]",
+                     fprintf(outfile,
+                             " [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]",
                              av_pix_fmt_descriptors[link->format].name,
-                             link->w, link->h, link->time_base.num, link->time_base.den);
+                             link->w, link->h, link->time_base.num,
+                             link->time_base.den);
                  } else if (link->type == AVMEDIA_TYPE_AUDIO) {
                      char buf[255];
-                     av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
-                     fprintf(outfile, " [ label= \"fmt:%s sr:%"PRId64" cl:%s tb:%d/%d\" ]",
+                     av_get_channel_layout_string(buf, sizeof(buf), -1,
+                                                  link->channel_layout);
+                     fprintf(outfile,
 -                            " [ label= \"fmt:%s sr:%"PRId64 " cl:%s\" ]",
++                            " [ label= \"fmt:%s sr:%"PRId64" cl:%s tb:%d/%d\" ]",
                              av_get_sample_fmt_name(link->format),
 -                            link->sample_rate, buf);
 +                            link->sample_rate, buf,
 +                            link->time_base.num, link->time_base.den);
                  }
                  fprintf(outfile, ";\n");
              }
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc tools/trasher.c
Simple merge