#ifndef BUTTONS_H
#define BUTTONS_H
typedef enum
{
RELEASE = 0,
PRESS //press
} PB_Status;
typedef enum
{
colorOFF = 0,
colorON,
BLINK,
fastBILNK,
BREATHING
} PBcolor;
typedef enum
{
OFFPB = 0, //notCOUNT
COUNTPB ,
SHORTPB ,
LONGPB ,
REPLONGPB //repeat long PB
}PBstat;
typedef enum
{
sttOFF = 0,
sttON,
sttIDLE,
sttDISABLE,
sttENABLE,
<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);
}
}
}
}