private (LocalAudioSourceCapability[] caps, bool success) GetCapabilities(DsDevice device)
        {
            Log.Information($"Audio ({device.Name}): Getting Caps");
            var list = new List <LocalAudioSourceCapability>();

            bool failed = false;

            IntPtr pCaps = IntPtr.Zero;

            IFilterGraph2   filterGraph2 = null;
            IBaseFilter     sourceFilter = null;
            IAMStreamConfig streamConfig = null;
            object          pin          = null;
            int             count        = 0;
            int             size         = 0;

            try
            {
                filterGraph2 = new FilterGraph() as IFilterGraph2;
                if (filterGraph2 == null)
                {
                    throw new NotSupportedException("filter2 is null");
                }

                LocalVideoSourceManager.AddCaptureFilter(filterGraph2, device, out sourceFilter);

                pin = DsFindPin.ByCategory(sourceFilter, PinCategory.Capture, 0);

                if (pin == null)
                {
                    Log.Information($"Audio ({device.Name}): First pin is null");
                    pin = sourceFilter;
                }

                streamConfig = pin as IAMStreamConfig;
                if (streamConfig == null)
                {
                    throw new NotSupportedException("pin is null");
                }

                LocalVideoSourceManager.Checked(() => streamConfig.GetNumberOfCapabilities(out count, out size), "GetNumberOfCapabilities", null);
                if (count <= 0)
                {
                    throw new NotSupportedException("This video source does not report capabilities.");
                }
                if (size != Marshal.SizeOf(typeof(AudioStreamConfigCaps)))
                {
                    throw new NotSupportedException("Unable to retrieve video source capabilities. This video source requires a larger VideoStreamConfigCaps structure.");
                }

                // Alloc memory for structure
                pCaps = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(AudioStreamConfigCaps)));

                for (int i = 0; i < count; i++)
                {
                    AMMediaType mediaType = null;
                    LocalVideoSourceManager.Checked(() => streamConfig.GetStreamCaps(i, out mediaType, pCaps), "GetStreamCaps", null);

                    AudioStreamConfigCaps caps = (AudioStreamConfigCaps)Marshal.PtrToStructure(pCaps, typeof(AudioStreamConfigCaps));

                    var result = new LocalAudioSourceCapability()
                    {
                        MinimumChannels        = caps.MinimumChannels,
                        MaximumChannels        = caps.MaximumChannels,
                        MinimumSampleFrequency = caps.MinimumSampleFrequency,
                        MaximumSampleFrequency = caps.MaximumSampleFrequency
                    };

                    list.Add(result);
                }
            }
            catch (Exception e)
            {
                Log.Error(e, $"Error during retreiving caps for '{device.Name}'");
                failed = true;
            }
            finally
            {
                if (pCaps != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(pCaps);
                }
            }

            Log.Information($"Audio ({device.Name}): Releasing");

            try
            {
                LocalVideoSourceManager.ReleaseComObject(sourceFilter);
                LocalVideoSourceManager.ReleaseComObject(filterGraph2);
                LocalVideoSourceManager.ReleaseComObject(streamConfig);
                LocalVideoSourceManager.ReleaseComObject(pin);
            }
            catch (Exception e)
            {
                Log.Error(e, $"ReleaseComObject({device.Name}) failed");
            }

            Log.Information($"Caps {device.Name}: Count: {list.Count}/{count}, Str={size} ({string.Join("; ", list.Where(s => !s.IsStandart()).Select(s => s.ToString()))})");

            return(list.ToArray(), !failed);
        }
示例#2
0
        public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
        {
            DateTime now = DateTime.UtcNow;

            if ((now - _last).TotalMilliseconds > 150) // just to avoid issues with bad cameras
            {
                _last = now;
                try
                {
                    if (_width == 0)
                    {
                        var mediaType = new AMMediaType();
                        _grabber.GetConnectedMediaType(mediaType);
                        LocalVideoSourceManager.GetMediaTypeInfo(mediaType, out _height, out _width, out var _, out var _, out var _);

                        if (_width == 0 || _height == 0)
                        {
                            throw new InvalidOperationException($"Unable to GetMediaTypeInfo");
                        }
                    }

                    if (_getFrames)
                    {
                        BitmapSource image = BitmapSource.Create(
                            _width,
                            _height,
                            96,
                            96,
                            PixelFormats.Bgr24,
                            null,
                            pBuffer,
                            BufferLen,
                            _width * 3);

                        JpegBitmapEncoder encoder = new JpegBitmapEncoder {
                            QualityLevel = _width > 500 ? 30 : 50
                        };

                        encoder.Frames.Add(BitmapFrame.Create(image));

                        _stream.Position = 0;
                        encoder.Save(_stream);

                        var buffer = new byte[_stream.Position];
                        Array.Copy(_stream.GetBuffer(), buffer, _stream.Position);
                        _callback(new VideoInputPreview
                        {
                            Data = buffer,
                            W    = _width,
                            H    = _height
                        });
                    }
                    else
                    {
                        _callback(null);
                    }
                }
                catch (Exception e)
                {
                    Log.Warning(e, $"Grabbing of '{_name}' failed");
                }
            }
            return(0);
        }
示例#3
0
        private (LocalVideoSourceCapability[] caps, InputDeviceState state) GetCapabilities(DsDevice device)
        {
            if (_initialLogging)
            {
                Log.Information($"Caps {device.Name}: getting");
            }
            var    list  = new List <LocalVideoSourceCapability>();
            IntPtr pCaps = IntPtr.Zero;

            IFilterGraph2    filterGraph2 = null;
            IBaseFilter      sourceFilter = null;
            IAMStreamConfig  streamConfig = null;
            object           pin          = null;
            InputDeviceState state        = InputDeviceState.Ready;

            try
            {
                filterGraph2 = new FilterGraph() as IFilterGraph2;
                if (filterGraph2 == null)
                {
                    throw new NotSupportedException("filter2 is null");
                }

                LocalVideoSourceManager.AddCaptureFilter(filterGraph2, device, out sourceFilter);

                pin = DsFindPin.ByCategory(sourceFilter, PinCategory.Capture, 0);

                if (pin == null)
                {
                    pin = sourceFilter;
                }

                streamConfig = pin as IAMStreamConfig;
                if (streamConfig == null)
                {
                    throw new NotSupportedException("pin is null");
                }

                int count = 0;
                int size  = 0;
                Checked(() => streamConfig.GetNumberOfCapabilities(out count, out size), "GetNumberOfCapabilities", null);

                if (count <= 0)
                {
                    throw new NotSupportedException("This video source does not report capabilities.");
                }
                if (size != Marshal.SizeOf(typeof(VideoStreamConfigCaps)))
                {
                    throw new NotSupportedException("Unable to retrieve video source capabilities. This video source requires a larger VideoStreamConfigCaps structure.");
                }

                // Alloc memory for structure
                pCaps = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(VideoStreamConfigCaps)));

                for (int i = 0; i < count; i++)
                {
                    AMMediaType mediaType = null;
                    Checked(() => streamConfig.GetStreamCaps(i, out mediaType, pCaps), "GetStreamCaps", null);

                    VideoStreamConfigCaps caps = (VideoStreamConfigCaps)Marshal.PtrToStructure(pCaps, typeof(VideoStreamConfigCaps));

                    var format = GetMediaTypeInfo(mediaType, out var height, out var width, out var compression, out var videoInfoHeader, out var videoInfoHeader2);

                    var result = new LocalVideoSourceCapability()
                    {
                        MaxF = GetFps(caps.MinFrameInterval),
                        MinF = GetFps(caps.MaxFrameInterval),
                        Fmt  = format,
                        W    = width,
                        H    = height,
                    };

                    list.Add(result);
                }
            }
            catch (UnauthorizedAccessException e)
            {
                Log.Warning(e, $"Error during retreiving caps for '{device.Name}' (Locked)");
                state = InputDeviceState.Locked;
            }
            catch (Exception e)
            {
                Log.Error(e, $"Error during retreiving caps for '{device.Name}'");
                state = InputDeviceState.Failed;
            }
            finally
            {
                if (pCaps != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(pCaps);
                }
            }

            try
            {
                ReleaseComObject(sourceFilter);
                ReleaseComObject(filterGraph2);
                ReleaseComObject(streamConfig);
                ReleaseComObject(pin);
            }
            catch (Exception e)
            {
                Log.Error(e, $"ReleaseComObject('{device.Name}') failed");
            }

            if (_initialLogging)
            {
                Log.Information($"Caps {device.Name}: {string.Join("; ", list.Select(s => s.ToString()))}");
            }

            return(list.ToArray(), state);
        }