Merge commit 'd872fb0f7ff2ff0ba87f5ccf6a1a55ca2be472c9'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 27 Sep 2013 10:13:41 +0000 (12:13 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 27 Sep 2013 10:13:41 +0000 (12:13 +0200)
* commit 'd872fb0f7ff2ff0ba87f5ccf6a1a55ca2be472c9':
  lavf: Reset the entry count and allocation size variables on av_reallocp failures

Conflicts:
libavformat/avienc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
12 files changed:
1  2 
libavformat/avidec.c
libavformat/avienc.c
libavformat/aviobuf.c
libavformat/mmst.c
libavformat/oggparsetheora.c
libavformat/oggparsevorbis.c
libavformat/rdt.c
libavformat/rtmphttp.c
libavformat/rtmpproto.c
libavformat/rtpdec_qt.c
libavformat/smacker.c
libavformat/smoothstreamingenc.c

diff --combined libavformat/avidec.c
@@@ -2,27 -2,25 +2,27 @@@
   * AVI demuxer
   * Copyright (c) 2001 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
 +#include "libavutil/avassert.h"
  #include "libavutil/avstring.h"
  #include "libavutil/bswap.h"
 +#include "libavutil/opt.h"
  #include "libavutil/dict.h"
  #include "libavutil/internal.h"
  #include "libavutil/intreadwrite.h"
@@@ -33,6 -31,9 +33,6 @@@
  #include "internal.h"
  #include "riff.h"
  
 -#undef NDEBUG
 -#include <assert.h>
 -
  typedef struct AVIStream {
      int64_t frame_offset;   /* current frame (video) or byte (audio) counter
                               * (used to compute the pts) */
      AVFormatContext *sub_ctx;
      AVPacket sub_pkt;
      uint8_t *sub_buffer;
 +
 +    int64_t seek_pos;
  } AVIStream;
  
  typedef struct {
 +    const AVClass *class;
      int64_t riff_end;
      int64_t movi_end;
      int64_t fsize;
 +    int64_t io_fsize;
      int64_t movi_list;
      int64_t last_pkt_pos;
      int index_loaded;
      int stream_index;
      DVDemuxContext *dv_demux;
      int odml_depth;
 +    int use_odml;
  #define MAX_ODML_DEPTH 1000
 +    int64_t dts_max;
  } AVIContext;
  
 +
 +static const AVOption options[] = {
 +    { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
 +    { NULL },
 +};
 +
 +static const AVClass demuxer_class = {
 +    .class_name = "avi",
 +    .item_name  = av_default_item_name,
 +    .option     = options,
 +    .version    = LIBAVUTIL_VERSION_INT,
 +    .category   = AV_CLASS_CATEGORY_DEMUXER,
 +};
 +
 +
  static const char avi_headers[][8] = {
      { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' '  },
      { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X'  },
@@@ -169,7 -149,7 +169,7 @@@ static int read_braindead_odml_indx(AVF
      AVIStream *ast;
      int i;
      int64_t last_pos = -1;
 -    int64_t filesize = avio_size(s->pb);
 +    int64_t filesize = avi->fsize;
  
      av_dlog(s,
              "longs_pre_entry:%d index_type:%d entries_in_use:%d "
              int key     = len >= 0;
              len &= 0x7FFFFFFF;
  
 -            av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);
 -
 -            if (pb->eof_reached)
 +#ifdef DEBUG_SEEK
 +            av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
 +#endif
 +            if (url_feof(pb))
                  return AVERROR_INVALIDDATA;
  
              if (last_pos == pos || pos == base - 8)
              avio_rl32(pb);       /* size */
              duration = avio_rl32(pb);
  
 -            if (pb->eof_reached)
 +            if (url_feof(pb))
                  return AVERROR_INVALIDDATA;
  
              pos = avio_tell(pb);
                  return AVERROR_INVALIDDATA;
              }
  
 -            avio_seek(pb, offset + 8, SEEK_SET);
 +            if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
 +                return -1;
              avi->odml_depth++;
              read_braindead_odml_indx(s, frame_num);
              avi->odml_depth--;
              frame_num += duration;
  
 -            avio_seek(pb, pos, SEEK_SET);
 +            if (avio_seek(pb, pos, SEEK_SET) < 0) {
 +                av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
 +                return -1;
 +            }
 +
          }
      }
 -    avi->index_loaded = 1;
 +    avi->index_loaded = 2;
      return 0;
  }
  
@@@ -390,7 -364,6 +390,7 @@@ static int avi_read_header(AVFormatCont
      int amv_file_format = 0;
      uint64_t list_end   = 0;
      int ret;
 +    AVDictionaryEntry *dict_entry;
  
      avi->stream_index = -1;
  
      if (ret < 0)
          return ret;
  
 -    avi->fsize = avio_size(pb);
 -    if (avi->fsize <= 0)
 +    av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
 +
 +    avi->io_fsize = avi->fsize = avio_size(pb);
 +    if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
          avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
  
      /* first list tag */
      codec_type   = -1;
      frame_period = 0;
      for (;;) {
 -        if (pb->eof_reached)
 +        if (url_feof(pb))
              goto fail;
          tag  = avio_rl32(pb);
          size = avio_rl32(pb);
                  if (size)
                      avi->movi_end = avi->movi_list + size + (size & 1);
                  else
 -                    avi->movi_end = avio_size(pb);
 +                    avi->movi_end = avi->fsize;
                  av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
                  goto end_of_header;
              } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
              /* AVI header */
              /* using frame_period is bad idea */
              frame_period = avio_rl32(pb);
 -            avio_skip(pb, 4);
 +            avio_rl32(pb); /* max. bytes per second */
              avio_rl32(pb);
              avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
  
                  ast = s->streams[0]->priv_data;
                  av_freep(&s->streams[0]->codec->extradata);
                  av_freep(&s->streams[0]->codec);
 +                if (s->streams[0]->info)
 +                    av_freep(&s->streams[0]->info->duration_error);
 +                av_freep(&s->streams[0]->info);
                  av_freep(&s->streams[0]);
                  s->nb_streams = 0;
                  if (CONFIG_DV_DEMUXER) {
                  break;
              }
  
 -            assert(stream_index < s->nb_streams);
 +            av_assert0(stream_index < s->nb_streams);
              st->codec->stream_codec_tag = handler;
  
              avio_rl32(pb); /* flags */
              st->start_time = 0;
              avio_rl32(pb); /* buffer size */
              avio_rl32(pb); /* quality */
 +            if (ast->cum_len*ast->scale/ast->rate > 3600) {
 +                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
 +                return AVERROR_INVALIDDATA;
 +            }
              ast->sample_size = avio_rl32(pb); /* sample ssize */
              ast->cum_len    *= FFMAX(1, ast->sample_size);
              av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
                  codec_type = AVMEDIA_TYPE_DATA;
                  break;
              default:
 -                av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
 -                goto fail;
 +                av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
              }
 -            if (ast->sample_size == 0)
 +            if (ast->sample_size == 0) {
                  st->duration = st->nb_frames;
 +                if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
 +                    av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
 +                    st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
 +                }
 +            }
              ast->frame_offset = ast->cum_len;
              avio_skip(pb, size - 12 * 4);
              break;
          case MKTAG('s', 't', 'r', 'f'):
              /* stream header */
 +            if (!size)
 +                break;
              if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
                  avio_skip(pb, size);
              } else {
                  uint64_t cur_pos = avio_tell(pb);
 +                unsigned esize;
                  if (cur_pos < list_end)
                      size = FFMIN(size, list_end - cur_pos);
                  st = s->streams[stream_index];
                          avio_skip(pb, size);
                          break;
                      }
 -                    tag1 = ff_get_bmp_header(pb, st);
 +                    tag1 = ff_get_bmp_header(pb, st, &esize);
  
                      if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
                          tag1 == MKTAG('D', 'X', 'S', 'A')) {
                          break;
                      }
  
 -                    if (size > 10 * 4 && size < (1 << 30)) {
 -                        st->codec->extradata_size = size - 10 * 4;
 +                    if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
 +                        if (esize == size-1 && (esize&1)) {
 +                            st->codec->extradata_size = esize - 10 * 4;
 +                        } else
 +                            st->codec->extradata_size =  size - 10 * 4;
                          st->codec->extradata      = av_malloc(st->codec->extradata_size +
                                                                FF_INPUT_BUFFER_PADDING_SIZE);
                          if (!st->codec->extradata) {
                      /* Extract palette from extradata if bpp <= 8.
                       * This code assumes that extradata contains only palette.
                       * This is true for all paletted codecs implemented in
 -                     * Libav. */
 +                     * FFmpeg. */
                      if (st->codec->extradata_size &&
                          (st->codec->bits_per_coded_sample <= 8)) {
                          int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
                          pal_size = FFMIN(pal_size, st->codec->extradata_size);
                          pal_src  = st->codec->extradata +
                                     st->codec->extradata_size - pal_size;
 -#if HAVE_BIGENDIAN
                          for (i = 0; i < pal_size / 4; i++)
 -                            ast->pal[i] = av_bswap32(((uint32_t *)pal_src)[i]);
 -#else
 -                        memcpy(ast->pal, pal_src, pal_size);
 -#endif
 +                            ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
                          ast->has_pal = 1;
                      }
  
                      /* This is needed to get the pict type which is necessary
                       * for generating correct pts. */
                      st->need_parsing = AVSTREAM_PARSE_HEADERS;
 -                    // Support "Resolution 1:1" for Avid AVI Codec
 -                    if (tag1 == MKTAG('A', 'V', 'R', 'n') &&
 -                        st->codec->extradata_size >= 31   &&
 -                        !memcmp(&st->codec->extradata[28], "1:1", 3))
 -                        st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
  
                      if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
                          st->codec->extradata_size < 1U << 30) {
                          st->codec->extradata_size += 9;
                          if ((ret = av_reallocp(&st->codec->extradata,
                                                 st->codec->extradata_size +
-                                                FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+                                                FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+                             st->codec->extradata_size = 0;
                              return ret;
-                         else
+                         else
                              memcpy(st->codec->extradata + st->codec->extradata_size - 9,
                                     "BottomUp", 9);
                      }
                      if (st->codec->stream_codec_tag == AV_RL32("Axan")) {
                          st->codec->codec_id  = AV_CODEC_ID_XAN_DPCM;
                          st->codec->codec_tag = 0;
 +                        ast->dshow_block_align = 0;
                      }
                      if (amv_file_format) {
                          st->codec->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;
                          ast->dshow_block_align = 0;
                      }
 +                    if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
 +                        av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
 +                        ast->dshow_block_align = 0;
 +                    }
 +                    if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
 +                       st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
 +                       st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
 +                        av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
 +                        ast->sample_size = 0;
 +                    }
                      break;
                  case AVMEDIA_TYPE_SUBTITLE:
                      st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
 -                    st->codec->codec_id   = AV_CODEC_ID_PROBE;
 +                    st->request_probe= 1;
 +                    avio_skip(pb, size);
                      break;
                  default:
                      st->codec->codec_type = AVMEDIA_TYPE_DATA;
                  }
              }
              break;
 +        case MKTAG('s', 't', 'r', 'd'):
 +            if (stream_index >= (unsigned)s->nb_streams
 +                || s->streams[stream_index]->codec->extradata_size
 +                || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) {
 +                avio_skip(pb, size);
 +            } else {
 +                uint64_t cur_pos = avio_tell(pb);
 +                if (cur_pos < list_end)
 +                    size = FFMIN(size, list_end - cur_pos);
 +                st = s->streams[stream_index];
 +
 +                if (size<(1<<30)) {
 +                    st->codec->extradata_size= size;
 +                    st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
 +                    if (!st->codec->extradata) {
 +                        st->codec->extradata_size= 0;
 +                        return AVERROR(ENOMEM);
 +                    }
 +                    avio_read(pb, st->codec->extradata, st->codec->extradata_size);
 +                }
 +
 +                if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
 +                    avio_r8(pb);
 +            }
 +            break;
          case MKTAG('i', 'n', 'd', 'x'):
              i = avio_tell(pb);
              if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
 +                avi->use_odml &&
                  read_braindead_odml_indx(s, 0) < 0 &&
                  (s->error_recognition & AV_EF_EXPLODE))
                  goto fail;
                  if (s->error_recognition & AV_EF_EXPLODE)
                      goto fail;
                  avi->movi_list = avio_tell(pb) - 4;
 -                avi->movi_end  = avio_size(pb);
 +                avi->movi_end  = avi->fsize;
                  goto end_of_header;
              }
              /* skip tag */
