aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItemPopup.cs
blob: 09512f405adf7dc051ae8aea0d1d52682e7571eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Tango.Scripting.Editors.Intellisense
{
    public class StructCompletionItemPopup : CompletionItemPopupControl
    {
        static StructCompletionItemPopup()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(StructCompletionItemPopup), new FrameworkPropertyMetadata(typeof(StructCompletionItemPopup)));
        }
    }
}
using DirectShowLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;

namespace Tango.Video.DirectShow
{
    internal class DSUtils
    {
        public static void SetSampleGrabber(IBaseFilter filter, SampleGrabberImpl sampleGrabberImpl)
        {
            var pVideoSampleGrabber = (ISampleGrabber)filter;
            var mtVideo = new AMMediaType { majorType = MediaType.Video, subType = MediaSubType.RGB24 };
            pVideoSampleGrabber.SetMediaType(mtVideo);
            pVideoSampleGrabber.SetBufferSamples(false);
            pVideoSampleGrabber.SetOneShot(false);
            pVideoSampleGrabber.SetCallback(sampleGrabberImpl, 1);
            DirectShowLib.DsUtils.FreeAMMediaType(mtVideo);
        }

        public static void SetSampleGrabber2(IBaseFilter filter, SampleGrabberImpl sampleGrabberImpl)
        {
            var pVideoSampleGrabber = (ISampleGrabber)filter;
            var mtVideo = new AMMediaType { majorType = MediaType.Video, subType = MediaSubType.RGB24 };
            pVideoSampleGrabber.SetMediaType(mtVideo);
            pVideoSampleGrabber.SetBufferSamples(false);
            pVideoSampleGrabber.SetOneShot(false);
            pVideoSampleGrabber.SetCallback(sampleGrabberImpl, 0);
            DirectShowLib.DsUtils.FreeAMMediaType(mtVideo);
        }

        public static IBaseFilter GetVideoInputDeviceFilter(Device device)
        {
            return GetFilterByNameAndCat(device);
        }
        /// <summary>
        /// Create IBaseFilter from the specified category by the specified name.
        /// </summary>
        /// <param name="category"></param>
        /// <param name="filterName"></param>
        /// <returns></returns>
        public static IBaseFilter GetFilterByNameAndCat(Device device)
        {
            object source = null;
            var iid = (typeof(IBaseFilter)).GUID;
            var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);

            foreach (DsDevice d in devices)
            {
                if (d.DevicePath == device.DevicePath)
                {
                    d.Mon.BindToObject(null, null, ref iid, out source);
                    break;
                }
            }

            return (IBaseFilter)source;
        }

        public static List<Device> GetVideoInputDevices()
        {
            var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
            return devices.Select(device => new Device() { DevicePath = device.DevicePath, Name = device.Name }).ToList();
        }

        /// <summary>
        /// Connect 2 filters. This is a special implementation of connect filters. It will loop through
        /// all of the unconnected output pins of the source filter and all of the unconnected input pins of the destination filter
        /// and it will try any connection, between any of the 2 pairs of pins. On the first succesfull connection
        /// it will return.
        /// </summary>
        /// <param name="graph">IGraphBuilder where source and destination filter are added.</param>
        /// <param name="pSrc">Source filter.</param>
        /// <param name="pDst">Destination filter.</param>
        /// <returns>true if the connection is succesfull, otherwise false.</returns>
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        public static bool ConnectFiltersTryAllPins(IGraphBuilder graph, IBaseFilter pSrc, IBaseFilter pDst)
        {
            int srcPins = CountPins(pSrc, PinDirection.Output);
            int dstPins = CountPins(pDst, PinDirection.Input);
            bool connection = false;
            for (int i = 0; i < srcPins; i++)
            {
                IPin pSrcPin = GetPinAtIndex(pSrc, PinDirection.Output, i, false);
                if (pSrcPin == null) continue;

                for (int j = 0; j < dstPins; j++)
                {
                    IPin pDstPin = GetPinAtIndex(pDst, PinDirection.Input, j, false);
                    if (pDstPin == null) continue;

                    int hr = graph.Connect(pSrcPin, pDstPin);

                    connection = (hr == 0) || (hr == 262722); // S_OK or VFW_S_PARTIAL_RENDER= 0x00040242 (262722)

                    Marshal.ReleaseComObject(pDstPin);
                    if (connection) break;
                }

                Marshal.ReleaseComObject(pSrcPin);
                if (connection) break;
            }
            return connection;
        }

        /// <summary>
        /// Count all of the pins on a filter with a specified direction.
        /// </summary>
        /// <param name="pFilter">Filter to count pins for.</param>
        /// <param name="pinDir">Pin direction required to count pins for.</param>
        /// <returns></returns>
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        public static int CountPins(IBaseFilter pFilter, PinDirection pinDir)
        {
            IEnumPins enumPins;
            var pins = new IPin[1];

            int hr = pFilter.EnumPins(out enumPins);
            if (hr != 0) return 0;

            var nrPins = 0;
            try
            {
                while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0)
                {
                    try
                    {
                        PinInfo pinInfo;
                        hr = pins[0].QueryPinInfo(out pinInfo);
                        if (pinInfo.dir == pinDir)
                        {
                            nrPins++;
                        }

                        if (pinInfo.filter != null)
                            Marshal.ReleaseComObject(pinInfo.filter);
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(pins[0]);
                    }
                }
            }
            finally
            {
                if (enumPins != null)
                    Marshal.ReleaseComObject(enumPins);
            }

