Beispiel #1
0
            // prepare to send texture
            void CreateSendInstance()
            {
                if (!initialized)
                {
                    return;
                }

                Monitor.Enter(sendInstanceLock);
                {
                    // reset flag
                    instanceCreated = false;

                    // .Net interop doesn't handle UTF-8 strings, so do it manually
                    // These must be freed later
                    IntPtr sourceNamePtr = UTF.StringToUtf8(FInSourceName[0]);
                    IntPtr groupsNamePtr = IntPtr.Zero;

                    // Create an NDI source description using sourceNamePtr and it's clocked to the video.
                    NDIlib.send_create_t createDesc = new NDIlib.send_create_t()
                    {
                        p_ndi_name  = sourceNamePtr,
                        p_groups    = groupsNamePtr,
                        clock_video = true,
                        clock_audio = false
                    };

                    // destroy if exists
                    if (sendInstancePtr != IntPtr.Zero)
                    {
                        NDIlib.send_destroy(sendInstancePtr);
                        sendInstancePtr = IntPtr.Zero;
                    }

                    // We create the NDI sender instance
                    sendInstancePtr = NDIlib.send_create(ref createDesc);

                    // free the strings we allocated
                    Marshal.FreeHGlobal(sourceNamePtr);
                    Marshal.FreeHGlobal(groupsNamePtr);

                    // did it succeed?
                    if (sendInstancePtr == IntPtr.Zero)
                    {
                        FLogger.Log(LogType.Error, "Failed to create send instance");
                        return;
                    }
                    else
                    {
                        FLogger.Log(LogType.Message, "Successed to create send instance");

                        instanceCreated = true;
                    }

                    // unlock
                    Monitor.Exit(sendInstanceLock);
                }
            }
Beispiel #2
0
    void Start()
    {
        var name        = Marshal.StringToHGlobalAnsi("Test Server");
        var sendOptions = new NDIlib.send_create_t {
            p_ndi_name = name
        };

        _sendInstance = NDIlib.send_create(ref sendOptions);
        Marshal.FreeHGlobal(name);
    }
Beispiel #3
0
        private void InitializeNdi()
        {
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }

            Monitor.Enter(sendInstanceLock);

            {
                // we need a name
                if (String.IsNullOrEmpty(NdiName))
                {
                    return;
                }

                // re-initialize?
                if (sendInstancePtr != IntPtr.Zero)
                {
                    NDIlib.send_destroy(sendInstancePtr);
                    sendInstancePtr = IntPtr.Zero;
                }

                // .Net interop doesn't handle UTF-8 strings, so do it manually
                // These must be freed later
                IntPtr sourceNamePtr = UTF.StringToUtf8(NdiName);

                IntPtr groupsNamePtr = IntPtr.Zero;

                // build a comma separated list of groups?
                if (NdiGroups.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < NdiGroups.Count(); i++)
                    {
                        sb.Append(NdiGroups[i]);

                        if (i < NdiGroups.Count - 1)
                        {
                            sb.Append(',');
                        }
                    }

                    groupsNamePtr = UTF.StringToUtf8(sb.ToString());
                }

                // Create an NDI source description using sourceNamePtr and it's clocked to the video.
                NDIlib.send_create_t createDesc = new NDIlib.send_create_t()
                {
                    p_ndi_name  = sourceNamePtr,
                    p_groups    = groupsNamePtr,
                    clock_video = NdiClockToVideo,
                    clock_audio = false
                };

                // We create the NDI finder instance
                sendInstancePtr = NDIlib.send_create(ref createDesc);

                // free the strings we allocated
                Marshal.FreeHGlobal(sourceNamePtr);
                Marshal.FreeHGlobal(groupsNamePtr);

                // unlock
                Monitor.Exit(sendInstanceLock);
            }
        }
Beispiel #4
0
        public Sender(String sourceName, bool clockVideo = true, bool clockAudio = false, String[] groups = null, String failoverName = null)
        {
            if (String.IsNullOrEmpty(sourceName))
            {
                throw new ArgumentException("sourceName can not be null or empty.", sourceName);
            }

            if (!NDIlib.initialize())
            {
                if (!NDIlib.is_supported_CPU())
                {
                    throw new InvalidOperationException("CPU incompatible with NDI.");
                }
                else
                {
                    throw new InvalidOperationException("Unable to initialize NDI.");
                }
            }

            // .Net interop doesn't handle UTF-8 strings, so do it manually
            // These must be freed later
            IntPtr sourceNamePtr = UTF.StringToUtf8(sourceName);

            IntPtr groupsNamePtr = IntPtr.Zero;

            // make a flat list of groups if needed
            if (groups != null)
            {
                StringBuilder flatGroups = new StringBuilder();
                foreach (String group in groups)
                {
                    flatGroups.Append(group);
                    if (group != groups.Last())
                    {
                        flatGroups.Append(',');
                    }
                }

                groupsNamePtr = UTF.StringToUtf8(flatGroups.ToString());
            }

            // Create an NDI source description
            NDIlib.send_create_t createDesc = new NDIlib.send_create_t()
            {
                p_ndi_name  = sourceNamePtr,
                p_groups    = groupsNamePtr,
                clock_video = clockVideo,
                clock_audio = clockAudio
            };

            // create the NDI send instance
            _sendInstancePtr = NDIlib.send_create(ref createDesc);

            // free the strings we allocated
            Marshal.FreeHGlobal(sourceNamePtr);
            Marshal.FreeHGlobal(groupsNamePtr);

            // did it succeed?
            if (_sendInstancePtr == IntPtr.Zero)
            {
                throw new InvalidOperationException("Failed to create send instance.");
            }

            if (!String.IsNullOrEmpty(failoverName))
            {
                // .Net interop doesn't handle UTF-8 strings, so do it manually
                // These must be freed later
                IntPtr failoverNamePtr = UTF.StringToUtf8(failoverName);

                NDIlib.source_t failoverDesc = new NDIlib.source_t()
                {
                    p_ndi_name    = failoverNamePtr,
                    p_url_address = IntPtr.Zero
                };

                NDIlib.send_set_failover(_sendInstancePtr, ref failoverDesc);

                // free the strings we allocated
                Marshal.FreeHGlobal(failoverNamePtr);
            }
        }
Beispiel #5
0
            public void OnImportsSatisfied()
            {
                frameNumber = 0;

                // .Net interop doesn't handle UTF-8 strings, so do it manually
                // These must be freed later
                sourceNamePtr = UTF.StringToUtf8("VVVV.NDI.SendTest");

                groupsNamePtr = IntPtr.Zero;

                // Not required, but "correct". (see the SDK documentation)
                if (!NDIlib.initialize())
                {
                    // Cannot run NDI. Most likely because the CPU is not sufficient (see SDK documentation).
                    // you can check this directly with a call to NDIlib_is_supported_CPU()
                    FLogger.Log(LogType.Error, "Cannot run NDI");
                    return;
                }
                else
                {
                    FLogger.Log(LogType.Message, "NDI initialized");
                }

                // Create an NDI source description using sourceNamePtr and it's clocked to the video.
                NDIlib.send_create_t createDesc = new NDIlib.send_create_t()
                {
                    p_ndi_name  = sourceNamePtr,
                    p_groups    = groupsNamePtr,
                    clock_video = true,
                    clock_audio = false
                };

                // We create the NDI finder instance
                sendInstancePtr = NDIlib.send_create(ref createDesc);

                // free the strings we allocated
                Marshal.FreeHGlobal(sourceNamePtr);
                Marshal.FreeHGlobal(groupsNamePtr);

                // did it succeed?
                if (sendInstancePtr == IntPtr.Zero)
                {
                    FLogger.Log(LogType.Error, "Failed to create send instance");
                    //Console.WriteLine("Failed to create send instance");
                    return;
                }
                else
                {
                    FLogger.Log(LogType.Message, "Successed to create send instance");
                }

                // define our bitmap properties
                int xres       = 1920;
                int yres       = 1080;
                int stride     = (xres * 32 /*BGRA bpp*/ + 7) / 8;
                int bufferSize = yres * stride;

                // allocate some memory for a video buffer
                bufferPtr = Marshal.AllocHGlobal((int)bufferSize);

                // We are going to create a 1920x1080 progressive frame at 29.97Hz.
                videoFrame = new NDIlib.video_frame_v2_t()
                {
                    // Resolution
                    xres = xres,
                    yres = yres,
                    // Use BGRA video
                    FourCC = NDIlib.FourCC_type_e.FourCC_type_BGRA,
                    // The frame-eate
                    frame_rate_N = 120000, //30000,
                    frame_rate_D = 1000,   //1001,
                    // The aspect ratio (16:9)
                    picture_aspect_ratio = (16.0f / 9.0f),
                    // This is a progressive frame
                    frame_format_type = NDIlib.frame_format_type_e.frame_format_type_progressive,
                    // Timecode.
                    timecode = NDIlib.send_timecode_synthesize,
                    // The video memory used for this frame
                    p_data = bufferPtr,
                    // The line to line stride of this image
                    line_stride_in_bytes = stride,
                    // no metadata
                    p_metadata = IntPtr.Zero,
                    // only valid on received frames
                    timestamp = 0//NDIlib.recv_timestamp_undefined
                };

                // get a compatible bitmap and graphics context
                bmp      = new Bitmap((int)xres, (int)yres, (int)stride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, bufferPtr);
                graphics = Graphics.FromImage(bmp);
                graphics.SmoothingMode = SmoothingMode.AntiAlias;

                // We'll use these later inside the loop
                textFormat               = new StringFormat();
                textFormat.Alignment     = StringAlignment.Center;
                textFormat.LineAlignment = StringAlignment.Center;

                fontFamily     = new FontFamily("Arial");
                outlinePen     = new Pen(Color.Black, 2.0f);
                thinOutlinePen = new Pen(Color.Black, 1.0f);
            }