@@@ -864,27 -790,13 +865,27 @@@ fail
  
      if (!avi->index_loaded && pb->seekable)
          avi_load_index(s);
 -    avi->index_loaded     = 1;
 -    avi->non_interleaved |= guess_ni_flag(s);
 +    avi->index_loaded    |= 1;
 +    avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
 +
 +    dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
 +    if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
 +        for (i = 0; i < s->nb_streams; i++) {
 +            AVStream *st = s->streams[i];
 +            if (   st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO
 +                || st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
 +                st->need_parsing = AVSTREAM_PARSE_FULL;
 +        }
 +
      for (i = 0; i < s->nb_streams; i++) {
          AVStream *st = s->streams[i];
          if (st->nb_index_entries)
              break;
      }
 +    // DV-in-AVI cannot be non-interleaved, if set this must be
 +    // a mis-detection.
 +    if (avi->dv_demux)
 +        avi->non_interleaved = 0;
      if (i == s->nb_streams && avi->non_interleaved) {
          av_log(s, AV_LOG_WARNING,
                 "Non-interleaved AVI without index, switching to interleaved\n");
  
  static int read_gab2_sub(AVStream *st, AVPacket *pkt)
  {
 -    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
 +    if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
          uint8_t desc[256];
          int score      = AVPROBE_SCORE_EXTENSION, ret;
          AVIStream *ast = st->priv_data;
@@@ -987,7 -899,7 +988,7 @@@ static AVStream *get_subtitle_pkt(AVFor
      return sub_st;
  }
  
 -static int get_stream_idx(int *d)
 +static int get_stream_idx(unsigned *d)
  {
      if (d[0] >= '0' && d[0] <= '9' &&
          d[1] >= '0' && d[1] <= '9') {
      }
  }
  
 +/**
 + *
 + * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
 + */
  static int avi_sync(AVFormatContext *s, int exit_early)
  {
      AVIContext *avi = s->priv_data;
  
  start_sync:
      memset(d, -1, sizeof(d));
 -    for (i = sync = avio_tell(pb); !pb->eof_reached; i++) {
 +    for (i = sync = avio_tell(pb); !url_feof(pb); i++) {
          int j;
  
          for (j = 0; j < 7; j++)
          n = get_stream_idx(d + 2);
          av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
                  d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
 -        if (i + (uint64_t)size > avi->fsize || d[0] > 127)
 +        if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
              continue;
  
          // parse ix##
              st  = s->streams[n];
              ast = st->priv_data;
  
 +            if (!ast) {
 +                av_log(s, AV_LOG_WARNING, "Skiping foreign stream %d packet\n", n);
 +                continue;
 +            }
 +
              if (s->nb_streams >= 2) {
                  AVStream *st1   = s->streams[1];
                  AVIStream *ast1 = st1->priv_data;
                  // workaround for broken small-file-bug402.avi
 -                if (d[2] == 'w' && d[3] == 'b' && n == 0 &&
 -                    st->codec->codec_type  == AVMEDIA_TYPE_VIDEO &&
 -                    st1->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
 -                    ast->prefix == 'd' * 256 + 'c' &&
 -                    (d[2] * 256 + d[3] == ast1->prefix ||
 -                     !ast1->prefix_count)) {
 +                if (   d[2] == 'w' && d[3] == 'b'
 +                   && n == 0
 +                   && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
 +                   && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
 +                   && ast->prefix == 'd'*256+'c'
 +                   && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
 +                  ) {
                      n   = 1;
                      st  = st1;
                      ast = ast1;
                  || st->discard >= AVDISCARD_ALL)) {
                  if (!exit_early) {
                      ast->frame_offset += get_duration(ast, size);
 +                    avio_skip(pb, size);
 +                    goto start_sync;
                  }
 -                avio_skip(pb, size);
 -                goto start_sync;
              }
  
              if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
  
                  // b + (g << 8) + (r << 16);
                  for (; k <= last; k++)
 -                    ast->pal[k] = avio_rb32(pb) >> 8;
 +                    ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
  
                  ast->has_pal = 1;
                  goto start_sync;
          }
      }
  
 +    if (pb->error)
 +        return pb->error;
      return AVERROR_EOF;
  }
  
@@@ -1197,7 -1097,10 +1198,7 @@@ static int avi_read_packet(AVFormatCont
              return AVERROR_EOF;
  
          best_ast = best_st->priv_data;
 -        best_ts  = av_rescale_q(best_ts,
 -                                (AVRational) { FFMAX(1, best_ast->sample_size),
 -                                               AV_TIME_BASE },
 -                                best_st->time_base);
 +        best_ts  = best_ast->frame_offset;
          if (best_ast->remaining) {
              i = av_index_search_timestamp(best_st,
                                            best_ts,
          if (i >= 0) {
              int64_t pos = best_st->index_entries[i].pos;
              pos += best_ast->packet_size - best_ast->remaining;
 -            avio_seek(s->pb, pos + 8, SEEK_SET);
 +            if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
 +              return AVERROR_EOF;
  
 -            assert(best_ast->remaining <= best_ast->packet_size);
 +            av_assert0(best_ast->remaining <= best_ast->packet_size);
  
              avi->stream_index = best_stream_index;
              if (!best_ast->remaining)
                  best_ast->packet_size =
                  best_ast->remaining   = best_st->index_entries[i].size;
          }
 +        else
 +          return AVERROR_EOF;
      }
  
  resync:
          err               = av_get_packet(pb, pkt, size);
          if (err < 0)
              return err;
 +        size = err;
  
 -        if (ast->has_pal && pkt->data && pkt->size < (unsigned)INT_MAX / 2) {
 +        if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
              uint8_t *pal;
              pal = av_packet_new_side_data(pkt,
                                            AV_PKT_DATA_PALETTE,
@@@ -1274,7 -1173,7 +1275,7 @@@ FF_DISABLE_DEPRECATION_WARNING
  FF_ENABLE_DEPRECATION_WARNINGS
  #endif
              size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
 -                                            pkt->data, pkt->size);
 +                                            pkt->data, pkt->size, pkt->pos);
  #if FF_API_DESTRUCT_PACKET
  FF_DISABLE_DEPRECATION_WARNINGS
              pkt->destruct = dstr;
@@@ -1312,32 -1211,14 +1313,32 @@@ FF_ENABLE_DEPRECATION_WARNING
              if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                  AVIndexEntry *e;
                  int index;
 -                assert(st->index_entries);
 +                av_assert0(st->index_entries);
  
                  index = av_index_search_timestamp(st, ast->frame_offset, 0);
                  e     = &st->index_entries[index];
  
 -                if (index >= 0 && e->timestamp == ast->frame_offset)
 +                if (index >= 0 && e->timestamp == ast->frame_offset) {
 +                    if (index == st->nb_index_entries-1) {
 +                        int key=1;
 +                        int i;
 +                        uint32_t state=-1;
 +                        for (i=0; i<FFMIN(size,256); i++) {
 +                            if (st->codec->codec_id == AV_CODEC_ID_MPEG4) {
 +                                if (state == 0x1B6) {
 +                                    key= !(pkt->data[i]&0xC0);
 +                                    break;
 +                                }
 +                            }else
 +                                break;
 +                            state= (state<<8) + pkt->data[i];
 +                        }
 +                        if (!key)
 +                            e->flags &= ~AVINDEX_KEYFRAME;
 +                    }
                      if (e->flags & AVINDEX_KEYFRAME)
                          pkt->flags |= AV_PKT_FLAG_KEY;
 +                }
              } else {
                  pkt->flags |= AV_PKT_FLAG_KEY;
              }
              ast->packet_size  = 0;
          }
  
 +        if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
 +            av_free_packet(pkt);
 +            goto resync;
 +        }
 +        ast->seek_pos= 0;
 +
 +        if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
 +            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
 +
 +            if (avi->dts_max - dts > 2*AV_TIME_BASE) {
 +                avi->non_interleaved= 1;
 +                av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
 +            }else if (avi->dts_max < dts)
 +                avi->dts_max = dts;
 +        }
 +
          return 0;
      }
  
@@@ -1384,9 -1249,7 +1385,9 @@@ static int avi_read_idx1(AVFormatContex
      AVIStream *ast;
      unsigned int index, tag, flags, pos, len, first_packet = 1;
      unsigned last_pos = -1;
 +    unsigned last_idx = -1;
      int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
 +    int anykey = 0;
  
      nb_index_entries = size / 16;
      if (nb_index_entries <= 0)
      avi->stream_index = -1;
      avio_seek(pb, idx1_pos, SEEK_SET);
  
 +    if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")) {
 +        first_packet_pos = 0;
 +        data_offset = avi->movi_list;
 +    }
 +
      /* Read the entries and sort them in each stream component. */
      for (i = 0; i < nb_index_entries; i++) {
 +        if (url_feof(pb))
 +            return -1;
 +
          tag   = avio_rl32(pb);
          flags = avio_rl32(pb);
          pos   = avio_rl32(pb);
          st  = s->streams[index];
          ast = st->priv_data;
  
 -        if (first_packet && first_packet_pos && len) {
 +        if (first_packet && first_packet_pos) {
              data_offset  = first_packet_pos - pos;
              first_packet = 0;
          }
  
          av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
  
 -        if (pb->eof_reached)
 -            return AVERROR_INVALIDDATA;
 -
 +        // even if we have only a single stream, we should
 +        // switch to non-interleaved to get correct timestamps
          if (last_pos == pos)
              avi->non_interleaved = 1;
 -        else if (len || !ast->sample_size)
 +        if (last_idx != pos && len) {
              av_add_index_entry(st, pos, ast->cum_len, len, 0,
                                 (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
 +            last_idx= pos;
 +        }
          ast->cum_len += get_duration(ast, len);
          last_pos      = pos;
 +        anykey       |= flags&AVIIF_INDEX;
 +    }
 +    if (!anykey) {
 +        for (index = 0; index < s->nb_streams; index++) {
 +            st = s->streams[index];
 +            if (st->nb_index_entries)
 +                st->index_entries[0].flags |= AVINDEX_KEYFRAME;
 +        }
      }
      return 0;
  }
@@@ -1460,8 -1306,6 +1461,8 @@@ static int guess_ni_flag(AVFormatContex
      int64_t last_start = 0;
      int64_t first_end  = INT64_MAX;
      int64_t oldpos     = avio_tell(s->pb);
 +    int *idx;
 +    int64_t min_pos, pos;
  
      for (i = 0; i < s->nb_streams; i++) {
          AVStream *st = s->streams[i];
              first_end = st->index_entries[n - 1].pos;
      }
      avio_seek(s->pb, oldpos, SEEK_SET);
 -    return last_start > first_end;
 +    if (last_start > first_end)
 +        return 1;
 +    idx= av_calloc(s->nb_streams, sizeof(*idx));
 +    if (!idx)
 +        return 0;
 +    for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) {
 +        int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;
 +        min_pos = INT64_MAX;
 +
 +        for (i=0; i<s->nb_streams; i++) {
 +            AVStream *st = s->streams[i];
 +            AVIStream *ast = st->priv_data;
 +            int n= st->nb_index_entries;
 +            while (idx[i]<n && st->index_entries[idx[i]].pos < pos)
 +                idx[i]++;
 +            if (idx[i] < n) {
 +                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
 +                min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
 +            }
 +            if (idx[i])
 +                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));
 +        }
 +        if (max_dts - min_dts > 2*AV_TIME_BASE) {
 +            av_free(idx);
 +            return 1;
 +        }
 +    }
 +    av_free(idx);
 +    return 0;
  }
  
  static int avi_load_index(AVFormatContext *s)
      AVIOContext *pb = s->pb;
      uint32_t tag, size;
      int64_t pos = avio_tell(pb);
 +    int64_t next;
      int ret     = -1;
  
      if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
          goto the_end; // maybe truncated file
      av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
      for (;;) {
 -        if (pb->eof_reached)
 -            break;
          tag  = avio_rl32(pb);
          size = avio_rl32(pb);
 +        if (url_feof(pb))
 +            break;
 +        next = avio_tell(pb) + size + (size & 1);
 +
          av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
                   tag        & 0xff,
                  (tag >>  8) & 0xff,
  
          if (tag == MKTAG('i', 'd', 'x', '1') &&
              avi_read_idx1(s, size) >= 0) {
 +            avi->index_loaded=2;
              ret = 0;
 +        }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
 +            uint32_t tag1 = avio_rl32(pb);
 +
 +            if (tag1 == MKTAG('I', 'N', 'F', 'O'))
 +                ff_read_riff_info(s, size - 4);
 +        }else if (!ret)
              break;
 -        }
  
 -        size += (size & 1);
 -        if (avio_skip(pb, size) < 0)
 +        if (avio_seek(pb, next, SEEK_SET) < 0)
              break; // something is wrong here
      }
  
@@@ -1579,29 -1387,23 +1580,29 @@@ static int avi_read_seek(AVFormatContex
      AVIContext *avi = s->priv_data;
      AVStream *st;
      int i, index;
 -    int64_t pos;
 +    int64_t pos, pos_min;
      AVIStream *ast;
  
      if (!avi->index_loaded) {
          /* we only load the index on demand */
          avi_load_index(s);
 -        avi->index_loaded = 1;
 +        avi->index_loaded |= 1;
      }
 -    assert(stream_index >= 0);
 +    av_assert0(stream_index >= 0);
  
      st    = s->streams[stream_index];
      ast   = st->priv_data;
      index = av_index_search_timestamp(st,
                                        timestamp * FFMAX(ast->sample_size, 1),
                                        flags);
 -    if (index < 0)
 +    if (index < 0) {
 +        if (st->nb_index_entries > 0)
 +            av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
 +                   timestamp * FFMAX(ast->sample_size, 1),
 +                   st->index_entries[0].timestamp,
 +                   st->index_entries[st->nb_index_entries - 1].timestamp);
          return AVERROR_INVALIDDATA;
 +    }
  
      /* find the position */
      pos       = st->index_entries[index].pos;
          /* One and only one real stream for DV in AVI, and it has video  */
          /* offsets. Calling with other stream indexes should have failed */
          /* the av_index_search_timestamp call above.                     */
 -        assert(stream_index == 0);
 +        av_assert0(stream_index == 0);
 +
 +        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
 +            return -1;
  
          /* Feed the DV video stream version of the timestamp to the */
          /* DV demux so it can synthesize correct timestamps.        */
          ff_dv_offset_reset(avi->dv_demux, timestamp);
  
 -        avio_seek(s->pb, pos, SEEK_SET);
          avi->stream_index = -1;
          return 0;
      }
  
 +    pos_min = pos;
      for (i = 0; i < s->nb_streams; i++) {
          AVStream *st2   = s->streams[i];
          AVIStream *ast2 = st2->priv_data;
          if (st2->nb_index_entries <= 0)
              continue;
  
 -//        assert(st2->codec->block_align);
 -        assert((int64_t)st2->time_base.num * ast2->rate ==
 -               (int64_t)st2->time_base.den * ast2->scale);
 +//        av_assert1(st2->codec->block_align);
 +        av_assert0((int64_t)st2->time_base.num * ast2->rate ==
 +                   (int64_t)st2->time_base.den * ast2->scale);
          index = av_index_search_timestamp(st2,
                                            av_rescale_q(timestamp,
                                                         st->time_base,
                                                         st2->time_base) *
                                            FFMAX(ast2->sample_size, 1),
 -                                          flags | AVSEEK_FLAG_BACKWARD);
 +                                          flags |
 +                                          AVSEEK_FLAG_BACKWARD |
 +                                          (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
          if (index < 0)
              index = 0;
 +        ast2->seek_pos = st2->index_entries[index].pos;
 +        pos_min = FFMIN(pos_min,ast2->seek_pos);
 +    }
 +    for (i = 0; i < s->nb_streams; i++) {
 +        AVStream *st2 = s->streams[i];
 +        AVIStream *ast2 = st2->priv_data;
  
 -        if (!avi->non_interleaved) {
 -            while (index > 0 && st2->index_entries[index].pos > pos)
 -                index--;
 -            while (index + 1 < st2->nb_index_entries &&
 -                   st2->index_entries[index].pos < pos)
 -                index++;
 -        }
 +        if (ast2->sub_ctx || st2->nb_index_entries <= 0)
 +            continue;
  
 -        av_dlog(s, "%"PRId64" %d %"PRId64"\n",
 -                timestamp, index, st2->index_entries[index].timestamp);
 -        /* extract the current frame number */
 +        index = av_index_search_timestamp(
 +                st2,
 +                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
 +                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
 +        if (index < 0)
 +            index = 0;
 +        while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
 +            index--;
          ast2->frame_offset = st2->index_entries[index].timestamp;
      }
  
      /* do the seek */
 -    avio_seek(s->pb, pos, SEEK_SET);
 +    if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
 +        av_log(s, AV_LOG_ERROR, "Seek failed\n");
 +        return -1;
 +    }
      avi->stream_index = -1;
 +    avi->dts_max      = INT_MIN;
      return 0;
  }
  
@@@ -1732,5 -1519,4 +1733,5 @@@ AVInputFormat ff_avi_demuxer = 
      .read_packet    = avi_read_packet,
      .read_close     = avi_read_close,
      .read_seek      = avi_read_seek,
 +    .priv_class = &demuxer_class,
  };
diff --combined libavformat/avienc.c
@@@ -2,25 -2,22 +2,25 @@@
   * AVI muxer
   * Copyright (c) 2000 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
 +
 +//#define DEBUG
 +
  #include "avformat.h"
  #include "internal.h"
  #include "avi.h"
@@@ -28,8 -25,6 +28,8 @@@
  #include "riff.h"
  #include "libavutil/intreadwrite.h"
  #include "libavutil/dict.h"
 +#include "libavutil/avassert.h"
 +#include "libavutil/timestamp.h"
  
  /*
   * TODO:
@@@ -57,7 -52,7 +57,7 @@@ typedef struct 
  
  typedef struct  {
      int64_t frames_hdr_strm;
 -    int audio_strm_length;
 +    int64_t audio_strm_length;
      int packet_count;
      int entry;
  
@@@ -122,7 -117,7 +122,7 @@@ static int avi_write_counters(AVFormatC
      for(n = 0; n < s->nb_streams; n++) {
          AVIStream *avist= s->streams[n]->priv_data;
  
 -        assert(avist->frames_hdr_strm);
 +        av_assert0(avist->frames_hdr_strm);
          stream = s->streams[n]->codec;
          avio_seek(pb, avist->frames_hdr_strm, SEEK_SET);
          ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
              nb_frames = FFMAX(nb_frames, avist->packet_count);
      }
      if(riff_id == 1) {
 -        assert(avi->frames_hdr_all);
 +        av_assert0(avi->frames_hdr_all);
          avio_seek(pb, avi->frames_hdr_all, SEEK_SET);
          avio_wl32(pb, nb_frames);
      }
@@@ -156,7 -151,7 +156,7 @@@ static int avi_write_header(AVFormatCon
      if (s->nb_streams > AVI_MAX_STREAM_COUNT) {
          av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n",
                 AVI_MAX_STREAM_COUNT);
 -        return -1;
 +        return AVERROR(EINVAL);
      }
  
      for(n=0;n<s->nb_streams;n++) {
  
          ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
  
 +        if (   stream->codec_type == AVMEDIA_TYPE_VIDEO
 +            && stream->codec_id != AV_CODEC_ID_XSUB
 +            && au_byterate > 1000LL*au_scale) {
 +            au_byterate = 600;
 +            au_scale    = 1;
 +        }
 +        avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
 +        if(stream->codec_id == AV_CODEC_ID_XSUB)
 +            au_scale = au_byterate = 0;
 +
          avio_wl32(pb, au_scale); /* scale */
          avio_wl32(pb, au_byterate); /* rate */
 -        avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
  
          avio_wl32(pb, 0); /* start */
          avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */
          ff_end_tag(pb, strh);
  
        if(stream->codec_type != AVMEDIA_TYPE_DATA){
 +          int ret;
 +
          strf = ff_start_tag(pb, "strf");
          switch(stream->codec_type) {
          case AVMEDIA_TYPE_SUBTITLE:
              ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0);
              break;
          case AVMEDIA_TYPE_AUDIO:
 -            if (ff_put_wav_header(pb, stream) < 0) {
 -                return -1;
 +            if ((ret = ff_put_wav_header(pb, stream)) < 0) {
 +                return ret;
              }
              break;
          default:
 -            return -1;
 +            av_log(s, AV_LOG_ERROR,
 +                   "Invalid or not supported codec type '%s' found in the input\n",
 +                   (char *)av_x_if_null(av_get_media_type_string(stream->codec_type), "?"));
 +            return AVERROR(EINVAL);
          }
          ff_end_tag(pb, strf);
          if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) {
@@@ -407,13 -388,10 +407,13 @@@ static int avi_write_ix(AVFormatContex
      char ix_tag[] = "ix00";
      int i, j;
  
 -    assert(pb->seekable);
 +    av_assert0(pb->seekable);
  
 -    if (avi->riff_id > AVI_MASTER_INDEX_SIZE)
 -        return -1;
 +    if (avi->riff_id > AVI_MASTER_INDEX_SIZE) {
 +        av_log(s, AV_LOG_ERROR, "Invalid riff index %d > %d\n",
 +               avi->riff_id, AVI_MASTER_INDEX_SIZE);
 +        return AVERROR(EINVAL);
 +    }
  
      for (i=0;i<s->nb_streams;i++) {
          AVIStream *avist= s->streams[i]->priv_data;
@@@ -522,21 -500,14 +522,21 @@@ static int avi_write_packet(AVFormatCon
      AVCodecContext *enc= s->streams[stream_index]->codec;
      int size= pkt->size;
  
 -    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){
 +    av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index);
 +    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB && avist->packet_count){
          AVPacket empty_packet;
  
 +        if(pkt->dts - avist->packet_count > 60000){
 +            av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", pkt->dts - avist->packet_count);
 +            return AVERROR(EINVAL);
 +        }
 +
          av_init_packet(&empty_packet);
          empty_packet.size= 0;
          empty_packet.data= NULL;
          empty_packet.stream_index= stream_index;
          avi_write_packet(s, &empty_packet);
 +        av_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(pkt->dts), avist->packet_count);
      }
      avist->packet_count++;
  
      }
  
      if (s->pb->seekable) {
 -        int err;
          AVIIndex* idx = &avist->indexes;
          int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
          int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
          if (idx->ents_allocated <= idx->entry) {
 -            if ((err = av_reallocp(&idx->cluster, (cl + 1) * sizeof(*idx->cluster))) < 0) {
 +            idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
-             if (!idx->cluster)
++            if (!idx->cluster) {
+                 idx->ents_allocated = 0;
+                 idx->entry = 0;
 -                return err;
 +                return AVERROR(ENOMEM);
+             }
              idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry));
              if (!idx->cluster[cl])
 -                return -1;
 +                return AVERROR(ENOMEM);
              idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE;
          }
  
