]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/utils.c
Merge commit '6cc4d3e9a982e926494f4b919d9733fe29774acf'
[ffmpeg] / libavformat / utils.c
index 66c3ed7ab2abbd5d112d923008fa4d18ef25a99e..fe3ff5abf56597c7ce304b6d8fc655e936fdd321 100644 (file)
@@ -1781,6 +1781,63 @@ int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries,
     return m;
 }
 
+void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
+{
+    int ist1, ist2;
+    int64_t pos_delta = 0;
+    int64_t skip = 0;
+    //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
+    const char *proto = avio_find_protocol_name(s->filename);
+
+    if (!proto) {
+        av_log(s, AV_LOG_INFO,
+               "Protocol name not provided, cannot determine if input is local or "
+               "a network protocol, buffers and access patterns cannot be configured "
+               "optimally without knowing the protocol\n");
+    }
+
+    if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
+        return;
+
+    for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
+        AVStream *st1 = s->streams[ist1];
+        for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
+            AVStream *st2 = s->streams[ist2];
+            int i1, i2;
+
+            if (ist1 == ist2)
+                continue;
+
+            for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
+                AVIndexEntry *e1 = &st1->index_entries[i1];
+                int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
+
+                skip = FFMAX(skip, e1->size);
+                for (; i2 < st2->nb_index_entries; i2++) {
+                    AVIndexEntry *e2 = &st2->index_entries[i2];
+                    int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
+                    if (e2_pts - e1_pts < time_tolerance)
+                        continue;
+                    pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
+                    break;
+                }
+            }
+        }
+    }
+
+    pos_delta *= 2;
+    /* XXX This could be adjusted depending on protocol*/
+    if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
+        av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
+        ffio_set_buf_size(s->pb, pos_delta);
+        s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
+    }
+
+    if (skip < (1<<23)) {
+        s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);
+    }
+}
+
 int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
 {
     return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
@@ -3033,6 +3090,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     int flush_codecs;
     int64_t max_analyze_duration = ic->max_analyze_duration2;
     int64_t max_stream_analyze_duration;
+    int64_t max_subtitle_analyze_duration;
     int64_t probesize = ic->probesize2;
 
     if (!max_analyze_duration)
@@ -3044,9 +3102,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
 
     max_stream_analyze_duration = max_analyze_duration;
+    max_subtitle_analyze_duration = max_analyze_duration;
     if (!max_analyze_duration) {
         max_stream_analyze_duration =
         max_analyze_duration        = 5*AV_TIME_BASE;
+        max_subtitle_analyze_duration = 30*AV_TIME_BASE;
         if (!strcmp(ic->iformat->name, "flv"))
             max_stream_analyze_duration = 30*AV_TIME_BASE;
     }
@@ -3264,6 +3324,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
         }
         if (st->codec_info_nb_frames>1) {
             int64_t t = 0;
+            int64_t limit;
 
             if (st->time_base.den > 0)
                 t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
@@ -3276,10 +3337,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                 && st->info->fps_last_dts  != AV_NOPTS_VALUE)
                 t = FFMAX(t, av_rescale_q(st->info->fps_last_dts - st->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
 
-            if (t >= (analyzed_all_streams ? max_analyze_duration : max_stream_analyze_duration)) {
-                av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds\n",
+            if (analyzed_all_streams)                                limit = max_analyze_duration;
+            else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
+            else                                                     limit = max_stream_analyze_duration;
+
+            if (t >= limit) {
+                av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds st:%d\n",
                        max_analyze_duration,
-                       t);
+                       t, pkt->stream_index);
                 if (ic->flags & AVFMT_FLAG_NOBUFFER)
                     av_packet_unref(pkt);
                 break;