[Bf-blender-cvs] [f01f394] decklink: BGE: BL_Shader.setUniformEyef(): new uniform type to pass stereo eye value.

Benoit Bolsee noreply at git.blender.org
Sun Mar 29 14:13:49 CEST 2015


Commit: f01f3949829fd71e87ece10744c42d523b414132
Author: Benoit Bolsee
Date:   Sun Mar 29 13:59:39 2015 +0200
Branches: decklink
https://developer.blender.org/rBf01f3949829fd71e87ece10744c42d523b414132

BGE: BL_Shader.setUniformEyef(): new uniform type to pass stereo eye value.

BL_Shader.setUniformEyef() python method to define a uniform that will
receive the eye value as a float: 0.0 when rendering the left eye, 0.5
when rendering the right eye.
This can be used in a shader to split a 3D texture sent to the GPU by
VideoDeckLink as the left+right eye frame is sent as a single texture in
bottom/top order.

Work around a bug in VideoDeckLink with the the DVP library: the call to
dvpBindToGLCtx() fails for the first frame. This needs to be investigated
but for now catch the exception thrown by this condition and release the
decklink frame anyway as otherwise it corrupts the reference count of the
decklink device.

===================================================================

M	source/gameengine/Ketsji/BL_Shader.cpp
M	source/gameengine/Ketsji/BL_Shader.h
M	source/gameengine/VideoTexture/VideoDeckLink.cpp

===================================================================

diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index a7d42f2..ec6410d 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -32,6 +32,7 @@
 #include "MT_Matrix4x4.h"
 #include "MT_Matrix3x3.h"
 #include "KX_PyMath.h"
+#include "KX_PythonInit.h"
 #include "MEM_guardedalloc.h"
 
 #include "RAS_GLExtensionManager.h"
@@ -82,6 +83,12 @@ void BL_Uniform::Apply(class BL_Shader *shader)
 			glUniform1fARB(mLoc,(GLfloat)*f);
 			break;
 		}
+		case UNI_FLOAT_EYE:
+		{
+			float *f = (float*)mData;
+			*f = (KX_GetActiveEngine()->GetRasterizer()->GetEye() == RAS_IRasterizer::RAS_STEREO_LEFTEYE) ? 0.0f : 0.5f;
+			glUniform1fARB(mLoc, (GLfloat)*f);
+		}
 		case UNI_INT:
 		{
 			int *f = (int*)mData;
@@ -794,6 +801,7 @@ PyMethodDef BL_Shader::Methods[] =
 	KX_PYMETHODTABLE( BL_Shader, validate),
 	/// access functions
 	KX_PYMETHODTABLE( BL_Shader, isValid),
+	KX_PYMETHODTABLE( BL_Shader, setUniformEyef),
 	KX_PYMETHODTABLE( BL_Shader, setUniform1f ),
 	KX_PYMETHODTABLE( BL_Shader, setUniform2f ),
 	KX_PYMETHODTABLE( BL_Shader, setUniform3f ),
@@ -1064,6 +1072,29 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) "
 }
 
 
