Пример #1
0
        // Determine the current tally sate. If you specify a timeout then it will wait until it has changed, otherwise it will simply poll it
        // and return the current tally immediately. The return value is whether anything has actually change (true) or whether it timed out (false)
        public bool GetTally(ref NDIlib.tally_t tally, int timeout)
        {
            if (_sendInstancePtr == IntPtr.Zero)
            {
                return(false);
            }

            return(NDIlib.send_get_tally(_sendInstancePtr, ref tally, (uint)timeout));
        }
Пример #2
0
            void SetTallyIndicators(bool onProgram, bool onPreview)
            {
                // we need to have a receive instance
                if (_recvInstancePtr != IntPtr.Zero)
                {
                    // set up a state descriptor
                    NDIlib.tally_t tallyState = new NDIlib.tally_t()
                    {
                        on_program = onProgram,
                        on_preview = onPreview
                    };

                    // set it on the receiver instance
                    NDIlib.recv_set_tally(_recvInstancePtr, ref tallyState);
                }
            }
Пример #3
0
            //

            private void SendThreadProc()
            {
                // look for changes in tally
                bool lastProg = false;
                bool lastPrev = false;

                NDIlib.tally_t tally = new NDIlib.tally_t();
                tally.on_program = lastProg;
                tally.on_preview = lastPrev;

                while (!exitThread)
                {
                    if (Monitor.TryEnter(sendInstanceLock))
                    {
                        // if this is not here, then we must be being reconfigured
                        if (sendInstancePtr == null)
                        {
                            // unlock
                            Monitor.Exit(sendInstanceLock);

                            // give up some time
                            Thread.Sleep(20);

                            // loop again
                            continue;
                        }

                        try
                        {
                            // get the next available frame
                            NDIlib.video_frame_v2_t frame;
                            if (pendingFrames.TryTake(out frame, 250))
                            {
                                // this dropps frames if the UI is rendernig ahead of the specified NDI frame rate
                                while (pendingFrames.Count > 1)
                                {
                                    NDIlib.video_frame_v2_t discardFrame = pendingFrames.Take();
                                    Marshal.FreeHGlobal(discardFrame.p_data);
                                }

                                // We now submit the frame. Note that this call will be clocked so that we end up submitting
                                // at exactly the requested rate.
                                // If WPF can't keep up with what you requested of NDI, then it will be sent at the rate WPF is rendering.
                                //if (!isPausedValue)
                                if (FInSend[0])
                                {
                                    NDIlib.send_send_video_v2(sendInstancePtr, ref frame);
                                }

                                // free the memory from this frame
                                Marshal.FreeHGlobal(frame.p_data);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            pendingFrames.CompleteAdding();
                        }
                        catch
                        {
                            //
                        }

                        // unlock
                        Monitor.Exit(sendInstanceLock);
                    }
                    else
                    {
                        Thread.Sleep(20);
                    }

                    // check tally
                    NDIlib.send_get_tally(sendInstancePtr, ref tally, 0);

                    // if tally changed trigger an update
                    if (lastProg != tally.on_program || lastPrev != tally.on_preview)
                    {
                        // save the last values
                        lastProg = tally.on_program;
                        lastPrev = tally.on_preview;
                    }
                }
            }
Пример #4
0
        public void PrepareFrame(string SenderToUse, long timeCode, int shift = 0, int markHeight = 250)
        {
            {
                int exists = senderNameList.IndexOf(SenderToUse);
                if (exists != -1)
                {
                    Sender sendInstance = senderList[exists];
                    // because we are clocking to the video it is better to always submit the audio first
                    // put tone in it every 25 frames
                    double frameNumber = senderFrameSentList[exists];
                    bool   dotone      = frameNumber % 25 == 0;
                    //          FillAudioBuffer(audioFrame, dotone);
                    // submit the audio buffer
                    doSend = CoreSettings.CoreSettings.Default.SendNDI;
                    //          if (doSend) sendInstance.Send(audioFrame);
                    // get the tally state of this source (we poll it),
                    NDIlib.tally_t ndi_tally = sendInstance.Tally;
                    if ((CoreSettings.CoreSettings.Default.MarkFrames) || (CoreSettings.CoreSettings.Default.CheckDroppedFrames))
                    {
                        Bitmap   bmp      = new Bitmap(senderVideoFrameList[2 * exists + shift].Width, senderVideoFrameList[2 * exists + shift].Height, senderVideoFrameList[2 * exists + shift].Stride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, senderVideoFrameList[2 * exists + shift].BufferPtr);
                        Graphics graphics = Graphics.FromImage(bmp);
                        graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        Pen outlinePen                = new Pen(Color.Black, 2.0f);
                        Pen thinOutlinePen            = new Pen(Color.Black, 1.0f);
                        Pen lineOutlinePen            = new Pen(Color.White, 10.0f);
                        Pen transparentlineOutlinePen = new Pen(Color.Transparent, 100.0f);
                        switch (exists)
                        {
                        case 0:
                            lineOutlinePen = new Pen(Color.Red, 10.0f);
                            break;

                        case 1:
                            lineOutlinePen = new Pen(Color.Blue, 10.0f);
                            break;

                        case 2:
                            lineOutlinePen = new Pen(Color.Green, 10.0f);
                            break;

                        case 3:
                            lineOutlinePen = new Pen(Color.Yellow, 10.0f);
                            break;
                        }
                        ;
                        if (CoreSettings.CoreSettings.Default.MarkFrames)
                        {
                            DrawPrettyText(graphics, String.Format("Frame {0}", frameNumber.ToString()), 96.0f, fontFamily, new Point(videoFrame.Width / 2, exists * 80 + 50), textFormat, Brushes.White, outlinePen);
                        }
                        if (CoreSettings.CoreSettings.Default.MarkFrames)
                        {
                            DrawPrettyText(graphics, System.DateTime.Now.ToString(), 96.0f, fontFamily, new Point(videoFrame.Width / 2, 1000), textFormat, Brushes.White, outlinePen);
                        }
                        if (CoreSettings.CoreSettings.Default.CheckDroppedFrames)
                        {
                            int   lineHeight = videoFrame.Height / senderFrameSentList.Count;
                            int   a          = (int)(senderFrameSentList[exists] * 20) % videoFrame.Width;
                            Point pt1        = new Point(a, (videoFrame.Height - (lineHeight * (exists) + markHeight)));
                            Point pt2        = new Point(a, videoFrame.Height - lineHeight * (exists));
                            Point pt3        = new Point(a, 0);
                            Point pt4        = new Point(a, videoFrame.Height);
                            graphics.CompositingMode = CompositingMode.SourceCopy;
                            graphics.DrawLine(transparentlineOutlinePen, pt3, pt4);
                            graphics.DrawLine(lineOutlinePen, pt1, pt2);
                            graphics.CompositingMode = CompositingMode.SourceOver;
                        }
                        graphics.Dispose();
                        bmp.Dispose();
                    }
                    // we now submit the frame. note that this call will be clocked so that we end up submitting
                    // at exactly 25fps.
                    //   if (doSend) sendInstance.SendAsync(senderVideoFrameList[2 * exists + shift]);
                    senderVideoFrameList[2 * exists + shift].TimeCode = timeCode;
                    senderFrameSentList[exists]++;
                }
            } // using bmp and graphics
        }     // using audioFrame and videoFrame
Пример #5
0
        // the receive thread runs though this loop until told to exit
        private void SendThreadProc()
        {
            // look for changes in tally
            bool lastProg = false;
            bool lastPrev = false;

            NDIlib.tally_t tally = new NDIlib.tally_t
            {
                on_program = lastProg,
                on_preview = lastPrev
            };

            while (!exitThread)
            {
                if (Monitor.TryEnter(sendInstanceLock))
                {
                    // if this is not here, then we must be being reconfigured
                    if (sendInstancePtr == null)
                    {
                        // unlock
                        Monitor.Exit(sendInstanceLock);

                        // give up some time
                        Thread.Sleep(20);

                        // loop again
                        continue;
                    }

                    // Audio should be send first
                    if (audioEnabled)
                    {
                        try
                        {
                            // get the next available frame
                            if (pendingAudioFrames.TryTake(out NDIlib.audio_frame_v2_t frame, 250))
                            {
                                // Submit the audio buffer
                                if (!IsSendPaused)
                                {
                                    NDIlib.send_send_audio_v2(sendInstancePtr, ref frame);
                                }

                                // free the memory from this frame
                                Marshal.FreeHGlobal(frame.p_data);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            pendingAudioFrames.CompleteAdding();
                        }
                        catch {}
                    }

                    try
                    {
                        // get the next available frame
                        if (pendingVideoFrames.TryTake(out NDIlib.video_frame_v2_t frame, 250))
                        {
                            // this drops frames if the UI is rendering ahead of the specified NDI frame rate
                            while (pendingVideoFrames.Count > 1)
                            {
                                NDIlib.video_frame_v2_t discardFrame = pendingVideoFrames.Take();
                                Marshal.FreeHGlobal(discardFrame.p_data);
                            }

                            // We now submit the frame. Note that this call will be clocked so that we end up submitting
                            // at exactly the requested rate.
                            // If WPF can't keep up with what you requested of NDI, then it will be sent at the rate WPF is rendering.
                            if (!IsSendPaused)
                            {
                                NDIlib.send_send_video_v2(sendInstancePtr, ref frame);
                            }

                            // free the memory from this frame
                            Marshal.FreeHGlobal(frame.p_data);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        pendingVideoFrames.CompleteAdding();
                    }
                    catch {}

                    // unlock
                    Monitor.Exit(sendInstanceLock);
                }
                else
                {
                    Thread.Sleep(20);
                }

                // check tally
                NDIlib.send_get_tally(sendInstancePtr, ref tally, 0);

                // if tally changed trigger an update
                if (lastProg != tally.on_program || lastPrev != tally.on_preview)
                {
                    // save the last values
                    lastProg = tally.on_program;
                    lastPrev = tally.on_preview;

                    // set these on the UI thread
                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        IsOnProgram = lastProg;
                        IsOnPreview = lastPrev;
                    }));
                }
            }
        }
Пример #6
0
            public void Evaluate(int SpreadMax)
            {
                if (FInUpdate[0])
                {
                    string msg = "";
                    frameNumber++;

                    // fill it with a lovely color
                    graphics.Clear(Color.Maroon);

                    // show which source we are
                    msg = DrawPrettyText(graphics, "C# Example Source", 96.0f, fontFamily, new Point(960, 100), textFormat, Brushes.White, outlinePen);
                    if (msg != "")
                    {
                        FLogger.Log(LogType.Error, "DrawPrettyText error: " + msg);
                    }

                    try
                    {
                        // Get the tally state of this source (we poll it),
                        NDIlib.tally_t NDI_tally = new NDIlib.tally_t();
                        NDIlib.send_get_tally(sendInstancePtr, ref NDI_tally, 0);

                        // Do something different depending on where we are shown
                        if (NDI_tally.on_program)
                        {
                            msg = DrawPrettyText(graphics, "On Program", 96.0f, fontFamily, new Point(960, 225), textFormat, Brushes.White, outlinePen);
                            if (msg != "")
                            {
                                FLogger.Log(LogType.Error, "DrawPrettyText error: " + msg);
                            }
                        }
                        else if (NDI_tally.on_preview)
                        {
                            msg = DrawPrettyText(graphics, "On Preview", 96.0f, fontFamily, new Point(960, 225), textFormat, Brushes.White, outlinePen);
                            if (msg != "")
                            {
                                FLogger.Log(LogType.Error, "DrawPrettyText error: " + msg);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        FLogger.Log(LogType.Error, "Update: " + e.Message);
                    }


                    //// show what frame we've rendered
                    msg = DrawPrettyText(graphics, String.Format("Frame {0}", frameNumber.ToString()), 96.0f, fontFamily, new Point(960, 350), textFormat, Brushes.White, outlinePen);
                    if (msg != "")
                    {
                        FLogger.Log(LogType.Error, "DrawPrettyText error: " + msg);
                    }

                    // show current time
                    msg = DrawPrettyText(graphics, System.DateTime.Now.ToString(), 96.0f, fontFamily, new Point(960, 900), textFormat, Brushes.White, outlinePen);
                    if (msg != "")
                    {
                        FLogger.Log(LogType.Error, "DrawPrettyText error: " + msg);
                    }
                }

                if (FInSend[0])
                {
                    // are we connected to anyone?
                    //if (NDI.Send.NDIlib_send_get_no_connections(sendInstancePtr, 10000) < 1)
                    if (NDIlib.send_get_no_connections(sendInstancePtr, FInTimeout[0]) < 1)
                    {
                        // no point rendering
                        FLogger.Log(LogType.Debug, "No current connections, so no rendering needed.");
                        //Console.WriteLine("No current connections, so no rendering needed.");

                        // Wait a bit, otherwise our limited example will end before you can connect to it
                        System.Threading.Thread.Sleep(50);
                    }
                    else
                    {
                        try
                        {
                            // We now submit the frame. Note that this call will be clocked so that we end up submitting
                            // at exactly 29.97fps.
                            NDIlib.send_send_video_v2(sendInstancePtr, ref videoFrame);

                            // Just display something helpful in the console
                            FLogger.Log(LogType.Debug, "Frame number " + frameNumber + " sent.");
                        }
                        catch (Exception e)
                        {
                            FLogger.Log(LogType.Error, "Send: " + e.Message);
                        }
                    }
                }
            }