Пример #1
0
        /// <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);
            }

            StreamInfoHandler audioStreams;
            StreamInfoHandler subtitleStreams;
            StreamInfoHandler titleStreams;

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

                // Release stream selectors
                ReleaseStreamSelectors();
                _streamSelectors = FilterGraphTools.FindFiltersByInterface <IAMStreamSelect>(_graphBuilder);
                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));
                        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.Video:
                            break;

                        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.Subtitle:
                        {
                            currentStream.IsAutoSubtitle = currentStream.Name.ToLowerInvariant().Contains(FORCED_SUBTITLES);
                            subtitleStreams.AddUnique(currentStream, true);
                        }
                        break;

                        case StreamGroup.VsFilterSubtitle:
                        case StreamGroup.VsFilterSubtitleOptions:
                        case StreamGroup.DirectVobSubtitle:
                            subtitleStreams.AddUnique(currentStream, true);
                            break;

                        case StreamGroup.MatroskaEdition: // This is a MKV Edition handled by Haali splitter
                            titleStreams.AddUnique(currentStream, true);
                            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);
                    }
                }

                SetPreferedAudio_intern(ref audioStreams, false);
                SetPreferredSubtitle_intern(ref subtitleStreams);
                lock (SyncObj)
                {
                    _streamInfoAudio     = audioStreams;
                    _streamInfoSubtitles = subtitleStreams;
                    _streamInfoTitles    = titleStreams;
                }
                return(true);
            }
            return(false);
        }
Пример #2
0
        /// <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);
            }

            StreamInfoHandler audioStreams;
            StreamInfoHandler subtitleStreams;
            StreamInfoHandler titleStreams;

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

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

                    for (int i = 0; i < streamCount; ++i)
                    {
                        AMMediaType             mediaType;
                        AMStreamSelectInfoFlags selectInfoFlags;
                        int    groupNumber, lcid;
                        string name;
                        object pppunk, ppobject;

                        streamSelector.Info(i, out mediaType, out selectInfoFlags, out lcid, out groupNumber, out name, out pppunk, out ppobject);

                        // 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.Video:
                            break;

                        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.Subtitle:
                        case StreamGroup.DirectVobSubtitle:
                            subtitleStreams.AddUnique(currentStream, true);
                            break;

                        case StreamGroup.MatroskaEdition: // This is a MKV Edition handled by Haali splitter
                            titleStreams.AddUnique(currentStream, true);
                            break;
                        }
                        // Free MediaType and references
                        FilterGraphTools.FreeAMMediaType(mediaType);
                    }
                }

                lock (SyncObj)
                {
                    _streamInfoAudio     = audioStreams;
                    _streamInfoSubtitles = subtitleStreams;
                    _streamInfoTitles    = titleStreams;
                }
                return(true);
            }
            return(false);
        }