+KX_PYMETHODDEF_DOC(BL_Shader, setUniformEyef, "setUniformEyef(name)")
+{
+	if (mError) {
+		Py_RETURN_NONE;
+	}
+	const char *uniform;
+	float value = 0.0f;
+	if (PyArg_ParseTuple(args, "s:setUniformEyef", &uniform))
+	{
+		int loc = GetUniformLocation(uniform);
+		if (loc != -1)
+		{
+#ifdef SORT_UNIFORMS
+			SetUniformfv(loc, BL_Uniform::UNI_FLOAT_EYE, &value, sizeof(float));
+#else
+			SetUniform(loc, (int)value);
+#endif
+		}
+		Py_RETURN_NONE;
+	}
+	return NULL;
+}
+
 KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
 {
 	if (mError) {
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index 4c671d0..539ac4c 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -67,6 +67,7 @@ public:
 		UNI_FLOAT4,
 		UNI_MAT3,
 		UNI_MAT4,
+		UNI_FLOAT_EYE,
 		UNI_MAX
 	};
 
@@ -240,6 +241,7 @@ public:
 	KX_PYMETHOD_DOC(BL_Shader, setUniform3i);
 	KX_PYMETHOD_DOC(BL_Shader, setUniform2i);
 	KX_PYMETHOD_DOC(BL_Shader, setUniform1i);
+	KX_PYMETHOD_DOC(BL_Shader, setUniformEyef);
 	KX_PYMETHOD_DOC(BL_Shader, setUniformfv);
 	KX_PYMETHOD_DOC(BL_Shader, setUniformiv);
 	KX_PYMETHOD_DOC(BL_Shader, setUniformMatrix4);
diff --git a/source/gameengine/VideoTexture/VideoDeckLink.cpp b/source/gameengine/VideoTexture/VideoDeckLink.cpp
index 64ff864..2522bc5 100644
--- a/source/gameengine/VideoTexture/VideoDeckLink.cpp
+++ b/source/gameengine/VideoTexture/VideoDeckLink.cpp
@@ -41,6 +41,8 @@
 #include "PIL_time.h"
 #include "VideoDeckLink.h"
 #include "Exception.h"
+#include "KX_KetsjiEngine.h"
+#include "KX_PythonInit.h"
 
 static struct 
 {
@@ -213,8 +215,8 @@ public:
 	}
 	~TextureTransferDvp()
 	{
-		DVP_CHECK(dvpUnbindFromGLCtx(mDvpSysMemHandle));
-		DVP_CHECK(dvpDestroyBuffer(mDvpSysMemHandle));
+		dvpUnbindFromGLCtx(mDvpSysMemHandle);
+		dvpDestroyBuffer(mDvpSysMemHandle);
 		delete mExtSync;
 		delete mGpuSync;
 	}
@@ -626,20 +628,28 @@ VideoDeckLink::~VideoDeckLink ()
 	LockCache();
 	mClosing = true;
 	if (mpCacheFrame)
+	{
 		mpCacheFrame->Release();
+		mpCacheFrame = NULL;
+	}
 	UnlockCache();
 	if (mDLInput != NULL)
 	{
 		// Cleanup for Capture
 		mDLInput->StopStreams();
 		mDLInput->SetCallback(NULL);
-		mDLInput->Release();
+		mDLInput->DisableVideoInput();
+		mDLInput->FlushStreams();
+		if (mDLInput->Release() != 0)
+			THRWEXCP(VideoDeckLinkInternalError, S_OK);
 		mDLInput = NULL;
 	}
 	
 	if (mpAllocator)
 	{
-		delete mpAllocator;
+		// if the device was properly cleared, this should be 0
+		if (mpAllocator->Release() != 0)
+			THRWEXCP(VideoDeckLinkInternalError, S_OK);
 		mpAllocator = NULL;
 	}
 	if (mpCaptureDelegate)
@@ -939,46 +949,58 @@ void VideoDeckLink::calcImage (unsigned int texId, double ts)
 	UnlockCache();
 	if (pFrame)
 	{
-		u_int rowSize = pFrame->GetRowBytes();
-		u_int textureSize = rowSize * pFrame->GetHeight();
-		u_int expectedSize;
-		void* videoPixels = NULL;
-		void* rightEyePixels = NULL;
-		if (!mTextureDesc.stride)
-		{
-			// we could not compute the texture size earlier (unknown pixel size)
-			// let's do it now
-			mTextureDesc.stride = rowSize;
-			mTextureDesc.width = mTextureDesc.stride / 4;
-		}
-		if (mTextureDesc.stride != rowSize)
-		{
-			// unexpected frame size, ignore
-			// TBD: print a warning
-		}
-		else
+		// BUG: the dvpBindToGLCtx function fails the first time it is used, don't know why.
+		// This causes an exception to be thrown.
+		// This should be fixed but in the meantime we will catch the exception because
+		// it is crucial that we release the frame to keep the reference count right on the DeckLink device
+		try
 		{
-			pFrame->GetBytes(&videoPixels);
-			if (mUse3D) {
-				IDeckLinkVideoFrame3DExtensions *if3DExtensions = NULL;
-				IDeckLinkVideoFrame *rightEyeFrame = NULL;
-				if (pFrame->QueryInterface(&if3DExtensions) == S_OK &&
-					if3DExtensions->GetFrameForRightEye(&rightEyeFrame) == S_OK) {
-					rightEyeFrame->GetBytes(&rightEyePixels);
-					textureSize += ((uint64_t)rightEyePixels - (uint64_t)videoPixels);
-				}
-				if (rightEyeFrame)
-					rightEyeFrame->Release();
-				if (if3DExtensions)
-					if3DExtensions->Release();
+			u_int rowSize = pFrame->GetRowBytes();
+			u_int textureSize = rowSize * pFrame->GetHeight();
+			u_int expectedSize;
+			void* videoPixels = NULL;
+			void* rightEyePixels = NULL;
+			if (!mTextureDesc.stride)
+			{
+				// we could not compute the texture size earlier (unknown pixel size)
+				// let's do it now
+				mTextureDesc.stride = rowSize;
+				mTextureDesc.width = mTextureDesc.stride / 4;
 			}
-			expectedSize = mTextureDesc.width * mTextureDesc.height * 4;
-			if (expectedSize == textureSize)
+			if (mTextureDesc.stride != rowSize)
 			{
-				// this means that both left and right frame are contiguous and that there is no padding
-				// do the transfer
-				mpAllocator->TransferBuffer(videoPixels, &mTextureDesc, texId);
+				// unexpected frame size, ignore
+				// TBD: print a warning
 			}
+			else
+			{
+				pFrame->GetBytes(&videoPixels);
+				if (mUse3D) {
+					IDeckLinkVideoFrame3DExtensions *if3DExtensions = NULL;
+					IDeckLinkVideoFrame *rightEyeFrame = NULL;
+					if (pFrame->QueryInterface(&if3DExtensions) == S_OK &&
+						if3DExtensions->GetFrameForRightEye(&rightEyeFrame) == S_OK) {
+						rightEyeFrame->GetBytes(&rightEyePixels);
+						textureSize += ((uint64_t)rightEyePixels - (uint64_t)videoPixels);
+					}
+					if (rightEyeFrame)
+						rightEyeFrame->Release();
+					if (if3DExtensions)
+						if3DExtensions->Release();
+				}
+				expectedSize = mTextureDesc.width * mTextureDesc.height * 4;
+				if (expectedSize == textureSize)
+				{
+					// this means that both left and right frame are contiguous and that there is no padding
+					// do the transfer
+					mpAllocator->TransferBuffer(videoPixels, &mTextureDesc, texId);
+				}
+			}
+		} 
+		catch (Exception & exp)
+		{
+			pFrame->Release();
+			throw;
 		}
 		// this will trigger PinnedMemoryAllocator::RealaseBuffer
 		pFrame->Release();




More information about the Bf-blender-cvs mailing list