protected override void Process() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN if (_device == null) { return; } if (_conversionMaterial != null) { //in this case, since we are dealing with non-srgb texture, need to do conversion from gamma to linear if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_bypassGamma) { _conversionMaterial.EnableKeyword("APPLY_GAMMA"); } else { _conversionMaterial.DisableKeyword("APPLY_GAMMA"); } } if (_convertedTexture != null && _convertedPointer == IntPtr.Zero) { _convertedPointer = _convertedTexture.GetNativeTexturePtr(); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedPointer); } if (_device.IsStreamingOutput) { CaptureFrame(); if (CanOutputFrame()) { if (DeckLinkSettings.Instance._multiOutput) { BlendCapturedFrames(); } RenderTexture input = _blended; input = Interlace(input); Convert(input); AdjustPlaybackFramerate(); DeckLinkPlugin.SetDeviceOutputReady(_deviceIndex); } } ProcessAudio(); #endif }
protected override void Process() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN if (_device == null) { return; } if (_convertedTexture != null && _convertedTexture.GetNativeTexturePtr() != _convertedPointer) { _convertedPointer = _convertedTexture.GetNativeTexturePtr(); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedTexture.GetNativeTexturePtr()); } if (_device.IsStreamingOutput) { CaptureFrame(); if (CanOutputFrame()) { if (DeckLinkSettings.Instance._multiOutput) { BlendCapturedFrames(); } RenderTexture input = _blended; input = ConvertColourSpace(input); input = Interlace(input); Convert(input); AdjustPlaybackFramerate(); DeckLinkPlugin.SetDeviceOutputReady(_deviceIndex); } } ProcessAudio(); #endif }
protected override void Cleanup() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN StopOutput(); if (_inputTexture != null) { RenderTexture.ReleaseTemporary(_inputTexture); _inputTexture = null; } if (_capturedFrames != null) { foreach (var frame in _capturedFrames) { RenderTexture.ReleaseTemporary(frame); } _capturedFrames = null; } if (_blended != null) { RenderTexture.ReleaseTemporary(_blended); _blended = null; } if (_lToGTexture != null) { RenderTexture.ReleaseTemporary(_lToGTexture); _blended = null; } if (_interlacedTexture != null) { RenderTexture.ReleaseTemporary(_interlacedTexture); _blended = null; } DeckLinkPlugin.SetOutputBufferPointer(_deviceIndex, null); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, IntPtr.Zero); if (_convertedTexture != null) { RenderTexture.ReleaseTemporary(_convertedTexture); _convertedTexture = null; } if (_outputBuffer != null) { _outputBuffer = 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 (_lToGMat != null) { Destroy(_lToGMat); _lToGMat = 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 (_conversionMaterial == null) { switch (format) { case DeckLinkPlugin.PixelFormat.YCbCr_8bpp_422: _conversionMaterial = new Material(_rgbaToYuv422Shader); texWidth = width / 2; 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); if (_convertedTexture != null) { RenderTexture.ReleaseTemporary(_convertedTexture); _convertedTexture = null; } if (_outputBuffer != null) { _outputBuffer = 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; _outputBuffer = 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); } else { _convertedTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, 1); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedTexture.GetNativeTexturePtr()); } } else { _convertedTexture = RenderTexture.GetTemporary(texWidth, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, 1); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedTexture.GetNativeTexturePtr()); } }
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); } } }
protected override void Process() { #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN if (_device == null) { return; } bool restartDevice = false; if (_current3DEnabled != _enable3D) { _current3DEnabled = _enable3D; restartDevice = true; } _device.LowLatencyMode = _lowLatencyMode; // If we're syncing to an input, then make sure we output using the same frame rate if (_syncedToInput != null && _syncedToInput.Device != null && _syncedToInput.Device.IsStreamingInput && _syncedToInput.ModeIndex >= 0) { // If we're using auto detect mode then we need to wait for frames to start coming in, otherwise // it may be still on the default mode awaiting auto detection if (!_syncedToInput._autoDetectMode || _syncedToInput.Device.FramesTotal > 1) { var inputMode = _syncedToInput.Device.CurrentMode; var outputMode = (Device == null) ? null : Device.CurrentOutputMode; // TODO: add better support for interlaced modes float inputFrameRate = inputMode.FrameRate; // * (inputMode.InterlacedFieldMode ? 2 : 1); if (outputMode == null || outputMode.FrameRate != inputFrameRate) { _filterModeByFPS = true; _filterModeByInterlacing = true; _modeFPS = inputFrameRate; _modeInterlacing = false; restartDevice = true; } } else { return; } } if (restartDevice) { StopOutput(); Begin(true); if (_device == null) { return; } } _enable3D = _current3DEnabled; if (_conversionMaterial != null) { //in this case, since we are dealing with non-srgb texture, need to do conversion from gamma to linear if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_bypassGamma) { _conversionMaterial.EnableKeyword("APPLY_GAMMA"); } else { _conversionMaterial.DisableKeyword("APPLY_GAMMA"); } if (_ignoreAlphaChannel) { _conversionMaterial.EnableKeyword(ShaderKeyIgnoreAlpha); } else { _conversionMaterial.DisableKeyword(ShaderKeyIgnoreAlpha); } switch (_colorspaceMode) { case DeckLink.ColorspaceMode.Rec709: _conversionMaterial.DisableKeyword(ShaderKeyRec2020); _conversionMaterial.DisableKeyword(ShaderKeyRec2100); _conversionMaterial.EnableKeyword(ShaderKeyRec709); break; case DeckLink.ColorspaceMode.Rec2020: _conversionMaterial.DisableKeyword(ShaderKeyRec709); _conversionMaterial.DisableKeyword(ShaderKeyRec2100); _conversionMaterial.EnableKeyword(ShaderKeyRec2020); break; case DeckLink.ColorspaceMode.Rec2100: _conversionMaterial.DisableKeyword(ShaderKeyRec709); _conversionMaterial.DisableKeyword(ShaderKeyRec2020); _conversionMaterial.EnableKeyword(ShaderKeyRec2100); break; } } if (_convertedTexture != null && _convertedPointer == IntPtr.Zero) { _convertedPointer = _convertedTexture.GetNativeTexturePtr(); DeckLinkPlugin.SetOutputTexturePointer(_deviceIndex, _convertedPointer); } if (_rightConvertedTexture != null && _rightConvertedPointer == IntPtr.Zero) { _rightConvertedPointer = _rightConvertedTexture.GetNativeTexturePtr(); DeckLinkPlugin.SetRightOutputTexturePointer(_deviceIndex, _rightConvertedPointer); } if (_device.IsStreamingOutput) { CaptureFrame(); if (CanOutputFrame()) { if (_syncedToInput) { _syncedToInput.UnsetInputReceivedFlag = true; } if (DeckLinkSettings.Instance._multiOutput) { BlendCapturedFrames(); } RenderTexture input = _blended; input = Interlace(input, !_current3DEnabled); Convert(input, _convertedTexture, _outputBuffer); if (_current3DEnabled) { input = _rightBlended; input = Interlace(input, true); Convert(input, _rightConvertedTexture, _rightOutputBuffer); } if (_syncedToInput == null) { AdjustPlaybackFramerate(); } DeckLinkPlugin.SetDeviceOutputReady(_deviceIndex); } } ProcessAudio(); #endif }