Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2020
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / OpenGL tools used by compositor filter, vout filter and WebGL bindings
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/tools.h>
27 : #include <gpac/filters.h>
28 :
29 : #ifndef GPAC_DISABLE_3D
30 :
31 : #include "../compositor/gl_inc.h"
32 :
33 : #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__)
34 : # if defined(GPAC_USE_TINYGL)
35 : # pragma comment(lib, "TinyGL")
36 :
37 : # elif defined(GPAC_USE_GLES1X)
38 :
39 : # if 0
40 : # pragma message("Using OpenGL-ES Common Lite Profile")
41 : # pragma comment(lib, "libGLES_CL")
42 : # define GL_ES_CL_PROFILE
43 : # else
44 : # pragma message("Using OpenGL-ES Common Profile")
45 : # pragma comment(lib, "libGLES_CM")
46 : # endif
47 :
48 : # elif defined(GPAC_USE_GLES2)
49 : # pragma comment(lib, "libGLESv2")
50 :
51 : # else
52 : # pragma comment(lib, "opengl32")
53 : # endif
54 :
55 : #ifdef GPAC_HAS_GLU
56 : # pragma comment(lib, "glu32")
57 : #endif
58 :
59 : #endif
60 :
61 : /*!! HORRIBLE HACK, but on my test devices, it seems that glClipPlanex is missing on the device but not in the SDK lib !!*/
62 : #if defined(GL_MAX_CLIP_PLANES) && defined(__SYMBIAN32__)
63 : #undef GL_MAX_CLIP_PLANES
64 : #endif
65 :
66 :
67 : #ifdef LOAD_GL_1_3
68 :
69 : GLDECL_FUNC(glActiveTexture);
70 : GLDECL_FUNC(glClientActiveTexture);
71 : GLDECL_FUNC(glBlendEquation);
72 :
73 : #endif //LOAD_GL_1_3
74 :
75 : #ifdef LOAD_GL_1_4
76 :
77 : GLDECL_FUNC(glPointParameterf);
78 : GLDECL_FUNC(glPointParameterfv);
79 :
80 : #endif //LOAD_GL_1_4
81 :
82 :
83 : #ifdef LOAD_GL_1_5
84 : GLDECL_FUNC(glGenBuffers);
85 : GLDECL_FUNC(glDeleteBuffers);
86 : GLDECL_FUNC(glBindBuffer);
87 : GLDECL_FUNC(glBufferData);
88 : GLDECL_FUNC(glBufferSubData);
89 : GLDECL_FUNC(glMapBuffer);
90 : GLDECL_FUNC(glUnmapBuffer);
91 : #endif //LOAD_GL_1_5
92 :
93 : #ifdef LOAD_GL_2_0
94 :
95 : GLDECL_FUNC(glCreateProgram);
96 : GLDECL_FUNC(glDeleteProgram);
97 : GLDECL_FUNC(glLinkProgram);
98 : GLDECL_FUNC(glUseProgram);
99 : GLDECL_FUNC(glCreateShader);
100 : GLDECL_FUNC(glDeleteShader);
101 : GLDECL_FUNC(glShaderSource);
102 : GLDECL_FUNC(glCompileShader);
103 : GLDECL_FUNC(glAttachShader);
104 : GLDECL_FUNC(glDetachShader);
105 : GLDECL_FUNC(glGetShaderiv);
106 : GLDECL_FUNC(glGetInfoLogARB);
107 : GLDECL_FUNC(glGetUniformLocation);
108 : GLDECL_FUNC(glGetUniformfv);
109 : GLDECL_FUNC(glGetUniformiv);
110 : GLDECL_FUNC(glUniform1f);
111 : GLDECL_FUNC(glUniform2f);
112 : GLDECL_FUNC(glUniform3f);
113 : GLDECL_FUNC(glUniform4f);
114 : GLDECL_FUNC(glUniform1i);
115 : GLDECL_FUNC(glUniform2i);
116 : GLDECL_FUNC(glUniform3i);
117 : GLDECL_FUNC(glUniform4i);
118 : GLDECL_FUNC(glUniform1fv);
119 : GLDECL_FUNC(glUniform2fv);
120 : GLDECL_FUNC(glUniform3fv);
121 : GLDECL_FUNC(glUniform4fv);
122 : GLDECL_FUNC(glUniform1iv);
123 : GLDECL_FUNC(glUniform2iv);
124 : GLDECL_FUNC(glUniform3iv);
125 : GLDECL_FUNC(glUniform4iv);
126 : GLDECL_FUNC(glUniformMatrix2fv);
127 : GLDECL_FUNC(glUniformMatrix3fv);
128 : GLDECL_FUNC(glUniformMatrix4fv);
129 : GLDECL_FUNC(glUniformMatrix2x3fv);
130 : GLDECL_FUNC(glUniformMatrix3x2fv);
131 : GLDECL_FUNC(glUniformMatrix2x4fv);
132 : GLDECL_FUNC(glUniformMatrix4x2fv);
133 : GLDECL_FUNC(glUniformMatrix3x4fv);
134 : GLDECL_FUNC(glUniformMatrix4x3fv);
135 : GLDECL_FUNC(glGetProgramiv);
136 : GLDECL_FUNC(glGetProgramInfoLog);
137 : GLDECL_FUNC(glGetAttribLocation);
138 : GLDECL_FUNC(glBindFramebuffer);
139 : GLDECL_FUNC(glFramebufferTexture2D);
140 : GLDECL_FUNC(glGenFramebuffers);
141 : GLDECL_FUNC(glGenRenderbuffers);
142 : GLDECL_FUNC(glBindRenderbuffer);
143 : GLDECL_FUNC(glRenderbufferStorage);
144 : GLDECL_FUNC(glFramebufferRenderbuffer);
145 : GLDECL_FUNC(glDeleteFramebuffers);
146 : GLDECL_FUNC(glDeleteRenderbuffers);
147 : GLDECL_FUNC(glCheckFramebufferStatus);
148 :
149 : GLDECL_FUNC(glBlendColor);
150 : GLDECL_FUNC(glBlendEquationSeparate);
151 : GLDECL_FUNC(glBlendFuncSeparate);
152 : GLDECL_FUNC(glCompressedTexImage2D);
153 : GLDECL_FUNC(glCompressedTexSubImage2D);
154 : GLDECL_FUNC(glGenerateMipmap);
155 : GLDECL_FUNC(glGetShaderInfoLog);
156 : GLDECL_FUNC(glGetShaderSource);
157 : GLDECL_FUNC(glGetActiveAttrib);
158 : GLDECL_FUNC(glGetActiveUniform);
159 : GLDECL_FUNC(glGetAttachedShaders);
160 : GLDECL_FUNC(glBindAttribLocation);
161 : GLDECL_FUNC(glIsBuffer);
162 : GLDECL_FUNC(glIsFramebuffer);
163 : GLDECL_FUNC(glIsProgram);
164 : GLDECL_FUNC(glIsRenderbuffer);
165 : GLDECL_FUNC(glIsShader);
166 : GLDECL_FUNC(glSampleCoverage);
167 : GLDECL_FUNC(glStencilFuncSeparate);
168 : GLDECL_FUNC(glStencilOpSeparate);
169 : GLDECL_FUNC(glStencilMaskSeparate);
170 : GLDECL_FUNC(glValidateProgram);
171 : GLDECL_FUNC(glVertexAttrib1fv);
172 : GLDECL_FUNC(glVertexAttrib1f);
173 : GLDECL_FUNC(glVertexAttrib2f);
174 : GLDECL_FUNC(glVertexAttrib2fv);
175 : GLDECL_FUNC(glVertexAttrib3f);
176 : GLDECL_FUNC(glVertexAttrib3fv);
177 : GLDECL_FUNC(glVertexAttrib4f);
178 : GLDECL_FUNC(glVertexAttrib4fv);
179 : GLDECL_FUNC(glGetBufferParameteriv);
180 : GLDECL_FUNC(glGetFramebufferAttachmentParameteriv);
181 : GLDECL_FUNC(glGetVertexAttribiv);
182 : GLDECL_FUNC(glGetVertexAttribfv);
183 : GLDECL_FUNC(glGetVertexAttribPointerv);
184 : GLDECL_FUNC(glGetRenderbufferParameteriv);
185 :
186 : #ifndef GPAC_CONFIG_ANDROID
187 : GLDECL_FUNC(glEnableVertexAttribArray);
188 : GLDECL_FUNC(glDisableVertexAttribArray);
189 : GLDECL_FUNC(glVertexAttribPointer);
190 : GLDECL_FUNC(glVertexAttribIPointer);
191 : #endif
192 :
193 : #endif //LOAD_GL_2_0
194 :
195 : static Bool gl_fun_loaded = GF_FALSE;
196 359 : void gf_opengl_init()
197 : {
198 359 : if (gl_fun_loaded) return;
199 154 : gl_fun_loaded = GF_TRUE;
200 :
201 154 : if (gf_opts_get_bool("core", "rmt-ogl")) {
202 1 : rmt_BindOpenGL();
203 : }
204 :
205 : #ifndef GPAC_USE_TINYGL
206 :
207 : #ifdef LOAD_GL_1_3
208 : GET_GLFUN(glActiveTexture);
209 : GET_GLFUN(glClientActiveTexture);
210 : GET_GLFUN(glBlendEquation);
211 : #endif
212 :
213 : #ifdef LOAD_GL_1_4
214 : GET_GLFUN(glPointParameterf);
215 : GET_GLFUN(glPointParameterfv);
216 : #endif
217 :
218 : #ifdef LOAD_GL_1_5
219 : GET_GLFUN(glGenBuffers);
220 : GET_GLFUN(glDeleteBuffers);
221 : GET_GLFUN(glBindBuffer);
222 : GET_GLFUN(glBufferData);
223 : GET_GLFUN(glBufferSubData);
224 :
225 : GET_GLFUN(glMapBuffer);
226 : GET_GLFUN(glUnmapBuffer);
227 : #endif
228 :
229 :
230 : #ifdef LOAD_GL_2_0
231 : GET_GLFUN(glCreateProgram);
232 :
233 : GET_GLFUN(glDeleteProgram);
234 : GET_GLFUN(glLinkProgram);
235 : GET_GLFUN(glUseProgram);
236 : GET_GLFUN(glCreateShader);
237 : GET_GLFUN(glDeleteShader);
238 : GET_GLFUN(glShaderSource);
239 : GET_GLFUN(glCompileShader);
240 : GET_GLFUN(glAttachShader);
241 : GET_GLFUN(glDetachShader);
242 : GET_GLFUN(glGetShaderiv);
243 : GET_GLFUN(glGetInfoLogARB);
244 : GET_GLFUN(glGetUniformLocation);
245 : GET_GLFUN(glGetUniformfv);
246 : GET_GLFUN(glGetUniformiv);
247 : GET_GLFUN(glUniform1f);
248 : GET_GLFUN(glUniform2f);
249 : GET_GLFUN(glUniform3f);
250 : GET_GLFUN(glUniform4f);
251 : GET_GLFUN(glUniform1i);
252 : GET_GLFUN(glUniform2i);
253 : GET_GLFUN(glUniform3i);
254 : GET_GLFUN(glUniform4i);
255 : GET_GLFUN(glUniform1fv);
256 : GET_GLFUN(glUniform2fv);
257 : GET_GLFUN(glUniform3fv);
258 : GET_GLFUN(glUniform4fv);
259 : GET_GLFUN(glUniform1iv);
260 : GET_GLFUN(glUniform2iv);
261 : GET_GLFUN(glUniform3iv);
262 : GET_GLFUN(glUniform4iv);
263 : GET_GLFUN(glUniformMatrix2fv);
264 : GET_GLFUN(glUniformMatrix3fv);
265 : GET_GLFUN(glUniformMatrix4fv);
266 : GET_GLFUN(glUniformMatrix2x3fv);
267 : GET_GLFUN(glUniformMatrix3x2fv);
268 : GET_GLFUN(glUniformMatrix2x4fv);
269 : GET_GLFUN(glUniformMatrix4x2fv);
270 : GET_GLFUN(glUniformMatrix3x4fv);
271 : GET_GLFUN(glUniformMatrix4x3fv);
272 : GET_GLFUN(glGetProgramiv);
273 : GET_GLFUN(glGetProgramInfoLog);
274 : GET_GLFUN(glBlendColor);
275 : GET_GLFUN(glBlendEquationSeparate);
276 : GET_GLFUN(glBlendFuncSeparate);
277 : GET_GLFUN(glCompressedTexImage2D);
278 : GET_GLFUN(glCompressedTexSubImage2D);
279 : GET_GLFUN(glGenerateMipmap);
280 : GET_GLFUN(glGetShaderInfoLog);
281 : GET_GLFUN(glGetShaderSource);
282 : GET_GLFUN(glGetActiveAttrib);
283 : GET_GLFUN(glGetActiveUniform);
284 : GET_GLFUN(glGetAttachedShaders);
285 : GET_GLFUN(glBindAttribLocation);
286 : GET_GLFUN(glIsBuffer);
287 : GET_GLFUN(glIsFramebuffer);
288 : GET_GLFUN(glIsProgram);
289 : GET_GLFUN(glIsRenderbuffer);
290 : GET_GLFUN(glIsShader);
291 : GET_GLFUN(glSampleCoverage);
292 : GET_GLFUN(glStencilFuncSeparate);
293 : GET_GLFUN(glStencilOpSeparate);
294 : GET_GLFUN(glStencilMaskSeparate);
295 : GET_GLFUN(glValidateProgram);
296 : GET_GLFUN(glVertexAttrib1fv);
297 : GET_GLFUN(glVertexAttrib1f);
298 : GET_GLFUN(glVertexAttrib2f);
299 : GET_GLFUN(glVertexAttrib2fv);
300 : GET_GLFUN(glVertexAttrib3f);
301 : GET_GLFUN(glVertexAttrib3fv);
302 : GET_GLFUN(glVertexAttrib4f);
303 : GET_GLFUN(glVertexAttrib4fv);
304 : GET_GLFUN(glGetBufferParameteriv);
305 : GET_GLFUN(glGetFramebufferAttachmentParameteriv);
306 : GET_GLFUN(glGetVertexAttribiv);
307 : GET_GLFUN(glGetVertexAttribfv);
308 : GET_GLFUN(glGetVertexAttribPointerv);
309 : GET_GLFUN(glGetRenderbufferParameteriv);
310 :
311 : #ifndef GPAC_CONFIG_ANDROID
312 : GET_GLFUN(glEnableVertexAttribArray);
313 : GET_GLFUN(glDisableVertexAttribArray);
314 : GET_GLFUN(glVertexAttribPointer);
315 : GET_GLFUN(glVertexAttribIPointer);
316 : GET_GLFUN(glGetAttribLocation);
317 :
318 : GET_GLFUN(glBindFramebuffer);
319 : GET_GLFUN(glFramebufferTexture2D);
320 : GET_GLFUN(glGenFramebuffers);
321 : GET_GLFUN(glGenRenderbuffers);
322 : GET_GLFUN(glBindRenderbuffer);
323 : GET_GLFUN(glRenderbufferStorage);
324 : GET_GLFUN(glFramebufferRenderbuffer);
325 : GET_GLFUN(glDeleteFramebuffers);
326 : GET_GLFUN(glDeleteRenderbuffers);
327 : GET_GLFUN(glCheckFramebufferStatus);
328 :
329 : #endif
330 :
331 : #endif //LOAD_GL_2_0
332 :
333 : #endif //GPAC_USE_TINYGL
334 :
335 : }
336 :
337 : static char *gl_shader_yuv_matrix = \
338 : "uniform mat4 _gf_%s_mx;\n\
339 : ";
340 :
341 :
342 : #if 0 //old code
343 : static char *gl_shader_yuv_coefs = \
344 : "const vec3 offset = vec3(-0.0625, -0.5, -0.5);\n\
345 : const vec3 R_mul = vec3(1.164, 0.000, 1.596);\n\
346 : const vec3 G_mul = vec3(1.164, -0.391, -0.813);\n\
347 : const vec3 B_mul = vec3(1.164, 2.018, 0.000);\n\
348 : ";
349 :
350 : static char *gl_shader_yuv_coefs_jpeg = \
351 : "const vec3 offset = vec3(0.0, -0.5, -0.5);\n\
352 : const vec3 R_mul = vec3(1, 0.000, 1.40200);\n\
353 : const vec3 G_mul = vec3(1, -0.34414, -0.71414);\n\
354 : const vec3 B_mul = vec3(1, 1.77200, 0.000);\n\
355 : ";
356 : #endif
357 :
358 : static char *gl_shader_vars_yuv = \
359 : "uniform sampler2D _gf_%s_1;\n\
360 : uniform sampler2D _gf_%s_2;\n\
361 : uniform sampler2D _gf_%s_3;\n\
362 : ";
363 :
364 : static char *gl_shader_fun_yuv = \
365 : "vec2 texc;\n\
366 : vec4 yuv;\n\
367 : texc = _gpacTexCoord.st;\n\
368 : yuv.x = texture2D(_gf_%s_1, texc).r;\n\
369 : yuv.y = texture2D(_gf_%s_2, texc).r;\n\
370 : yuv.z = texture2D(_gf_%s_3, texc).r;\n\
371 : yuv.w = 1.0;\n\
372 : yuv = _gf_%s_mx * yuv;\n\
373 : yuv.w = 1.0;\n\
374 : return yuv;\n\
375 : ";
376 :
377 : static char *gl_shader_fun_yvu = \
378 : "vec2 texc;\n\
379 : vec4 yuv;\n\
380 : texc = _gpacTexCoord.st;\n\
381 : yuv.x = texture2D(_gf_%s_1, texc).r;\n\
382 : yuv.y = texture2D(_gf_%s_3, texc).r;\n\
383 : yuv.z = texture2D(_gf_%s_2, texc).r;\n\
384 : yuv.w = 1.0;\n\
385 : yuv = _gf_%s_mx * yuv;\n\
386 : yuv.w = 1.0;\n\
387 : return yuv;\n\
388 : ";
389 : static char *gl_shader_vars_yuva = \
390 : "uniform sampler2D _gf_%s_1;\n\
391 : uniform sampler2D _gf_%s_2;\n\
392 : uniform sampler2D _gf_%s_3;\n\
393 : uniform sampler2D _gf_%s_4;\n\
394 : ";
395 :
396 : static char *gl_shader_fun_yuva = \
397 : "vec2 texc;\n\
398 : vec4 yuv;\n\
399 : texc = _gpacTexCoord.st;\n\
400 : yuv.x = texture2D(_gf_%s_1, texc).r;\n\
401 : yuv.y = texture2D(_gf_%s_2, texc).r;\n\
402 : yuv.z = texture2D(_gf_%s_3, texc).r;\n\
403 : yuv.w = 1.0;\n\
404 : yuv = _gf_%s_mx * yuv;\n\
405 : yuv.w = texture2D(_gf_%s_4, texc).r;\n\
406 : return yuv;\n\
407 : ";
408 :
409 : static char *gl_shader_vars_nv12 = \
410 : "uniform sampler2D _gf_%s_1;\n\
411 : uniform sampler2D _gf_%s_2;\n\
412 : ";
413 :
414 : static char *gl_shader_fun_nv12 = \
415 : "vec2 texc;\n\
416 : vec4 yuv;\n\
417 : texc = _gpacTexCoord.st;\n\
418 : yuv.x = texture2D(_gf_%s_1, texc).r;\n\
419 : yuv.yz = texture2D(_gf_%s_2, texc).ra;\n\
420 : yuv.w = 1.0;\n\
421 : yuv = _gf_%s_mx * yuv;\n\
422 : yuv.w = 1.0;\n\
423 : return yuv;\n\
424 : ";
425 :
426 :
427 : static char *gl_shader_vars_nv21 = \
428 : "uniform sampler2D _gf_%s_1;\n\
429 : uniform sampler2D _gf_%s_2;\n\
430 : ";
431 :
432 : static char *gl_shader_fun_nv21 = \
433 : "vec2 texc;\n\
434 : vec4 yuv;\n\
435 : texc = _gpacTexCoord.st;\n\
436 : yuv.x = texture2D(_gf_%s_1, texc).r;\n\
437 : yuv.yz = texture2D(_gf_%s_2, texc).ar;\n\
438 : yuv.w = 1.0;\n\
439 : yuv = _gf_%s_mx * yuv;\n\
440 : yuv.w = 1.0;\n\
441 : return yuv;\n\
442 : ";
443 :
444 :
445 : static char *gl_shader_vars_uyvu = \
446 : "uniform sampler2D _gf_%s_1;\
447 : uniform float _gf_%s_width;\
448 : ";
449 :
450 : static char *gl_shader_fun_uyvy = \
451 : "vec2 texc, t_texc;\
452 : vec4 yuv;\
453 : vec4 uyvy;\
454 : float tex_s;\
455 : texc = _gpacTexCoord.st;\
456 : t_texc = texc * vec2(1, 1);\
457 : uyvy = texture2D(_gf_%s_1, t_texc); \
458 : tex_s = texc.x*_gf_%s_width;\
459 : if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
460 : uyvy.g = uyvy.a; \
461 : }\
462 : yuv.r = uyvy.g;\
463 : yuv.g = uyvy.r;\
464 : yuv.b = uyvy.b;\
465 : yuv.w = 1.0;\n\
466 : yuv = _gf_%s_mx * yuv;\n\
467 : yuv.w = 1.0;\n\
468 : return yuv;\n\
469 : ";
470 :
471 :
472 : static char *gl_shader_fun_vyuy = \
473 : "vec2 texc, t_texc;\
474 : vec4 yuv;\
475 : vec4 vyuy;\
476 : float tex_s;\
477 : texc = _gpacTexCoord.st;\
478 : t_texc = texc * vec2(1, 1);\
479 : vyuy = texture2D(_gf_%s_1, t_texc); \
480 : tex_s = texc.x*_gf_%s_width;\
481 : if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
482 : vyuy.g = vyuy.a; \
483 : }\
484 : yuv.r = vyuy.g;\
485 : yuv.g = vyuy.b;\
486 : yuv.b = vyuy.r;\
487 : yuv.w = 1.0;\n\
488 : yuv = _gf_%s_mx * yuv;\n\
489 : yuv.w = 1.0;\n\
490 : return yuv;\n\
491 : ";
492 :
493 :
494 : static char *gl_shader_fun_yuyv = \
495 : "vec2 texc, t_texc;\
496 : vec4 yuv;\
497 : vec4 yvyu;\
498 : float tex_s;\
499 : texc = _gpacTexCoord.st;\
500 : t_texc = texc * vec2(1, 1);\
501 : yvyu = texture2D(_gf_%s_1, t_texc); \
502 : tex_s = texc.x*_gf_%s_width;\
503 : if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
504 : yvyu.r = yvyu.b; \
505 : }\
506 : yuv.r = yvyu.r;\
507 : yuv.g = yvyu.g;\
508 : yuv.b = yvyu.a;\
509 : yuv.w = 1.0;\n\
510 : yuv = _gf_%s_mx * yuv;\n\
511 : yuv.w = 1.0;\n\
512 : return yuv;\n\
513 : ";
514 :
515 : static char *gl_shader_fun_yvyu = \
516 : "vec2 texc, t_texc;\
517 : vec4 yuv;\
518 : vec4 yuyv;\
519 : float tex_s;\
520 : texc = _gpacTexCoord.st;\
521 : t_texc = texc * vec2(1, 1);\
522 : yuyv = texture2D(_gf_%s_1, t_texc); \
523 : tex_s = texc.x*_gf_%s_width;\
524 : if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
525 : yuyv.r = yuyv.b; \
526 : }\
527 : yuv.r = yuyv.r;\
528 : yuv.g = yuyv.a;\
529 : yuv.b = yuyv.g;\
530 : yuv.w = 1.0;\n\
531 : yuv = _gf_%s_mx * yuv;\n\
532 : yuv.w = 1.0;\n\
533 : return yuv;\n\
534 : ";
535 :
536 :
537 : static char *gl_shader_vars_yuv4_pack = \
538 : "uniform sampler2D _gf_%s_1;\n\
539 : ";
540 :
541 : static char *gl_shader_fun_yuv4_pack = \
542 : "vec2 texc;\n\
543 : vec4 yuv;\n\
544 : texc = _gpacTexCoord.st;\n\
545 : yuv = texture2D(_gf_%s_1, texc).gbr;\n\
546 : yuv.w = 1.0;\n\
547 : yuv = _gf_%s_mx * yuv;\n\
548 : yuv.w = 1.0;\n\
549 : return yuv;\n\
550 : ";
551 :
552 : static char *gl_shader_fun_yuv4a_pack = \
553 : "vec2 texc;\n\
554 : vec4 tex;\n\
555 : vec4 yuv;\n\
556 : texc = _gpacTexCoord.st;\n\
557 : tex = texture2D(_gf_%s_1, texc).rgba;\n\
558 : yuv.r = tex.g;\n\
559 : yuv.g = tex.r;\n\
560 : yuv.b = tex.b;\n\
561 : yuv.w = 1.0;\n\
562 : yuv = _gf_%s_mx * yuv;\n\
563 : yuv.w = 1.0;\n\
564 : return yuv;\n\
565 : ";
566 :
567 : #if 1
568 : //10 bit V, 10 bit Y, 10 bit U, 2 bits lost
569 : //V: 8 bit R + 2 bits G
570 : //Y: 6 bit G + 4 bits B
571 : //U: 4 bit R + 6 bits A
572 : static char *gl_shader_fun_yuv4_10_pack = \
573 : "vec2 texc;\n\
574 : vec4 val;\n\
575 : int valr, valg, valb, vala, interm1, interm2;\n\
576 : vec4 yuv;\n\
577 : texc = _gpacTexCoord.st;\n\
578 : val = texture2D(_gf_%s_1, texc).rgba;\n\
579 : valr = int(val.r*255);\n\
580 : valg = int(val.g*255);\n\
581 : valb = int(val.b*255);\n\
582 : vala = int(val.a*63);\n\
583 : interm1 = valg / 64;\n\
584 : yuv.b = float( (valr * 4) + (interm1) ) / 1023.0;\n\
585 : interm1 *= 64;\n\
586 : interm2 = valb / 16;\n\
587 : yuv.r = float( ((valg - interm1) * 16) + (interm2) ) / 1023.0;\n\
588 : interm2 *= 16;\n\
589 : yuv.g = float( ((valb - interm2) * 64) + vala ) / 1023.0;\n\
590 : yuv.w = 1.0;\n\
591 : yuv = _gf_%s_mx * yuv;\n\
592 : yuv.w = 1.0;\n\
593 : return yuv;\n\
594 : ";
595 :
596 : #else
597 :
598 :
599 : //in byte order:
600 : //2 bits lost, 10 bit U, 10 bit Y, 10 bit V
601 : //U: 6 bit R + 4 bits G
602 : //Y: 4 bit G + 6 bits B
603 : //V: 2 bit B + 8 bits A
604 : static char *gl_shader_fun_yuv4_10_pack = \
605 : "vec2 texc;\n\
606 : vec4 val;\n\
607 : int valr, valg, valb, vala, interm1, interm2;\n\
608 : vec4 yuv;\n\
609 : texc = _gpacTexCoord.st;\n\
610 : val = texture2D(_gf_%s_1, texc).rgba;\n\
611 : valr = int(val.r*63);\n\
612 : valg = int(val.g*255);\n\
613 : valb = int(val.b*255);\n\
614 : vala = int(val.a*255);\n\
615 : interm1 = valg / 16;\n\
616 : yuv.b = float( (valr * 16) + (interm1) ) / 1023.0;\n\
617 : interm1 *= 16;\n\
618 : interm2 = valb / 4;\n\
619 : yuv.g = float( ((valg - interm1) * 64) + (interm2) ) / 1023.0;\n\
620 : interm2 *= 4;\n\
621 : yuv.r = float( ((valb - interm2) * 256) + vala ) / 1023.0;\n\
622 : yuv.w = 1.0;\n\
623 : yuv = _gf_%s_mx * yuv;\n\
624 : yuv.w = 1.0;\n\
625 : return yuv;\n\
626 : ";
627 :
628 : #endif
629 :
630 : static char *gl_shader_vars_rgb = \
631 : "uniform sampler2D _gf_%s_1;\n\
632 : ";
633 :
634 : static char *gl_shader_fun_alphagrey = \
635 : "vec4 col, ocol;\n\
636 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
637 : ocol.r = ocol.g = ocol.b = col.a;\n\
638 : ocol.a = col.r;\n\
639 : return ocol;\n\
640 : ";
641 :
642 :
643 : static char *gl_shader_fun_rgb444 = \
644 : "vec4 col, ocol;\n\
645 : float res, col_g, col_b;\n\
646 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
647 : res = floor( 255.0 * col.a );\n\
648 : col_g = floor(res / 16.0);\n\
649 : col_b = floor(res - col_g*16.0);\n\
650 : ocol.r = col.r * 17.0;\n\
651 : ocol.g = col_g / 15.0;\n\
652 : ocol.b = col_b / 15.0;\n\
653 : ocol.a = 1.0;\n\
654 : return ocol;\
655 : ";
656 :
657 :
658 : static char *gl_shader_fun_rgb555 = \
659 : "vec4 col, ocol;\n\
660 : float res, col_r, col_g1, col_g, col_b;\n\
661 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
662 : res = floor(255.0 * col.r);\n\
663 : col_r = floor(res / 4.0);\n\
664 : col_g1 = floor(res - col_r*4.0);\n\
665 : res = floor(255.0 * col.a);\n\
666 : col_g = floor(res / 32);\n\
667 : col_b = floor(res - col_g*32.0);\n\
668 : col_g += col_g1 * 8;\n\
669 : ocol.r = col_r / 31.0;\n\
670 : ocol.g = col_g / 31.0;\n\
671 : ocol.b = col_b / 31.0;\n\
672 : ocol.a = 1.0:\n\
673 : return ocol;\
674 : ";
675 :
676 : static char *gl_shader_fun_rgb565 = \
677 : "vec4 col, ocol;\n\
678 : float res, col_r, col_g1, col_g, col_b;\n\
679 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
680 : res = floor(255.0 * col.r);\n\
681 : col_r = floor(res / 8.0);\n\
682 : col_g1 = floor(res - col_r*8.0);\n\
683 : res = floor(255.0 * col.a);\n\
684 : col_g = floor(res / 32);\n\
685 : col_b = floor(res - col_g*32.0);\n\
686 : col_g += col_g1 * 8;\n\
687 : ocol.r = col_r / 31.0;\n\
688 : ocol.g = col_g / 63.0;\n\
689 : ocol.b = col_b / 31.0;\n\
690 : ocol.a = 1.0;\n\
691 : return ocol;\
692 : ";
693 :
694 :
695 : static char *gl_shader_fun_argb = \
696 : "vec4 col, ocol;\n\
697 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
698 : ocol.r = col.g;\n\
699 : ocol.g = col.b;\n\
700 : ocol.b = col.a;\n\
701 : ocol.a = col.r;\n\
702 : return ocol;\
703 : ";
704 :
705 : static char *gl_shader_fun_abgr = \
706 : "vec4 col, ocol;\n\
707 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
708 : ocol.r = col.a;\n\
709 : ocol.g = col.b;\n\
710 : ocol.b = col.g;\n\
711 : ocol.a = col.r;\n\
712 : return ocol;\
713 : ";
714 :
715 :
716 : static char *gl_shader_fun_bgra = \
717 : "vec4 col, ocol;\n\
718 : col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
719 : ocol.r = col.b;\n\
720 : ocol.g = col.g;\n\
721 : ocol.b = col.r;\n\
722 : ocol.a = col.a;\n\
723 : return ocol;\
724 : ";
725 :
726 :
727 : static char *gl_shader_fun_rgb = \
728 : "return texture2D(_gf_%s_1, _gpacTexCoord.st);\
729 : ";
730 :
731 : static char *gl_shader_vars_externalOES = \
732 : "uniform samplerExternalOES _gf_%s_1;\n\
733 : ";
734 :
735 :
736 157 : Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source)
737 : {
738 : char szCode[4000];
739 : const char *shader_vars = NULL;
740 : const char *shader_fun = NULL;
741 :
742 157 : switch (pix_fmt) {
743 1 : case GF_PIXEL_NV21:
744 : case GF_PIXEL_NV21_10:
745 1 : shader_vars = gl_shader_vars_nv21;
746 1 : shader_fun = gl_shader_fun_nv21;
747 1 : break;
748 1 : case GF_PIXEL_NV12:
749 : case GF_PIXEL_NV12_10:
750 1 : shader_vars = gl_shader_vars_nv12;
751 1 : shader_fun = gl_shader_fun_nv12;
752 1 : break;
753 1 : case GF_PIXEL_UYVY:
754 : case GF_PIXEL_UYVY_10:
755 1 : shader_vars = gl_shader_vars_uyvu;
756 1 : shader_fun = gl_shader_fun_uyvy;
757 1 : break;
758 1 : case GF_PIXEL_YUYV:
759 : case GF_PIXEL_YUYV_10:
760 1 : shader_vars = gl_shader_vars_uyvu; //same as uyvy
761 1 : shader_fun = gl_shader_fun_yuyv;
762 1 : break;
763 1 : case GF_PIXEL_VYUY:
764 : case GF_PIXEL_VYUY_10:
765 1 : shader_vars = gl_shader_vars_uyvu; //same as uyvy
766 1 : shader_fun = gl_shader_fun_vyuy;
767 1 : break;
768 1 : case GF_PIXEL_YVYU:
769 : case GF_PIXEL_YVYU_10:
770 1 : shader_vars = gl_shader_vars_uyvu; //same as uyvy
771 1 : shader_fun = gl_shader_fun_yvyu;
772 1 : break;
773 0 : case GF_PIXEL_YUV444_PACK:
774 0 : shader_vars = gl_shader_vars_yuv4_pack;
775 0 : shader_fun = gl_shader_fun_yuv4_pack;
776 0 : break;
777 0 : case GF_PIXEL_YUVA444_PACK:
778 0 : shader_vars = gl_shader_vars_yuv4_pack;
779 0 : shader_fun = gl_shader_fun_yuv4a_pack;
780 0 : break;
781 0 : case GF_PIXEL_YUV444_10_PACK:
782 0 : shader_vars = gl_shader_vars_yuv4_pack;
783 0 : shader_fun = gl_shader_fun_yuv4_10_pack;
784 0 : break;
785 0 : case GF_PIXEL_ALPHAGREY:
786 0 : shader_vars = gl_shader_vars_rgb;
787 0 : shader_fun = gl_shader_fun_alphagrey;
788 0 : break;
789 0 : case GF_PIXEL_RGB_444:
790 0 : shader_vars = gl_shader_vars_rgb;
791 0 : shader_fun = gl_shader_fun_rgb444;
792 0 : break;
793 0 : case GF_PIXEL_RGB_555:
794 0 : shader_vars = gl_shader_vars_rgb;
795 0 : shader_fun = gl_shader_fun_rgb555;
796 0 : break;
797 0 : case GF_PIXEL_RGB_565:
798 0 : shader_vars = gl_shader_vars_rgb;
799 0 : shader_fun = gl_shader_fun_rgb565;
800 0 : break;
801 1 : case GF_PIXEL_ARGB:
802 : case GF_PIXEL_XRGB:
803 1 : shader_vars = gl_shader_vars_rgb;
804 1 : shader_fun = gl_shader_fun_argb;
805 1 : break;
806 1 : case GF_PIXEL_ABGR:
807 : case GF_PIXEL_XBGR:
808 1 : shader_vars = gl_shader_vars_rgb;
809 1 : shader_fun = gl_shader_fun_abgr;
810 1 : break;
811 2 : case GF_PIXEL_BGR:
812 : case GF_PIXEL_BGRA:
813 : case GF_PIXEL_BGRX:
814 2 : shader_vars = gl_shader_vars_rgb;
815 2 : shader_fun = gl_shader_fun_bgra;
816 2 : break;
817 :
818 22 : case GF_PIXEL_YUV:
819 : case GF_PIXEL_YUV_10:
820 : case GF_PIXEL_YUVD:
821 : case GF_PIXEL_YUV422:
822 : case GF_PIXEL_YUV422_10:
823 : case GF_PIXEL_YUV444:
824 : case GF_PIXEL_YUV444_10:
825 22 : shader_vars = gl_shader_vars_yuv;
826 22 : shader_fun = gl_shader_fun_yuv;
827 22 : break;
828 0 : case GF_PIXEL_YVU:
829 0 : shader_vars = gl_shader_vars_yuv;
830 0 : shader_fun = gl_shader_fun_yvu;
831 0 : break;
832 0 : case GF_PIXEL_YUVA:
833 : case GF_PIXEL_YUVA444:
834 0 : shader_vars = gl_shader_vars_yuva;
835 0 : shader_fun = gl_shader_fun_yuva;
836 0 : break;
837 0 : case GF_PIXEL_GL_EXTERNAL:
838 0 : shader_vars = gl_shader_vars_externalOES;
839 0 : shader_fun = gl_shader_fun_rgb;
840 0 : break;
841 125 : default:
842 125 : shader_vars = gl_shader_vars_rgb;
843 125 : shader_fun = gl_shader_fun_rgb;
844 125 : break;
845 : }
846 :
847 157 : if (!shader_vars || !shader_fun) return GF_FALSE;
848 : /*format with max 4 tx_name (for yuva)*/
849 : sprintf(szCode, shader_vars, tx_name, tx_name, tx_name, tx_name);
850 157 : gf_dynstrcat(f_source, szCode, NULL);
851 :
852 157 : if (gf_pixel_fmt_is_yuv(pix_fmt)) {
853 : // gf_dynstrcat(f_source, gl_shader_yuv_matrix, NULL);
854 :
855 35 : sprintf(szCode, gl_shader_yuv_matrix, tx_name);
856 35 : gf_dynstrcat(f_source, szCode, NULL);
857 : }
858 :
859 157 : gf_dynstrcat(f_source, "\nvec4 ", NULL);
860 157 : gf_dynstrcat(f_source, tx_name, NULL);
861 157 : gf_dynstrcat(f_source, "_sample(vec2 _gpacTexCoord) {\n", NULL);
862 : /*format with max 4 tx_name (for yuva) + matrix for yuv*/
863 : sprintf(szCode, shader_fun, tx_name, tx_name, tx_name, tx_name, tx_name);
864 :
865 157 : gf_dynstrcat(f_source, szCode, NULL);
866 157 : gf_dynstrcat(f_source, "\n}\n", NULL);
867 :
868 157 : return GF_TRUE;
869 : }
870 :
871 :
872 409 : Bool gf_gl_txw_setup(GF_GLTextureWrapper *tx, u32 pix_fmt, u32 width, u32 height, u32 stride, u32 uv_stride, Bool linear_interp, GF_FilterFrameInterface *frame_ifce, Bool full_range, s32 matrix_coef_or_neg)
873 : {
874 : u32 i;
875 :
876 409 : tx->width = width;
877 409 : tx->height = height;
878 409 : tx->pix_fmt = pix_fmt;
879 409 : tx->stride = stride;
880 409 : tx->uv_stride = uv_stride;
881 409 : tx->internal_textures = GF_TRUE;
882 409 : tx->nb_textures = 1;
883 409 : tx->is_yuv = GF_FALSE;
884 409 : tx->bit_depth = 8;
885 409 : tx->gl_format = GL_LUMINANCE;
886 409 : tx->bytes_per_pix = 1;
887 409 : tx->fullrange = full_range;
888 409 : if (matrix_coef_or_neg==GF_CICP_MX_UNSPECIFIED)
889 405 : tx->mx_cicp = -1;
890 : else
891 4 : tx->mx_cicp = matrix_coef_or_neg;
892 :
893 409 : switch (tx->pix_fmt) {
894 1 : case GF_PIXEL_YUV444_10:
895 1 : tx->bit_depth = 10;
896 2 : case GF_PIXEL_YUV444:
897 : case GF_PIXEL_YUVA444:
898 2 : tx->uv_w = tx->width;
899 2 : tx->uv_h = tx->height;
900 2 : if (!tx->uv_stride)
901 0 : tx->uv_stride = tx->stride;
902 2 : tx->is_yuv = GF_TRUE;
903 2 : tx->nb_textures = 3;
904 2 : if (tx->pix_fmt==GF_PIXEL_YUVA444) {
905 0 : tx->nb_textures = 4;
906 0 : tx->has_alpha = GF_TRUE;
907 : }
908 : break;
909 1 : case GF_PIXEL_YUV422_10:
910 1 : tx->bit_depth = 10;
911 2 : case GF_PIXEL_YUV422:
912 2 : tx->uv_w = tx->width/2;
913 2 : tx->uv_h = tx->height;
914 2 : if (!tx->uv_stride)
915 0 : tx->uv_stride = tx->stride/2;
916 2 : tx->is_yuv = GF_TRUE;
917 2 : tx->nb_textures = 3;
918 2 : break;
919 1 : case GF_PIXEL_YUV_10:
920 1 : tx->bit_depth = 10;
921 19 : case GF_PIXEL_YUV:
922 : case GF_PIXEL_YVU:
923 19 : tx->uv_w = tx->width/2;
924 19 : if (tx->width % 2) tx->uv_w++;
925 19 : tx->uv_h = tx->height/2;
926 19 : if (tx->height % 2) tx->uv_h++;
927 19 : if (!tx->uv_stride) {
928 11 : tx->uv_stride = tx->stride/2;
929 11 : if (tx->stride%2) tx->uv_stride ++;
930 : }
931 19 : tx->is_yuv = GF_TRUE;
932 19 : tx->nb_textures = 3;
933 19 : break;
934 0 : case GF_PIXEL_NV12_10:
935 : case GF_PIXEL_NV21_10:
936 0 : tx->bit_depth = 10;
937 2 : case GF_PIXEL_NV12:
938 : case GF_PIXEL_NV21:
939 2 : tx->uv_w = tx->width/2;
940 2 : tx->uv_h = tx->height/2;
941 2 : if (!tx->uv_stride)
942 0 : tx->uv_stride = tx->stride;
943 2 : tx->is_yuv = GF_TRUE;
944 2 : tx->nb_textures = 2;
945 2 : break;
946 0 : case GF_PIXEL_UYVY_10:
947 : case GF_PIXEL_YUYV_10:
948 : case GF_PIXEL_YVYU_10:
949 : case GF_PIXEL_VYUY_10:
950 0 : tx->bit_depth = 16;
951 4 : case GF_PIXEL_UYVY:
952 : case GF_PIXEL_YUYV:
953 : case GF_PIXEL_YVYU:
954 : case GF_PIXEL_VYUY:
955 4 : tx->uv_w = tx->width/2;
956 4 : tx->uv_h = tx->height;
957 4 : if (!tx->uv_stride) {
958 0 : tx->uv_stride = tx->stride/2;
959 0 : if (tx->stride%2) tx->uv_stride ++;
960 : }
961 4 : tx->is_yuv = GF_TRUE;
962 : tx->nb_textures = 1;
963 4 : break;
964 0 : case GF_PIXEL_YUVA444_PACK:
965 0 : tx->has_alpha = GF_TRUE;
966 0 : case GF_PIXEL_YUV444_PACK:
967 : case GF_PIXEL_YUV444_10_PACK:
968 0 : tx->uv_w = tx->width;
969 0 : tx->uv_h = tx->height;
970 0 : if (!tx->uv_stride) {
971 0 : tx->uv_stride = tx->stride;
972 : }
973 0 : tx->is_yuv = GF_TRUE;
974 : tx->nb_textures = 1;
975 0 : break;
976 : case GF_PIXEL_GREYSCALE:
977 : tx->gl_format = GL_LUMINANCE;
978 : tx->bytes_per_pix = 1;
979 : break;
980 0 : case GF_PIXEL_ALPHAGREY:
981 : case GF_PIXEL_GREYALPHA:
982 0 : tx->gl_format = GL_LUMINANCE_ALPHA;
983 0 : tx->bytes_per_pix = 2;
984 0 : break;
985 48 : case GF_PIXEL_RGB:
986 48 : tx->gl_format = GL_RGB;
987 48 : tx->bytes_per_pix = 3;
988 48 : break;
989 1 : case GF_PIXEL_BGR:
990 1 : tx->gl_format = GL_RGB;
991 1 : tx->bytes_per_pix = 3;
992 1 : break;
993 0 : case GF_PIXEL_BGRA:
994 0 : tx->has_alpha = GF_TRUE;
995 1 : case GF_PIXEL_BGRX:
996 1 : tx->gl_format = GL_RGBA;
997 1 : tx->bytes_per_pix = 4;
998 1 : break;
999 0 : case GF_PIXEL_ARGB:
1000 0 : tx->has_alpha = GF_TRUE;
1001 1 : case GF_PIXEL_XRGB:
1002 1 : tx->gl_format = GL_RGBA;
1003 1 : tx->bytes_per_pix = 4;
1004 1 : break;
1005 0 : case GF_PIXEL_ABGR:
1006 0 : tx->has_alpha = GF_TRUE;
1007 1 : case GF_PIXEL_XBGR:
1008 1 : tx->gl_format = GL_RGBA;
1009 1 : tx->bytes_per_pix = 4;
1010 1 : break;
1011 320 : case GF_PIXEL_RGBA:
1012 320 : tx->has_alpha = GF_TRUE;
1013 321 : case GF_PIXEL_RGBX:
1014 321 : tx->gl_format = GL_RGBA;
1015 321 : tx->bytes_per_pix = 4;
1016 321 : break;
1017 0 : case GF_PIXEL_RGB_444:
1018 0 : tx->gl_format = GL_LUMINANCE_ALPHA;
1019 0 : tx->bytes_per_pix = 2;
1020 0 : break;
1021 0 : case GF_PIXEL_RGB_555:
1022 0 : tx->gl_format = GL_LUMINANCE_ALPHA;
1023 0 : tx->bytes_per_pix = 2;
1024 0 : break;
1025 0 : case GF_PIXEL_RGB_565:
1026 0 : tx->gl_format = GL_LUMINANCE_ALPHA;
1027 0 : tx->bytes_per_pix = 2;
1028 0 : break;
1029 0 : case GF_PIXEL_GL_EXTERNAL:
1030 0 : tx->internal_textures = GF_FALSE;
1031 0 : break;
1032 0 : default:
1033 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Pixel format %s unknown, cannot setup texture wrapper\n", gf_4cc_to_str(tx->pix_fmt)));
1034 : return GF_FALSE;
1035 : }
1036 :
1037 409 : if (tx->bit_depth>8)
1038 3 : tx->bytes_per_pix = 2;
1039 :
1040 409 : if (frame_ifce && frame_ifce->get_gl_texture) {
1041 0 : tx->internal_textures = GF_FALSE;
1042 : }
1043 :
1044 : /*create textures*/
1045 409 : if (tx->internal_textures) {
1046 : #if !defined(GPAC_USE_GLES1X)
1047 : u32 glmode = GL_NEAREST;
1048 409 : if ((tx->nb_textures==1) && linear_interp && !tx->is_yuv)
1049 : glmode = GL_LINEAR;
1050 : #endif
1051 409 : tx->first_tx_load = GF_TRUE;
1052 409 : tx->scale_10bit = 0;
1053 :
1054 409 : tx->memory_format = GL_UNSIGNED_BYTE;
1055 409 : if (tx->is_yuv && tx->bit_depth>8) {
1056 : #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1057 : //we use x bits but GL will normalise using 16 bits, so we need to multiply the normalized result by 2^(16-x)
1058 3 : u32 nb_bits = (16 - tx->bit_depth);
1059 : u32 scale = 1;
1060 24 : while (nb_bits) {
1061 18 : scale*=2;
1062 18 : nb_bits--;
1063 : }
1064 3 : tx->scale_10bit = scale;
1065 : #endif
1066 3 : tx->memory_format = GL_UNSIGNED_SHORT;
1067 : }
1068 :
1069 :
1070 : GL_CHECK_ERR()
1071 409 : glGenTextures(tx->nb_textures, tx->textures);
1072 : GL_CHECK_ERR()
1073 :
1074 : #ifndef GPAC_USE_GLES2
1075 409 : glEnable(GL_TEXTURE_2D);
1076 : GL_CHECK_ERR()
1077 : #endif
1078 :
1079 866 : for (i=0; i<tx->nb_textures; i++) {
1080 : #if !defined(GPAC_USE_GLES1X)
1081 457 : glBindTexture(GL_TEXTURE_2D, tx->textures[i] );
1082 : GL_CHECK_ERR()
1083 : #if defined(GPAC_USE_GLES2)
1084 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1085 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1086 : #else
1087 457 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1088 457 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1089 : #endif
1090 457 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);
1091 457 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode);
1092 : #endif
1093 : }
1094 :
1095 :
1096 : #if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1097 409 : if (tx->is_yuv && tx->pbo_state) {
1098 0 : tx->first_tx_load = GF_FALSE;
1099 0 : glGenBuffers(1, &tx->PBOs[0]);
1100 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1101 :
1102 0 : if (tx->nb_textures>1) {
1103 0 : glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->width*tx->height, NULL, GL_DYNAMIC_DRAW_ARB);
1104 :
1105 0 : glGenBuffers(1, &tx->PBOs[1]);
1106 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1107 : } else {
1108 : //packed YUV
1109 0 : glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 4*tx->width/2*tx->height, NULL, GL_DYNAMIC_DRAW_ARB);
1110 : }
1111 :
1112 0 : if (tx->nb_textures==3) {
1113 0 : glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1114 :
1115 0 : glGenBuffers(1, &tx->PBOs[2]);
1116 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1117 0 : glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1118 : }
1119 : //nv12/21
1120 : else {
1121 0 : glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 2*tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1122 : }
1123 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1124 : }
1125 : #endif
1126 :
1127 : #ifndef GPAC_USE_GLES2
1128 409 : glDisable(GL_TEXTURE_2D);
1129 : GL_CHECK_ERR()
1130 : #endif
1131 : }
1132 : return GF_TRUE;
1133 : }
1134 :
1135 4242 : Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce)
1136 : {
1137 : Bool use_stride = GF_FALSE;
1138 : u32 stride_luma, stride_chroma;
1139 4242 : const u8 *pY=NULL, *pU=NULL, *pV=NULL, *pA=NULL;
1140 :
1141 :
1142 4242 : tx->frame_ifce = NULL;
1143 :
1144 4242 : if (!frame_ifce && !data) return GF_FALSE;
1145 :
1146 4242 : if (!tx->internal_textures) {
1147 0 : if (frame_ifce && frame_ifce->get_gl_texture) {
1148 0 : tx->frame_ifce = frame_ifce;
1149 0 : return GF_TRUE;
1150 : }
1151 : return GF_FALSE;
1152 : }
1153 :
1154 4242 : stride_luma = tx->stride;
1155 4242 : stride_chroma = tx->uv_stride;
1156 4242 : if (!frame_ifce) {
1157 4242 : if (tx->is_yuv) {
1158 1540 : if (tx->nb_textures==2) {
1159 2 : if (tx->has_alpha) {
1160 0 : pA = data + tx->stride * tx->height;
1161 : } else {
1162 2 : pU = data + tx->stride * tx->height;
1163 : }
1164 1538 : } else if (tx->nb_textures>=3) {
1165 1534 : pU = data + tx->stride * tx->height;
1166 1534 : pV = pU + tx->uv_stride * tx->uv_h;
1167 1534 : if (tx->nb_textures==4) {
1168 0 : pA = pV + tx->uv_stride * tx->uv_h;
1169 : }
1170 : }
1171 : }
1172 : } else {
1173 : u32 st_o;
1174 0 : if (tx->nb_textures)
1175 0 : frame_ifce->get_plane(frame_ifce, 0, &data, &stride_luma);
1176 0 : if (tx->nb_textures>1)
1177 0 : frame_ifce->get_plane(frame_ifce, 1, &pU, &stride_chroma);
1178 : //todo we need to cleanup alpha frame fetch, how do we differentiate between NV12+alpha (3 planes) and YUV420 ?
1179 0 : if (tx->nb_textures>2)
1180 0 : frame_ifce->get_plane(frame_ifce, 2, &pV, &st_o);
1181 0 : if (tx->nb_textures>3)
1182 0 : frame_ifce->get_plane(frame_ifce, 3, &pA, &st_o);
1183 : }
1184 :
1185 4242 : pY = data;
1186 :
1187 4242 : if (tx->is_yuv && (stride_luma != tx->width)) {
1188 : use_stride = GF_TRUE; //whether >8bits or real stride
1189 : }
1190 : GL_CHECK_ERR()
1191 :
1192 : //push data
1193 : #ifndef GPAC_USE_GLES2
1194 4242 : glEnable(GL_TEXTURE_2D);
1195 : GL_CHECK_ERR()
1196 : #endif
1197 :
1198 :
1199 4242 : if (tx->scale_10bit) {
1200 : #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1201 3 : glPixelTransferi(GL_RED_SCALE, tx->scale_10bit);
1202 3 : if (tx->nb_textures==2)
1203 0 : glPixelTransferi(GL_ALPHA_SCALE, tx->scale_10bit);
1204 :
1205 3 : glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
1206 : #endif
1207 : } else {
1208 : #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1209 4239 : glPixelTransferi(GL_RED_SCALE, 1);
1210 4239 : glPixelTransferi(GL_ALPHA_SCALE, 1);
1211 4239 : glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
1212 : #endif
1213 4239 : glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1214 : }
1215 : GL_CHECK_ERR()
1216 :
1217 :
1218 4242 : if (!tx->is_yuv) {
1219 2702 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1220 : GL_CHECK_ERR()
1221 2702 : if (use_stride) {
1222 : #if !defined(GPAC_GL_NO_STRIDE)
1223 0 : glPixelStorei(GL_UNPACK_ROW_LENGTH, tx->stride / tx->bytes_per_pix);
1224 : #endif
1225 : }
1226 2702 : if (tx->first_tx_load) {
1227 375 : glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, GL_UNSIGNED_BYTE, data);
1228 375 : tx->first_tx_load = GF_FALSE;
1229 : } else {
1230 2327 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, data);
1231 : }
1232 : #if !defined(GPAC_GL_NO_STRIDE)
1233 2702 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1234 : #endif
1235 :
1236 : GL_CHECK_ERR()
1237 : }
1238 : #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1239 1540 : else if (tx->pbo_state && tx->PBOs[0]) {
1240 : u32 i, linesize, count, p_stride;
1241 : u8 *ptr;
1242 :
1243 : //packed YUV
1244 0 : if (tx->nb_textures==1) {
1245 0 : if (tx->pbo_state!=GF_GL_PBO_TEXIMG) {
1246 0 : glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1247 :
1248 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1249 0 : ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1250 :
1251 0 : if (tx->pix_fmt==GF_PIXEL_YUV444_PACK)
1252 0 : linesize = 3 * tx->width;
1253 0 : else if (tx->pix_fmt==GF_PIXEL_YUVA444_PACK)
1254 0 : linesize = 4 * tx->width;
1255 0 : else if (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK)
1256 0 : linesize = 4 * tx->width;
1257 : else
1258 0 : linesize = tx->width/2 * tx->bytes_per_pix * 4;
1259 :
1260 0 : p_stride = stride_luma;
1261 0 : count = tx->height;
1262 :
1263 0 : for (i=0; i<count; i++) {
1264 0 : memcpy(ptr, pY, linesize);
1265 0 : pY += p_stride;
1266 0 : ptr += linesize;
1267 : }
1268 :
1269 0 : glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1270 : }
1271 0 : if (tx->pbo_state!=GF_GL_PBO_PUSH) {
1272 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1273 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1274 :
1275 0 : if (tx->pix_fmt==GF_PIXEL_YUV444_PACK)
1276 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx->width, tx->height, 0, GL_RGB, tx->memory_format, NULL);
1277 0 : else if (tx->pix_fmt==GF_PIXEL_YUVA444_PACK)
1278 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1279 0 : else if (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK)
1280 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1281 : else
1282 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1283 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1284 : }
1285 : } else {
1286 0 : if (tx->pbo_state!=GF_GL_PBO_TEXIMG) {
1287 0 : glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1288 :
1289 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1290 0 : ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1291 :
1292 0 : linesize = tx->width*tx->bytes_per_pix;
1293 0 : p_stride = stride_luma;
1294 0 : count = tx->height;
1295 :
1296 0 : for (i=0; i<count; i++) {
1297 0 : memcpy(ptr, pY, linesize);
1298 0 : pY += p_stride;
1299 0 : ptr += linesize;
1300 : }
1301 :
1302 0 : glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1303 :
1304 0 : if (pU) {
1305 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1306 0 : ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1307 :
1308 0 : linesize = tx->uv_w * tx->bytes_per_pix;
1309 0 : p_stride = stride_chroma;
1310 0 : count = tx->uv_h;
1311 : //NV12 and NV21
1312 0 : if (!pV) {
1313 0 : linesize *= 2;
1314 : }
1315 :
1316 0 : for (i=0; i<count; i++) {
1317 0 : memcpy(ptr, pU, linesize);
1318 0 : pU += p_stride;
1319 0 : ptr += linesize;
1320 : }
1321 :
1322 0 : glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1323 : }
1324 :
1325 :
1326 0 : if (pV) {
1327 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1328 0 : ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1329 :
1330 0 : for (i=0; i<count; i++) {
1331 0 : memcpy(ptr, pV, linesize);
1332 0 : pV += p_stride;
1333 0 : ptr += linesize;
1334 : }
1335 :
1336 0 : glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1337 : }
1338 : }
1339 :
1340 0 : if (tx->pbo_state!=GF_GL_PBO_PUSH) {
1341 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1342 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1343 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, NULL);
1344 :
1345 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1346 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1347 0 : glTexImage2D(GL_TEXTURE_2D, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->uv_w, tx->uv_h, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->memory_format, NULL);
1348 :
1349 0 : if (pV) {
1350 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1351 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1352 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, NULL);
1353 : }
1354 :
1355 0 : glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1356 : }
1357 : }
1358 : }
1359 : #endif
1360 1540 : else if ((tx->nb_textures==1) || ((tx->nb_textures==2) && tx->has_alpha)) {
1361 : u32 uv_stride = 0;
1362 4 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1363 :
1364 : use_stride = GF_FALSE;
1365 4 : if ((tx->pix_fmt==GF_PIXEL_YUV444_PACK) || (tx->pix_fmt==GF_PIXEL_YUVA444_PACK) || (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK)) {
1366 : u32 nb_bytes = 3;
1367 : GLuint fmt = GL_RGB;
1368 0 : if (tx->pix_fmt!=GF_PIXEL_YUV444_PACK) {
1369 : nb_bytes = 4;
1370 : fmt = GL_RGBA;
1371 : }
1372 0 : if (stride_luma > nb_bytes*tx->width) {
1373 : use_stride = GF_TRUE;
1374 : }
1375 :
1376 : #if !defined(GPAC_GL_NO_STRIDE)
1377 0 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1378 : #endif
1379 0 : if (tx->first_tx_load) {
1380 0 : glTexImage2D(GL_TEXTURE_2D, 0, fmt, tx->width, tx->height, 0, fmt, tx->memory_format, pY);
1381 0 : tx->first_tx_load = GF_FALSE;
1382 : } else {
1383 0 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, fmt, tx->memory_format, pY);
1384 : }
1385 :
1386 : } else {
1387 4 : u32 scaler = tx->scale_10bit ? 4 : 2;
1388 4 : if (stride_luma > scaler*tx->width) {
1389 : //stride is given in bytes for packed formats, so divide by 2 to get the number of pixels
1390 : //for YUYV, and we upload as a texture with half the wsize so redivide again by two
1391 : //since GL_UNPACK_ROW_LENGTH counts in component and we moved the set 2 bytes per comp on 10 bits
1392 : //no need to further divide
1393 0 : uv_stride = stride_luma/scaler/2;
1394 : use_stride = GF_TRUE;
1395 : }
1396 : #if !defined(GPAC_GL_NO_STRIDE)
1397 0 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, uv_stride);
1398 : #endif
1399 4 : if (tx->first_tx_load) {
1400 4 : glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, pY);
1401 4 : tx->first_tx_load = GF_FALSE;
1402 : } else {
1403 0 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width/2, tx->height, GL_RGBA, tx->memory_format, pY);
1404 : }
1405 : }
1406 :
1407 : #if !defined(GPAC_GL_NO_STRIDE)
1408 4 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1409 : #endif
1410 :
1411 : }
1412 1536 : else if (tx->first_tx_load) {
1413 25 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1414 : #if !defined(GPAC_GL_NO_STRIDE)
1415 25 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1416 : #endif
1417 25 : glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pY);
1418 :
1419 25 : glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1420 : #if !defined(GPAC_GL_NO_STRIDE)
1421 25 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2);
1422 : #endif
1423 25 : glTexImage2D(GL_TEXTURE_2D, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->uv_w, tx->uv_h, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->memory_format, pU);
1424 :
1425 25 : if (pV) {
1426 23 : glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1427 : #if !defined(GPAC_GL_NO_STRIDE)
1428 23 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix);
1429 : #endif
1430 23 : glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, pV);
1431 : }
1432 :
1433 25 : if (pA) {
1434 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[3] );
1435 : #if !defined(GPAC_GL_NO_STRIDE)
1436 0 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1437 : #endif
1438 0 : glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pA);
1439 : }
1440 :
1441 : #if !defined(GPAC_GL_NO_STRIDE)
1442 25 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1443 : #endif
1444 25 : tx->first_tx_load = GF_FALSE;
1445 : }
1446 : else {
1447 1511 : glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1448 : #if !defined(GPAC_GL_NO_STRIDE)
1449 1511 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1450 : #endif
1451 1511 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pY);
1452 1511 : glBindTexture(GL_TEXTURE_2D, 0);
1453 :
1454 1511 : glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1455 : #if !defined(GPAC_GL_NO_STRIDE)
1456 1511 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2);
1457 : #endif
1458 1511 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->memory_format, pU);
1459 1511 : glBindTexture(GL_TEXTURE_2D, 0);
1460 :
1461 1511 : if (pV) {
1462 1511 : glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1463 : #if !defined(GPAC_GL_NO_STRIDE)
1464 1511 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix);
1465 : #endif
1466 1511 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, tx->gl_format, tx->memory_format, pV);
1467 1511 : glBindTexture(GL_TEXTURE_2D, 0);
1468 : }
1469 :
1470 1511 : if (pA) {
1471 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[3] );
1472 : #if !defined(GPAC_GL_NO_STRIDE)
1473 0 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1474 : #endif
1475 0 : glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pA);
1476 0 : glBindTexture(GL_TEXTURE_2D, 0);
1477 : }
1478 :
1479 : #if !defined(GPAC_GL_NO_STRIDE)
1480 1511 : if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1481 : #endif
1482 : }
1483 :
1484 : //restore red/alpha scale
1485 4242 : if (tx->scale_10bit) {
1486 : #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1487 3 : glPixelTransferi(GL_RED_SCALE, 1);
1488 3 : glPixelTransferi(GL_ALPHA_SCALE, 1);
1489 3 : glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
1490 : #endif
1491 3 : glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1492 : }
1493 :
1494 : return GF_TRUE;
1495 : }
1496 :
1497 :
1498 : struct yuv_coefs {
1499 : u32 cicp;
1500 : Double Kr, Kb;
1501 : } YUVMatrices[] = {
1502 : {GF_CICP_MX_BT709, 0.2126, 0.0722},
1503 : {GF_CICP_MX_FCC47, 0.3, 0.11},
1504 : {GF_CICP_MX_BT601_625, 0.299, 0.114},
1505 : {GF_CICP_MX_SMPTE240, 0.299, 0.114},
1506 : {GF_CICP_MX_SMPTE240, 0.212, 0.087},
1507 : {GF_CICP_MX_BT2020, 0.2627, 0.0593},
1508 : {GF_CICP_MX_BT2020_CL, 0.2627, 0.0593}
1509 : };
1510 :
1511 29 : static void get_yuv_color_matrix(GF_GLTextureWrapper *tx, GF_Matrix *mx)
1512 : {
1513 : Double Kg;
1514 : struct yuv_coefs *yc = NULL;
1515 :
1516 : //setup YUV->RGB matrix, in row-major
1517 58 : gf_mx_init(*mx);
1518 :
1519 29 : if (tx->mx_cicp>=0) {
1520 : u32 i, count=GF_ARRAY_LENGTH(YUVMatrices);
1521 2 : u32 mx_code = (u32) tx->mx_cicp;
1522 :
1523 2 : if (mx_code==GF_CICP_MX_IDENTITY) {
1524 : return;
1525 : }
1526 :
1527 0 : if (mx_code==GF_CICP_MX_YCgCo) {
1528 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YCgCo matrix not supported, will use BT709\n"));
1529 : yc = &YUVMatrices[1];
1530 : }
1531 0 : else if (mx_code==GF_CICP_MX_YDzDx) {
1532 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YDxDy matrix not supported, will use BT709\n"));
1533 : yc = &YUVMatrices[1];
1534 : } else {
1535 0 : for (i=0; i<count; i++) {
1536 0 : if (YUVMatrices[i].cicp == mx_code) {
1537 0 : yc = &YUVMatrices[i];
1538 : break;
1539 : }
1540 : }
1541 0 : if (!yc) {
1542 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GL] Unrecognized matrix coefficient value %d, will use BT709\n", mx_code));
1543 : yc = &YUVMatrices[1];
1544 : }
1545 : }
1546 : } else {
1547 : yc = &YUVMatrices[1];
1548 : }
1549 :
1550 27 : Kg = 1.0 - yc->Kr - yc->Kb;
1551 :
1552 27 : mx->m[0] = 1.0f;
1553 27 : mx->m[2] = (Float) (2.0 * (1.0 - yc->Kr) );
1554 :
1555 27 : mx->m[4] = 1.0;
1556 27 : mx->m[5] = (Float) ( - 2.0 * (1.0 - yc->Kb) * yc->Kb / Kg );
1557 27 : mx->m[6] = (Float) ( - 2.0 * (1.0 - yc->Kr) * yc->Kr / Kg );
1558 :
1559 27 : mx->m[8] = 1.0f;
1560 27 : mx->m[9] = (Float) (2.0 * (1.0 - yc->Kb) );
1561 27 : mx->m[10] = 0.0;
1562 :
1563 : //move to column major
1564 27 : gf_mx_transpose(mx);
1565 :
1566 27 : if (tx->fullrange) {
1567 0 : gf_mx_add_translation(mx, 0, FLT2FIX(-0.5), FLT2FIX(-0.5));
1568 : } else {
1569 27 : gf_mx_add_scale(mx, FLT2FIX(255.0/216.0), FLT2FIX(255.0/224.0), FLT2FIX(255.0/224.0) );
1570 27 : gf_mx_add_translation(mx, FLT2FIX(-0.0625), FLT2FIX(-0.5), FLT2FIX(-0.5));
1571 : }
1572 :
1573 27 : GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[GL] YUV2RGB matrix is (column-major):\n"
1574 : "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1575 : "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1576 : "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1577 : "\t%.4f\t%.4f\t%.4f\t%.4f\n",
1578 : mx->m[0], mx->m[1], mx->m[2], mx->m[3],
1579 : mx->m[4], mx->m[5], mx->m[6], mx->m[7],
1580 : mx->m[8], mx->m[9], mx->m[10], mx->m[11],
1581 : mx->m[12], mx->m[13], mx->m[14], mx->m[15]
1582 : ));
1583 :
1584 : }
1585 :
1586 :
1587 18353 : Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit)
1588 : {
1589 18353 : if (!texture_unit)
1590 : texture_unit = GL_TEXTURE0;
1591 :
1592 : #if !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X)
1593 18353 : if (!tx->uniform_setup && gl_program) {
1594 : char szName[100];
1595 : u32 i;
1596 415 : u32 start_idx = texture_unit - GL_TEXTURE0;
1597 : s32 loc;
1598 1284 : for (i=0; i<tx->nb_textures; i++) {
1599 454 : sprintf(szName, "_gf_%s_%d", tx_name, i+1);
1600 454 : loc = glGetUniformLocation(gl_program, szName);
1601 : GL_CHECK_ERR()
1602 454 : if (loc == -1) {
1603 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate texture %s in shader\n", szName));
1604 0 : return GF_FALSE;
1605 : }
1606 454 : glUniform1i(loc, start_idx + i);
1607 : GL_CHECK_ERR()
1608 : }
1609 : GL_CHECK_ERR()
1610 :
1611 415 : if (tx->is_yuv) {
1612 : GF_Matrix mx;
1613 29 : get_yuv_color_matrix(tx, &mx);
1614 : sprintf(szName, "_gf_%s_mx", tx_name);
1615 29 : loc = glGetUniformLocation(gl_program, szName);
1616 29 : if (loc == -1) {
1617 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate texture %s in shader\n", szName));
1618 0 : return GF_FALSE;
1619 : }
1620 29 : glUniformMatrix4fv(loc, 1, GL_FALSE, mx.m);
1621 : }
1622 415 : switch (tx->pix_fmt) {
1623 : case GF_PIXEL_UYVY:
1624 : case GF_PIXEL_YUYV:
1625 : case GF_PIXEL_VYUY:
1626 : case GF_PIXEL_YVYU:
1627 : case GF_PIXEL_UYVY_10:
1628 : case GF_PIXEL_YUYV_10:
1629 : case GF_PIXEL_VYUY_10:
1630 : case GF_PIXEL_YVYU_10:
1631 : sprintf(szName, "_gf_%s_width", tx_name);
1632 4 : loc = glGetUniformLocation(gl_program, szName);
1633 4 : if (loc == -1) {
1634 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate uniform %s in shader\n", szName));
1635 : return GF_FALSE;
1636 : }
1637 4 : glUniform1f(loc, (GLfloat) tx->width);
1638 4 : break;
1639 : default:
1640 : break;
1641 : }
1642 415 : tx->uniform_setup = GF_TRUE;
1643 : }
1644 : #endif // !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X)
1645 :
1646 : GL_CHECK_ERR()
1647 :
1648 18353 : if (!tx->internal_textures) {
1649 : u32 i;
1650 : GF_Matrix txmx;
1651 :
1652 429 : gf_mx_init(txmx);
1653 1102 : for (i=0; i<tx->nb_textures; i++) {
1654 122 : u32 gl_format = GL_TEXTURE_2D;
1655 122 : if (tx->frame_ifce && tx->frame_ifce->get_gl_texture(tx->frame_ifce, i, &gl_format, &tx->textures[i], &txmx) != GF_OK) {
1656 0 : if (!i) {
1657 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to get frame interface OpenGL texture ID for plane %d\n", i));
1658 0 : return GF_FALSE;
1659 : }
1660 0 : break;
1661 : }
1662 : #ifndef GPAC_USE_GLES2
1663 122 : if (!gl_program)
1664 0 : glEnable(gl_format);
1665 : #endif
1666 122 : if (!tx->textures[i])
1667 : break;
1668 122 : glActiveTexture(texture_unit + i);
1669 122 : glBindTexture(gl_format, tx->textures[i]);
1670 122 : glTexParameteri(gl_format, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1671 122 : glTexParameteri(gl_format, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1672 122 : glTexParameteri(gl_format, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1673 122 : glTexParameteri(gl_format, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1674 : /*todo pass matrix to shader !!*/
1675 : }
1676 429 : tx->flip = (txmx.m[5]<0) ? GF_TRUE : GF_FALSE;
1677 :
1678 429 : if (tx->nb_textures) {
1679 : #ifndef GPAC_USE_GLES2
1680 122 : glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1681 122 : glClientActiveTexture(texture_unit);
1682 : #endif
1683 : }
1684 : return GF_TRUE;
1685 : }
1686 17924 : if (tx->nb_textures>3) {
1687 0 : glActiveTexture(texture_unit + 3);
1688 0 : glBindTexture(GL_TEXTURE_2D, tx->textures[3]);
1689 : }
1690 17924 : if (tx->nb_textures>2) {
1691 4094 : glActiveTexture(texture_unit + 2);
1692 4094 : glBindTexture(GL_TEXTURE_2D, tx->textures[2]);
1693 : }
1694 17924 : if (tx->nb_textures>1) {
1695 4096 : glActiveTexture(texture_unit + 1);
1696 4096 : glBindTexture(GL_TEXTURE_2D, tx->textures[1]);
1697 : }
1698 17924 : if (tx->nb_textures) {
1699 17924 : glActiveTexture(texture_unit);
1700 17924 : glBindTexture(GL_TEXTURE_2D, tx->textures[0]);
1701 :
1702 : #ifndef GPAC_USE_GLES2
1703 17924 : glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1704 17924 : glClientActiveTexture(texture_unit);
1705 : #endif
1706 : }
1707 :
1708 : #ifndef GPAC_USE_GLES2
1709 17924 : glEnable(GL_TEXTURE_2D);
1710 : #endif
1711 :
1712 : GL_CHECK_ERR()
1713 17924 : return GF_TRUE;
1714 : }
1715 :
1716 1822 : void gf_gl_txw_reset(GF_GLTextureWrapper *tx)
1717 : {
1718 1822 : if (tx->nb_textures) {
1719 404 : if (tx->internal_textures) {
1720 403 : glDeleteTextures(tx->nb_textures, tx->textures);
1721 403 : if (tx->pbo_state && tx->PBOs[0]) {
1722 0 : glDeleteBuffers(tx->nb_textures, tx->PBOs);
1723 : }
1724 : }
1725 404 : tx->nb_textures = 0;
1726 : }
1727 1822 : tx->width = 0;
1728 1822 : tx->height = 0;
1729 1822 : tx->pix_fmt = 0;
1730 1822 : tx->stride = 0;
1731 1822 : tx->uv_stride = 0;
1732 1822 : tx->internal_textures = GF_FALSE;
1733 1822 : tx->uniform_setup = GF_FALSE;
1734 1822 : }
1735 :
1736 : #else
1737 :
1738 : void gf_opengl_init()
1739 : {
1740 : }
1741 :
1742 : Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source)
1743 : {
1744 : return GF_FALSE;
1745 : }
1746 : Bool gf_gl_txw_setup(GF_GLTextureWrapper *tx, u32 pix_fmt, u32 width, u32 height, u32 stride, u32 uv_stride, Bool linear_interp, GF_FilterFrameInterface *frame_ifce, Bool full_range, s32 matrix_coef_or_neg)
1747 : {
1748 : return GF_FALSE;
1749 : }
1750 :
1751 : Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce)
1752 : {
1753 : return GF_FALSE;
1754 : }
1755 :
1756 : Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit)
1757 : {
1758 : return GF_FALSE;
1759 : }
1760 : void gf_gl_txw_reset(GF_GLTextureWrapper *tx)
1761 : {
1762 : }
1763 :
1764 : #endif //GPAC_DISABLE_3D
|