コード例 #1
0
ファイル: VideoPlayer.cs プロジェクト: zeroxist/MediaPortal-2
        private void SetPreferredSubtitle_intern(ref BaseStreamInfoHandler subtitleStreams)
        {
            if (subtitleStreams == null)
            {
                return;
            }

            VideoSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <VideoSettings>() ?? new VideoSettings();

            // first try to find a stream by it's exact LCID.
            StreamInfo streamInfo = subtitleStreams.FindStream(settings.PreferredSubtitleLanguage) ?? subtitleStreams.FindSimilarStream(settings.PreferredSubtitleStreamName);

            if (streamInfo == null || !settings.EnableMpcSubtitlesEngine)
            {
                // auto-activate forced subtitles
                StreamInfo forced = subtitleStreams.FindForcedStream();
                if (forced != null)
                {
                    subtitleStreams.EnableStream(forced.Name);
                }
                else
                {
                    StreamInfo noSubtitleStream = subtitleStreams.FindSimilarStream(GetNoSubsName());
                    if (noSubtitleStream != null)
                    {
                        subtitleStreams.EnableStream(noSubtitleStream.Name);
                    }
                }
            }
            else
            {
                subtitleStreams.EnableStream(streamInfo.Name);
            }
        }
コード例 #2
0
ファイル: VideoPlayer.cs プロジェクト: zeroxist/MediaPortal-2
 /// <summary>
 /// Release all COM object references to IAMStreamSelect instances.
 /// </summary>
 protected virtual void ReleaseStreamSelectors()
 {
     // Release all existing stream selector references
     if (_streamSelectors != null)
     {
         foreach (IAMStreamSelect streamSelector in _streamSelectors)
         {
             FilterGraphTools.TryReleaseComObject(streamSelector);
         }
     }
     _streamSelectors     = null;
     _streamInfoAudio     = null;
     _streamInfoSubtitles = null;
     _streamInfoTitles    = null;
 }
コード例 #3
0
 /// <summary>
 /// Release all COM object references to IAMStreamSelect instances.
 /// </summary>
 protected virtual void ReleaseStreamSelectors()
 {
     // Release all existing stream selector references
     if (_streamSelectors != null)
     {
         foreach (IAMStreamSelect streamSelector in _streamSelectors)
         {
             if (Marshal.IsComObject(streamSelector))
             {
                 Marshal.ReleaseComObject(streamSelector);
             }
         }
     }
     _streamSelectors     = null;
     _streamInfoAudio     = null;
     _streamInfoSubtitles = null;
     _streamInfoTitles    = null;
 }
