26 #include "AampUtils.h"
28 #ifdef RENDER_FRAMES_IN_APP_CONTEXT
30 static const char *VSHADER =
31 "attribute vec2 vertexIn;"
32 "attribute vec2 textureIn;"
33 "varying vec2 textureOut;"
36 "gl_Position = trans * vec4(vertexIn,0, 1);"
37 "textureOut = textureIn;"
40 static const char *FSHADER =
42 " precision mediump float; \n"
44 "varying vec2 textureOut;"
45 "uniform sampler2D tex_y;"
46 "uniform sampler2D tex_u;"
47 "uniform sampler2D tex_v;"
51 "yuv.x = texture2D(tex_y, textureOut).r;"
52 "yuv.y = texture2D(tex_u, textureOut).r - 0.5;"
53 "yuv.z = texture2D(tex_v, textureOut).r - 0.5;"
54 "rgb = mat3( 1, 1, 1, 0, -0.39465, 2.03211, 1.13983, -0.58060, 0) * yuv;"
55 "gl_FragColor = vec4(rgb, 1);"
58 AppsinkData Shader::appsinkData = AppsinkData();
59 std::mutex Shader::appsinkData_mutex;
60 GLuint Shader::mProgramID = 0;
61 GLuint Shader::id_y = 0;
62 GLuint Shader::id_u = 0;
63 GLuint Shader::id_v = 0;
64 GLuint Shader::textureUniformY = 0;
65 GLuint Shader::textureUniformU = 0;
66 GLuint Shader::textureUniformV = 0;
67 GLuint Shader::_vertexArray = 0;
68 GLuint Shader::_vertexBuffer[2] = {0};
69 GLfloat Shader::currentAngleOfRotation = 0;
71 GLuint Shader::LoadShader( GLenum type )
73 GLuint shaderHandle = 0;
74 const char *sources[1];
76 if(GL_VERTEX_SHADER == type)
87 shaderHandle = glCreateShader(type);
88 glShaderSource(shaderHandle, 1, sources, 0);
89 glCompileShader(shaderHandle);
91 glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);
92 if (compileSuccess == GL_FALSE)
95 glGetShaderInfoLog(shaderHandle,
sizeof(msg), 0, &msg[0]);
96 printf(
"[AAMPCLI] %s\n", msg );
103 void Shader::InitShaders()
107 GLint vShader = LoadShader(GL_VERTEX_SHADER);
108 GLint fShader = LoadShader(GL_FRAGMENT_SHADER);
109 mProgramID = glCreateProgram();
110 glAttachShader(mProgramID,vShader);
111 glAttachShader(mProgramID,fShader);
113 glBindAttribLocation(mProgramID, ATTRIB_VERTEX,
"vertexIn");
114 glBindAttribLocation(mProgramID, ATTRIB_TEXTURE,
"textureIn");
115 glLinkProgram(mProgramID);
116 glValidateProgram(mProgramID);
118 glGetProgramiv(mProgramID, GL_LINK_STATUS, &linked);
119 if( linked == GL_FALSE )
122 glGetProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &logLen);
123 GLchar *msg = (GLchar *)malloc(
sizeof(GLchar)*logLen);
124 glGetProgramInfoLog(mProgramID, logLen, &logLen, msg );
125 printf(
"%s\n", msg );
128 glUseProgram(mProgramID);
129 glDeleteShader(vShader);
130 glDeleteShader(fShader);
133 textureUniformY = glGetUniformLocation(mProgramID,
"tex_y");
134 textureUniformU = glGetUniformLocation(mProgramID,
"tex_u");
135 textureUniformV = glGetUniformLocation(mProgramID,
"tex_v");
137 typedef struct _vertex
143 static const Vertex vertexPtr[4] =
145 {{-1,-1}, {0.0,1 } },
147 {{ 1, 1}, {1,0.0 } },
148 {{-1, 1}, {0.0,0.0} }
150 static const unsigned short index[6] =
155 glGenVertexArrays(1, &_vertexArray);
156 glBindVertexArray(_vertexArray);
157 glGenBuffers(2, _vertexBuffer);
158 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer[0]);
159 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertexPtr), vertexPtr, GL_STATIC_DRAW );
160 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vertexBuffer[1]);
161 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(index), index, GL_STATIC_DRAW );
162 glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE,
163 sizeof(Vertex), (
const GLvoid *)offsetof(Vertex,p) );
164 glEnableVertexAttribArray(ATTRIB_VERTEX);
166 glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE,
167 sizeof(Vertex), (
const GLvoid *)offsetof(Vertex, uv ) );
168 glEnableVertexAttribArray(ATTRIB_TEXTURE);
169 glBindVertexArray(0);
171 glGenTextures(1, &id_y);
172 glBindTexture(GL_TEXTURE_2D, id_y);
173 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
174 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
178 glGenTextures(1, &id_u);
179 glBindTexture(GL_TEXTURE_2D, id_u);
180 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
181 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
185 glGenTextures(1, &id_v);
186 glBindTexture(GL_TEXTURE_2D, id_v);
187 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
188 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
193 void Shader::glRender(
void){
208 uint8_t *yuvBuffer = NULL;
209 unsigned char *yPlane, *uPlane, *vPlane;
212 std::lock_guard<std::mutex> lock(appsinkData_mutex);
213 yuvBuffer = appsinkData.yuvBuffer;
214 appsinkData.yuvBuffer = NULL;
215 pixel_w = appsinkData.width;
216 pixel_h = appsinkData.height;
221 uPlane = yPlane + (pixel_w*pixel_h);
222 vPlane = uPlane + (pixel_w*pixel_h)/4;
224 glClearColor(0.0,0.0,0.0,0.0);
225 glClear(GL_COLOR_BUFFER_BIT);
228 glActiveTexture(GL_TEXTURE0);
229 glBindTexture(GL_TEXTURE_2D, id_y);
230 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, pixel_w, pixel_h, 0, GL_RED, GL_UNSIGNED_BYTE, yPlane);
231 glUniform1i(textureUniformY, 0);
234 glActiveTexture(GL_TEXTURE1);
235 glBindTexture(GL_TEXTURE_2D, id_u);
236 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, pixel_w/2, pixel_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, uPlane);
237 glUniform1i(textureUniformU, 1);
240 glActiveTexture(GL_TEXTURE2);
241 glBindTexture(GL_TEXTURE_2D, id_v);
242 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, pixel_w/2, pixel_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, vPlane);
243 glUniform1i(textureUniformV, 2);
246 glm::mat4 trans = glm::rotate(
248 currentAngleOfRotation * 360,
249 glm::vec3(1.0f, 1.0f, 1.0f)
251 GLint uniTrans = glGetUniformLocation(mProgramID,
"trans");
252 glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));
254 glBindVertexArray(_vertexArray);
255 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 );
256 glBindVertexArray(0);
259 SAFE_DELETE(yuvBuffer);
263 void Shader::updateYUVFrame(uint8_t *buffer,
int size,
int width,
int height)
265 uint8_t* frameBuf =
new uint8_t[size];
266 memcpy(frameBuf, buffer, size);
269 std::lock_guard<std::mutex> lock(appsinkData_mutex);
270 if(appsinkData.yuvBuffer)
272 printf(
"[AAMPCLI] Drops frame.\n");
273 SAFE_DELETE(appsinkData.yuvBuffer);
275 appsinkData.yuvBuffer = frameBuf;
276 appsinkData.width = width;
277 appsinkData.height = height;
281 void Shader::timer(
int v)
283 currentAngleOfRotation += 0.0001;
284 if (currentAngleOfRotation >= 1.0)
286 currentAngleOfRotation = 0.0;
290 glutTimerFunc(1000/FPS, timer, v);