From 3bf70ab7968058da709698bc8599d9aa54faadd8 Mon Sep 17 00:00:00 2001 From: epbk Date: Sun, 27 Oct 2024 18:22:33 +0100 Subject: [PATCH] MP1-5226: VideoPlayer: Fix AnalyseStream to support individual video/audio source filter --- mediaportal/Core/Player/VideoPlayerVMR7.cs | 389 +++++++++++---------- 1 file changed, 200 insertions(+), 189 deletions(-) diff --git a/mediaportal/Core/Player/VideoPlayerVMR7.cs b/mediaportal/Core/Player/VideoPlayerVMR7.cs index 18dae85be97..45211de09e6 100644 --- a/mediaportal/Core/Player/VideoPlayerVMR7.cs +++ b/mediaportal/Core/Player/VideoPlayerVMR7.cs @@ -18,7 +18,8 @@ #endregion -using System; +using System; +using System.Linq; using System.Globalization; using System.Drawing; using System.IO; @@ -2084,192 +2085,202 @@ public void AnalyseStreamsChapters() } } - public bool AnalyseStreams() - { - try - { - if (FStreams == null) - { - FStreams = new FilterStreams(); - } - FStreams.DeleteAllStreams(); - //RETRIEVING THE CURRENT SPLITTER - string filter; - IBaseFilter[] foundfilter = new IBaseFilter[2]; - int fetched = 0; - IEnumFilters enumFilters; - graphBuilder.EnumFilters(out enumFilters); - if (enumFilters != null) - { - enumFilters.Reset(); - while (enumFilters.Next(1, foundfilter, out fetched) == 0) - { - if (foundfilter[0] != null && fetched == 1) - { - if (chapters == null) - { - IAMExtendedSeeking pEs = foundfilter[0] as IAMExtendedSeeking; - if (pEs != null) - { - int markerCount = 0; - if (pEs.get_MarkerCount(out markerCount) == 0 && markerCount > 0) - { - chapters = new double[markerCount]; - chaptersname = new string[markerCount]; - for (int i = 1; i <= markerCount; i++) - { - double markerTime = 0; - pEs.GetMarkerTime(i, out markerTime); - chapters[i - 1] = markerTime; - //fill up chapter names - string name = null; - pEs.GetMarkerName(i, out name); - chaptersname[i - 1] = name; - } - } - } - } - IAMStreamSelect pStrm = foundfilter[0] as IAMStreamSelect; - if (pStrm != null) - { - FilterInfo foundfilterinfos = new FilterInfo(); - foundfilter[0].QueryFilterInfo(out foundfilterinfos); - filter = foundfilterinfos.achName; - int cStreams = 0; - pStrm.Count(out cStreams); - if (cStreams < 2) - { - continue; - } - //GET STREAMS - for (int istream = 0; istream < cStreams; istream++) - { - AMMediaType sType; - AMStreamSelectInfoFlags sFlag; - int sPDWGroup, sPLCid; - string sName; - object pppunk, ppobject; - //STREAM INFO - pStrm.Info(istream, out sType, out sFlag, out sPLCid, - out sPDWGroup, out sName, out pppunk, out ppobject); - FilterStreamInfos FSInfos = new FilterStreamInfos(); - FSInfos.Current = false; - FSInfos.Filter = filter; - FSInfos.Name = sName; - FSInfos.LCID = sPLCid; - FSInfos.Id = istream; - FSInfos.Type = StreamType.Unknown; - FSInfos.sFlag = sFlag; - //Avoid listing ffdshow video filter's plugins amongst subtitle and audio streams and editions. - if ((FSInfos.Filter == "ffdshow DXVA Video Decoder" || FSInfos.Filter == "ffdshow Video Decoder" || - FSInfos.Filter == "ffdshow raw video filter") && - ((sPDWGroup == 1) || (sPDWGroup == 2) || (sPDWGroup == 18) || (sPDWGroup == 4))) - { - FSInfos.Type = StreamType.Unknown; - } - //VIDEO - else if (sPDWGroup == 0) - { - FSInfos.Type = StreamType.Video; - } - //AUDIO - else if (sPDWGroup == 1) - { - FSInfos.Type = StreamType.Audio; - } - //SUBTITLE - else if (sPDWGroup == 2 && sName.LastIndexOf("off", StringComparison.Ordinal) == -1 && sName.LastIndexOf("Hide ", StringComparison.Ordinal) == -1 && - sName.LastIndexOf("No ", StringComparison.Ordinal) == -1 && sName.LastIndexOf("Miscellaneous ", StringComparison.Ordinal) == -1) - { - FSInfos.Type = StreamType.Subtitle; - } - //NO SUBTITILE TAG - else if ((sPDWGroup == 2 && (sName.LastIndexOf("off", StringComparison.Ordinal) != -1 || sName.LastIndexOf("No ", StringComparison.Ordinal) != -1)) || - (sPDWGroup == 6590033 && sName.LastIndexOf("Hide ", StringComparison.Ordinal) != -1)) - { - FSInfos.Type = StreamType.Subtitle_hidden; - } - //DirectVobSub SHOW SUBTITLE TAG - else if (sPDWGroup == 6590033 && sName.LastIndexOf("Show ", StringComparison.Ordinal) != -1) - { - FSInfos.Type = StreamType.Subtitle_shown; - } - //EDITION - else if (sPDWGroup == 18) - { - FSInfos.Type = StreamType.Edition; - } - else if (sPDWGroup == 4) //Subtitle file - { - FSInfos.Type = StreamType.Subtitle_file; - } - else if (sPDWGroup == 10) //Postprocessing filter - { - FSInfos.Type = StreamType.PostProcessing; - } - Log.Debug("VideoPlayer: FoundStreams: Type={0}; Name={1}, Filter={2}, Id={3}, PDWGroup={4}, LCID={5}", - FSInfos.Type.ToString(), FSInfos.Name, FSInfos.Filter, FSInfos.Id.ToString(), - sPDWGroup.ToString(), sPLCid.ToString()); - - switch (FSInfos.Type) - { - case StreamType.Unknown: - case StreamType.Subtitle: - case StreamType.Subtitle_file: - case StreamType.Subtitle_hidden: - case StreamType.Subtitle_shown: - if (streamLAVSelection && - (FSInfos.Filter.ToLowerInvariant().Contains("LAV Splitter".ToLowerInvariant()) || - FSInfos.Filter.ToUpperInvariant().Contains(@"\BDMV\INDEX.BDMV"))) - { - if (FSInfos.sFlag == AMStreamSelectInfoFlags.Enabled || - FSInfos.sFlag == (AMStreamSelectInfoFlags.Enabled | AMStreamSelectInfoFlags.Exclusive)) - { - FSInfos.Current = true; - pStrm.Enable(FSInfos.Id, 0); - pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); - } - goto default; - } - break; - case StreamType.Video: - case StreamType.Audio: - case StreamType.Edition: - case StreamType.PostProcessing: - if (FSInfos.Type == StreamType.Audio && FSInfos.Filter == MEDIAPORTAL_AUDIOSWITCHER_FILTER && FSInfos.Name == "Audio " && !AutoRenderingCheck && GetInterface) - { - FStreams.AddStreamInfosEx(FSInfos); - break; - } - if (streamLAVSelection) + public bool AnalyseStreams() + { + try + { + if (FStreams == null) + { + FStreams = new FilterStreams(); + } + FStreams.DeleteAllStreams(); + //RETRIEVING THE CURRENT SPLITTER + string filter; + IBaseFilter[] foundfilter = new IBaseFilter[2]; + int fetched = 0; + IEnumFilters enumFilters; + graphBuilder.EnumFilters(out enumFilters); + if (enumFilters != null) + { + string[] sourceFilters = null; + while (true) + { + enumFilters.Reset(); + while (enumFilters.Next(1, foundfilter, out fetched) == 0) + { + if (foundfilter[0] != null && fetched == 1) + { + if (chapters == null) + { + IAMExtendedSeeking pEs = foundfilter[0] as IAMExtendedSeeking; + if (pEs != null) + { + int markerCount = 0; + if (pEs.get_MarkerCount(out markerCount) == 0 && markerCount > 0) + { + chapters = new double[markerCount]; + chaptersname = new string[markerCount]; + for (int i = 1; i <= markerCount; i++) { - if (FSInfos.sFlag == AMStreamSelectInfoFlags.Enabled || FSInfos.sFlag == (AMStreamSelectInfoFlags.Enabled | AMStreamSelectInfoFlags.Exclusive)) + double markerTime = 0; + pEs.GetMarkerTime(i, out markerTime); + chapters[i - 1] = markerTime; + //fill up chapter names + string name = null; + pEs.GetMarkerName(i, out name); + chaptersname[i - 1] = name; + } + } + } + } + IAMStreamSelect pStrm = foundfilter[0] as IAMStreamSelect; + if (pStrm != null) + { + FilterInfo foundfilterinfos = new FilterInfo(); + foundfilter[0].QueryFilterInfo(out foundfilterinfos); + filter = foundfilterinfos.achName; + int cStreams = 0; + pStrm.Count(out cStreams); + if (cStreams < 2 && (sourceFilters == null || cStreams != 1 || !sourceFilters.Any(f => filter.StartsWith(f)))) + { + continue; + } + //GET STREAMS + for (int istream = 0; istream < cStreams; istream++) + { + AMMediaType sType; + AMStreamSelectInfoFlags sFlag; + int sPDWGroup, sPLCid; + string sName; + object pppunk, ppobject; + //STREAM INFO + pStrm.Info(istream, out sType, out sFlag, out sPLCid, + out sPDWGroup, out sName, out pppunk, out ppobject); + FilterStreamInfos FSInfos = new FilterStreamInfos(); + FSInfos.Current = false; + FSInfos.Filter = filter; + FSInfos.Name = sName; + FSInfos.LCID = sPLCid; + FSInfos.Id = istream; + FSInfos.Type = StreamType.Unknown; + FSInfos.sFlag = sFlag; + //Avoid listing ffdshow video filter's plugins amongst subtitle and audio streams and editions. + if ((FSInfos.Filter == "ffdshow DXVA Video Decoder" || FSInfos.Filter == "ffdshow Video Decoder" || + FSInfos.Filter == "ffdshow raw video filter") && + ((sPDWGroup == 1) || (sPDWGroup == 2) || (sPDWGroup == 18) || (sPDWGroup == 4))) + { + FSInfos.Type = StreamType.Unknown; + } + //VIDEO + else if (sPDWGroup == 0) + { + FSInfos.Type = StreamType.Video; + } + //AUDIO + else if (sPDWGroup == 1) + { + FSInfos.Type = StreamType.Audio; + } + //SUBTITLE + else if (sPDWGroup == 2 && sName.LastIndexOf("off", StringComparison.Ordinal) == -1 && sName.LastIndexOf("Hide ", StringComparison.Ordinal) == -1 && + sName.LastIndexOf("No ", StringComparison.Ordinal) == -1 && sName.LastIndexOf("Miscellaneous ", StringComparison.Ordinal) == -1) + { + FSInfos.Type = StreamType.Subtitle; + } + //NO SUBTITILE TAG + else if ((sPDWGroup == 2 && (sName.LastIndexOf("off", StringComparison.Ordinal) != -1 || sName.LastIndexOf("No ", StringComparison.Ordinal) != -1)) || + (sPDWGroup == 6590033 && sName.LastIndexOf("Hide ", StringComparison.Ordinal) != -1)) + { + FSInfos.Type = StreamType.Subtitle_hidden; + } + //DirectVobSub SHOW SUBTITLE TAG + else if (sPDWGroup == 6590033 && sName.LastIndexOf("Show ", StringComparison.Ordinal) != -1) + { + FSInfos.Type = StreamType.Subtitle_shown; + } + //EDITION + else if (sPDWGroup == 18) + { + FSInfos.Type = StreamType.Edition; + } + else if (sPDWGroup == 4) //Subtitle file + { + FSInfos.Type = StreamType.Subtitle_file; + } + else if (sPDWGroup == 10) //Postprocessing filter + { + FSInfos.Type = StreamType.PostProcessing; + } + Log.Debug("VideoPlayer: FoundStreams: Type={0}; Name={1}, Filter={2}, Id={3}, PDWGroup={4}, LCID={5}", + FSInfos.Type.ToString(), FSInfos.Name, FSInfos.Filter, FSInfos.Id.ToString(), + sPDWGroup.ToString(), sPLCid.ToString()); + + switch (FSInfos.Type) + { + case StreamType.Unknown: + case StreamType.Subtitle: + case StreamType.Subtitle_file: + case StreamType.Subtitle_hidden: + case StreamType.Subtitle_shown: + if (streamLAVSelection && + (FSInfos.Filter.ToLowerInvariant().Contains("LAV Splitter".ToLowerInvariant()) || + FSInfos.Filter.ToUpperInvariant().Contains(@"\BDMV\INDEX.BDMV"))) { - FSInfos.Current = true; - pStrm.Enable(FSInfos.Id, 0); - pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); - } - } - else - { - if (FStreams.GetStreamCount(FSInfos.Type) == 0) - { - FSInfos.Current = true; - pStrm.Enable(FSInfos.Id, 0); - pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); - } - } - goto default; - default: - FStreams.AddStreamInfos(FSInfos); - break; - } - } - } - DirectShowUtil.ReleaseComObject(foundfilter[0]); - } - } - DirectShowUtil.ReleaseComObject(enumFilters); + if (FSInfos.sFlag == AMStreamSelectInfoFlags.Enabled || + FSInfos.sFlag == (AMStreamSelectInfoFlags.Enabled | AMStreamSelectInfoFlags.Exclusive)) + { + FSInfos.Current = true; + pStrm.Enable(FSInfos.Id, 0); + pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); + } + goto default; + } + break; + case StreamType.Video: + case StreamType.Audio: + case StreamType.Edition: + case StreamType.PostProcessing: + if (FSInfos.Type == StreamType.Audio && FSInfos.Filter == MEDIAPORTAL_AUDIOSWITCHER_FILTER && FSInfos.Name == "Audio " && !AutoRenderingCheck && GetInterface) + { + FStreams.AddStreamInfosEx(FSInfos); + break; + } + if (streamLAVSelection) + { + if (FSInfos.sFlag == AMStreamSelectInfoFlags.Enabled || FSInfos.sFlag == (AMStreamSelectInfoFlags.Enabled | AMStreamSelectInfoFlags.Exclusive)) + { + FSInfos.Current = true; + pStrm.Enable(FSInfos.Id, 0); + pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); + } + } + else + { + if (FStreams.GetStreamCount(FSInfos.Type) == 0) + { + FSInfos.Current = true; + pStrm.Enable(FSInfos.Id, 0); + pStrm.Enable(FSInfos.Id, AMStreamSelectEnableFlags.Enable); + } + } + goto default; + default: + FStreams.AddStreamInfos(FSInfos); + break; + } + } + } + DirectShowUtil.ReleaseComObject(foundfilter[0]); + } + } + + if (FStreams.GetStreamCount(StreamType.Video) > 0 || FStreams.GetStreamCount(StreamType.Audio) > 0 || sourceFilters != null) + break; + + //Try another pass where the filter is source type and has only one stream (individual video/audio sources) + sourceFilters = (string[])FilterHelper.GetFilterSource().ToArray(typeof(string)); + } + DirectShowUtil.ReleaseComObject(enumFilters); } if (streamLAVSelection) { @@ -2282,10 +2293,10 @@ public bool AnalyseStreams() // Set LAV Splitter stream CurrentSubtitleStream = CurrentSubtitleLAVStream; EnableSubtitle = CurrentSubtitleLAVStream != -1; - } - } - catch { } - return true; + } + } + catch { } + return true; } public bool EnableStream(int Id, AMStreamSelectEnableFlags dwFlags, string Filter)