@@@ -636,7 -610,7 +639,7 @@@ static int avi_write_trailer(AVFormatCo
      for (i=0; i<s->nb_streams; i++) {
           AVIStream *avist= s->streams[i]->priv_data;
           for (j=0; j<avist->indexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++)
 -              av_free(avist->indexes.cluster[j]);
 +              av_freep(&avist->indexes.cluster[j]);
           av_freep(&avist->indexes.cluster);
           avist->indexes.ents_allocated = avist->indexes.entry = 0;
      }
diff --combined libavformat/aviobuf.c
@@@ -2,20 -2,20 +2,20 @@@
   * buffered I/O
   * Copyright (c) 2000,2001 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -24,7 -24,6 +24,7 @@@
  #include "libavutil/intreadwrite.h"
  #include "libavutil/log.h"
  #include "libavutil/opt.h"
 +#include "libavutil/avassert.h"
  #include "avformat.h"
  #include "avio.h"
  #include "avio_internal.h"
@@@ -81,7 -80,6 +81,7 @@@ int ffio_init_context(AVIOContext *s
      s->buffer_size = buffer_size;
      s->buf_ptr     = buffer;
      s->opaque      = opaque;
 +    s->direct      = 0;
  
      url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
  
@@@ -123,34 -121,28 +123,34 @@@ AVIOContext *avio_alloc_context
      return s;
  }
  
 +static void writeout(AVIOContext *s, const uint8_t *data, int len)
 +{
 +    if (s->write_packet && !s->error) {
 +        int ret = s->write_packet(s->opaque, (uint8_t *)data, len);
 +        if (ret < 0) {
 +            s->error = ret;
 +        }
 +    }
 +    s->writeout_count ++;
 +    s->pos += len;
 +}
 +
  static void flush_buffer(AVIOContext *s)
  {
      if (s->buf_ptr > s->buffer) {
 -        if (s->write_packet && !s->error) {
 -            int ret = s->write_packet(s->opaque, s->buffer,
 -                                      s->buf_ptr - s->buffer);
 -            if (ret < 0) {
 -                s->error = ret;
 -            }
 -        }
 +        writeout(s, s->buffer, s->buf_ptr - s->buffer);
          if (s->update_checksum) {
              s->checksum     = s->update_checksum(s->checksum, s->checksum_ptr,
                                                   s->buf_ptr - s->checksum_ptr);
              s->checksum_ptr = s->buffer;
          }
 -        s->pos += s->buf_ptr - s->buffer;
      }
      s->buf_ptr = s->buffer;
  }
  
  void avio_w8(AVIOContext *s, int b)
  {
 +    av_assert2(b>=-128 && b<=255);
      *s->buf_ptr++ = b;
      if (s->buf_ptr >= s->buf_end)
          flush_buffer(s);
@@@ -172,11 -164,6 +172,11 @@@ void ffio_fill(AVIOContext *s, int b, i
  
  void avio_write(AVIOContext *s, const unsigned char *buf, int size)
  {
 +    if (s->direct && !s->update_checksum) {
 +        avio_flush(s);
 +        writeout(s, buf, size);
 +        return;
 +    }
      while (size > 0) {
          int len = FFMIN(s->buf_end - s->buf_ptr, size);
          memcpy(s->buf_ptr, buf, len);
@@@ -218,14 -205,13 +218,14 @@@ int64_t avio_seek(AVIOContext *s, int64
          offset += offset1;
      }
      offset1 = offset - pos;
 -    if (!s->must_flush &&
 +    if (!s->must_flush && (!s->direct || !s->seek) &&
          offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
          /* can do the seek inside the buffer */
          s->buf_ptr = s->buffer + offset1;
      } else if ((!s->seekable ||
                 offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
                 !s->write_flag && offset1 >= 0 &&
 +               (!s->direct || !s->seek) &&
                (whence != SEEK_END || force)) {
          while(s->pos < offset && !s->eof_reached)
              fill_buffer(s);
              return AVERROR(EPIPE);
          if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
              return res;
 +        s->seek_count ++;
          if (!s->write_flag)
              s->buf_end = s->buffer;
          s->buf_ptr = s->buffer;
      return offset;
  }
  
 +int64_t avio_skip(AVIOContext *s, int64_t offset)
 +{
 +    return avio_seek(s, offset, SEEK_CUR);
 +}
 +
  int64_t avio_size(AVIOContext *s)
  {
      int64_t size;
      return size;
  }
  
 +int url_feof(AVIOContext *s)
 +{
 +    if(!s)
 +        return 0;
 +    if(s->eof_reached){
 +        s->eof_reached=0;
 +        fill_buffer(s);
 +    }
 +    return s->eof_reached;
 +}
 +
  void avio_wl32(AVIOContext *s, unsigned int val)
  {
 -    avio_w8(s, val);
 -    avio_w8(s, val >> 8);
 -    avio_w8(s, val >> 16);
 -    avio_w8(s, val >> 24);
 +    avio_w8(s, (uint8_t) val       );
 +    avio_w8(s, (uint8_t)(val >> 8 ));
 +    avio_w8(s, (uint8_t)(val >> 16));
 +    avio_w8(s,           val >> 24 );
  }
  
  void avio_wb32(AVIOContext *s, unsigned int val)
  {
 -    avio_w8(s, val >> 24);
 -    avio_w8(s, val >> 16);
 -    avio_w8(s, val >> 8);
 -    avio_w8(s, val);
 +    avio_w8(s,           val >> 24 );
 +    avio_w8(s, (uint8_t)(val >> 16));
 +    avio_w8(s, (uint8_t)(val >> 8 ));
 +    avio_w8(s, (uint8_t) val       );
  }
  
  int avio_put_str(AVIOContext *s, const char *str)
@@@ -347,7 -316,7 +347,7 @@@ void ff_put_v(AVIOContext *bc, uint64_
      int i = ff_get_v_length(val);
  
      while (--i > 0)
 -        avio_w8(bc, 128 | (val >> (7 * i)));
 +        avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
  
      avio_w8(bc, val & 127);
  }
@@@ -366,37 -335,38 +366,37 @@@ void avio_wb64(AVIOContext *s, uint64_
  
  void avio_wl16(AVIOContext *s, unsigned int val)
  {
 -    avio_w8(s, val);
 -    avio_w8(s, val >> 8);
 +    avio_w8(s, (uint8_t)val);
 +    avio_w8(s, (int)val >> 8);
  }
  
  void avio_wb16(AVIOContext *s, unsigned int val)
  {
 -    avio_w8(s, val >> 8);
 -    avio_w8(s, val);
 +    avio_w8(s, (int)val >> 8);
 +    avio_w8(s, (uint8_t)val);
  }
  
  void avio_wl24(AVIOContext *s, unsigned int val)
  {
      avio_wl16(s, val & 0xffff);
 -    avio_w8(s, val >> 16);
 +    avio_w8(s, (int)val >> 16);
  }
  
  void avio_wb24(AVIOContext *s, unsigned int val)
  {
 -    avio_wb16(s, val >> 8);
 -    avio_w8(s, val);
 +    avio_wb16(s, (int)val >> 8);
 +    avio_w8(s, (uint8_t)val);
  }
  
  /* Input stream */
  
  static void fill_buffer(AVIOContext *s)
  {
 -    uint8_t *dst        = !s->max_packet_size &&
 -                          s->buf_end - s->buffer < s->buffer_size ?
 -                          s->buf_end : s->buffer;
 -    int len             = s->buffer_size - (dst - s->buffer);
      int max_buffer_size = s->max_packet_size ?
                            s->max_packet_size : IO_BUFFER_SIZE;
 +    uint8_t *dst        = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ?
 +                          s->buf_end : s->buffer;
 +    int len             = s->buffer_size - (dst - s->buffer);
  
      /* can't fill the buffer without read_packet, just set EOF if appropriate */
      if (!s->read_packet && s->buf_ptr >= s->buf_end)
      }
  
      /* make buffer smaller in case it ended up large after probing */
 -    if (s->buffer_size > max_buffer_size) {
 -        ffio_set_buf_size(s, max_buffer_size);
 +    if (s->read_packet && s->buffer_size > max_buffer_size) {
 +        if (dst == s->buffer) {
 +            ffio_set_buf_size(s, max_buffer_size);
  
 -        s->checksum_ptr = dst = s->buffer;
 -        len = s->buffer_size;
 +            s->checksum_ptr = dst = s->buffer;
 +        }
 +        av_assert0(len >= max_buffer_size);
 +        len = max_buffer_size;
      }
  
      if (s->read_packet)
          s->pos += len;
          s->buf_ptr = dst;
          s->buf_end = dst + len;
 +        s->bytes_read += len;
      }
  }
  
@@@ -487,7 -453,7 +487,7 @@@ int avio_read(AVIOContext *s, unsigned 
          if (len > size)
              len = size;
          if (len == 0 || s->write_flag) {
 -            if(size > s->buffer_size && !s->update_checksum){
 +            if((s->direct || size > s->buffer_size) && !s->update_checksum){
                  if(s->read_packet)
                      len = s->read_packet(s->opaque, buf, size);
                  if (len <= 0) {
                      break;
                  } else {
                      s->pos += len;
 +                    s->bytes_read += len;
                      size -= len;
                      buf += len;
                      s->buf_ptr = s->buffer;
          }
      }
      if (size1 == size) {
 -        if (s->error)         return s->error;
 -        if (s->eof_reached)   return AVERROR_EOF;
 +        if (s->error)      return s->error;
 +        if (url_feof(s))   return AVERROR_EOF;
      }
      return size1 - size;
  }
@@@ -568,8 -533,8 +568,8 @@@ int ffio_read_partial(AVIOContext *s, u
      memcpy(buf, s->buf_ptr, len);
      s->buf_ptr += len;
      if (!len) {
 -        if (s->error)         return s->error;
 -        if (s->eof_reached)   return AVERROR_EOF;
 +        if (s->error)      return s->error;
 +        if (url_feof(s))   return AVERROR_EOF;
      }
      return len;
  }
@@@ -721,12 -686,11 +721,12 @@@ int ffio_fdopen(AVIOContext **s, URLCon
          return AVERROR(ENOMEM);
  
      *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
 -                            ffurl_read, ffurl_write, ffurl_seek);
 +                            (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);
      if (!*s) {
          av_free(buffer);
          return AVERROR(ENOMEM);
      }
 +    (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
      (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
      (*s)->max_packet_size = max_packet_size;
      if(h->prot) {
      return 0;
  }
  
 +int ffio_ensure_seekback(AVIOContext *s, int buf_size)
 +{
 +    uint8_t *buffer;
 +    int max_buffer_size = s->max_packet_size ?
 +                          s->max_packet_size : IO_BUFFER_SIZE;
 +
 +    buf_size += s->buf_ptr - s->buffer + max_buffer_size;
 +
 +    if (buf_size < s->buffer_size || s->seekable)
 +        return 0;
 +    av_assert0(!s->write_flag);
 +
 +    buffer = av_malloc(buf_size);
 +    if (!buffer)
 +        return AVERROR(ENOMEM);
 +
 +    memcpy(buffer, s->buffer, s->buffer_size);
 +    av_free(s->buffer);
 +    s->buf_ptr = buffer + (s->buf_ptr - s->buffer);
 +    s->buf_end = buffer + (s->buf_end - s->buffer);
 +    s->buffer = buffer;
 +    s->buffer_size = buf_size;
 +    return 0;
 +}
 +
  int ffio_set_buf_size(AVIOContext *s, int buf_size)
  {
      uint8_t *buffer;
  
  static int url_resetbuf(AVIOContext *s, int flags)
  {
 -    assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
 +    av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
  
      if (flags & AVIO_FLAG_WRITE) {
          s->buf_end = s->buffer + s->buffer_size;
      return 0;
  }
  
 -int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size)
 +int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
  {
      int64_t buffer_start;
      int buffer_size;
      int overlap, new_size, alloc_size;
 +    uint8_t *buf = *bufp;
  
 -    if (s->write_flag)
 +    if (s->write_flag) {
 +        av_freep(bufp);
          return AVERROR(EINVAL);
 +    }
  
      buffer_size = s->buf_end - s->buffer;
  
      /* the buffers must touch or overlap */
 -    if ((buffer_start = s->pos - buffer_size) > buf_size)
 +    if ((buffer_start = s->pos - buffer_size) > buf_size) {
 +        av_freep(bufp);
          return AVERROR(EINVAL);
 +    }
  
      overlap = buf_size - buffer_start;
      new_size = buf_size + buffer_size - overlap;
  
      alloc_size = FFMAX(s->buffer_size, new_size);
      if (alloc_size > buf_size)
 -        if (!(buf = av_realloc(buf, alloc_size)))
 +        if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
              return AVERROR(ENOMEM);
  
      if (new_size > buf_size) {
@@@ -867,10 -801,6 +867,10 @@@ int avio_close(AVIOContext *s
      avio_flush(s);
      h = s->opaque;
      av_freep(&s->buffer);
 +    if (s->write_flag)
 +        av_log(s, AV_LOG_DEBUG, "Statistics: %d seeks, %d writeouts\n", s->seek_count, s->writeout_count);
 +    else
 +        av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count);
      av_free(s);
      return ffurl_close(h);
  }
@@@ -950,8 -880,11 +950,11 @@@ static int dyn_buf_write(void *opaque, 
  
      if (new_allocated_size > d->allocated_size) {
          int err;
-         if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0)
+         if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
+             d->allocated_size = 0;
+             d->size = 0;
              return err;
+         }
          d->allocated_size = new_allocated_size;
      }
      memcpy(d->buffer + d->pos, buf, buf_size);
diff --combined libavformat/mmst.c
@@@ -4,20 -4,20 +4,20 @@@
   * Copyright (c) 2007 Bj√∂rn Axelsson
   * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -152,7 -152,7 +152,7 @@@ static int send_command_packet(MMSTCont
      return 0;
  }
  
 -static void mms_put_utf16(MMSContext *mms, uint8_t *src)
 +static void mms_put_utf16(MMSContext *mms, const uint8_t *src)
  {
      AVIOContext bic;
      int size = mms->write_out_ptr - mms->out_buffer;
@@@ -337,8 -337,10 +337,10 @@@ static MMSSCPacketType get_tcp_server_r
                  if(!mms->header_parsed) {
                      if ((err = av_reallocp(&mms->asf_header,
                                             mms->asf_header_size +
-                                            mms->remaining_in_len)) < 0)
+                                            mms->remaining_in_len)) < 0) {
+                         mms->asf_header_size = 0;
                          return err;
+                     }
                      memcpy(mms->asf_header + mms->asf_header_size,
                             mms->read_in_ptr, mms->remaining_in_len);
                      mms->asf_header_size += mms->remaining_in_len;
@@@ -110,6 -110,7 +110,6 @@@ theora_header (AVFormatContext * s, in
          st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
          st->codec->codec_id = AV_CODEC_ID_THEORA;
          st->need_parsing = AVSTREAM_PARSE_HEADERS;
 -
      }
      break;
      case 0x81:
              return -1;
          break;
      default:
 +        av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
          return -1;
      }
  
      if ((err = av_reallocp(&st->codec->extradata,
-                            cds + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+                            cds + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+         st->codec->extradata_size = 0;
          return err;
+     }
      cdp = st->codec->extradata + st->codec->extradata_size;
      *cdp++ = os->psize >> 8;
      *cdp++ = os->psize & 0xff;
@@@ -161,47 -163,10 +163,47 @@@ theora_gptopts(AVFormatContext *ctx, in
      return iframe + pframe;
  }
  
 +static int theora_packet(AVFormatContext *s, int idx)
 +{
 +    struct ogg *ogg = s->priv_data;
 +    struct ogg_stream *os = ogg->streams + idx;
 +    int duration;
 +
 +    /* first packet handling
 +       here we parse the duration of each packet in the first page and compare
 +       the total duration to the page granule to find the encoder delay and
 +       set the first timestamp */
 +
 +    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
 +        int seg;
 +
 +        duration = 1;
 +        for (seg = os->segp; seg < os->nsegs; seg++) {
 +            if (os->segments[seg] < 255)
 +                duration ++;
 +        }
 +
 +        os->lastpts = os->lastdts   = theora_gptopts(s, idx, os->granule, NULL) - duration;
 +        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
 +            s->streams[idx]->start_time = os->lastpts;
 +            if (s->streams[idx]->duration)
 +                s->streams[idx]->duration -= s->streams[idx]->start_time;
 +        }
 +    }
 +
 +    /* parse packet duration */
 +    if (os->psize > 0) {
 +        os->pduration = 1;
 +    }
 +
 +    return 0;
 +}
 +
  const struct ogg_codec ff_theora_codec = {
      .magic = "\200theora",
      .magicsize = 7,
      .header = theora_header,
 +    .packet = theora_packet,
      .gptopts = theora_gptopts,
      .nb_header = 3,
  };
  
  #include <stdlib.h>
  #include "libavutil/avstring.h"
 +#include "libavutil/base64.h"
  #include "libavutil/bswap.h"
  #include "libavutil/dict.h"
  #include "libavcodec/get_bits.h"
  #include "libavcodec/bytestream.h"
  #include "libavcodec/vorbis_parser.h"
  #include "avformat.h"
 +#include "flacdec.h"
  #include "internal.h"
  #include "oggdec.h"
  #include "vorbiscomment.h"
@@@ -41,10 -39,10 +41,10 @@@ static int ogm_chapter(AVFormatContext 
      int i, cnum, h, m, s, ms, keylen = strlen(key);
      AVChapter *chapter = NULL;
  
 -    if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
 +    if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
          return 0;
  
 -    if (keylen == 9) {
 +    if (keylen <= 10) {
          if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
              return 0;
  
@@@ -52,7 -50,7 +52,7 @@@
                         ms + 1000*(s + 60*(m + 60*h)),
                         AV_NOPTS_VALUE, NULL);
          av_free(val);
 -    } else if (!strcmp(key+9, "NAME")) {
 +    } else if (!strcmp(key+(keylen-4), "NAME")) {
          for(i = 0; i < as->nb_chapters; i++)
              if (as->chapters[i]->id == cnum) {
                  chapter = as->chapters[i];
@@@ -130,26 -128,7 +130,26 @@@ ff_vorbis_comment(AVFormatContext * as
              memcpy(ct, v, vl);
              ct[vl] = 0;
  
 -            if (!ogm_chapter(as, tt, ct))
 +            if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
 +                int ret;
 +                char *pict = av_malloc(vl);
 +
 +                if (!pict) {
 +                    av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
 +                    av_freep(&tt);
 +                    av_freep(&ct);
 +                    continue;
 +                }
 +                if ((ret = av_base64_decode(pict, ct, vl)) > 0)
 +                    ret = ff_flac_parse_picture(as, pict, ret);
 +                av_freep(&pict);
 +                av_freep(&tt);
 +                av_freep(&ct);
 +                if (ret < 0) {
 +                    av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
 +                    continue;
 +                }
 +            } else if (!ogm_chapter(as, tt, ct))
                  av_dict_set(m, tt, ct,
                                     AV_DICT_DONT_STRDUP_KEY |
                                     AV_DICT_DONT_STRDUP_VAL);
@@@ -195,15 -174,10 +195,15 @@@ fixup_vorbis_headers(AVFormatContext * 
                       uint8_t **buf)
  {
      int i, offset, len, err;
 +    int buf_len;
      unsigned char *ptr;
  
      len = priv->len[0] + priv->len[1] + priv->len[2];
 -    ptr = *buf = av_mallocz(len + len/255 + 64);
 +    buf_len = len + len/255 + 64;
 +    ptr = *buf = av_realloc(NULL, buf_len);
 +    if (!*buf)
 +        return 0;
 +    memset(*buf, '\0', buf_len);
  
      ptr[0] = 2;
      offset = 1;
@@@ -242,7 -216,7 +242,7 @@@ vorbis_header (AVFormatContext * s, in
      if (!os->private) {
          os->private = av_mallocz(sizeof(struct oggvorbis_private));
          if (!os->private)
 -            return 0;
 +            return -1;
      }
  
      if (!(pkt_type & 1))
  
      priv->len[pkt_type >> 1] = os->psize;
      priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
 +    if (!priv->packet[pkt_type >> 1])
 +        return AVERROR(ENOMEM);
      memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
      if (os->buf[os->pstart] == 1) {
          const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
          unsigned blocksize, bs0, bs1;
          int srate;
 +        int channels;
  
          if (os->psize != 30)
              return -1;
          if (bytestream_get_le32(&p) != 0) /* vorbis_version */
              return -1;
  
 -        st->codec->channels = bytestream_get_byte(&p);
 +        channels= bytestream_get_byte(&p);
 +        if (st->codec->channels && channels != st->codec->channels) {
 +            av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
 +            return AVERROR_PATCHWELCOME;
 +        }
 +        st->codec->channels = channels;
          srate = bytestream_get_le32(&p);
          p += 4; // skip maximum bitrate
          st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
              }
          }
      } else {
-         int ret;
-         st->codec->extradata_size =
-             fixup_vorbis_headers(s, priv, &st->codec->extradata);
+         int ret = fixup_vorbis_headers(s, priv, &st->codec->extradata);
+         if (ret < 0) {
+             st->codec->extradata_size = 0;
+             return ret;
+         }
+         st->codec->extradata_size = ret;
          if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
              av_freep(&st->codec->extradata);
              st->codec->extradata_size = 0;
@@@ -341,39 -310,33 +344,39 @@@ static int vorbis_packet(AVFormatContex
         here we parse the duration of each packet in the first page and compare
         the total duration to the page granule to find the encoder delay and
         set the first timestamp */
 -    if (!os->lastpts) {
 -        int seg;
 +    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
 +        int seg, d;
          uint8_t *last_pkt = os->buf + os->pstart;
          uint8_t *next_pkt = last_pkt;
 -        int first_duration = 0;
  
          avpriv_vorbis_parse_reset(&priv->vp);
          duration = 0;
 -        for (seg = 0; seg < os->nsegs; seg++) {
 +        seg = os->segp;
 +        d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
 +        if (d < 0) {
 +            os->pflags |= AV_PKT_FLAG_CORRUPT;
 +            return 0;
 +        }
 +        duration += d;
 +        last_pkt = next_pkt =  next_pkt + os->psize;
 +        for (; seg < os->nsegs; seg++) {
              if (os->segments[seg] < 255) {
                  int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
                  if (d < 0) {
                      duration = os->granule;
                      break;
                  }
 -                if (!duration)
 -                    first_duration = d;
                  duration += d;
                  last_pkt = next_pkt + os->segments[seg];
              }
              next_pkt += os->segments[seg];
          }
          os->lastpts = os->lastdts   = os->granule - duration;
 -        s->streams[idx]->start_time = os->lastpts + first_duration;
 -        if (s->streams[idx]->duration)
 -            s->streams[idx]->duration -= s->streams[idx]->start_time;
 -        s->streams[idx]->cur_dts    = AV_NOPTS_VALUE;
 +        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
 +            s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
 +            if (s->streams[idx]->duration)
 +                s->streams[idx]->duration -= s->streams[idx]->start_time;
 +        }
          priv->final_pts             = AV_NOPTS_VALUE;
          avpriv_vorbis_parse_reset(&priv->vp);
      }
      /* parse packet duration */
      if (os->psize > 0) {
          duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
 -        if (duration <= 0) {
 +        if (duration < 0) {
              os->pflags |= AV_PKT_FLAG_CORRUPT;
              return 0;
          }
diff --combined libavformat/rdt.c
@@@ -2,20 -2,20 +2,20 @@@
   * Realmedia RTSP protocol (RDT) support.
   * Copyright (c) 2007 Ronald S. Bultje
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -98,7 -98,7 +98,7 @@@ ff_rdt_calc_response_and_checksum(char 
      unsigned char zres[16],
          buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 };
  #define XOR_TABLE_SIZE 37
 -    const unsigned char xor_table[XOR_TABLE_SIZE] = {
 +    static const unsigned char xor_table[XOR_TABLE_SIZE] = {
          0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
          0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
          0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
@@@ -176,7 -176,7 +176,7 @@@ rdt_load_mdpr (PayloadContext *rdt, AVS
          size = rdt->mlti_data_size;
          avio_seek(&pb, 0, SEEK_SET);
      }
 -    if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size) < 0)
 +    if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size, NULL) < 0)
          return -1;
  
      return 0;
@@@ -423,8 -423,10 +423,10 @@@ rdt_parse_sdp_line (AVFormatContext *s
                  if (first == -1) first = n;
                  if (rdt->nb_rmst < count) {
                      if ((err = av_reallocp(&rdt->rmst,
-                                            count * sizeof(*rdt->rmst))) < 0)
+                                            count * sizeof(*rdt->rmst))) < 0) {
+                         rdt->nb_rmst = 0;
                          return err;
+                     }
                      memset(rdt->rmst + rdt->nb_rmst, 0,
                             (count - rdt->nb_rmst) * sizeof(*rdt->rmst));
                      rdt->nb_rmst = count;
diff --combined libavformat/rtmphttp.c
@@@ -2,20 -2,20 +2,20 @@@
   * RTMP HTTP network protocol
   * Copyright (c) 2012 Samuel Pitoiset
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -89,8 -89,11 +89,11 @@@ static int rtmp_http_write(URLContext *
      if (rt->out_size + size > rt->out_capacity) {
          int err;
          rt->out_capacity = (rt->out_size + size) * 2;
-         if ((err = av_reallocp(&rt->out_data, rt->out_capacity)) < 0)
+         if ((err = av_reallocp(&rt->out_data, rt->out_capacity)) < 0) {
+             rt->out_size = 0;
+             rt->out_capacity = 0;
              return err;
+         }
      }
  
      memcpy(rt->out_data + rt->out_size, buf, size);
diff --combined libavformat/rtmpproto.c
@@@ -2,20 -2,20 +2,20 @@@
   * RTMP network protocol
   * Copyright (c) 2009 Konstantin Shishkov
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -48,7 -48,7 +48,7 @@@
  #include <zlib.h>
  #endif
  
 -#define APP_MAX_LENGTH 128
 +#define APP_MAX_LENGTH 1024
  #define PLAYPATH_MAX_LENGTH 256
  #define TCURL_MAX_LENGTH 512
  #define FLASHVER_MAX_LENGTH 64
@@@ -156,8 -156,11 +156,11 @@@ static int add_tracked_method(RTMPConte
      if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
          rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
          if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
-                                sizeof(*rt->tracked_methods))) < 0)
+                                sizeof(*rt->tracked_methods))) < 0) {
+             rt->nb_tracked_methods = 0;
+             rt->tracked_methods_size = 0;
              return err;
+         }
      }
  
      rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
@@@ -265,6 -268,9 +268,6 @@@ static int rtmp_write_amf_data(URLConte
          *value = '\0';
          value++;
  
 -        if (!field || !value)
 -            goto fail;
 -
          ff_amf_write_field_name(p, field);
      } else {
          goto fail;
@@@ -311,7 -317,7 +314,7 @@@ static int gen_connect(URLContext *s, R
      int ret;
  
      if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
 -                                     0, 4096)) < 0)
 +                                     0, 4096 + APP_MAX_LENGTH)) < 0)
          return ret;
  
      p = pkt.data;
@@@ -1164,7 -1170,7 +1167,7 @@@ static int rtmp_handshake(URLContext *s
      for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
          tosend[i] = av_lfg_get(&rnd) >> 24;
  
 -    if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +    if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
          /* When the client wants to use RTMPE, we have to change the command
           * byte to 0x06 which means to use encrypted data and we have to set
           * the flash version to at least 9.0.115.0. */
          if (ret < 0)
              return ret;
  
 -        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
              /* Compute the shared secret key sent by the server and initialize
               * the RC4 encryption. */
              if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
          if (ret < 0)
              return ret;
  
 -        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
              /* Encrypt the signature to be send to the server. */
              ff_rtmpe_encrypt_sig(rt->stream, tosend +
                                   RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
                                 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
              return ret;
  
 -        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
              /* Set RC4 keys for encryption and update the keystreams. */
              if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
                  return ret;
          }
      } else {
 -        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
              /* Compute the shared secret key sent by the server and initialize
               * the RC4 encryption. */
              if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
                                 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
              return ret;
  
 -        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
 +        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
              /* Set RC4 keys for encryption and update the keystreams. */
              if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
                  return ret;
@@@ -2250,7 -2256,7 +2253,7 @@@ static int get_packet(URLContext *s, in
              }
          }
          rt->bytes_read += ret;
 -        if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
 +        if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
              av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
              if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
                  return ret;
@@@ -2459,20 -2465,16 +2462,20 @@@ reconnect
              fname = strchr(p + 1, '/');
              if (!fname || (c && c < fname)) {
                  fname = p + 1;
 -                av_strlcpy(rt->app, path + 1, p - path);
 +                av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
              } else {
                  fname++;
 -                av_strlcpy(rt->app, path + 1, fname - path - 1);
 +                av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
              }
          }
      }
  
      if (old_app) {
          // The name of application has been defined by the user, override it.
 +        if (strlen(old_app) >= APP_MAX_LENGTH) {
 +            ret = AVERROR(EINVAL);
 +            goto fail;
 +        }
          av_free(rt->app);
          rt->app = old_app;
      }
diff --combined libavformat/rtpdec_qt.c
@@@ -2,20 -2,20 +2,20 @@@
   * RTP/Quicktime support.
   * Copyright (c) 2009 Ronald S. Bultje
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -174,8 -174,10 +174,10 @@@ static int qt_rtp_parse_packet(AVFormat
          if (qt->pkt.size > 0 && qt->timestamp == *timestamp) {
              int err;
              if ((err = av_reallocp(&qt->pkt.data, qt->pkt.size + alen +
-                                    FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+                                    FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+                 qt->pkt.size = 0;
                  return err;
+             }
          } else {
              av_freep(&qt->pkt.data);
              av_init_packet(&qt->pkt);
diff --combined libavformat/smacker.c
@@@ -2,20 -2,20 +2,20 @@@
   * Smacker demuxer
   * Copyright (c) 2006 Konstantin Shishkov
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -110,7 -110,7 +110,7 @@@ static int smacker_read_header(AVFormat
      /* read and check header */
      smk->magic = avio_rl32(pb);
      if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      smk->width = avio_rl32(pb);
      smk->height = avio_rl32(pb);
      smk->frames = avio_rl32(pb);
  
      if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant)
          av_log(s, AV_LOG_ERROR, "treesize too large\n");
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
  //FIXME remove extradata "rebuilding"
      /* setup data */
      if(smk->frames > 0xFFFFFF) {
          av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
 -    smk->frm_size = av_malloc(smk->frames * 4);
 +    smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size));
      smk->frm_flags = av_malloc(smk->frames);
 +    if (!smk->frm_size || !smk->frm_flags) {
 +        av_freep(&smk->frm_size);
 +        av_freep(&smk->frm_flags);
 +        return AVERROR(ENOMEM);
 +    }
  
      smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2'));
  
      /* init video codec */
      st = avformat_new_stream(s, NULL);
      if (!st)
 -        return -1;
 +        return AVERROR(ENOMEM);
      smk->videoindex = st->index;
      st->codec->width = smk->width;
      st->codec->height = smk->height;
          smk->indexes[i] = -1;
          if (smk->rates[i]) {
              ast[i] = avformat_new_stream(s, NULL);
 +            if (!ast[i])
 +                return AVERROR(ENOMEM);
              smk->indexes[i] = ast[i]->index;
              ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
              if (smk->aflags[i] & SMK_AUD_BINKAUD) {
      st->codec->extradata_size = smk->treesize + 16;
      if(!st->codec->extradata){
          av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
 -        av_free(smk->frm_size);
 -        av_free(smk->frm_flags);
 -        return -1;
 +        av_freep(&smk->frm_size);
 +        av_freep(&smk->frm_flags);
 +        return AVERROR(ENOMEM);
      }
      ret = avio_read(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
      if(ret != st->codec->extradata_size - 16){
 -        av_free(smk->frm_size);
 -        av_free(smk->frm_flags);
 +        av_freep(&smk->frm_size);
 +        av_freep(&smk->frm_flags);
          return AVERROR(EIO);
      }
      ((int32_t*)st->codec->extradata)[0] = av_le2ne32(smk->mmap_size);
@@@ -253,7 -246,7 +253,7 @@@ static int smacker_read_packet(AVFormat
      int frame_size = 0;
      int palchange = 0;
  
 -    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)
 +    if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
          return AVERROR_EOF;
  
      /* if we demuxed all streams, pass another frame */
              memcpy(oldpal, pal, 768);
              size = avio_r8(s->pb);
              size = size * 4 - 1;
 +            if(size + 1 > frame_size)
 +                return AVERROR_INVALIDDATA;
              frame_size -= size;
              frame_size--;
              sz = 0;
                  int err;
  
                  size = avio_rl32(s->pb) - 4;
 -                if (!size || size > frame_size) {
 +                if (!size || size + 4L > frame_size) {
                      av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
                      return AVERROR_INVALIDDATA;
                  }
                  frame_size -= size;
                  frame_size -= 4;
                  smk->curstream++;
-                 if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0)
+                 if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
+                     smk->buf_sizes[smk->curstream] = 0;
                      return err;
+                 }
                  smk->buf_sizes[smk->curstream] = size;
                  ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
                  if(ret != size)
          smk->cur_frame++;
          smk->nextpos = avio_tell(s->pb);
      } else {
 -        if (smk->stream_id[smk->curstream] < 0)
 +        if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream])
              return AVERROR_INVALIDDATA;
          if (av_new_packet(pkt, smk->buf_sizes[smk->curstream]))
              return AVERROR(ENOMEM);
@@@ -372,16 -365,16 +374,16 @@@ static int smacker_read_close(AVFormatC
      int i;
  
      for(i = 0; i < 7; i++)
 -        av_free(smk->bufs[i]);
 -    av_free(smk->frm_size);
 -    av_free(smk->frm_flags);
 +        av_freep(&smk->bufs[i]);
 +    av_freep(&smk->frm_size);
 +    av_freep(&smk->frm_flags);
  
      return 0;
  }
  
  AVInputFormat ff_smacker_demuxer = {
      .name           = "smk",
 -    .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
 +    .long_name      = NULL_IF_CONFIG_SMALL("Smacker"),
      .priv_data_size = sizeof(SmackerContext),
      .read_probe     = smacker_probe,
      .read_header    = smacker_read_header,
@@@ -2,20 -2,20 +2,20 @@@
   * Live smooth streaming fragmenter
   * Copyright (c) 2012 Martin Storsjo
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -289,11 -289,7 +289,11 @@@ static int ism_write_header(AVFormatCon
      int ret = 0, i;
      AVOutputFormat *oformat;
  
 -    mkdir(s->filename, 0777);
 +    if (mkdir(s->filename, 0777) < 0) {
 +        av_log(s, AV_LOG_ERROR, "mkdir failed\n");
 +        ret = AVERROR(errno);
 +        goto fail;
 +    }
  
      oformat = av_guess_format("ismv", NULL, NULL);
      if (!oformat) {
              goto fail;
          }
          snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%d)", s->filename, s->streams[i]->codec->bit_rate);
 -        mkdir(os->dirname, 0777);
 +        if (mkdir(os->dirname, 0777) < 0) {
 +            ret = AVERROR(errno);
 +            av_log(s, AV_LOG_ERROR, "mkdir failed\n");
 +            goto fail;
 +        }
  
          ctx = avformat_alloc_context();
          if (!ctx) {
@@@ -430,7 -422,7 +430,7 @@@ static int parse_fragment(AVFormatConte
          if (len < 8 || len >= *moof_size)
              goto fail;
          if (tag == MKTAG('u','u','i','d')) {
 -            const uint8_t tfxd[] = {
 +            static const uint8_t tfxd[] = {
                  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
                  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
              };
@@@ -458,8 -450,11 +458,11 @@@ static int add_fragment(OutputStream *o
      if (os->nb_fragments >= os->fragments_size) {
          os->fragments_size = (os->fragments_size + 1) * 2;
          if ((err = av_reallocp(&os->fragments, sizeof(*os->fragments) *
-                                os->fragments_size)) < 0)
+                                os->fragments_size)) < 0) {
+             os->fragments_size = 0;
+             os->nb_fragments = 0;
              return err;
+         }
      }
      frag = av_mallocz(sizeof(*frag));
      if (!frag)
@@@ -570,7 -565,7 +573,7 @@@ static int ism_write_packet(AVFormatCon
      SmoothStreamingContext *c = s->priv_data;
      AVStream *st = s->streams[pkt->stream_index];
      OutputStream *os = &c->streams[pkt->stream_index];
 -    int64_t end_dts = (c->nb_fragments + 1) * c->min_frag_duration;
 +    int64_t end_dts = (c->nb_fragments + 1LL) * c->min_frag_duration;
      int ret;
  
      if (st->first_dts == AV_NOPTS_VALUE)