From 4dc3fa8f3bee5e5bdfc299b0ba9ae619d5aece51 Mon Sep 17 00:00:00 2001 From: Justin Qian Date: Mon, 27 Jul 2026 16:45:53 +0800 Subject: [PATCH 1/3] ffmpeg7: remove the legacy Blu-ray direct M2TS patch --- ...find-the-right-m2ts-then-read-seek-i.patch | 71 ------------------- 1 file changed, 71 deletions(-) delete mode 100644 patches/ffmpeg-n7.1.1/0028-bluray-open-and-find-the-right-m2ts-then-read-seek-i.patch diff --git a/patches/ffmpeg-n7.1.1/0028-bluray-open-and-find-the-right-m2ts-then-read-seek-i.patch b/patches/ffmpeg-n7.1.1/0028-bluray-open-and-find-the-right-m2ts-then-read-seek-i.patch deleted file mode 100644 index a6591dfa..00000000 --- a/patches/ffmpeg-n7.1.1/0028-bluray-open-and-find-the-right-m2ts-then-read-seek-i.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 6e7abe54b59f8227df2c1149665b314cd2ac5892 Mon Sep 17 00:00:00 2001 -From: qianlongxu -Date: Tue, 12 May 2026 11:45:56 +0800 -Subject: [PATCH] bluray open and find the right m2ts, then read/seek it - direactly instread of bluray logic. - ---- - libavformat/bluray.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - -diff --git a/libavformat/bluray.c b/libavformat/bluray.c -index cd50523..7fdffdd 100644 ---- a/libavformat/bluray.c -+++ b/libavformat/bluray.c -@@ -42,6 +42,7 @@ typedef struct { - int chapter; - /*int region;*/ - int title_idx; -+ int stream_opened; - } BlurayContext; - - #define OFFSET(x) offsetof(BlurayContext, x) -@@ -222,7 +223,8 @@ static int bluray_open(URLContext *h, const char *path, int flags, AVDictionary - if (bd->chapter > 1) { - bd_seek_chapter(bd->bd, bd->chapter - 1); - } -- -+ /* will read ts soon */ -+ bd->stream_opened = 1; - return 0; - } - -@@ -234,7 +236,13 @@ static int bluray_read(URLContext *h, unsigned char *buf, int size) - if (!bd || !bd->bd) { - return AVERROR(EFAULT); - } -- -+ if (bd->stream_opened) { -+ int read = (int)bd_file_read(bd->bd, buf, size); -+ if (read == 0) { -+ return AVERROR_EOF; -+ } -+ return read; -+ } - len = bd_read(bd->bd, buf, size); - - return len == 0 ? AVERROR_EOF : len; -@@ -252,10 +260,17 @@ static int64_t bluray_seek(URLContext *h, int64_t pos, int whence) - case SEEK_SET: - case SEEK_CUR: - case SEEK_END: -- return bd_seek(bd->bd, pos); -- -+ if (bd->stream_opened) { -+ return bd_file_seek(bd->bd, pos, whence); -+ } else { -+ return bd_seek(bd->bd, pos); -+ } - case AVSEEK_SIZE: -- return bd_get_title_size(bd->bd); -+ if (bd->stream_opened) { -+ return bd_file_size(bd->bd); -+ } else { -+ return bd_get_title_size(bd->bd); -+ } - } - - av_log(h, AV_LOG_ERROR, "Unsupported whence operation %d\n", whence); --- -2.50.1 (Apple Git-155) - From 0e7dc16946fda53e2c03d0a074357222ce4c71c4 Mon Sep 17 00:00:00 2001 From: Justin Qian Date: Mon, 27 Jul 2026 16:46:34 +0800 Subject: [PATCH 2/3] ffmpeg7: split Blu-ray language parsing and fix PID mapping --- ...fs-for-network-Blu-ray-Disc-and-BDMV.patch | 101 ++------- .../0028-bluray-fix-language-override.patch | 196 ++++++++++++++++++ 2 files changed, 208 insertions(+), 89 deletions(-) create mode 100644 patches/ffmpeg-n7.1.1/0028-bluray-fix-language-override.patch diff --git a/patches/ffmpeg-n7.1.1/0027-custom-bluray-fs-for-network-Blu-ray-Disc-and-BDMV.patch b/patches/ffmpeg-n7.1.1/0027-custom-bluray-fs-for-network-Blu-ray-Disc-and-BDMV.patch index f0a7f70d..ea872e8a 100644 --- a/patches/ffmpeg-n7.1.1/0027-custom-bluray-fs-for-network-Blu-ray-Disc-and-BDMV.patch +++ b/patches/ffmpeg-n7.1.1/0027-custom-bluray-fs-for-network-Blu-ray-Disc-and-BDMV.patch @@ -1,14 +1,14 @@ -From 5582bd1c8aa667f9dc0ca6c14ffb916e7a666c0e Mon Sep 17 00:00:00 2001 +From 4fd069b5ab73b35872f01657cb274db8afae5663 Mon Sep 17 00:00:00 2001 From: qianlongxu Date: Tue, 12 May 2026 16:26:37 +0800 Subject: [PATCH] custom bluray fs for network Blu-ray Disc and BDMV --- libavformat/Makefile | 2 +- - libavformat/bluray.c | 128 ++++++++- + libavformat/bluray.c | 63 ++++- libavformat/bluray_custom_fs.c | 459 +++++++++++++++++++++++++++++++++ libavformat/bluray_custom_fs.h | 33 +++ - 4 files changed, 610 insertions(+), 12 deletions(-) + 4 files changed, 544 insertions(+), 13 deletions(-) create mode 100644 libavformat/bluray_custom_fs.c create mode 100644 libavformat/bluray_custom_fs.h @@ -26,10 +26,10 @@ index e299e72..1f32e4c 100644 OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o OBJS-$(CONFIG_CONCATF_PROTOCOL) += concat.o diff --git a/libavformat/bluray.c b/libavformat/bluray.c -index 1845551..eb43340 100644 +index 1845551..f23bfa4 100644 --- a/libavformat/bluray.c +++ b/libavformat/bluray.c -@@ -21,23 +21,27 @@ +@@ -21,19 +21,21 @@ */ #include @@ -40,7 +40,6 @@ index 1845551..eb43340 100644 #include "libavutil/opt.h" +#include "bluray_custom_fs.h" +#include "libavutil/dict.h" -+#include "libavformat/avformat.h" -#define BLURAY_PROTO_PREFIX "bluray:" +#define BLURAY_PROTO_PREFIX "bluray://" @@ -55,12 +54,7 @@ index 1845551..eb43340 100644 int playlist; int angle; int chapter; - /*int region;*/ -+ int title_idx; - } BlurayContext; - - #define OFFSET(x) offsetof(BlurayContext, x) -@@ -106,23 +110,58 @@ static int bluray_close(URLContext *h) +@@ -106,23 +108,57 @@ static int bluray_close(URLContext *h) if (bd->bd) { bd_close(bd->bd); } @@ -75,16 +69,15 @@ index 1845551..eb43340 100644 +#define BLURAY_DEBUG_MASK 0xFFFFF //(0xFFFFF & ~DBG_STREAM) + +static void bluray_DebugHandler(const char *psz) - { ++{ + size_t len = strlen(psz); + if(len < 1) return; + av_log(NULL, AV_LOG_INFO, "[bluray] %s\n",psz); +} +#endif + -+ +static int bluray_open(URLContext *h, const char *path, int flags, AVDictionary **options) -+{ + { +#ifdef DEBUG_BLURAY + bd_set_debug_mask(BLURAY_DEBUG_MASK); + bd_set_debug_handler(bluray_DebugHandler); @@ -123,7 +116,7 @@ index 1845551..eb43340 100644 /* check if disc can be played */ if (check_disc_info(h) < 0) { -@@ -150,6 +189,9 @@ static int bluray_open(URLContext *h, const char *path, int flags) +@@ -150,6 +186,9 @@ static int bluray_open(URLContext *h, const char *path, int flags) int i; for (i = 0; i < num_title_idx; i++) { BLURAY_TITLE_INFO *info = bd_get_title_info(bd->bd, i, 0); @@ -133,13 +126,7 @@ index 1845551..eb43340 100644 av_log(h, AV_LOG_INFO, "playlist %05d.mpls (%d:%02d:%02d)\n", info->playlist, -@@ -159,17 +201,19 @@ static int bluray_open(URLContext *h, const char *path, int flags) - - if (info->duration > duration) { - bd->playlist = info->playlist; -+ bd->title_idx = i; - duration = info->duration; - } +@@ -164,12 +203,13 @@ static int bluray_open(URLContext *h, const char *path, int flags) bd_free_title_info(info); } @@ -156,72 +143,11 @@ index 1845551..eb43340 100644 return AVERROR(EIO); } -@@ -222,13 +266,75 @@ static int64_t bluray_seek(URLContext *h, int64_t pos, int whence) +@@ -222,11 +262,10 @@ static int64_t bluray_seek(URLContext *h, int64_t pos, int whence) return AVERROR(EINVAL); } -+static int bluray_parse_priv(AVFormatContext *ic, URLContext *h) -+{ -+ BlurayContext *bd = h->priv_data; -+ BLURAY_TITLE_INFO *title_info = NULL; -+ BLURAY_CLIP_INFO clip_info; -+ -+ int v_idx = 0; -+ int a_idx = 0; -+ int s_idx = 0; -+ int ret = 0; -+ -+ if (!bd || !bd->bd) { -+ return AVERROR(EFAULT); -+ } -+ -+ title_info = bd_get_title_info(bd->bd, bd->title_idx, 0); -+ if (!title_info) { -+ return AVERROR(EFAULT); -+ } -+ -+ if (title_info->clip_count <= 0) { -+ ret = EFAULT; -+ goto fail; -+ } -+ clip_info = title_info->clips[0]; -+ -+ for (int i = 0; i < ic->nb_streams; i++) { -+ if (ic->streams[i] && ic->streams[i]->codecpar) { -+ switch (ic->streams[i]->codecpar->codec_type) { -+ case AVMEDIA_TYPE_VIDEO: -+ if (v_idx < clip_info.video_stream_count) { -+ av_log(h, AV_LOG_INFO, "video stream %d lang = %s\n", v_idx, clip_info.video_streams[v_idx].lang); -+ av_dict_set(&ic->streams[i]->metadata, "language", clip_info.video_streams[v_idx].lang, AV_DICT_DONT_OVERWRITE); -+ v_idx++; -+ } -+ break; -+ case AVMEDIA_TYPE_AUDIO: -+ if (a_idx < clip_info.audio_stream_count) { -+ av_log(h, AV_LOG_INFO, "audio stream %d lang = %s\n", a_idx, clip_info.audio_streams[a_idx].lang); -+ av_dict_set(&ic->streams[i]->metadata, "language", clip_info.audio_streams[a_idx].lang, AV_DICT_DONT_OVERWRITE); -+ a_idx++; -+ } -+ break; -+ case AVMEDIA_TYPE_SUBTITLE: -+ if (s_idx < clip_info.pg_stream_count) { -+ av_log(h, AV_LOG_INFO, "subtitle stream %d lang = %s\n", s_idx, clip_info.pg_streams[s_idx].lang); -+ av_dict_set(&ic->streams[i]->metadata, "language", clip_info.pg_streams[s_idx].lang, AV_DICT_DONT_OVERWRITE); -+ s_idx++; -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ } -+ -+fail: -+ bd_free_title_info(title_info); -+ -+ return ret != 0 ? AVERROR(ret) : 0; -+} - +- const URLProtocol ff_bluray_protocol = { .name = "bluray", .url_close = bluray_close, @@ -229,10 +155,7 @@ index 1845551..eb43340 100644 + .url_open2 = bluray_open, .url_read = bluray_read, .url_seek = bluray_seek, -+ .url_parse_priv = bluray_parse_priv, .priv_data_size = sizeof(BlurayContext), - .priv_data_class = &bluray_context_class, - }; diff --git a/libavformat/bluray_custom_fs.c b/libavformat/bluray_custom_fs.c new file mode 100644 index 0000000..b82e0b2 diff --git a/patches/ffmpeg-n7.1.1/0028-bluray-fix-language-override.patch b/patches/ffmpeg-n7.1.1/0028-bluray-fix-language-override.patch new file mode 100644 index 00000000..5018660a --- /dev/null +++ b/patches/ffmpeg-n7.1.1/0028-bluray-fix-language-override.patch @@ -0,0 +1,196 @@ +From fac36cc918fb56cc1057d6d94dec6977ceaec462 Mon Sep 17 00:00:00 2001 +From: Justin +Date: Mon, 27 Jul 2026 11:09:03 +0800 +Subject: [PATCH] bluray map stream languages by PID + +--- + libavformat/bluray.c | 126 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 126 insertions(+) + +diff --git a/libavformat/bluray.c b/libavformat/bluray.c +index f23bfa4..2bed615 100644 +--- a/libavformat/bluray.c ++++ b/libavformat/bluray.c +@@ -27,6 +27,7 @@ + #include "libavutil/opt.h" + #include "bluray_custom_fs.h" + #include "libavutil/dict.h" ++#include "libavformat/avformat.h" + + #define BLURAY_PROTO_PREFIX "bluray://" + #define MIN_PLAYLIST_LENGTH 180 /* 3 min */ +@@ -40,6 +41,7 @@ typedef struct { + int angle; + int chapter; + /*int region;*/ ++ int title_idx; + } BlurayContext; + + #define OFFSET(x) offsetof(BlurayContext, x) +@@ -102,6 +104,81 @@ static int check_disc_info(URLContext *h) + return 0; + } + ++static int bluray_lang_is_unknown(const char *lang) ++{ ++ return !lang || !lang[0] || ++ !av_strcasecmp(lang, "und") || ++ !av_strcasecmp(lang, "unknown"); ++} ++ ++static const char *bluray_find_stream_language(const BLURAY_TITLE_INFO *title_info, ++ enum AVMediaType type, int pid) ++{ ++ uint32_t clip_idx; ++ ++ for (clip_idx = 0; clip_idx < title_info->clip_count; clip_idx++) { ++ const BLURAY_CLIP_INFO *clip = &title_info->clips[clip_idx]; ++ const BLURAY_STREAM_INFO *streams = NULL; ++ int stream_count = 0; ++ int stream_idx; ++ ++ switch (type) { ++ case AVMEDIA_TYPE_VIDEO: ++ streams = clip->video_streams; ++ stream_count = clip->video_stream_count; ++ break; ++ case AVMEDIA_TYPE_AUDIO: ++ streams = clip->audio_streams; ++ stream_count = clip->audio_stream_count; ++ break; ++ case AVMEDIA_TYPE_SUBTITLE: ++ streams = clip->pg_streams; ++ stream_count = clip->pg_stream_count; ++ break; ++ default: ++ continue; ++ } ++ ++ for (stream_idx = 0; stream_idx < stream_count; stream_idx++) { ++ const char *lang = (const char *)streams[stream_idx].lang; ++ ++ if (streams[stream_idx].pid == pid && ++ !bluray_lang_is_unknown(lang)) { ++ return lang; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++static void bluray_set_stream_language(URLContext *h, AVStream *st, ++ const BLURAY_TITLE_INFO *title_info) ++{ ++ const AVDictionaryEntry *old_lang; ++ const char *lang; ++ ++ if (!st || !st->codecpar) { ++ return; ++ } ++ ++ lang = bluray_find_stream_language(title_info, st->codecpar->codec_type, ++ st->id); ++ if (!lang) { ++ return; ++ } ++ ++ old_lang = av_dict_get(st->metadata, "language", NULL, 0); ++ if (old_lang && !bluray_lang_is_unknown(old_lang->value)) { ++ return; ++ } ++ ++ av_log(h, AV_LOG_INFO, ++ "bluray stream %d pid=0x%x language %s -> %s\n", ++ st->index, st->id, old_lang ? old_lang->value : "unset", lang); ++ av_dict_set(&st->metadata, "language", lang, 0); ++} ++ + static int bluray_close(URLContext *h) + { + BlurayContext *bd = h->priv_data; +@@ -124,6 +201,7 @@ static void bluray_DebugHandler(const char *psz) + } + #endif + ++ + static int bluray_open(URLContext *h, const char *path, int flags, AVDictionary **options) + { + #ifdef DEBUG_BLURAY +@@ -198,12 +276,29 @@ static int bluray_open(URLContext *h, const char *path, int flags, AVDictionary + + if (info->duration > duration) { + bd->playlist = info->playlist; ++ bd->title_idx = i; + duration = info->duration; + } + + bd_free_title_info(info); + } + av_log(h, AV_LOG_INFO, "select longest playlist: %05d.mpls\n", bd->playlist); ++ } else { ++ int i; ++ ++ for (i = 0; i < num_title_idx; i++) { ++ BLURAY_TITLE_INFO *info = bd_get_title_info(bd->bd, i, 0); ++ ++ if (!info) { ++ continue; ++ } ++ if (info->playlist == bd->playlist) { ++ bd->title_idx = i; ++ bd_free_title_info(info); ++ break; ++ } ++ bd_free_title_info(info); ++ } + } + + /* select playlist */ +@@ -262,12 +357,43 @@ static int64_t bluray_seek(URLContext *h, int64_t pos, int whence) + return AVERROR(EINVAL); + } + ++static int bluray_parse_priv(AVFormatContext *ic, URLContext *h) ++{ ++ BlurayContext *bd = h->priv_data; ++ BLURAY_TITLE_INFO *title_info = NULL; ++ unsigned int i; ++ int ret = 0; ++ ++ if (!bd || !bd->bd) { ++ return AVERROR(EFAULT); ++ } ++ ++ title_info = bd_get_title_info(bd->bd, bd->title_idx, 0); ++ if (!title_info) { ++ return AVERROR(EFAULT); ++ } ++ ++ if (title_info->clip_count <= 0) { ++ ret = EFAULT; ++ goto fail; ++ } ++ ++ for (i = 0; i < ic->nb_streams; i++) { ++ bluray_set_stream_language(h, ic->streams[i], title_info); ++ } ++ ++fail: ++ bd_free_title_info(title_info); ++ return ret != 0 ? AVERROR(ret) : 0; ++} ++ + const URLProtocol ff_bluray_protocol = { + .name = "bluray", + .url_close = bluray_close, + .url_open2 = bluray_open, + .url_read = bluray_read, + .url_seek = bluray_seek, ++ .url_parse_priv = bluray_parse_priv, + .priv_data_size = sizeof(BlurayContext), + .priv_data_class = &bluray_context_class, + }; +-- +2.50.1 (Apple Git-155) + From 128b4ee0a633c06f5c0d58113ca14137635dab18 Mon Sep 17 00:00:00 2001 From: Justin Qian Date: Wed, 19 Aug 2026 17:13:22 +0800 Subject: [PATCH 3/3] ffmpeg: probe streams from later Blu-ray clips Extend the probe budget when audio or subtitle streams first appear in later playlist clips. This allows the MPEG-TS demuxer to discover those streams normally and updates their language metadata after probing. --- ...be-streams-from-later-playlist-clips.patch | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 patches/ffmpeg-n8.1.2/0028-bluray-probe-streams-from-later-playlist-clips.patch diff --git a/patches/ffmpeg-n8.1.2/0028-bluray-probe-streams-from-later-playlist-clips.patch b/patches/ffmpeg-n8.1.2/0028-bluray-probe-streams-from-later-playlist-clips.patch new file mode 100644 index 00000000..3f90bce6 --- /dev/null +++ b/patches/ffmpeg-n8.1.2/0028-bluray-probe-streams-from-later-playlist-clips.patch @@ -0,0 +1,181 @@ +From 65624c5e5a0427461d43feaadec6d780de71fcbb Mon Sep 17 00:00:00 2001 +From: Justin +Date: Wed, 19 Aug 2026 12:06:29 +0800 +Subject: [PATCH] bluray probe streams from later playlist clips + +--- + libavformat/bluray.c | 121 +++++++++++++++++++++++++++++++++++++++++++ + libavformat/demux.c | 14 +++++ + 2 files changed, 135 insertions(+) + +diff --git a/libavformat/bluray.c b/libavformat/bluray.c +index 2bed615..c171b96 100644 +--- a/libavformat/bluray.c ++++ b/libavformat/bluray.c +@@ -179,6 +179,125 @@ static void bluray_set_stream_language(URLContext *h, AVStream *st, + av_dict_set(&st->metadata, "language", lang, 0); + } + ++static int bluray_pid_seen_before(const BLURAY_TITLE_INFO *title_info, ++ enum AVMediaType type, uint32_t clip_idx, ++ int pid) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < clip_idx; i++) { ++ const BLURAY_CLIP_INFO *clip = &title_info->clips[i]; ++ const BLURAY_STREAM_INFO *streams; ++ int stream_count; ++ int j; ++ ++ if (type == AVMEDIA_TYPE_AUDIO) { ++ streams = clip->audio_streams; ++ stream_count = clip->audio_stream_count; ++ } else { ++ streams = clip->pg_streams; ++ stream_count = clip->pg_stream_count; ++ } ++ ++ for (j = 0; j < stream_count; j++) { ++ if (streams[j].pid == pid) ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static uint64_t bluray_latest_deferred_stream_time(const BLURAY_TITLE_INFO *title_info) ++{ ++ uint64_t latest_start_time = 0; ++ uint32_t clip_idx; ++ ++ for (clip_idx = 1; clip_idx < title_info->clip_count; clip_idx++) { ++ const BLURAY_CLIP_INFO *clip = &title_info->clips[clip_idx]; ++ const BLURAY_STREAM_INFO *streams[] = { ++ clip->audio_streams, ++ clip->pg_streams, ++ }; ++ const int stream_counts[] = { ++ clip->audio_stream_count, ++ clip->pg_stream_count, ++ }; ++ const enum AVMediaType types[] = { ++ AVMEDIA_TYPE_AUDIO, ++ AVMEDIA_TYPE_SUBTITLE, ++ }; ++ int group_idx; ++ ++ for (group_idx = 0; group_idx < FF_ARRAY_ELEMS(streams); group_idx++) { ++ int stream_idx; ++ ++ for (stream_idx = 0; stream_idx < stream_counts[group_idx]; stream_idx++) { ++ int pid = streams[group_idx][stream_idx].pid; ++ ++ if (pid > 0 && ++ !bluray_pid_seen_before(title_info, types[group_idx], ++ clip_idx, pid)) { ++ latest_start_time = FFMAX(latest_start_time, ++ clip->start_time); ++ } ++ } ++ } ++ } ++ ++ return latest_start_time; ++} ++ ++#define BLURAY_PROBE_MARGIN (3LL * AV_TIME_BASE) ++#define BLURAY_PROBE_BITRATE 64000000LL ++#define BLURAY_MAX_PROBE_SIZE (256LL * 1024 * 1024) ++ ++static void bluray_configure_stream_probe(URLContext *h, AVFormatContext *ic, ++ const BLURAY_TITLE_INFO *title_info) ++{ ++ uint64_t deferred_start_time; ++ int64_t analyze_duration; ++ int64_t probe_size; ++ int64_t uncapped_probe_size; ++ ++ deferred_start_time = bluray_latest_deferred_stream_time(title_info); ++ if (!deferred_start_time) ++ return; ++ ++ analyze_duration = av_rescale_q(deferred_start_time, ++ (AVRational){ 1, 90000 }, ++ AV_TIME_BASE_Q); ++ analyze_duration = FFMIN(analyze_duration, INT64_MAX - BLURAY_PROBE_MARGIN) + ++ BLURAY_PROBE_MARGIN; ++ uncapped_probe_size = av_rescale(analyze_duration, BLURAY_PROBE_BITRATE, ++ 8LL * AV_TIME_BASE); ++ probe_size = FFMIN(uncapped_probe_size, BLURAY_MAX_PROBE_SIZE); ++ ++ if (ic->max_analyze_duration >= analyze_duration && ++ ic->probesize >= probe_size) ++ return; ++ ++ if (uncapped_probe_size > BLURAY_MAX_PROBE_SIZE) { ++ av_log(h, AV_LOG_WARNING, ++ "bluray deferred streams require probe size %"PRId64 ++ ", capped at %"PRId64" bytes\n", ++ uncapped_probe_size, BLURAY_MAX_PROBE_SIZE); ++ } ++ ++ av_log(h, AV_LOG_INFO, ++ "bluray deferred streams start by %.3f seconds; " ++ "analyzeduration %"PRId64" -> %"PRId64 ++ ", probesize %"PRId64" -> %"PRId64"\n", ++ deferred_start_time / 90000.0, ++ ic->max_analyze_duration, ++ FFMAX(ic->max_analyze_duration, analyze_duration), ++ ic->probesize, FFMAX(ic->probesize, probe_size)); ++ ++ ic->max_analyze_duration = FFMAX(ic->max_analyze_duration, ++ analyze_duration); ++ ic->probesize = FFMAX(ic->probesize, probe_size); ++} ++ + static int bluray_close(URLContext *h) + { + BlurayContext *bd = h->priv_data; +@@ -378,6 +497,8 @@ static int bluray_parse_priv(AVFormatContext *ic, URLContext *h) + goto fail; + } + ++ bluray_configure_stream_probe(h, ic, title_info); ++ + for (i = 0; i < ic->nb_streams; i++) { + bluray_set_stream_language(h, ic->streams[i], title_info); + } +diff --git a/libavformat/demux.c b/libavformat/demux.c +index f40defa..1d10292 100644 +--- a/libavformat/demux.c ++++ b/libavformat/demux.c +@@ -50,6 +50,18 @@ + #include "internal.h" + #include "url.h" + ++static void call_url_parse_priv(AVFormatContext *s) ++{ ++ URLContext *url_context; ++ ++ if (!s->pb) ++ return; ++ ++ url_context = ffio_geturlcontext(s->pb); ++ if (url_context && url_context->prot && url_context->prot->url_parse_priv) ++ url_context->prot->url_parse_priv(s, url_context); ++} ++ + static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp) + { + const FFStream *const sti = cffstream(st); +@@ -3245,6 +3257,8 @@ find_stream_info_err: + av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n", + avio_tell(ic->pb), ctx->bytes_read, ctx->seek_count, count); + } ++ if (ret >= 0) ++ call_url_parse_priv(ic); + return ret; + + unref_then_goto_end: