unsafe void Update() { if (_sourceTexture == null || !_sourceTexture.IsCreated()) { return; } var w = _sourceTexture.width / 2; var h = _sourceTexture.height * (_alphaSupport ? 3 : 2) / 2; ReadbackBuffer buffer = null; if (_readbackQueue.Count > 0 && _readbackQueue.Peek().IsCompleted) { buffer = _sending; _sending = _readbackQueue.Dequeue(); // Wait for the plugin to complete the previous frame. NDI_SyncSender(_plugin); // Get the pointer to the data buffer, and give it to the plugin. NDI_SendFrame( _plugin, (IntPtr)_sending.Data.GetUnsafePtr(), _sourceTexture.width, _sourceTexture.height, _alphaSupport ? FourCC.UYVA : FourCC.UYVY ); NDI_SyncSender(_plugin); // Dispose the buffer if it can't be reused. if (_sending.Source.count != w * h) { NDI_SyncSender(_plugin); // Wait before disposing. DisposeBuffer(_sending); _sending = null; } } // Readback buffer allocation if (buffer == null) { buffer = new ReadbackBuffer(new ComputeBuffer(w * h, 4)); } // Invoke the compute. _compute.SetTexture(0, "Source", _sourceTexture); _compute.SetBuffer(0, "Destination", buffer.Source); _compute.Dispatch(0, w / 8, _sourceTexture.height / 8, 1); if (_alphaSupport) { _compute.SetTexture(1, "Source", _sourceTexture); _compute.SetBuffer(1, "Destination", buffer.Source); _compute.Dispatch(1, w / 16, _sourceTexture.height / 8, 1); } // Push to the readback queue. buffer.RequestReadback(); _readbackQueue.Enqueue(buffer); }
void DisposeBuffer(ReadbackBuffer buffer) { buffer.Source.Dispose(); buffer.Dispose(); }