protected override void Cleanup()
        {
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
            StopOutput();

            if (_inputTexture != null)
            {
                RenderTexture.ReleaseTemporary(_inputTexture);
                _inputTexture = null;
            }

            if (_rightInputTexture != null)
            {
                RenderTexture.ReleaseTemporary(_rightInputTexture);
                _rightInputTexture = null;
            }

            if (_capturedFrames != null)
            {
                foreach (var frame in _capturedFrames)
                {
                    RenderTexture.ReleaseTemporary(frame);
                }
                _capturedFrames = null;
            }

            if (_rightCapturedFrames != null)
            {
                foreach (var frame in _rightCapturedFrames)
                {
                    RenderTexture.ReleaseTemporary(frame);
                }
                _rightCapturedFrames = null;
            }

            if (_blended != null)
            {
                RenderTexture.ReleaseTemporary(_blended);
                _blended = null;
            }

            if (_rightBlended != null)
            {
                RenderTexture.ReleaseTemporary(_rightBlended);
                _rightBlended = null;
            }

            if (_interlacedTexture != null)
            {
                RenderTexture.ReleaseTemporary(_interlacedTexture);
                _blended = null;
            }

            DeckLinkPlugin.SetOutputBufferPointer(_deviceIndex, null);
            DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, IntPtr.Zero);
            DeckLinkPlugin.SetRightOutputBufferPointer(_deviceIndex, null);
            DeckLinkPlugin.SetRightOutputTexturePointer(_deviceIndex, IntPtr.Zero);

            if (_convertedTexture != null)
            {
                RenderTexture.ReleaseTemporary(_convertedTexture);
                _convertedTexture = null;
                _convertedPointer = IntPtr.Zero;
            }

            if (_rightConvertedTexture)
            {
                RenderTexture.ReleaseTemporary(_rightConvertedTexture);
                _rightConvertedTexture = null;
                _rightConvertedPointer = IntPtr.Zero;
            }

            if (_outputBuffer != null)
            {
                _outputBuffer = null;
            }

            if (_rightOutputBuffer != null)
            {
                _rightOutputBuffer = null;
            }

            if (_parameters != null)
            {
                _parameters.Release();
                _parameters = null;
            }

            if (_convertedCompBuffer != null)
            {
                _convertedCompBuffer.Release();
                _convertedCompBuffer = null;
            }

            if (_interlaceMaterial != null)
            {
                Destroy(_interlaceMaterial);
                _interlaceMaterial = null;
            }

            if (_conversionMaterial != null)
            {
                Destroy(_conversionMaterial);
                _conversionMaterial = null;
            }

            if (_blendMat != null)
            {
                Destroy(_blendMat);
                _blendMat = null;
            }
