]> git.sesse.net Git - ffmpeg/commitdiff
Merge commit '9d599e3f6e61438772d8cddd6c9b7c495251f51e'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 2 Apr 2014 16:01:48 +0000 (18:01 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 2 Apr 2014 16:03:02 +0000 (18:03 +0200)
* commit '9d599e3f6e61438772d8cddd6c9b7c495251f51e':
  avi: Improve non-interleaved detection

Conflicts:
libavformat/avidec.c

See: 8df774be88c347c40f1b2411ed9e391dfec0ebb7 and others
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/avidec.c

index 52d0425507101d9b620ff9b6028a07c8fb48c2fc,c24a6c495dcf7ad10f6541596d72e549a3c46b5a..9a2424f7bdf77dfba1d38469540782b0e0cb4323
@@@ -903,19 -794,12 +903,23 @@@ fail
  
      if (!avi->index_loaded && pb->seekable)
          avi_load_index(s);
 -    avi->index_loaded     = 1;
 +    calculate_bitrate(s);
 +    avi->index_loaded    |= 1;
-     avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
+     if ((ret = guess_ni_flag(s)) < 0)
+         return ret;
 -    avi->non_interleaved |= ret;
++    avi->non_interleaved |= ret | (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)
@@@ -1504,14 -1311,70 +1508,70 @@@ static int avi_read_idx1(AVFormatContex
      return 0;
  }
  
 -
+ /* Scan the index and consider any file with streams more than
+  * 2 seconds or 64MB apart non-interleaved. */
+ static int check_stream_max_drift(AVFormatContext *s)
+ {
+     int64_t min_pos, pos;
+     int i;
+     int *idx = av_mallocz_array(s->nb_streams, sizeof(*idx));
+     if (!idx)
+         return AVERROR(ENOMEM);
+     for (min_pos = pos = 0; min_pos != INT64_MAX; pos = min_pos + 1LU) {
+         int64_t max_dts = INT64_MIN / 2;
+         int64_t min_dts = INT64_MAX / 2;
+         int64_t max_buffer = 0;
+         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) {
+                 int64_t dts;
+                 dts = av_rescale_q(st->index_entries[idx[i]].timestamp /
+                                    FFMAX(ast->sample_size, 1),
+                                    st->time_base, AV_TIME_BASE_Q);
+                 min_dts = FFMIN(min_dts, dts);
+                 min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
+             }
+         }
+         for (i = 0; i < s->nb_streams; i++) {
+             AVStream *st = s->streams[i];
+             AVIStream *ast = st->priv_data;
+             if (idx[i] && min_dts != INT64_MAX / 2) {
+                 int64_t dts;
+                 dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp /
+                                    FFMAX(ast->sample_size, 1),
+                                    st->time_base, AV_TIME_BASE_Q);
+                 max_dts = FFMAX(max_dts, dts);
+                 max_buffer = FFMAX(max_buffer,
+                                    av_rescale(dts - min_dts,
+                                               st->codec->bit_rate,
+                                               AV_TIME_BASE));
+             }
+         }
+         if (max_dts - min_dts > 2 * AV_TIME_BASE ||
+             max_buffer > 1024 * 1024 * 8 * 8) {
+             av_free(idx);
+             return 1;
+         }
+     }
+     av_free(idx);
+     return 0;
+ }
  static int guess_ni_flag(AVFormatContext *s)
  {
      int i;
      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];