using System.Runtime.InteropServices; namespace TeamsISO.Engine.NdiInterop; /// /// P/Invoke declarations for the NewTek/Vizrt NDI SDK 6 native library. /// On Windows the import target is Processing.NDI.Lib.x64.dll; the loader resolves it /// from the NDI Runtime installation path or from the application directory. /// internal static class NdiNative { private const string LibName = "Processing.NDI.Lib.x64"; // ---- Lifecycle ---- [DllImport(LibName, EntryPoint = "NDIlib_initialize", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool Initialize(); [DllImport(LibName, EntryPoint = "NDIlib_destroy", CallingConvention = CallingConvention.Cdecl)] public static extern void Destroy(); [DllImport(LibName, EntryPoint = "NDIlib_version", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr Version(); // ---- Find ---- [DllImport(LibName, EntryPoint = "NDIlib_find_create_v2", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr FindCreateV2(IntPtr p_create_settings); [DllImport(LibName, EntryPoint = "NDIlib_find_destroy", CallingConvention = CallingConvention.Cdecl)] public static extern void FindDestroy(IntPtr p_instance); [DllImport(LibName, EntryPoint = "NDIlib_find_get_current_sources", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr FindGetCurrentSources(IntPtr p_instance, out uint p_no_sources); // ---- Receive ---- [DllImport(LibName, EntryPoint = "NDIlib_recv_create_v3", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr RecvCreateV3(ref RecvCreateV3Settings p_create_settings); [DllImport(LibName, EntryPoint = "NDIlib_recv_destroy", CallingConvention = CallingConvention.Cdecl)] public static extern void RecvDestroy(IntPtr p_instance); [DllImport(LibName, EntryPoint = "NDIlib_recv_capture_v3", CallingConvention = CallingConvention.Cdecl)] public static extern FrameType RecvCaptureV3( IntPtr p_instance, out VideoFrameV2 p_video_data, IntPtr p_audio_data, IntPtr p_metadata, uint timeout_in_ms); [DllImport(LibName, EntryPoint = "NDIlib_recv_free_video_v2", CallingConvention = CallingConvention.Cdecl)] public static extern void RecvFreeVideoV2(IntPtr p_instance, ref VideoFrameV2 p_video_data); // ---- Send ---- [DllImport(LibName, EntryPoint = "NDIlib_send_create", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr SendCreate(ref SendCreateSettings p_create_settings); [DllImport(LibName, EntryPoint = "NDIlib_send_destroy", CallingConvention = CallingConvention.Cdecl)] public static extern void SendDestroy(IntPtr p_instance); [DllImport(LibName, EntryPoint = "NDIlib_send_send_video_v2", CallingConvention = CallingConvention.Cdecl)] public static extern void SendSendVideoV2(IntPtr p_instance, ref VideoFrameV2 p_video_data); // ---- Enums ---- public enum FrameType { None = 0, Video = 1, Audio = 2, Metadata = 3, Error = 4, StatusChange = 100 } public enum RecvBandwidth { MetadataOnly = -10, AudioOnly = 10, Lowest = 0, Highest = 100 } public enum RecvColorFormat { BgrxBgra = 0, UyvyBgra = 1, Rgbx_Rgba = 2, UyvyRgba = 3, Fastest = 100, Best = 101 } public enum FrameFormatType { Progressive = 1, Interleaved = 0, FieldZero = 2, FieldOne = 3, Max = 0x7FFFFFFF } public static class FourCC { public const uint UYVY = 0x59565955; // 'U','Y','V','Y' public const uint BGRA = 0x41524742; // 'B','G','R','A' public const uint BGRX = 0x58524742; // 'B','G','R','X' public const uint RGBA = 0x41424752; // 'R','G','B','A' } // ---- Structs ---- [StructLayout(LayoutKind.Sequential)] public struct Source { public IntPtr p_ndi_name; // const char* public IntPtr p_url_address; // const char* (union, treat as URL) } [StructLayout(LayoutKind.Sequential)] public struct RecvCreateV3Settings { public Source source_to_connect_to; public RecvColorFormat color_format; public RecvBandwidth bandwidth; [MarshalAs(UnmanagedType.U1)] public bool allow_video_fields; public IntPtr p_ndi_recv_name; // const char* } [StructLayout(LayoutKind.Sequential)] public struct SendCreateSettings { public IntPtr p_ndi_name; // const char* public IntPtr p_groups; // const char* [MarshalAs(UnmanagedType.U1)] public bool clock_video; [MarshalAs(UnmanagedType.U1)] public bool clock_audio; } [StructLayout(LayoutKind.Sequential)] public struct VideoFrameV2 { public int xres; public int yres; public uint FourCC; public int frame_rate_N; public int frame_rate_D; public float picture_aspect_ratio; public FrameFormatType frame_format_type; public long timecode; public IntPtr p_data; public int line_stride_in_bytes; // (union with data_size_in_bytes) public IntPtr p_metadata; public long timestamp; } }