using DirectShowLib;
using System.Runtime.InteropServices;

namespace DualScreenDemo.Services
{
    public class Video
    {
        protected IBaseFilter AddFilterByClsid(IGraphBuilder graphBuilder, string name, Guid clsid)
        {
            try
            {
                Type filterType = Type.GetTypeFromCLSID(clsid);
                object filterObject = Activator.CreateInstance(filterType);
                IBaseFilter filter = filterObject as IBaseFilter;

                if (filter == null)
                {
                    IntPtr comObjectPointer = Marshal.GetIUnknownForObject(filterObject);
                    filter = (IBaseFilter)Marshal.GetObjectForIUnknown(comObjectPointer);
                }
                
                // 添加过滤器到图形构建器
                int hr = graphBuilder.AddFilter(filter, name);
                DsError.ThrowExceptionForHR(hr);
                return filter;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception in AddFilterByClsid: {ex.Message}");
                throw; // Rethrow the exception to handle it further up the call stack
            }
        }
        protected int ConnectFilters(IGraphBuilder graphBuilder, IBaseFilter sourceFilter, string sourcePinName, IBaseFilter destFilter, string destPinName)
        {
            IPin outPin = FindPin(sourceFilter, sourcePinName);
            IPin inPin = FindPin(destFilter, destPinName);
            if (outPin == null || inPin == null)
            {
                Console.WriteLine(String.Format("Cannot find pins: {0} or {1}", sourcePinName, destPinName));
                return -1;
            }
            int hr = graphBuilder.Connect(outPin, inPin);
            return hr;
        }
        protected IPin FindPin(IBaseFilter filter, string pinName)
        {
            IEnumPins enumPins;
            IPin[] pins = new IPin[1];

            filter.EnumPins(out enumPins);
            enumPins.Reset();

            while (enumPins.Next(1, pins, IntPtr.Zero) == 0)
            {
                PinInfo pinInfo;
                pins[0].QueryPinInfo(out pinInfo);
                Console.WriteLine(pinInfo);

                if (pinInfo.name == pinName)
                {
                    return pins[0];
                }
            }
            return null;
        }
        protected void SafeRelease<T>(ref T comObject) where T : class
        {
            if (comObject != null)
            {
                Marshal.ReleaseComObject(comObject);
                comObject = null;
            }
        }
    }
}