#endif
        }
        private void InitConversionResources(DeckLinkPlugin.PixelFormat format, int width, int height)
        {
            if (_conversionMaterial != null || _format != format)
            {
                Material.Destroy(_conversionMaterial);
                _conversionMaterial = null;
                _format             = format;
            }

            int texWidth = -1;

            // If we are doing keying and a non-RGBA mode is used for output, then use an RGBA texture,
            // as this conversion will be handled by the DeckLink hardware.
            if (_keyerMode != KeyerMode.None && !HasAlphaChannel(format))
            {
                _conversionMaterial = new Material(_rgbaToArgbShader);
                texWidth            = width;
            }
            else
            {
                // Otherwise convert to the output format
                switch (format)
                {
                case DeckLinkPlugin.PixelFormat.YCbCr_8bpp_422:
                    _conversionMaterial = new Material(_rgbaToYuv422Shader);
                    texWidth            = width / 2;
                    break;

                case DeckLinkPlugin.PixelFormat.YCbCr_10bpp_422:
                    _conversionMaterial = new Material(_rgbaToYuv422Shader2);
                    texWidth            = (width / 6) * 4;
                    _conversionMaterial.SetFloat("_TextureWidth", texWidth);
                    break;

                case DeckLinkPlugin.PixelFormat.BGRA_8bpp_444:
                    _conversionMaterial = new Material(_rgbaToBgraShader);
                    texWidth            = width;
                    break;

                case DeckLinkPlugin.PixelFormat.ARGB_8bpp_444:
                    _conversionMaterial = new Material(_rgbaToArgbShader);
                    texWidth            = width;
                    break;

                default:
                    break;
                }
            }

            if (_parameters != null)
            {
                _parameters.Release();
                _parameters = null;
            }

            DeckLinkPlugin.SetOutputBufferPointer(_deviceIndex, null);
            DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, IntPtr.Zero);
            DeckLinkPlugin.SetRightOutputBufferPointer(_deviceIndex, null);
            DeckLinkPlugin.SetRightOutputTexturePointer(_deviceIndex, IntPtr.Zero);

            if (_convertedTexture != null)
            {
                RenderTexture.ReleaseTemporary(_convertedTexture);
                _convertedTexture = null;
                _convertedPointer = IntPtr.Zero;
            }

            if (_rightConvertedTexture != null)
            {
                RenderTexture.ReleaseTemporary(_rightConvertedTexture);
                _rightConvertedTexture = null;
                _rightConvertedPointer = IntPtr.Zero;
            }

            if (_outputBuffer != null)
            {
                _outputBuffer = null;
            }

            if (_rightOutputBuffer != null)
            {
                _rightOutputBuffer = null;
            }

            if (_convertedCompBuffer != null)
            {
                _convertedCompBuffer.Release();
                _convertedCompBuffer = null;
            }

            if (texWidth < 0)
            {
                //sets up compute buffers
                if (_format == DeckLinkPlugin.PixelFormat.RGBX_10bpp_444 ||
                    _format == DeckLinkPlugin.PixelFormat.RGBX_10bpp_444_LE ||
                    _format == DeckLinkPlugin.PixelFormat.RGB_10bpp_444)
                {
                    _parameters = new ComputeBuffer(1, ComputeBufferParams.Size());

                    ComputeBufferParams[] parms = new ComputeBufferParams[1];
                    parms[0].height      = (uint)height;
                    parms[0].width       = (uint)width;
                    parms[0].bufferWidth = (uint)(width + 63) / 64 * 64;
                    parms[0].leading     = _format == DeckLinkPlugin.PixelFormat.RGB_10bpp_444 ? 1U : 0U;
                    bool formatBigEndian = _format != DeckLinkPlugin.PixelFormat.RGBX_10bpp_444_LE ? true : false;
                    if (BitConverter.IsLittleEndian)
                    {
                        formatBigEndian = !formatBigEndian;
                    }
                    parms[0].bigEndian = formatBigEndian ? 1U : 0U;
                    parms[0].isLinear  = QualitySettings.activeColorSpace == ColorSpace.Linear ? 1U : 0U;

                    _outputBuffer = new byte[parms[0].bufferWidth * parms[0].height * 4];
                    if (_current3DEnabled)
                    {
                        _rightOutputBuffer = new byte[parms[0].bufferWidth * parms[0].height * 4];
                    }

                    _convertedCompBuffer = new ComputeBuffer((int)(parms[0].bufferWidth * parms[0].height), 4, ComputeBufferType.Raw);

                    _parameters.SetData(parms);

                    DeckLinkPlugin.SetOutputBufferPointer(_deviceIndex, _outputBuffer);
                    DeckLinkPlugin.SetRightOutputBufferPointer(_deviceIndex, _rightOutputBuffer);
                }
                else
                {
                    RenderTextureReadWrite readWriteMode = (QualitySettings.activeColorSpace == ColorSpace.Linear ? RenderTextureReadWrite.Linear : RenderTextureReadWrite.Default);

                    _convertedTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, readWriteMode, 1);
                    _convertedPointer = _convertedTexture.GetNativeTexturePtr();
                    DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedPointer);

                    if (_current3DEnabled)
                    {
                        _rightConvertedTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, readWriteMode, 1);
                        _rightConvertedPointer = _rightConvertedTexture.GetNativeTexturePtr();
                        DeckLinkPlugin.SetRightOutputTexturePointer(_deviceIndex, _rightConvertedPointer);
                    }
                }
            }
            else
            {
                RenderTextureReadWrite readWriteMode = (QualitySettings.activeColorSpace == ColorSpace.Linear ? RenderTextureReadWrite.Linear : RenderTextureReadWrite.Default);

                RenderTextureFormat textureFormat = RenderTextureFormat.ARGB32;
                if (format == DeckLinkPlugin.PixelFormat.YCbCr_10bpp_422)
                {
                    textureFormat = RenderTextureFormat.ARGB2101010;
                }

                _convertedTexture = RenderTexture.GetTemporary(texWidth, height, 0, textureFormat, readWriteMode, 1);
                _convertedPointer = _convertedTexture.GetNativeTexturePtr();
                DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedPointer);

                if (_current3DEnabled)
                {
                    _rightConvertedTexture = RenderTexture.GetTemporary(texWidth, height, 0, textureFormat, readWriteMode, 1);
                    _rightConvertedPointer = _rightConvertedTexture.GetNativeTexturePtr();
                    DeckLinkPlugin.SetRightOutputTexturePointer(_deviceIndex, _rightConvertedPointer);
                }
            }
        }