示例#1
0
        /// <summary>
        /// QueryConnect checks if two Pins can be connected.
        /// </summary>
        /// <param name="pin">Pin 1</param>
        /// <param name="other">Pin 2</param>
        /// <returns>True if they accept connection</returns>
        static bool QueryConnect(IPin pin, IPin other)
        {
            IEnumMediaTypes enumTypes;
            int             hr = pin.EnumMediaTypes(out enumTypes);

            if (hr != 0 || enumTypes == null)
            {
                return(false);
            }

            int    count      = 0;
            IntPtr ptrFetched = Marshal.AllocCoTaskMem(4);

            try
            {
                for (; ;)
                {
                    AMMediaType[] types = new AMMediaType[1];
                    hr = enumTypes.Next(1, types, ptrFetched);
                    if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0)
                    {
                        break;
                    }

                    count++;
                    try
                    {
                        if (other.QueryAccept(types[0]) == 0)
                        {
                            return(true);
                        }
                    }
                    finally
                    {
                        FilterGraphTools.FreeAMMediaType(types[0]);
                    }
                }
                PinInfo info;
                PinInfo infoOther;
                pin.QueryPinInfo(out info);
                other.QueryPinInfo(out infoOther);
                ServiceRegistration.Get <ILogger>().Info("Pins {0} and {1} do not accept each other. Tested {2} media types", info.name, infoOther.name, count);
                FilterGraphTools.FreePinInfo(info);
                FilterGraphTools.FreePinInfo(infoOther);
                return(false);
            }
            finally
            {
                Marshal.FreeCoTaskMem(ptrFetched);
            }
        }
示例#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);
        }