Ejemplo n.º 1
0
        public void Open(IReadOnlyList <ushort> ports)
        {
            if (contexts.Count > 0)
            {
                throw new InvalidOperationException("Bug: please close the transmitter before opening it again");
            }

            denominators = new List <uint>();
            for (int d = 0; d < ports.Count; d++)
            {
                unsafe
                {
                    var res = SnvBackend.ScrGetResolution(d);
                    if (res == 0)
                    {
                        throw new Exception("Cannot determine display resolution");
                    }

                    S2TransmitterContext *tc = (S2TransmitterContext *)Marshal.AllocHGlobal(sizeof(S2TransmitterContext));
                    if (SnvBackend.S2TransmitterInit(tc, serverAddr.ToString(), ports[d], 0) != 0)
                    {
                        throw new InvalidOperationException("Failed to initialize video stream transmission");
                    }

                    contexts.Add(d, (IntPtr)tc);
                }

                denominators.Add(InitialDenominator);
            }

            ctxKeys = contexts.Keys.ToArray();
        }
Ejemplo n.º 2
0
        private static void OnProcessExit(object sender = null, EventArgs e = null)
        {
            if (icon)
            {
                SnvBackend.RemoveClientIcon();
            }

            ScreenRecorder.IsApplicationRunning = false;
            SnvBackend.Quit();
        }
Ejemplo n.º 3
0
        public int GetDisplaysCount()
        {
            var displays = SnvBackend.ScrCountDisplays();

            if (displays < 0)
            {
                throw new Exception("Cannot count displays available");
            }

            return(displays);
        }
Ejemplo n.º 4
0
        public void Close()
        {
            foreach (var k in contexts.Keys)
            {
                unsafe
                {
                    var tc = contexts[k];
                    SnvBackend.S2TransmitterClose((S2TransmitterContext *)tc);
                    Marshal.FreeHGlobal(tc);
                }
            }

            contexts.Clear();
            ctxKeys      = null;
            denominators = null;
            Closed?.Invoke(this, new EventArgs());
        }
Ejemplo n.º 5
0
        public static void Initialize(bool clientIcon = false)
        {
            if (SnvBackend.Init() != 0)
            {
                throw new Exception("Core initialization failed");
            }

            if (clientIcon)
            {
                callback += ClientIconInvokedCallback;
                GC.KeepAlive(callback);

                SnvBackend.SetupClientIcon(callback);
                icon = true;
            }

            AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
        }
Ejemplo n.º 6
0
        public void Run()
        {
            if (rcThread != null)
            {
                throw new InvalidOperationException("Thread cannot be run twice");
            }

            rcThread = new Thread(() =>
            {
                unsafe
                {
                    int err        = 0;
                    Exception eObj = null;

                    try
                    {
                        rcPtr = Marshal.AllocHGlobal(sizeof(S2ReceiverContext));
                        err   = SnvBackend.ReceiverThread((S2ReceiverContext *)rcPtr, recvPort, 0, callback);
                    }

                    catch (ThreadAbortException) { }
                    catch (Exception e)
                    {
                        eObj = e;
                    }

                    finally
                    {
                        AppTools.TryInvoke(() =>
                        {
                            Interrupted?.Invoke(this, new ReceiverInterruptedEventArgs(err, eObj));
                        });

                        Marshal.FreeHGlobal(rcPtr);
                        rcPtr    = IntPtr.Zero;
                        rcThread = null;
                    }
                }
            });

            rcThread.IsBackground = true;
            rcThread.Start();
        }
Ejemplo n.º 7
0
        public void Loop()
        {
            Configure();
            transmitter = new ScreenTransmitter(RemoteIPAddress);

            SendPacket(new LoginPacket()
            {
                Name    = Name,
                Id      = Id,
                Mode    = LoginMode.Client,
                Version = PacketBase.ProtocolVersion
            }).Flush();

            var pkt = new DisplayInfoPacket();

            for (int d = 0; d < transmitter.GetDisplaysCount(); d++)
            {
                var res = SnvBackend.ScrGetResolution(d);
                if (res == 0)
                {
                    goto Halt;
                }

                pkt.Displays.Add(new DisplaySize((ushort)(res >> 16), (ushort)res));
            }

            SendPacket(pkt).Flush();

            while (IsRunning)
            {
                Thread.Sleep(delay);
                if (!transmitter.Send())
                {
                    break;
                }
            }

Halt:
            transmitter.Close();
            Shutdown();
        }
