[PATCH 2/9] qv4l2: fix YUY2 shader

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fixed the YUY2 shaders to support scaling.
The new solution has cleaner shader code and texture upload
uses a better format for OpenGL.

Signed-off-by: Bård Eirik Winther <bwinther@xxxxxxxxx>
---
 utils/qv4l2/capture-win-gl.cpp | 68 ++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp
index c499f1f..6071410 100644
--- a/utils/qv4l2/capture-win-gl.cpp
+++ b/utils/qv4l2/capture-win-gl.cpp
@@ -1,5 +1,5 @@
 /*
- * The YUY2 shader code was copied and simplified from face-responder. The code is under public domain:
+ * The YUY2 shader code is based on face-responder. The code is under public domain:
  * https://bitbucket.org/nateharward/face-responder/src/0c3b4b957039d9f4bf1da09b9471371942de2601/yuv42201_laplace.frag?at=master
  *
  * All other OpenGL code:
@@ -446,47 +446,51 @@ QString CaptureWinGLEngine::shader_YUY2_invariant(__u32 format)
 {
 	switch (format) {
 	case V4L2_PIX_FMT_YUYV:
-		return QString("y = (luma_chroma.r - 0.0625) * 1.1643;"
-			       "if (mod(xcoord, 2.0) == 0.0) {"
-			       "   u = luma_chroma.a;"
-			       "   v = texture2D(tex, vec2(pixelx + texl_w, pixely)).a;"
+		return QString("if (mod(xcoord, 2.0) == 0.0) {"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+			       "   y = (luma_chroma.r - 0.0625) * 1.1643;"
 			       "} else {"
-			       "   v = luma_chroma.a;"
-			       "   u = texture2D(tex, vec2(pixelx - texl_w, pixely)).a;"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+			       "   y = (luma_chroma.b - 0.0625) * 1.1643;"
 			       "}"
+			       "u = luma_chroma.g - 0.5;"
+			       "v = luma_chroma.a - 0.5;"
 			       );
 
 	case V4L2_PIX_FMT_YVYU:
-		return QString("y = (luma_chroma.r - 0.0625) * 1.1643;"
-			       "if (mod(xcoord, 2.0) == 0.0) {"
-			       "   v = luma_chroma.a;"
-			       "   u = texture2D(tex, vec2(pixelx + texl_w, pixely)).a;"
+		return QString("if (mod(xcoord, 2.0) == 0.0) {"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+			       "   y = (luma_chroma.r - 0.0625) * 1.1643;"
 			       "} else {"
-			       "   u = luma_chroma.a;"
-			       "   v = texture2D(tex, vec2(pixelx - texl_w, pixely)).a;"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+			       "   y = (luma_chroma.b - 0.0625) * 1.1643;"
 			       "}"
+			       "u = luma_chroma.a - 0.5;"
+			       "v = luma_chroma.g - 0.5;"
 			       );
 
 	case V4L2_PIX_FMT_UYVY:
-		return QString("y = (luma_chroma.a - 0.0625) * 1.1643;"
-			       "if (mod(xcoord, 2.0) == 0.0) {"
-			       "   u = luma_chroma.r;"
-			       "   v = texture2D(tex, vec2(pixelx + texl_w, pixely)).r;"
+		return QString("if (mod(xcoord, 2.0) == 0.0) {"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+			       "   y = (luma_chroma.g - 0.0625) * 1.1643;"
 			       "} else {"
-			       "   v = luma_chroma.r;"
-			       "   u = texture2D(tex, vec2(pixelx - texl_w, pixely)).r;"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+			       "   y = (luma_chroma.a - 0.0625) * 1.1643;"
 			       "}"
+			       "u = luma_chroma.r - 0.5;"
+			       "v = luma_chroma.b - 0.5;"
 			       );
 
 	case V4L2_PIX_FMT_VYUY:
-		return QString("y = (luma_chroma.a - 0.0625) * 1.1643;"
-			       "if (mod(xcoord, 2.0) == 0.0) {"
-			       "   v = luma_chroma.r;"
-			       "   u = texture2D(tex, vec2(pixelx + texl_w, pixely)).r;"
+		return QString("if (mod(xcoord, 2.0) == 0.0) {"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
+			       "   y = (luma_chroma.g - 0.0625) * 1.1643;"
 			       "} else {"
-			       "   u = luma_chroma.r;"
-			       "   v = texture2D(tex, vec2(pixelx - texl_w, pixely)).r;"
+			       "   luma_chroma = texture2D(tex, vec2(pixelx - texl_w, pixely));"
+			       "   y = (luma_chroma.a - 0.0625) * 1.1643;"
 			       "}"
+			       "u = luma_chroma.b - 0.5;"
+			       "v = luma_chroma.r - 0.5;"
 			       );
 
 	default:
@@ -499,8 +503,8 @@ void CaptureWinGLEngine::shader_YUY2(__u32 format)
 	m_screenTextureCount = 1;
 	glGenTextures(m_screenTextureCount, m_screenTexture);
 	configureTexture(0);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, m_frameWidth, m_frameHeight, 0,
-		     GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_frameWidth / 2, m_frameHeight, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 	checkError("YUY2 shader");
 
 	QString codeHead = QString("uniform sampler2D tex;"
@@ -509,17 +513,15 @@ void CaptureWinGLEngine::shader_YUY2(__u32 format)
 				   "void main()"
 				   "{"
 				   "   float y, u, v;"
+				   "   vec4 luma_chroma;"
 				   "   float pixelx = gl_TexCoord[0].x;"
 				   "   float pixely = gl_TexCoord[0].y;"
 				   "   float xcoord = floor(pixelx * tex_w);"
-				   "   vec4 luma_chroma = texture2D(tex, vec2(pixelx, pixely));"
 				   );
 
 	QString codeBody = shader_YUY2_invariant(format);
 
-	QString codeTail = QString("   u = u - 0.5;"
-				   "   v = v - 0.5;"
-				   "   float r = y + 1.5958 * v;"
+	QString codeTail = QString("   float r = y + 1.5958 * v;"
 				   "   float g = y - 0.39173 * u - 0.81290 * v;"
 				   "   float b = y + 2.017 * u;"
 				   "   gl_FragColor = vec4(r, g, b, 1.0);"
@@ -548,8 +550,8 @@ void CaptureWinGLEngine::render_YUY2()
 	glBindTexture(GL_TEXTURE_2D, m_screenTexture[0]);
 	GLint Y = m_glfunction.glGetUniformLocation(m_shaderProgram.programId(), "tex");
 	glUniform1i(Y, 0);
-	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_frameWidth, m_frameHeight,
-			GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_frameData);
+	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_frameWidth / 2, m_frameHeight,
+			GL_RGBA, GL_UNSIGNED_BYTE, m_frameData);
 	checkError("YUY2 paint");
 }
 #endif
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux