Exemplo n.º 1
0
        public override unsafe Task RenderFrameAsync(VideoFrameRenderer renderer, VideoFrameData frame, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(TaskHelper.CanceledTask);

                fixed(void *p = _screenBuffer)
                {
                    renderer.RenderVideoFrame32(frame, (IntPtr)p, 160 * 4);
                }

                if (cancellationToken.IsCancellationRequested)
                    return(TaskHelper.CanceledTask); }

                // Setting up a task completion source may not be needed here, but I don't know if there's something to gain by not doing so.
                if (SynchronizationContext != null)
                {
                    var tcs = new TaskCompletionSource <bool>();
                    SynchronizationContext.Post(UpdateScreenAndPresent, tcs);
                    return(tcs.Task);
                }
                else
                {
                    UpdateScreenAndPresent(null);
                    return(TaskHelper.TrueTask);
                }
        }
Exemplo n.º 2
0
        public override Task RenderFrameAsync(VideoFrameRenderer renderer, VideoFrameData frame, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(TaskHelper.CanceledTask);
            }

            var bitmap = _screenBitmapTripleBufferingSystem.GetCurrentProducerBuffer();

            // Calls to GDI+ should be thread-safe for the most part, so we only have to take a little bit of care for ensuring correctness.
            bitmap.LockBits(_screenRectangle, ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb, _lockedScreenBitmapData);

            renderer.RenderVideoFrame32(frame, _lockedScreenBitmapData.Scan0, _lockedScreenBitmapData.Stride);

            bitmap.UnlockBits(_lockedScreenBitmapData);

            _screenBitmapTripleBufferingSystem.GetNextProducerBuffer();

            if (cancellationToken.IsCancellationRequested)
            {
                return(TaskHelper.CanceledTask);
            }

            // Setting up a task completion source may not be needed here, but I don't know if there's something to gain by not doing so.
            if (SynchronizationContext != null)
            {
                var tcs = new TaskCompletionSource <bool>();
                SynchronizationContext.Post(Render, tcs);
                return(tcs.Task);
            }
            else
            {
                Render(null);
                return(CompletedTask);
            }
        }