Ejemplo n.º 8
0
        unsafe int FrameAcceptedCallback(S2Frame *frm)
        {
            if (frm->Error != 0 || frm->Width == 0 || frm->Height == 0)
            {
                return(0);
            }

            if (FrameAccepted == null)
            {
                SnvBackend.FreeFrame(frm);
                return(0);
            }

            AppTools.TryInvoke(() =>
            {
                bool changed = false;
                if (bitmap == null || bitmap.Width != frm->Width || bitmap.Height != frm->Height)
                {
                    bitmap  = new WriteableBitmap(frm->Width, frm->Height, 96, 96, PixelFormats.Bgr24, null);
                    changed = true;
                }

                unsafe
                {
                    bitmap.Lock();
                    UnmanagedTools.CopyMemory(bitmap.BackBuffer, frm->Pixels, (uint)(frm->Height * bitmap.BackBufferStride));
                    bitmap.AddDirtyRect(new Int32Rect(0, 0, frm->Width, frm->Height));
                    bitmap.Unlock();

                    SnvBackend.FreeFrame(frm);
                }

                FrameAccepted?.Invoke(this, new FrameAcceptedEventArgs(bitmap, changed));
            });

            return(0);
        }
Ejemplo n.º 9
0
        public bool Send()
        {
            if (ctxKeys == null)
            {
                return(true);
            }

            int kn = 0;

            foreach (var k in ctxKeys)
            {
                unsafe
                {
                    S2Frame frm;

                    if (SnvBackend.ScrCapture(&frm, k, denominators[kn]) != 0)
                    {
                        return(false);
                    }

                    var tc  = contexts[k];
                    var err = SnvBackend.S2Send((S2TransmitterContext *)tc, &frm);
                    contexts[k] = tc;
                    SnvBackend.FreeFrame(&frm);

                    if (err != 0)
                    {
                        return(false);
                    }
                }

                kn++;
            }

            return(true);
        }
Ejemplo n.º 10
0
 public RecorderWindowViewModel()
 {
     StopRecordingCommand = new DelegateCommand(delegate { SnvBackend.RecStop(); });
 }
Ejemplo n.º 11
0
        protected override bool HandlePacket(string packet)
        {
            var pingPkt = new PingPacket();

            if (pingPkt.ParsePacket(packet))
            {
                SendPacket(new PongPacket()
                {
                    Text = pingPkt.Text
                }).Flush();
                return(true);
            }

            var errPkt = new ErrorPacket();

            if (errPkt.ParsePacket(packet))
            {
                return(false);
            }

            var dpPkt = new DisplayPortsPacket();

            if (dpPkt.ParsePacket(packet) && transmitter != null)
            {
                transmitter.Close();
                transmitter.Open(dpPkt.Ports);
                return(true);
            }

            var valPkt = new ValuePacket();

            if (valPkt.ParsePacket(packet))
            {
                if (valPkt.Data.ContainsKey("delay"))
                {
                    delay = (int)valPkt.Data["delay"];
                }

                if (valPkt.Data.ContainsKey("den"))
                {
                    var d = new List <uint>();
                    foreach (var v in valPkt.Data["den"].ToString().Split('/'))
                    {
                        d.Add(Convert.ToUInt32(v));
                    }

                    transmitter.SetDenominators(d);
                }

                return(true);
            }

            var ntPkt = new NotificationPacket();

            if (ntPkt.ParsePacket(packet))
            {
                SnvBackend.ShowNotification(ntPkt.Text, ntPkt.SoundAlert ? 1 : 0);
                return(true);
            }

            return(true);
        }
Ejemplo n.º 12
0
        public FullScreenDisplayWindow(Display display)
        {
            InitializeComponent();
            DataContext  = display;
            this.display = display;

            var res = SnvBackend.ScrGetResolution(0);

            if (res <= 0)
            {
                return;
            }

            scrW = res >> 16;
            scrH = res & 0xffff;

            const double opacity = 0.64;

            restoreIcon.Opacity     = opacity;
            closeIcon.Opacity       = opacity;
            restoreIcon.MouseEnter += delegate { restoreIcon.Opacity = 1.0; };
            restoreIcon.MouseLeave += delegate { restoreIcon.Opacity = opacity; };
            closeIcon.MouseEnter   += delegate { closeIcon.Opacity = 1.0; };
            closeIcon.MouseLeave   += delegate { closeIcon.Opacity = opacity; };
            closeIcon.MouseUp      += delegate { Close(); };
            panel.Opacity           = 0;
            panel.IsEnabled         = false;

            bool running = true;

            Title = display.WindowHeader;
            display.Origin.Disconnected += OnClientDisconnected;
            display.IsFullScreen         = true;

            Loaded += delegate
            {
                HwndSource.FromHwnd(new WindowInteropHelper(this).Handle).AddHook(new HwndSourceHook(WndProc));
            };

            Closed += delegate
            {
                running = false;
                if (display != null)
                {
                    display.IsFullScreen = false;
                }
            };

            restoreIcon.MouseUp += delegate
            {
                Width           = pW;
                Height          = pH;
                panel.Opacity   = 0;
                panel.IsEnabled = false;
                WindowState     = WindowState.Normal;
                WindowStyle     = WindowStyle.SingleBorderWindow;
                ResizeMode      = ResizeMode.CanResize;
            };

            // Size polling thread
            new Thread(() =>
            {
                uint pw      = 0, ph = 0;
                bool changed = false;

                while (running)
                {
                    Thread.Sleep(500);
                    AppTools.TryInvoke(() =>
                    {
                        try
                        {
                            if ((uint)image.ActualWidth != pw || (uint)image.ActualHeight != ph)
                            {
                                pw      = (uint)image.ActualWidth;
                                ph      = (uint)image.ActualHeight;
                                changed = true;
                            }

                            if (display != null)
                            {
                                if (changed)
                                {
                                    display.OnActualSizeChanged(pw, ph);
                                    changed = false;
                                }

                                if (!display.Origin.IsRunning)
                                {
                                    running = false;
                                }
                            }

                            else
                            {
                                running = false;
                            }
                        }

                        catch
                        {
                            running = false;
                        }
                    });
                }

                display.RestoreDenominator();
            }).Start();
        }
Ejemplo n.º 13
0
        void RecorderThread()
        {
            Dictionary <int, IntPtr> contexts = new Dictionary <int, IntPtr>();

            while (running && IsApplicationRunning)
            {
                unsafe
                {
                    try
                    {
                        var displays = SnvBackend.ScrCountDisplays();
                        if (displays < 0)
                        {
                            throw new Exception("Cannot count the displays available");
                        }

                        for (int i = 0; i < displays; i++)
                        {
                            var ptr = Marshal.AllocHGlobal(sizeof(RecorderContext));
                            UnmanagedTools.SetMemory(ptr, 0, sizeof(RecorderContext));
                            contexts.Add(i, ptr);
                        }

                        while (running && IsApplicationRunning)
                        {
                            foreach (var k in contexts.Keys)
                            {
                                S2Frame frmRaw;
                                if (SnvBackend.ScrCapture(&frmRaw, k, 1) != 0)
                                {
                                    break;
                                }

                                SnvBackend.RecCommitFrame((RecorderContext *)contexts[k], &frmRaw, k);
                                SnvBackend.FreeFrame(&frmRaw);
                            }

                            Thread.Sleep(25);
                        }
                    }

                    catch { }

                    try
                    {
                        SnvBackend.RecStop();
                        foreach (var k in contexts.Keys)
                        {
                            SnvBackend.RecCommitFrame((RecorderContext *)contexts[k], null, k);
                            Marshal.FreeHGlobal(contexts[k]);
                        }

                        contexts.Clear();
                    }

                    catch { }
                }

                Thread.Sleep(250);
            }
        }
Ejemplo n.º 14
0
        public RecorderWindow()
        {
            InitializeComponent();
            MouseDown += OnMouseDown;
            Closing   += OnClosing;
            Visibility = Visibility.Hidden;

            var desktop = SystemParameters.WorkArea;

            Left = desktop.Right - Width;
            Top  = desktop.Bottom - Height;

            // Back-end query thread
            new Thread(() =>
            {
                int recState = 0;
                int token    = 0;
                bool isSettingsWindowOpen = false;

                var watch = new Stopwatch();

                while (true)
                {
                    Thread.Sleep(50);

                    var recStateNew = SnvBackend.RecIsRunning();
                    if (recStateNew != recState)
                    {
                        recState = recStateNew;
                        AppTools.TryInvoke(() =>
                        {
                            Visibility = recState == 0 ? Visibility.Hidden : Visibility.Visible;
                        });

                        if (recState == 0)
                        {
                            watch.Stop();
                        }
                    }

                    var tokenNew = SnvBackend.RecGetSessionId();
                    if (tokenNew != token)
                    {
                        token = tokenNew;
                        watch.Restart();
                    }

                    AppTools.TryInvoke(() =>
                    {
                        var ts = watch.Elapsed;
                        timerTextBlock.Text = string.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                                            ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
                    });

                    if (SnvBackend.RecGetSettingsWindowFlag() == 1)
                    {
                        SnvBackend.RecSetSettingsWindowFlag(0);
                        if (!isSettingsWindowOpen)
                        {
                            AppTools.TryInvoke(() =>
                            {
                                new SettingsWindow(() => { isSettingsWindowOpen = false; }).Show();
                                isSettingsWindowOpen = true;
                            });
                        }
                    }
                }
            }).Start();
        }