            return nrPins;
        }
        
        /// <summary>
        /// Get pin at a specified index on a filter.
        /// </summary>
        /// <param name="pFilter">IBaseFilter to find pin on.</param>
        /// <param name="pinDir">Pin direction.</param>
        /// <param name="index">Zero based index of the pin. Indexes are counted depending on the pin direction.</param>
        /// <param name="connected">Should the pin be connected or not.</param>
        /// <returns></returns>
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        public static IPin GetPinAtIndex(IBaseFilter pFilter, PinDirection pinDir, int index, bool connected)
        {
            IEnumPins enumPins;
            var pins = new IPin[1];

            int hr = pFilter.EnumPins(out enumPins);
            if (hr != 0) return null;

            var nrPins = -1;
            bool found = false;
            try
            {
                while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0)
                {
                    try
                    {
                        PinInfo pinInfo;
                        hr = pins[0].QueryPinInfo(out pinInfo);
                        if (pinInfo.dir == pinDir)
                        {
                            nrPins++;
                        }

                        if (pinInfo.filter != null)
                            Marshal.ReleaseComObject(pinInfo.filter);

                        // Check if a pin is connected
                        IPin pConPin = null;
                        pins[0].ConnectedTo(out pConPin);
                        if (pConPin != null && !connected)
                        {
                            Marshal.ReleaseComObject(pConPin);
                            continue;
                        }
                        else if (pConPin == null && connected) continue;

                        if (nrPins == index)
                        {
                            found = true;
                            break;
                        }
                    }
                    finally
                    {
                        if (!found)
                            Marshal.ReleaseComObject(pins[0]);
                    }
                }
            }
            finally
            {
                if (enumPins != null)
                    Marshal.ReleaseComObject(enumPins);
            }

            return pins[0];
        }

        /// <summary>
        /// Searches for the next connected filter. If the start filter is connected to some downstream
        /// filter it will return that filter, otherwise, null.
        /// </summary>
        /// <param name="pGraph"></param>
        /// <param name="pStartFilter"></param>
        /// <returns></returns>
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        public static IBaseFilter GetNextConnectedFilter(IGraphBuilder pGraph, IBaseFilter pStartFilter)
        {
            int pinCount = CountPins(pStartFilter, PinDirection.Output);
            IBaseFilter pReturnFilter = null;
            for (int i = 0; i < pinCount; i++)
            {
                IPin pOutPin = GetPinAtIndex(pStartFilter, PinDirection.Output, i, true);
                if (pOutPin != null)
                {
                    IPin pConnectedToPin = null;
                    pOutPin.ConnectedTo(out pConnectedToPin);
                    if (pConnectedToPin != null)
                    {
                        PinInfo pinInfo;
                        pConnectedToPin.QueryPinInfo(out pinInfo);
                        pReturnFilter = pinInfo.filter;
                        Marshal.ReleaseComObject(pConnectedToPin);
                    }

                    Marshal.ReleaseComObject(pOutPin);
                }

                if (pReturnFilter != null) break;
            }
            return pReturnFilter;
        }

        /// <summary>
        /// Save a DirectShow Graph to a GRF file
        /// </summary>
        /// <param name="graphBuilder">the IGraphBuilder interface of the graph</param>
        /// <param name="fileName">the file to be saved</param>
        /// <exception cref="System.ArgumentNullException">Thrown if graphBuilder is null</exception>
        /// <exception cref="System.Runtime.InteropServices.COMException">Thrown if errors occur during the file creation</exception>
        /// <seealso cref="LoadGraphFile"/>
        /// <remarks>This method overwrites any existing file</remarks>
        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        public static void SaveGraphFile(IGraphBuilder graphBuilder, string fileName)
        {
            int hr = 0;
            IStorage storage = null;
#if USING_NET11
            UCOMIStream stream = null;
#else
            IStream stream = null;
#endif

            if (graphBuilder == null)
                throw new ArgumentNullException("graphBuilder");

            try
            {
                hr = NativeMethods.StgCreateDocfile(
                    fileName,
                    STGM.Create | STGM.Transacted | STGM.ReadWrite | STGM.ShareExclusive,
                    0,
                    out storage
                    );

                Marshal.ThrowExceptionForHR(hr);

                hr = storage.CreateStream(
                    @"ActiveMovieGraph",
                    STGM.Write | STGM.Create | STGM.ShareExclusive,
                    0,
                    0,
                    out stream
                    );

                Marshal.ThrowExceptionForHR(hr);

                hr = (graphBuilder as IPersistStream).Save(stream, true);
                Marshal.ThrowExceptionForHR(hr);

                hr = storage.Commit(STGC.Default);
                Marshal.ThrowExceptionForHR(hr);
            }
            finally
            {
                if (stream != null)
                    Marshal.ReleaseComObject(stream);
                if (storage != null)
                    Marshal.ReleaseComObject(storage);
            }
        }
    }
}