コード例 #4
0
ファイル: VideoPlayer.cs プロジェクト: zeroxist/MediaPortal-2
        /// <summary>
        /// Enumerates streams from video (audio, subtitles).
        /// </summary>
        /// <param name="forceRefresh">Force refresh</param>
        /// <returns><c>true</c> if information has been changed.</returns>
        protected virtual bool EnumerateStreams(bool forceRefresh)
        {
            if (_graphBuilder == null || !_initialized)
            {
                return(false);
            }

            BaseStreamInfoHandler audioStreams;
            BaseStreamInfoHandler titleStreams;

            lock (SyncObj)
            {
                audioStreams = _streamInfoAudio;
                titleStreams = _streamInfoTitles;
            }
            if (forceRefresh || audioStreams == null || titleStreams == null)
            {
                audioStreams = new StreamInfoHandler();
                titleStreams = new StreamInfoHandler();

                // Release stream selectors
                ReleaseStreamSelectors();
                _streamSelectors = FilterGraphTools.FindFiltersByInterface <IAMStreamSelect>(_graphBuilder);
                _hasEdition      = false; // To decide for stream enumerations in SetTitle
                foreach (IAMStreamSelect streamSelector in _streamSelectors)
                {
                    FilterInfo fi = FilterGraphTools.QueryFilterInfoAndFree((IBaseFilter)streamSelector);
                    int        streamCount;
                    streamSelector.Count(out streamCount);

                    for (int i = 0; i < streamCount; ++i)
                    {
                        IntPtr pp_punk            = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_object          = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_name            = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_groupNumber     = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_lcid            = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_selectInfoFlags = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        IntPtr pp_mediaType       = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                        int    hr = streamSelector.Info(i, pp_mediaType, pp_selectInfoFlags, pp_lcid, pp_groupNumber, pp_name, pp_punk, pp_object);
                        new HRESULT(hr).Throw();

                        // We get a pointer to pointer for a structure.
                        AMMediaType mediaType = (AMMediaType)Marshal.PtrToStructure(Marshal.ReadIntPtr(pp_mediaType), typeof(AMMediaType));
                        if (mediaType == null)
                        {
                            ServiceRegistration.Get <ILogger>().Warn("Stream {0}: Could not determine MediaType!", i);
                            continue;
                        }
                        int    groupNumber = Marshal.ReadInt32(pp_groupNumber);
                        int    lcid        = Marshal.ReadInt32(pp_lcid);
                        string name        = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(pp_name));

                        // If stream does not contain a LCID, try a lookup from stream name.
                        if (lcid == 0)
                        {
                            lcid = LookupLcidFromName(name);
                        }

                        ServiceRegistration.Get <ILogger>().Debug("Stream {4}|{0}: MajorType {1}; Name {2}; PWDGroup: {3}; LCID: {5}",
                                                                  i, mediaType.majorType, name, groupNumber, fi.achName, lcid);

                        StreamInfo currentStream = new StreamInfo(streamSelector, i, name, lcid);
                        switch ((StreamGroup)groupNumber)
                        {
                        case StreamGroup.Audio:
                            if (mediaType.majorType == MediaType.AnalogAudio || mediaType.majorType == MediaType.Audio)
                            {
                                String streamName = name.Trim();
                                String streamAppendix;
                                if (!CodecHandler.MediaSubTypes.TryGetValue(mediaType.subType, out streamAppendix))
                                {
                                    streamAppendix = string.Empty;
                                }

                                // if audio information is available via WaveEx format, query the channel count
                                if (mediaType.formatType == FormatType.WaveEx && mediaType.formatPtr != IntPtr.Zero)
                                {
                                    WaveFormatEx waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx));
                                    currentStream.ChannelCount = waveFormatEx.nChannels;
                                    streamAppendix             = String.Format("{0} {1}ch", streamAppendix, currentStream.ChannelCount);
                                }

                                if (!string.IsNullOrEmpty(streamAppendix))
                                {
                                    currentStream.Name = String.Format("{0} ({1})", streamName, streamAppendix);
                                }

                                audioStreams.AddUnique(currentStream);
                            }
                            break;

                        case StreamGroup.Video: // Used for multiple video streams inside a single MKV, i.e. to have both 2D and 3D video in same file
                            titleStreams.AddUnique(currentStream, true);
                            break;

                        case StreamGroup.MatroskaEdition: // This is a MKV Edition handled by Haali splitter
                            titleStreams.AddUnique(currentStream, true);
                            _hasEdition = true;           // To decide for stream enumerations in SetTitle
                            break;
                        }
                        // Free MediaType and references
                        DsUtils.FreeAMMediaType(mediaType);
                        Marshal.FreeHGlobal(pp_punk);
                        Marshal.FreeHGlobal(pp_object);
                        Marshal.FreeHGlobal(pp_name);
                        Marshal.FreeHGlobal(pp_groupNumber);
                        Marshal.FreeHGlobal(pp_lcid);
                        Marshal.FreeHGlobal(pp_selectInfoFlags);
                        Marshal.FreeHGlobal(pp_mediaType);
                    }
                }

                // MPC engine uses it's own way to enumerate subs.
                BaseStreamInfoHandler subtitleStreams = new MpcStreamInfoHandler();
                SetPreferredSubtitle_intern(ref subtitleStreams);
                SetPreferedAudio_intern(ref audioStreams, false);

                lock (SyncObj)
                {
                    _streamInfoAudio     = audioStreams;
                    _streamInfoSubtitles = subtitleStreams;
                    _streamInfoTitles    = titleStreams;
                }
                return(true);
            }
            return(false);
        }
コード例 #5
0
ファイル: VideoPlayer.cs プロジェクト: zeroxist/MediaPortal-2
        private void SetPreferedAudio_intern(ref BaseStreamInfoHandler audioStreams, bool useFirstAsDefault)
        {
            if (audioStreams == null || audioStreams.Count == 0)
            {
                return;
            }

            VideoSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <VideoSettings>();

            // When multiple streams are available, we select the stream by channel count preference (PreferMultiChannelAudio).
            Predicate <StreamInfo> channelCountPreference;

            if (settings.PreferMultiChannelAudio)
            {
                channelCountPreference = (a => a.ChannelCount > 2); // Prefer more then stereo (usually 6ch)
            }
            else
            {
                channelCountPreference = (a => a.ChannelCount <= 2); // Stereo or even mono
            }
            // Check if there are multiple audio streams for the PreferredAudioLanguage.
            int preferredAudioLCID = settings.PreferredAudioLanguage;

            List <StreamInfo> streamsForLCID = audioStreams.ToList().FindAll(a => a.LCID == preferredAudioLCID && a.LCID != 0);
            int count = streamsForLCID.Count;

            if (count > 0)
            {
                // If we have only one choice, select this stream.
                if (count == 1)
                {
                    audioStreams.EnableStream(streamsForLCID[0].Name);
                    return;
                }

                StreamInfo bestChannelStream = streamsForLCID.Find(channelCountPreference);
                if (bestChannelStream != null)
                {
                    audioStreams.EnableStream(bestChannelStream.Name);
                    return;
                }
            }

            // If we did not find matching languages by LCID no try to find them by name.
            StreamInfo streamInfo = null;

            if (preferredAudioLCID != 0)
            {
                try
                {
                    CultureInfo ci           = new CultureInfo(preferredAudioLCID);
                    string      languagePart = ci.EnglishName.Substring(0, ci.EnglishName.IndexOf("(") - 1);
                    streamInfo = audioStreams.FindSimilarStream(languagePart);
                }
                catch { }
            }

            // Still no matching languages? Then select the first that matches channelCountPreference.
            if (streamInfo == null)
            {
                streamInfo = audioStreams.ToList().Find(channelCountPreference);
            }

            if (streamInfo != null)
            {
                audioStreams.EnableStream(streamInfo.Name);
            }
            else
            if (useFirstAsDefault)
            {
                audioStreams.EnableStream(audioStreams[0].Name);
            }
        }