Coverage Report

Created: 2026-01-09 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/utils/gltools.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2022
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
void gf_opengl_init()
197
{
198
  if (gl_fun_loaded) return;
199
  gl_fun_loaded = GF_TRUE;
200
201
202
#ifndef GPAC_USE_TINYGL
203
204
#ifdef LOAD_GL_1_3
205
  GET_GLFUN(glActiveTexture);
206
  GET_GLFUN(glClientActiveTexture);
207
  GET_GLFUN(glBlendEquation);
208
#endif
209
210
#ifdef LOAD_GL_1_4
211
  GET_GLFUN(glPointParameterf);
212
  GET_GLFUN(glPointParameterfv);
213
#endif
214
215
#ifdef LOAD_GL_1_5
216
  GET_GLFUN(glGenBuffers);
217
  GET_GLFUN(glDeleteBuffers);
218
  GET_GLFUN(glBindBuffer);
219
  GET_GLFUN(glBufferData);
220
  GET_GLFUN(glBufferSubData);
221
222
  GET_GLFUN(glMapBuffer);
223
  GET_GLFUN(glUnmapBuffer);
224
#endif
225
226
227
#ifdef LOAD_GL_2_0
228
  GET_GLFUN(glCreateProgram);
229
230
  GET_GLFUN(glDeleteProgram);
231
  GET_GLFUN(glLinkProgram);
232
  GET_GLFUN(glUseProgram);
233
  GET_GLFUN(glCreateShader);
234
  GET_GLFUN(glDeleteShader);
235
  GET_GLFUN(glShaderSource);
236
  GET_GLFUN(glCompileShader);
237
  GET_GLFUN(glAttachShader);
238
  GET_GLFUN(glDetachShader);
239
  GET_GLFUN(glGetShaderiv);
240
  GET_GLFUN(glGetInfoLogARB);
241
  GET_GLFUN(glGetUniformLocation);
242
  GET_GLFUN(glGetUniformfv);
243
  GET_GLFUN(glGetUniformiv);
244
  GET_GLFUN(glUniform1f);
245
  GET_GLFUN(glUniform2f);
246
  GET_GLFUN(glUniform3f);
247
  GET_GLFUN(glUniform4f);
248
  GET_GLFUN(glUniform1i);
249
  GET_GLFUN(glUniform2i);
250
  GET_GLFUN(glUniform3i);
251
  GET_GLFUN(glUniform4i);
252
  GET_GLFUN(glUniform1fv);
253
  GET_GLFUN(glUniform2fv);
254
  GET_GLFUN(glUniform3fv);
255
  GET_GLFUN(glUniform4fv);
256
  GET_GLFUN(glUniform1iv);
257
  GET_GLFUN(glUniform2iv);
258
  GET_GLFUN(glUniform3iv);
259
  GET_GLFUN(glUniform4iv);
260
  GET_GLFUN(glUniformMatrix2fv);
261
  GET_GLFUN(glUniformMatrix3fv);
262
  GET_GLFUN(glUniformMatrix4fv);
263
  GET_GLFUN(glUniformMatrix2x3fv);
264
  GET_GLFUN(glUniformMatrix3x2fv);
265
  GET_GLFUN(glUniformMatrix2x4fv);
266
  GET_GLFUN(glUniformMatrix4x2fv);
267
  GET_GLFUN(glUniformMatrix3x4fv);
268
  GET_GLFUN(glUniformMatrix4x3fv);
269
  GET_GLFUN(glGetProgramiv);
270
  GET_GLFUN(glGetProgramInfoLog);
271
  GET_GLFUN(glBlendColor);
272
  GET_GLFUN(glBlendEquationSeparate);
273
  GET_GLFUN(glBlendFuncSeparate);
274
  GET_GLFUN(glCompressedTexImage2D);
275
  GET_GLFUN(glCompressedTexSubImage2D);
276
  GET_GLFUN(glGenerateMipmap);
277
  GET_GLFUN(glGetShaderInfoLog);
278
  GET_GLFUN(glGetShaderSource);
279
  GET_GLFUN(glGetActiveAttrib);
280
  GET_GLFUN(glGetActiveUniform);
281
  GET_GLFUN(glGetAttachedShaders);
282
  GET_GLFUN(glBindAttribLocation);
283
  GET_GLFUN(glIsBuffer);
284
  GET_GLFUN(glIsFramebuffer);
285
  GET_GLFUN(glIsProgram);
286
  GET_GLFUN(glIsRenderbuffer);
287
  GET_GLFUN(glIsShader);
288
  GET_GLFUN(glSampleCoverage);
289
  GET_GLFUN(glStencilFuncSeparate);
290
  GET_GLFUN(glStencilOpSeparate);
291
  GET_GLFUN(glStencilMaskSeparate);
292
  GET_GLFUN(glValidateProgram);
293
  GET_GLFUN(glVertexAttrib1fv);
294
  GET_GLFUN(glVertexAttrib1f);
295
  GET_GLFUN(glVertexAttrib2f);
296
  GET_GLFUN(glVertexAttrib2fv);
297
  GET_GLFUN(glVertexAttrib3f);
298
  GET_GLFUN(glVertexAttrib3fv);
299
  GET_GLFUN(glVertexAttrib4f);
300
  GET_GLFUN(glVertexAttrib4fv);
301
  GET_GLFUN(glGetBufferParameteriv);
302
  GET_GLFUN(glGetFramebufferAttachmentParameteriv);
303
  GET_GLFUN(glGetVertexAttribiv);
304
  GET_GLFUN(glGetVertexAttribfv);
305
  GET_GLFUN(glGetVertexAttribPointerv);
306
  GET_GLFUN(glGetRenderbufferParameteriv);
307
308
#ifndef GPAC_CONFIG_ANDROID
309
  GET_GLFUN(glEnableVertexAttribArray);
310
  GET_GLFUN(glDisableVertexAttribArray);
311
  GET_GLFUN(glVertexAttribPointer);
312
  GET_GLFUN(glVertexAttribIPointer);
313
  GET_GLFUN(glGetAttribLocation);
314
315
  GET_GLFUN(glBindFramebuffer);
316
  GET_GLFUN(glFramebufferTexture2D);
317
  GET_GLFUN(glGenFramebuffers);
318
  GET_GLFUN(glGenRenderbuffers);
319
  GET_GLFUN(glBindRenderbuffer);
320
  GET_GLFUN(glRenderbufferStorage);
321
  GET_GLFUN(glFramebufferRenderbuffer);
322
  GET_GLFUN(glDeleteFramebuffers);
323
  GET_GLFUN(glDeleteRenderbuffers);
324
  GET_GLFUN(glCheckFramebufferStatus);
325
326
#endif
327
328
#endif //LOAD_GL_2_0
329
330
#endif //GPAC_USE_TINYGL
331
332
}
333
334
static char *gl_shader_yuv_matrix = \
335
"uniform mat4 _gf_%s_mx;\n\
336
";
337
338
339
#if 0 //old code
340
static char *gl_shader_yuv_coefs = \
341
"const vec3 offset = vec3(-0.0625, -0.5, -0.5);\n\
342
const vec3 R_mul = vec3(1.164,  0.000,  1.596);\n\
343
const vec3 G_mul = vec3(1.164, -0.391, -0.813);\n\
344
const vec3 B_mul = vec3(1.164,  2.018,  0.000);\n\
345
";
346
347
static char *gl_shader_yuv_coefs_jpeg = \
348
"const vec3 offset = vec3(0.0, -0.5, -0.5);\n\
349
const vec3 R_mul = vec3(1,  0.000,  1.40200);\n\
350
const vec3 G_mul = vec3(1, -0.34414, -0.71414);\n\
351
const vec3 B_mul = vec3(1,  1.77200,  0.000);\n\
352
";
353
#endif
354
355
static char *gl_shader_vars_yuv = \
356
"uniform sampler2D _gf_%s_1;\n\
357
uniform sampler2D _gf_%s_2;\n\
358
uniform sampler2D _gf_%s_3;\n\
359
";
360
361
#if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2)
362
static char *gl_shader_fun_yuv_gles10 = \
363
"vec2 texc;\n\
364
vec4 yuv, col;\n\
365
texc = _gpacTexCoord.st;\n\
366
col = texture2D(_gf_%s_1, texc);\n\
367
yuv.x = (col.a*65280.0 + col.r*255.0)/1023.0;\n\
368
col = texture2D(_gf_%s_2, texc);\n\
369
yuv.y = (col.a*65280.0 + col.r*255.0)/1023.0;\n\
370
col = texture2D(_gf_%s_3, texc);\n\
371
yuv.z = (col.a*65280.0 + col.r*255.0)/1023.0;\n\
372
yuv.w = 1.0;\n\
373
yuv = _gf_%s_mx * yuv;\n\
374
yuv.w = 1.0;\n\
375
return yuv;\n\
376
";
377
#endif
378
379
static char *gl_shader_fun_yuv = \
380
"vec2 texc;\n\
381
vec4 yuv;\n\
382
texc = _gpacTexCoord.st;\n\
383
yuv.x = texture2D(_gf_%s_1, texc).r;\n\
384
yuv.y = texture2D(_gf_%s_2, texc).r;\n\
385
yuv.z = texture2D(_gf_%s_3, texc).r;\n\
386
yuv.w = 1.0;\n\
387
yuv = _gf_%s_mx * yuv;\n\
388
yuv.w = 1.0;\n\
389
return yuv;\n\
390
";
391
392
393
static char *gl_shader_fun_yvu = \
394
"vec2 texc;\n\
395
vec4 yuv;\n\
396
texc = _gpacTexCoord.st;\n\
397
yuv.x = texture2D(_gf_%s_1, texc).r;\n\
398
yuv.y = texture2D(_gf_%s_3, texc).r;\n\
399
yuv.z = texture2D(_gf_%s_2, texc).r;\n\
400
yuv.w = 1.0;\n\
401
yuv = _gf_%s_mx * yuv;\n\
402
yuv.w = 1.0;\n\
403
return yuv;\n\
404
";
405
static char *gl_shader_vars_yuva = \
406
"uniform sampler2D _gf_%s_1;\n\
407
uniform sampler2D _gf_%s_2;\n\
408
uniform sampler2D _gf_%s_3;\n\
409
uniform sampler2D _gf_%s_4;\n\
410
";
411
412
static char *gl_shader_fun_yuva = \
413
"vec2 texc;\n\
414
vec4 yuv;\n\
415
texc = _gpacTexCoord.st;\n\
416
yuv.x = texture2D(_gf_%s_1, texc).r;\n\
417
yuv.y = texture2D(_gf_%s_2, texc).r;\n\
418
yuv.z = texture2D(_gf_%s_3, texc).r;\n\
419
yuv.w = 1.0;\n\
420
yuv = _gf_%s_mx * yuv;\n\
421
yuv.w = texture2D(_gf_%s_4, texc).r;\n\
422
return yuv;\n\
423
";
424
425
static char *gl_shader_vars_nv12 = \
426
"uniform sampler2D _gf_%s_1;\n\
427
uniform sampler2D _gf_%s_2;\n\
428
";
429
430
static char *gl_shader_fun_nv12 = \
431
"vec2 texc;\n\
432
vec4 yuv;\n\
433
texc = _gpacTexCoord.st;\n\
434
yuv.x = texture2D(_gf_%s_1, texc).r;\n\
435
yuv.yz = texture2D(_gf_%s_2, texc).ra;\n\
436
yuv.w = 1.0;\n\
437
yuv = _gf_%s_mx * yuv;\n\
438
yuv.w = 1.0;\n\
439
return yuv;\n\
440
";
441
442
443
static char *gl_shader_vars_nv21 = \
444
"uniform sampler2D _gf_%s_1;\n\
445
uniform sampler2D _gf_%s_2;\n\
446
";
447
448
static char *gl_shader_fun_nv21 = \
449
"vec2 texc;\n\
450
vec4 yuv;\n\
451
texc = _gpacTexCoord.st;\n\
452
yuv.x = texture2D(_gf_%s_1, texc).r;\n\
453
yuv.yz = texture2D(_gf_%s_2, texc).ar;\n\
454
yuv.w = 1.0;\n\
455
yuv = _gf_%s_mx * yuv;\n\
456
yuv.w = 1.0;\n\
457
return yuv;\n\
458
";
459
460
461
static char *gl_shader_vars_uyvu = \
462
"uniform sampler2D _gf_%s_1;\
463
uniform float _gf_%s_width;\
464
";
465
466
static char *gl_shader_fun_uyvy = \
467
"vec2 texc, t_texc;\
468
vec4 yuv;\
469
vec4 uyvy;\
470
float tex_s;\
471
texc = _gpacTexCoord.st;\
472
t_texc = texc * vec2(1, 1);\
473
uyvy = texture2D(_gf_%s_1, t_texc); \
474
tex_s = texc.x*_gf_%s_width;\
475
if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
476
  uyvy.g = uyvy.a; \
477
}\
478
yuv.r = uyvy.g;\
479
yuv.g = uyvy.r;\
480
yuv.b = uyvy.b;\
481
yuv.w = 1.0;\n\
482
yuv = _gf_%s_mx * yuv;\n\
483
yuv.w = 1.0;\n\
484
return yuv;\n\
485
";
486
487
488
static char *gl_shader_fun_vyuy = \
489
"vec2 texc, t_texc;\
490
vec4 yuv;\
491
vec4 vyuy;\
492
float tex_s;\
493
texc = _gpacTexCoord.st;\
494
t_texc = texc * vec2(1, 1);\
495
vyuy = texture2D(_gf_%s_1, t_texc); \
496
tex_s = texc.x*_gf_%s_width;\
497
if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
498
  vyuy.g = vyuy.a; \
499
}\
500
yuv.r = vyuy.g;\
501
yuv.g = vyuy.b;\
502
yuv.b = vyuy.r;\
503
yuv.w = 1.0;\n\
504
yuv = _gf_%s_mx * yuv;\n\
505
yuv.w = 1.0;\n\
506
return yuv;\n\
507
";
508
509
510
static char *gl_shader_fun_yuyv = \
511
"vec2 texc, t_texc;\
512
vec4 yuv;\
513
vec4 yvyu;\
514
float tex_s;\
515
texc = _gpacTexCoord.st;\
516
t_texc = texc * vec2(1, 1);\
517
yvyu = texture2D(_gf_%s_1, t_texc); \
518
tex_s = texc.x*_gf_%s_width;\
519
if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
520
  yvyu.r = yvyu.b; \
521
}\
522
yuv.r = yvyu.r;\
523
yuv.g = yvyu.g;\
524
yuv.b = yvyu.a;\
525
yuv.w = 1.0;\n\
526
yuv = _gf_%s_mx * yuv;\n\
527
yuv.w = 1.0;\n\
528
return yuv;\n\
529
";
530
531
static char *gl_shader_fun_yvyu = \
532
"vec2 texc, t_texc;\
533
vec4 yuv;\
534
vec4 yuyv;\
535
float tex_s;\
536
texc = _gpacTexCoord.st;\
537
t_texc = texc * vec2(1, 1);\
538
yuyv = texture2D(_gf_%s_1, t_texc); \
539
tex_s = texc.x*_gf_%s_width;\
540
if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\
541
  yuyv.r = yuyv.b; \
542
}\
543
yuv.r = yuyv.r;\
544
yuv.g = yuyv.a;\
545
yuv.b = yuyv.g;\
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
553
554
static char *gl_shader_vars_yuv4_pack = \
555
"uniform sampler2D _gf_%s_1;\n\
556
";
557
558
static char *gl_shader_fun_yuv4_pack = \
559
"vec2 texc;\n\
560
vec4 yuv;\n\
561
texc = _gpacTexCoord.st;\n\
562
yuv = texture2D(_gf_%s_1, texc);\n\
563
yuv.w = 1.0;\n\
564
yuv = _gf_%s_mx * yuv;\n\
565
yuv.w = 1.0;\n\
566
return yuv;\n\
567
";
568
569
static char *gl_shader_fun_vyu4_pack = \
570
"vec2 texc;\n\
571
vec4 yuv;\n\
572
texc = _gpacTexCoord.st;\n\
573
yuv.rgb = texture2D(_gf_%s_1, texc).gbr;\n\
574
yuv.w = 1.0;\n\
575
yuv = _gf_%s_mx * yuv;\n\
576
yuv.w = 1.0;\n\
577
return yuv;\n\
578
";
579
580
581
static char *gl_shader_fun_yuv4a_pack = \
582
"vec2 texc;\n\
583
vec4 tex;\n\
584
vec4 yuv;\n\
585
texc = _gpacTexCoord.st;\n\
586
tex = texture2D(_gf_%s_1, texc);\n\
587
yuv.rgb = tex.rgb;\n\
588
yuv.w = 1.0;\n\
589
yuv = _gf_%s_mx * yuv;\n\
590
yuv.w = tex.a;\n\
591
return yuv;\n\
592
";
593
594
static char *gl_shader_fun_uyv4a_pack = \
595
"vec2 texc;\n\
596
vec4 tex;\n\
597
vec4 yuv;\n\
598
texc = _gpacTexCoord.st;\n\
599
tex = texture2D(_gf_%s_1, texc);\n\
600
yuv.rgb = tex.grb;\n\
601
yuv.w = 1.0;\n\
602
yuv = _gf_%s_mx * yuv;\n\
603
yuv.w = tex.a;\n\
604
return yuv;\n\
605
";
606
607
//uploaded as RGBA describing 10 bit V + 10 bit Y + 10 bit U + 2 bits lost, lost bits in R (first byte)
608
//V: 8 bit A + 2 bits B
609
//Y: 6 bit B + 4 bits G
610
//U: 4 bit G + 6 bits R
611
//
612
//we do the maths for bit reading, we should add support for GLES3 shift operators as well (but no support in WebGL1)
613
static char *gl_shader_fun_yuv4_10_pack = \
614
"vec2 texc;\n\
615
vec4 val;\n\
616
int valr, valg, valb, vala, interm1, interm2;\n\
617
vec4 yuv;\n\
618
texc = _gpacTexCoord.st;\n\
619
val = texture2D(_gf_%s_1, texc).rgba;\n\
620
vala = int(val.a*255.0);\n\
621
valb = int(val.b*255.0);\n\
622
valg = int(val.g*255.0);\n\
623
valr = int(val.r*255.0 / 64.0);\n\
624
interm1 = valb / 64;\n\
625
yuv.b = float( (vala * 4) + (interm1) ) / 1023.0;\n\
626
interm1 *= 64;\n\
627
interm2 = valg / 16;\n\
628
yuv.r = float( ((valb - interm1) * 16) + (interm2) ) / 1023.0;\n\
629
interm2 *= 16;\n\
630
yuv.g = float( ((valg - interm2) * 64) + valr ) / 1023.0;\n\
631
yuv.w = 1.0;\n\
632
yuv = _gf_%s_mx * yuv;\n\
633
yuv.w = 1.0;\n\
634
return yuv;\n\
635
";
636
637
638
static char *gl_shader_vars_v210 = \
639
"uniform sampler2D _gf_%s_1;\
640
uniform float _gf_%s_width;\
641
uniform float _gf_%s_gpu_width;\
642
";
643
644
//uploaded as RGBA describing 2 bits lost (in A, last byte) + 3 * 10 bit {U,Y,V} , pattern repeating 6 times
645
//first pattern (x%6==0) is {00b, Cr, Y, Cb} in {A, B, G, R} bytes
646
//we decompose RGBA pixel x and x+1 as follows
647
//.R: 8 bit R + 2 bits G
648
//.G: 6 bit G + 4 bits B
649
//.B: 4 bit G + 6 bits A
650
//
651
//s coordinate is remapped to line pos x in source width pixels
652
//the GPU sees the texture as a {stride/4, height} texture
653
//so when we fetch from sampler2D we need to convert 6 pixels v210 to 4 pixels RGBA for x
654
//but the next pixel we need is 1/gpu_width after x
655
//
656
//we do the maths for bit reading, we should add support for GLES3 shift operators as well (but no support in WebGL1)
657
static char *gl_shader_fun_v210 = \
658
"vec2 texc;\n\
659
vec4 yuv, yuv1, yuv2, val;\n\
660
int x, off_x, dec_x, valr, valg, valb, vala, interm1, interm2;\n\
661
float tx_width = _gf_%s_width;\n\
662
float tx_gpu_width = _gf_%s_gpu_width;\n\
663
x = int(_gpacTexCoord.s * tx_width);\n\
664
interm1 = x/6;\n\
665
off_x = x - (interm1 * 6);\n\
666
x-=off_x;\n\
667
if (off_x>=4) dec_x = 2;\n\
668
else if (off_x>=2) dec_x = 1;\n\
669
else dec_x = 0;\n\
670
texc.t = _gpacTexCoord.t;\n\
671
texc.s = float(x * 4 / 6 + dec_x) / tx_gpu_width;\n\
672
val = texture2D(_gf_%s_1, texc);\n\
673
vala = int(val.a*255.0);\n\
674
valb = int(val.b*255.0);\n\
675
valg = int(val.g*255.0);\n\
676
valr = int(val.r*255.0);\n\
677
vala = vala - ((vala/64) * 64);\n\
678
interm1 = valg / 4;\n\
679
yuv1.r = float( valr + (valg - interm1*4)*256 ) / 1023.0;\n\
680
interm2 = valb / 16;\n\
681
yuv1.g = float( (valb - interm2*16) * 64 + interm1 ) / 1023.0;\n\
682
yuv1.b = float( interm2 + vala*16 ) / 1023.0;\n\
683
if (off_x==0) {\n\
684
yuv.g = yuv1.r;\n\
685
yuv.r = yuv1.g;\n\
686
yuv.b = yuv1.b;\n\
687
} else {\n\
688
texc.s = float(x * 4 / 6 + dec_x + 1) / tx_gpu_width;\n\
689
val = texture2D(_gf_%s_1, texc);\n\
690
vala = int(val.a*255.0);\n\
691
valb = int(val.b*255.0);\n\
692
valg = int(val.g*255.0);\n\
693
valr = int(val.r*255.0);\n\
694
vala = vala - ((vala/64) * 64);\n\
695
interm1 = valg / 4;\n\
696
yuv2.r = float( valr + (valg - interm1*4)*256 ) / 1023.0;\n\
697
interm2 = valb / 16;\n\
698
yuv2.g = float( (valb - interm2*16) * 64 + interm1 ) / 1023.0;\n\
699
yuv2.b = float( interm2 + vala*16 ) / 1023.0;\n\
700
if (off_x==1) {\n\
701
yuv.g = yuv1.r;\n\
702
yuv.r = yuv2.r;\n\
703
yuv.b = yuv1.b;\n\
704
} else if (off_x==2) {\n\
705
yuv.g = yuv1.g;\n\
706
yuv.r = yuv1.b;\n\
707
yuv.b = yuv2.r;\n\
708
} else if (off_x==3) {\n\
709
yuv.g = yuv1.g;\n\
710
yuv.r = yuv2.g;\n\
711
yuv.b = yuv2.r;\n\
712
} else if (off_x==4) {\n\
713
yuv.g = yuv1.b;\n\
714
yuv.r = yuv2.r;\n\
715
yuv.b = yuv2.g;\n\
716
} else {\n\
717
yuv.g = yuv1.b;\n\
718
yuv.r = yuv2.b;\n\
719
yuv.b = yuv2.g;\n\
720
}\n\
721
}\n\
722
yuv.w = 1.0;\n\
723
yuv = _gf_%s_mx * yuv;\n\
724
yuv.w = 1.0;\n\
725
return yuv;\n\
726
";
727
728
729
730
static char *gl_shader_vars_rgb = \
731
"uniform sampler2D _gf_%s_1;\n\
732
";
733
734
static char *gl_shader_fun_alphagrey = \
735
"vec4 col, ocol;\n\
736
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
737
ocol.r = ocol.g = ocol.b = col.a;\n\
738
ocol.a = col.r;\n\
739
return ocol;\n\
740
";
741
742
static char *gl_shader_fun_rgb332 = \
743
"vec4 col, ocol;\n\
744
float res, col_r, col_g, col_b;\n\
745
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
746
res = floor( 255.0 * col.r );\n\
747
col_r = floor(res / 32.0);\n\
748
col_g = floor((res - col_r*32.0)/4.0);\n\
749
col_b = floor(res - col_r*128.0 - col_g*4.0);\n\
750
ocol.r = col_r / 7.0;\n\
751
ocol.g = col_g / 7.0;\n\
752
ocol.b = col_b / 3.0;\n\
753
ocol.a = 1.0;\n\
754
return ocol;\
755
";
756
757
static char *gl_shader_fun_rgb444 = \
758
"vec4 col, ocol;\n\
759
float res, col_g, col_b;\n\
760
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
761
res = floor( 255.0 * col.a );\n\
762
col_g = floor(res / 16.0);\n\
763
col_b = floor(res - col_g*16.0);\n\
764
ocol.r = col.r * 17.0;\n\
765
ocol.g = col_g / 15.0;\n\
766
ocol.b = col_b / 15.0;\n\
767
ocol.a = 1.0;\n\
768
return ocol;\
769
";
770
771
772
static char *gl_shader_fun_rgb555 = \
773
"vec4 col, ocol;\n\
774
float res, col_r, col_g1, col_g, col_b;\n\
775
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
776
res = floor(255.0 * col.r);\n\
777
col_r = floor(res / 4.0);\n\
778
col_g1 = floor(res - col_r*4.0);\n\
779
res = floor(255.0 * col.a);\n\
780
col_g = floor(res / 32);\n\
781
col_b = floor(res - col_g*32.0);\n\
782
col_g += col_g1 * 8;\n\
783
ocol.r = col_r / 31.0;\n\
784
ocol.g = col_g / 31.0;\n\
785
ocol.b = col_b / 31.0;\n\
786
ocol.a = 1.0;\n\
787
return ocol;\
788
";
789
790
static char *gl_shader_fun_rgb565 = \
791
"vec4 col, ocol;\n\
792
float res, col_r, col_g1, col_g, col_b;\n\
793
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
794
res = floor(255.0 * col.r);\n\
795
col_r = floor(res / 8.0);\n\
796
col_g1 = floor(res - col_r*8.0);\n\
797
res = floor(255.0 * col.a);\n\
798
col_g = floor(res / 32);\n\
799
col_b = floor(res - col_g*32.0);\n\
800
col_g += col_g1 * 8;\n\
801
ocol.r = col_r / 31.0;\n\
802
ocol.g = col_g / 63.0;\n\
803
ocol.b = col_b / 31.0;\n\
804
ocol.a = 1.0;\n\
805
return ocol;\
806
";
807
808
809
static char *gl_shader_fun_argb = \
810
"vec4 col, ocol;\n\
811
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
812
ocol.r = col.g;\n\
813
ocol.g = col.b;\n\
814
ocol.b = col.a;\n\
815
ocol.a = col.r;\n\
816
return ocol;\
817
";
818
819
static char *gl_shader_fun_abgr = \
820
"vec4 col, ocol;\n\
821
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
822
ocol.r = col.a;\n\
823
ocol.g = col.b;\n\
824
ocol.b = col.g;\n\
825
ocol.a = col.r;\n\
826
return ocol;\
827
";
828
829
830
static char *gl_shader_fun_bgra = \
831
"vec4 col, ocol;\n\
832
col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\
833
ocol.r = col.b;\n\
834
ocol.g = col.g;\n\
835
ocol.b = col.r;\n\
836
ocol.a = col.a;\n\
837
return ocol;\
838
";
839
840
841
static char *gl_shader_fun_rgb = \
842
"return texture2D(_gf_%s_1, _gpacTexCoord.st);\
843
";
844
845
static char *gl_shader_vars_externalOES = \
846
"uniform samplerExternalOES _gf_%s_1;\n\
847
";
848
849
850
Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source, Bool y_flip)
851
{
852
  char szCode[4000];
853
  const char *shader_vars = NULL;
854
  const char *shader_fun = NULL;
855
856
  switch (pix_fmt) {
857
  case GF_PIXEL_NV21:
858
  case GF_PIXEL_NV21_10:
859
    shader_vars = gl_shader_vars_nv21;
860
    shader_fun = gl_shader_fun_nv21;
861
    break;
862
  case GF_PIXEL_NV12:
863
  case GF_PIXEL_NV12_10:
864
    shader_vars = gl_shader_vars_nv12;
865
    shader_fun = gl_shader_fun_nv12;
866
    break;
867
  case GF_PIXEL_UYVY:
868
  case GF_PIXEL_UYVY_10:
869
    shader_vars = gl_shader_vars_uyvu;
870
    shader_fun = gl_shader_fun_uyvy;
871
    break;
872
  case GF_PIXEL_YUYV:
873
  case GF_PIXEL_YUYV_10:
874
    shader_vars = gl_shader_vars_uyvu; //same as uyvy
875
    shader_fun = gl_shader_fun_yuyv;
876
    break;
877
  case GF_PIXEL_VYUY:
878
  case GF_PIXEL_VYUY_10:
879
    shader_vars = gl_shader_vars_uyvu; //same as uyvy
880
    shader_fun = gl_shader_fun_vyuy;
881
    break;
882
  case GF_PIXEL_YVYU:
883
  case GF_PIXEL_YVYU_10:
884
    shader_vars = gl_shader_vars_uyvu; //same as uyvy
885
    shader_fun = gl_shader_fun_yvyu;
886
    break;
887
  case GF_PIXEL_YUV444_PACK:
888
    shader_vars = gl_shader_vars_yuv4_pack;
889
    shader_fun = gl_shader_fun_yuv4_pack;
890
    break;
891
  case GF_PIXEL_VYU444_PACK:
892
    shader_vars = gl_shader_vars_yuv4_pack;
893
    shader_fun = gl_shader_fun_vyu4_pack;
894
    break;
895
  case GF_PIXEL_YUVA444_PACK:
896
    shader_vars = gl_shader_vars_yuv4_pack;
897
    shader_fun = gl_shader_fun_yuv4a_pack;
898
    break;
899
  case GF_PIXEL_UYVA444_PACK:
900
    shader_vars = gl_shader_vars_yuv4_pack;
901
    shader_fun = gl_shader_fun_uyv4a_pack;
902
    break;
903
  case GF_PIXEL_YUV444_10_PACK:
904
    shader_vars = gl_shader_vars_yuv4_pack;
905
    shader_fun = gl_shader_fun_yuv4_10_pack;
906
    break;
907
  case GF_PIXEL_V210:
908
    shader_vars = gl_shader_vars_v210;
909
    shader_fun = gl_shader_fun_v210;
910
    break;
911
  case GF_PIXEL_ALPHAGREY:
912
    shader_vars = gl_shader_vars_rgb;
913
    shader_fun = gl_shader_fun_alphagrey;
914
    break;
915
  case GF_PIXEL_RGB_332:
916
    shader_vars = gl_shader_vars_rgb;
917
    shader_fun = gl_shader_fun_rgb332;
918
    break;
919
  case GF_PIXEL_RGB_444:
920
    shader_vars = gl_shader_vars_rgb;
921
    shader_fun = gl_shader_fun_rgb444;
922
    break;
923
  case GF_PIXEL_RGB_555:
924
    shader_vars = gl_shader_vars_rgb;
925
    shader_fun = gl_shader_fun_rgb555;
926
    break;
927
  case GF_PIXEL_RGB_565:
928
    shader_vars = gl_shader_vars_rgb;
929
    shader_fun = gl_shader_fun_rgb565;
930
    break;
931
  case GF_PIXEL_ARGB:
932
  case GF_PIXEL_XRGB:
933
    shader_vars = gl_shader_vars_rgb;
934
    shader_fun = gl_shader_fun_argb;
935
    break;
936
  case GF_PIXEL_ABGR:
937
  case GF_PIXEL_XBGR:
938
    shader_vars = gl_shader_vars_rgb;
939
    shader_fun = gl_shader_fun_abgr;
940
    break;
941
  case GF_PIXEL_BGR:
942
  case GF_PIXEL_BGRA:
943
  case GF_PIXEL_BGRX:
944
    shader_vars = gl_shader_vars_rgb;
945
    shader_fun = gl_shader_fun_bgra;
946
    break;
947
948
  case GF_PIXEL_YUV_10:
949
  case GF_PIXEL_YUV422_10:
950
  case GF_PIXEL_YUV444_10:
951
#if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2)
952
    shader_vars = gl_shader_vars_yuv;
953
    shader_fun = gl_shader_fun_yuv_gles10;
954
    break;
955
#endif
956
  case GF_PIXEL_YUVD:
957
  case GF_PIXEL_YUV422:
958
  case GF_PIXEL_YUV444:
959
  case GF_PIXEL_YUV:
960
    shader_vars = gl_shader_vars_yuv;
961
    shader_fun = gl_shader_fun_yuv;
962
    break;
963
  case GF_PIXEL_YVU:
964
    shader_vars = gl_shader_vars_yuv;
965
    shader_fun = gl_shader_fun_yvu;
966
    break;
967
  case GF_PIXEL_YUVA:
968
  case GF_PIXEL_YUVA444:
969
    shader_vars = gl_shader_vars_yuva;
970
    shader_fun = gl_shader_fun_yuva;
971
    break;
972
  case GF_PIXEL_GL_EXTERNAL:
973
    shader_vars = gl_shader_vars_externalOES;
974
    shader_fun = gl_shader_fun_rgb;
975
    break;
976
  default:
977
    shader_vars = gl_shader_vars_rgb;
978
    shader_fun = gl_shader_fun_rgb;
979
    break;
980
  }
981
982
  if (!shader_vars || !shader_fun) return GF_FALSE;
983
  /*format with max 4 tx_name (for yuva)*/
984
  sprintf(szCode, shader_vars, tx_name, tx_name, tx_name, tx_name);
985
  gf_dynstrcat(f_source, szCode, NULL);
986
987
  if (gf_pixel_fmt_is_yuv(pix_fmt)) {
988
//    gf_dynstrcat(f_source, gl_shader_yuv_matrix, NULL);
989
990
    sprintf(szCode, gl_shader_yuv_matrix, tx_name);
991
    gf_dynstrcat(f_source, szCode, NULL);
992
  }
993
994
  gf_dynstrcat(f_source, "\nvec4 ", NULL);
995
  gf_dynstrcat(f_source, tx_name, NULL);
996
  gf_dynstrcat(f_source, "_sample(vec2 _gpacTexCoord) {\n", NULL);
997
  if (y_flip) {
998
    gf_dynstrcat(f_source, "_gpacTexCoord.t = 1.0 - _gpacTexCoord.t;\n", NULL);
999
  }
1000
  /*format with max 4 tx_name (for yuva) + matrix for yuv*/
1001
  sprintf(szCode, shader_fun, tx_name, tx_name, tx_name, tx_name, tx_name);
1002
1003
  gf_dynstrcat(f_source, szCode, NULL);
1004
  gf_dynstrcat(f_source, "\n}\n", NULL);
1005
1006
  return GF_TRUE;
1007
}
1008
1009
1010
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)
1011
{
1012
  u32 i;
1013
1014
  tx->width = width;
1015
  tx->height = height;
1016
  tx->pix_fmt = pix_fmt;
1017
  tx->stride = stride;
1018
  tx->uv_stride = uv_stride;
1019
  tx->internal_textures = GF_TRUE;
1020
  tx->nb_textures = 1;
1021
  tx->is_yuv = GF_FALSE;
1022
  tx->bit_depth = 8;
1023
  tx->gl_format = GL_LUMINANCE;
1024
  tx->bytes_per_pix = 1;
1025
  tx->fullrange = full_range;
1026
  if (matrix_coef_or_neg==GF_CICP_MX_UNSPECIFIED)
1027
    tx->mx_cicp = -1;
1028
  else
1029
    tx->mx_cicp = matrix_coef_or_neg;
1030
1031
  if (!tx->stride)
1032
    gf_pixel_get_size_info(tx->pix_fmt, tx->width, tx->height, NULL, &tx->stride, &tx->uv_stride, NULL, &tx->uv_h);
1033
1034
  switch (tx->pix_fmt) {
1035
  case GF_PIXEL_YUV444_10:
1036
    tx->bit_depth = 10;
1037
  case GF_PIXEL_YUV444:
1038
  case GF_PIXEL_YUVA444:
1039
    tx->uv_w = tx->width;
1040
    tx->uv_h = tx->height;
1041
    if (!tx->uv_stride)
1042
      tx->uv_stride = tx->stride;
1043
    tx->is_yuv = GF_TRUE;
1044
    tx->nb_textures = 3;
1045
    if (tx->pix_fmt==GF_PIXEL_YUVA444) {
1046
      tx->nb_textures = 4;
1047
      tx->has_alpha = GF_TRUE;
1048
    }
1049
    break;
1050
  case GF_PIXEL_YUV422_10:
1051
    tx->bit_depth = 10;
1052
  case GF_PIXEL_YUV422:
1053
    tx->uv_w = tx->width/2;
1054
    tx->uv_h = tx->height;
1055
    if (!tx->uv_stride)
1056
      tx->uv_stride = tx->stride/2;
1057
    tx->is_yuv = GF_TRUE;
1058
    tx->nb_textures = 3;
1059
    break;
1060
  case GF_PIXEL_YUV_10:
1061
    tx->bit_depth = 10;
1062
  case GF_PIXEL_YUV:
1063
  case GF_PIXEL_YVU:
1064
  case GF_PIXEL_YUVA:
1065
    tx->uv_w = tx->width/2;
1066
    if (tx->width % 2) tx->uv_w++;
1067
    tx->uv_h = tx->height/2;
1068
    if (tx->height % 2) tx->uv_h++;
1069
    if (!tx->uv_stride) {
1070
      tx->uv_stride = tx->stride/2;
1071
      if (tx->stride%2) tx->uv_stride ++;
1072
    }
1073
    tx->is_yuv = GF_TRUE;
1074
    tx->nb_textures = 3;
1075
    if (tx->pix_fmt==GF_PIXEL_YUVA) {
1076
      tx->nb_textures = 4;
1077
      tx->has_alpha = GF_TRUE;
1078
    }
1079
    break;
1080
  case GF_PIXEL_NV12_10:
1081
  case GF_PIXEL_NV21_10:
1082
    tx->bit_depth = 10;
1083
  case GF_PIXEL_NV12:
1084
  case GF_PIXEL_NV21:
1085
    tx->uv_w = tx->width/2;
1086
    tx->uv_h = tx->height/2;
1087
    if (!tx->uv_stride)
1088
      tx->uv_stride = tx->stride;
1089
    tx->is_yuv = GF_TRUE;
1090
    tx->nb_textures = 2;
1091
    break;
1092
  case GF_PIXEL_UYVY_10:
1093
  case GF_PIXEL_YUYV_10:
1094
  case GF_PIXEL_YVYU_10:
1095
  case GF_PIXEL_VYUY_10:
1096
    tx->bit_depth = 16;
1097
  case GF_PIXEL_UYVY:
1098
  case GF_PIXEL_YUYV:
1099
  case GF_PIXEL_YVYU:
1100
  case GF_PIXEL_VYUY:
1101
    tx->uv_w = tx->width/2;
1102
    tx->uv_h = tx->height;
1103
    if (!tx->uv_stride) {
1104
      tx->uv_stride = tx->stride/2;
1105
      if (tx->stride%2) tx->uv_stride ++;
1106
    }
1107
    tx->is_yuv = GF_TRUE;
1108
    tx->nb_textures = 1;
1109
    break;
1110
  case GF_PIXEL_V210:
1111
    tx->is_yuv = GF_TRUE;
1112
    tx->nb_textures = 1;
1113
    break;
1114
1115
  case GF_PIXEL_YUVA444_PACK:
1116
  case GF_PIXEL_UYVA444_PACK:
1117
    tx->has_alpha = GF_TRUE;
1118
  case GF_PIXEL_YUV444_PACK:
1119
  case GF_PIXEL_VYU444_PACK:
1120
  case GF_PIXEL_YUV444_10_PACK:
1121
    tx->uv_w = tx->width;
1122
    tx->uv_h = tx->height;
1123
    if (!tx->uv_stride) {
1124
      tx->uv_stride = tx->stride;
1125
    }
1126
    tx->is_yuv = GF_TRUE;
1127
    tx->nb_textures = 1;
1128
    break;
1129
  case GF_PIXEL_GREYSCALE:
1130
    tx->gl_format = GL_LUMINANCE;
1131
    tx->bytes_per_pix = 1;
1132
    break;
1133
  case GF_PIXEL_ALPHAGREY:
1134
  case GF_PIXEL_GREYALPHA:
1135
    tx->gl_format = GL_LUMINANCE_ALPHA;
1136
    tx->bytes_per_pix = 2;
1137
    break;
1138
  case GF_PIXEL_RGB:
1139
    tx->gl_format = GL_RGB;
1140
    tx->bytes_per_pix = 3;
1141
    break;
1142
  case GF_PIXEL_BGR:
1143
    tx->gl_format = GL_RGB;
1144
    tx->bytes_per_pix = 3;
1145
    break;
1146
  case GF_PIXEL_BGRA:
1147
    tx->has_alpha = GF_TRUE;
1148
  case GF_PIXEL_BGRX:
1149
    tx->gl_format = GL_RGBA;
1150
    tx->bytes_per_pix = 4;
1151
    break;
1152
  case GF_PIXEL_ARGB:
1153
    tx->has_alpha = GF_TRUE;
1154
  case GF_PIXEL_XRGB:
1155
    tx->gl_format = GL_RGBA;
1156
    tx->bytes_per_pix = 4;
1157
    break;
1158
  case GF_PIXEL_ABGR:
1159
    tx->has_alpha = GF_TRUE;
1160
  case GF_PIXEL_XBGR:
1161
    tx->gl_format = GL_RGBA;
1162
    tx->bytes_per_pix = 4;
1163
    break;
1164
  case GF_PIXEL_RGBA:
1165
    tx->has_alpha = GF_TRUE;
1166
  case GF_PIXEL_RGBX:
1167
    tx->gl_format = GL_RGBA;
1168
    tx->bytes_per_pix = 4;
1169
    break;
1170
  case GF_PIXEL_RGB_332:
1171
    tx->gl_format = GL_LUMINANCE;
1172
    tx->bytes_per_pix = 1;
1173
    break;
1174
  case GF_PIXEL_RGB_444:
1175
    tx->gl_format = GL_LUMINANCE_ALPHA;
1176
    tx->bytes_per_pix = 2;
1177
    break;
1178
  case GF_PIXEL_RGB_555:
1179
    tx->gl_format = GL_LUMINANCE_ALPHA;
1180
    tx->bytes_per_pix = 2;
1181
    break;
1182
  case GF_PIXEL_RGB_565:
1183
    tx->gl_format = GL_LUMINANCE_ALPHA;
1184
    tx->bytes_per_pix = 2;
1185
    break;
1186
  case GF_PIXEL_GL_EXTERNAL:
1187
    tx->internal_textures = GF_FALSE;
1188
    break;
1189
  default:
1190
    GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Pixel format %s unsupported, cannot setup texture wrapper\n", gf_4cc_to_str(tx->pix_fmt)));
1191
    return GF_FALSE;
1192
  }
1193
1194
  if (tx->bit_depth>8)
1195
    tx->bytes_per_pix = 2;
1196
1197
  if (frame_ifce && frame_ifce->get_gl_texture) {
1198
    tx->internal_textures = GF_FALSE;
1199
  }
1200
1201
  /*create textures*/
1202
  if (tx->internal_textures) {
1203
#if !defined(GPAC_USE_GLES1X)
1204
    u32 glmode = GL_NEAREST;
1205
    if ((tx->nb_textures==1) && linear_interp && !tx->is_yuv)
1206
      glmode = GL_LINEAR;
1207
#endif
1208
    tx->first_tx_load = GF_TRUE;
1209
    tx->scale_10bit = 0;
1210
1211
    tx->memory_format = GL_UNSIGNED_BYTE;
1212
    if (tx->is_yuv && tx->bit_depth>8) {
1213
#if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1214
      //we use x bits but GL will normalise using 16 bits, so we need to multiply the normalized result by 2^(16-x)
1215
      u32 nb_bits = (16 - tx->bit_depth);
1216
      u32 scale = 1;
1217
      while (nb_bits) {
1218
        scale*=2;
1219
        nb_bits--;
1220
      }
1221
      tx->scale_10bit = scale;
1222
      tx->memory_format = GL_UNSIGNED_SHORT;
1223
#else
1224
1225
      switch (tx->pix_fmt) {
1226
      case GF_PIXEL_YUV_10:
1227
      case GF_PIXEL_YUV422_10:
1228
      case GF_PIXEL_YUV444_10:
1229
        tx->gl_format = GL_LUMINANCE_ALPHA;
1230
        tx->memory_format = GL_UNSIGNED_BYTE;
1231
        break;
1232
      default:
1233
        GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Pixel format %s unsupported, cannot setup texture wrapper\n", gf_4cc_to_str(tx->pix_fmt)));
1234
        return GF_FALSE;
1235
      }
1236
#endif
1237
    }
1238
1239
1240
    GL_CHECK_ERR()
1241
    glGenTextures(tx->nb_textures, tx->textures);
1242
    GL_CHECK_ERR()
1243
1244
#ifndef GPAC_USE_GLES2
1245
    glEnable(GL_TEXTURE_2D);
1246
    GL_CHECK_ERR()
1247
#endif
1248
1249
    for (i=0; i<tx->nb_textures; i++) {
1250
#if !defined(GPAC_USE_GLES1X)
1251
      glBindTexture(GL_TEXTURE_2D, tx->textures[i] );
1252
      GL_CHECK_ERR()
1253
#if defined(GPAC_USE_GLES2)
1254
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1255
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1256
#else
1257
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1258
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1259
#endif
1260
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);
1261
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode);
1262
#endif
1263
      GL_CHECK_ERR()
1264
    }
1265
1266
1267
#if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1268
    if (tx->is_yuv && tx->pbo_state) {
1269
      tx->first_tx_load = GF_FALSE;
1270
      glGenBuffers(1, &tx->PBOs[0]);
1271
      glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1272
1273
      if (tx->nb_textures>1) {
1274
        glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->width*tx->height, NULL, GL_DYNAMIC_DRAW_ARB);
1275
1276
        glGenBuffers(1, &tx->PBOs[1]);
1277
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1278
      } else {
1279
        //packed YUV
1280
        glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 4*tx->width/2*tx->height, NULL, GL_DYNAMIC_DRAW_ARB);
1281
      }
1282
1283
      if (tx->nb_textures==3) {
1284
        glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1285
1286
        glGenBuffers(1, &tx->PBOs[2]);
1287
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1288
        glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1289
      }
1290
      //nv12/21
1291
      else {
1292
        glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 2*tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB);
1293
      }
1294
      glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1295
    }
1296
#endif
1297
1298
#ifndef GPAC_USE_GLES2
1299
    glDisable(GL_TEXTURE_2D);
1300
    GL_CHECK_ERR()
1301
#endif
1302
  }
1303
  return GF_TRUE;
1304
}
1305
1306
Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce)
1307
{
1308
  Bool use_stride = GF_FALSE;
1309
  u32 stride_luma, stride_chroma;
1310
  const u8 *pY=NULL, *pU=NULL, *pV=NULL, *pA=NULL;
1311
1312
1313
  tx->frame_ifce = NULL;
1314
1315
  if (!frame_ifce && !data) return GF_FALSE;
1316
1317
  if (!tx->internal_textures) {
1318
    if (frame_ifce && frame_ifce->get_gl_texture) {
1319
      tx->frame_ifce = frame_ifce;
1320
      return GF_TRUE;
1321
    }
1322
    return GF_FALSE;
1323
  }
1324
1325
  stride_luma = tx->stride;
1326
  stride_chroma = tx->uv_stride;
1327
  if (!frame_ifce) {
1328
    if (tx->is_yuv) {
1329
      if (tx->nb_textures==2) {
1330
        if (tx->has_alpha) {
1331
          pA = data + tx->stride * tx->height;
1332
        } else {
1333
          pU = data + tx->stride * tx->height;
1334
        }
1335
      } else if (tx->nb_textures>=3) {
1336
        pU = data + tx->stride * tx->height;
1337
        pV = pU + tx->uv_stride * tx->uv_h;
1338
        if (tx->nb_textures==4) {
1339
          pA = pV + tx->uv_stride * tx->uv_h;
1340
        }
1341
      }
1342
    }
1343
  } else {
1344
    u32 st_o;
1345
    if (!frame_ifce->get_plane)
1346
      return GF_FALSE;
1347
    if (tx->nb_textures)
1348
      frame_ifce->get_plane(frame_ifce, 0, &data, &stride_luma);
1349
    if (tx->nb_textures>1)
1350
      frame_ifce->get_plane(frame_ifce, 1, &pU, &stride_chroma);
1351
    //todo we need to cleanup alpha frame fetch, how do we differentiate between NV12+alpha (3 planes) and YUV420 ?
1352
    if (tx->nb_textures>2)
1353
      frame_ifce->get_plane(frame_ifce, 2, &pV, &st_o);
1354
    if (tx->nb_textures>3)
1355
      frame_ifce->get_plane(frame_ifce, 3, &pA, &st_o);
1356
  }
1357
1358
  pY = data;
1359
1360
  if (tx->is_yuv && (stride_luma != tx->width)) {
1361
    use_stride = GF_TRUE; //whether >8bits or real stride
1362
  }
1363
  GL_CHECK_ERR()
1364
1365
  //push data
1366
#ifndef GPAC_USE_GLES2
1367
  glEnable(GL_TEXTURE_2D);
1368
  GL_CHECK_ERR()
1369
#endif
1370
1371
1372
  if (tx->scale_10bit) {
1373
#if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1374
    glPixelTransferi(GL_RED_SCALE, tx->scale_10bit);
1375
    if (tx->nb_textures==2)
1376
      glPixelTransferi(GL_ALPHA_SCALE, tx->scale_10bit);
1377
1378
    glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
1379
#endif
1380
  } else {
1381
#if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1382
    glPixelTransferi(GL_RED_SCALE, 1);
1383
    glPixelTransferi(GL_ALPHA_SCALE, 1);
1384
    glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
1385
#endif
1386
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1387
  }
1388
  GL_CHECK_ERR()
1389
1390
1391
  if (!tx->is_yuv) {
1392
    glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1393
    GL_CHECK_ERR()
1394
    if (use_stride) {
1395
#if !defined(GPAC_GL_NO_STRIDE)
1396
      glPixelStorei(GL_UNPACK_ROW_LENGTH, tx->stride / tx->bytes_per_pix);
1397
#endif
1398
    }
1399
    if (tx->first_tx_load) {
1400
      glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, GL_UNSIGNED_BYTE, data);
1401
      tx->first_tx_load = GF_FALSE;
1402
    } else {
1403
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, data);
1404
    }
1405
#if !defined(GPAC_GL_NO_STRIDE)
1406
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1407
#endif
1408
1409
    GL_CHECK_ERR()
1410
  }
1411
#if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1412
  else if (tx->pbo_state && tx->PBOs[0]) {
1413
    u32 i, linesize, count, p_stride;
1414
    u8 *ptr;
1415
1416
    //packed YUV
1417
    if (tx->nb_textures==1) {
1418
      if (tx->pbo_state!=GF_GL_PBO_TEXIMG) {
1419
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1420
1421
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1422
        ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1423
1424
        switch (tx->pix_fmt) {
1425
        case  GF_PIXEL_YUV444_PACK:
1426
        case  GF_PIXEL_VYU444_PACK:
1427
          linesize = 3 * tx->width;
1428
          break;
1429
        case GF_PIXEL_YUVA444_PACK:
1430
        case GF_PIXEL_UYVA444_PACK:
1431
          linesize = 4 * tx->width;
1432
          break;
1433
        case GF_PIXEL_YUV444_10_PACK:
1434
          linesize = 4 * tx->width;
1435
          break;
1436
        case GF_PIXEL_V210:
1437
          linesize = tx->width * 16 / 6;
1438
          break;
1439
        default:
1440
          linesize = tx->width/2 * tx->bytes_per_pix * 4;
1441
        }
1442
1443
        p_stride = stride_luma;
1444
        count = tx->height;
1445
1446
        for (i=0; i<count; i++) {
1447
          memcpy(ptr, pY, linesize);
1448
          pY += p_stride;
1449
          ptr += linesize;
1450
        }
1451
1452
        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1453
      }
1454
      if (tx->pbo_state!=GF_GL_PBO_PUSH) {
1455
        glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1456
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1457
1458
        if ((tx->pix_fmt==GF_PIXEL_YUV444_PACK) || (tx->pix_fmt==GF_PIXEL_VYU444_PACK))
1459
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx->width, tx->height, 0, GL_RGB, tx->memory_format, NULL);
1460
        else if ((tx->pix_fmt==GF_PIXEL_YUVA444_PACK) || (tx->pix_fmt==GF_PIXEL_UYVA444_PACK))
1461
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1462
        else if (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK)
1463
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1464
        else if (tx->pix_fmt==GF_PIXEL_V210)
1465
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1466
        else
1467
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, NULL);
1468
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1469
      }
1470
    } else {
1471
      if (tx->pbo_state!=GF_GL_PBO_TEXIMG) {
1472
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1473
1474
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1475
        ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1476
1477
        linesize = tx->width*tx->bytes_per_pix;
1478
        p_stride = stride_luma;
1479
        count = tx->height;
1480
1481
        for (i=0; i<count; i++) {
1482
          memcpy(ptr, pY, linesize);
1483
          pY += p_stride;
1484
          ptr += linesize;
1485
        }
1486
1487
        glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1488
1489
        if (pU) {
1490
          glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1491
          ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1492
1493
          linesize = tx->uv_w * tx->bytes_per_pix;
1494
          p_stride = stride_chroma;
1495
          count = tx->uv_h;
1496
          //NV12 and  NV21
1497
          if (!pV) {
1498
            linesize *= 2;
1499
          }
1500
1501
          for (i=0; i<count; i++) {
1502
            memcpy(ptr, pU, linesize);
1503
            pU += p_stride;
1504
            ptr += linesize;
1505
          }
1506
1507
          glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1508
        }
1509
1510
1511
        if (pV) {
1512
          glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1513
          ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1514
1515
          for (i=0; i<count; i++) {
1516
            memcpy(ptr, pV, linesize);
1517
            pV += p_stride;
1518
            ptr += linesize;
1519
          }
1520
1521
          glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
1522
        }
1523
      }
1524
1525
      if (tx->pbo_state!=GF_GL_PBO_PUSH) {
1526
        glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1527
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]);
1528
        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, NULL);
1529
1530
        glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1531
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]);
1532
        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);
1533
1534
        if (pV) {
1535
          glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1536
          glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]);
1537
          glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, NULL);
1538
        }
1539
1540
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1541
      }
1542
    }
1543
  }
1544
#endif
1545
  else if ((tx->nb_textures==1) || ((tx->nb_textures==2) && tx->has_alpha)) {
1546
#if !defined(GPAC_GL_NO_STRIDE)
1547
    u32 uv_stride = 0;
1548
#endif
1549
    glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1550
1551
    use_stride = GF_FALSE;
1552
    if ((tx->pix_fmt==GF_PIXEL_YUV444_PACK)
1553
      || (tx->pix_fmt==GF_PIXEL_VYU444_PACK)
1554
      || (tx->pix_fmt==GF_PIXEL_YUVA444_PACK)
1555
      || (tx->pix_fmt==GF_PIXEL_UYVA444_PACK)
1556
      || (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK)
1557
      || (tx->pix_fmt==GF_PIXEL_V210)
1558
    ) {
1559
      u32 tx_width = tx->width;
1560
      u32 nb_bytes = 3;
1561
      GLuint fmt = GL_RGB;
1562
      switch (tx->pix_fmt) {
1563
      case GF_PIXEL_YUV444_PACK:
1564
      case GF_PIXEL_VYU444_PACK:
1565
        break;
1566
      default:
1567
        nb_bytes = 4;
1568
        fmt = GL_RGBA;
1569
      }
1570
      if (tx->pix_fmt==GF_PIXEL_V210) {
1571
        //inverse stride to get number of pixels - this is less than out actual width, we'll undo while repacking
1572
        tx_width = tx->stride / 4;
1573
        use_stride = GF_FALSE;
1574
      }
1575
      else if (stride_luma > nb_bytes*tx->width) {
1576
        use_stride = GF_TRUE;
1577
      }
1578
1579
#if !defined(GPAC_GL_NO_STRIDE)
1580
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1581
#endif
1582
      if (tx->first_tx_load) {
1583
        glTexImage2D(GL_TEXTURE_2D, 0, fmt, tx_width, tx->height, 0, fmt, tx->memory_format, pY);
1584
        tx->first_tx_load = GF_FALSE;
1585
      } else {
1586
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx_width, tx->height, fmt, tx->memory_format, pY);
1587
      }
1588
1589
    } else {
1590
      u32 scaler = tx->scale_10bit ? 4 : 2;
1591
      if (stride_luma > scaler*tx->width) {
1592
        //stride is given in bytes for packed formats, so divide by 2 to get the number of pixels
1593
        //for YUYV, and we upload as a texture with half the wsize so redivide again by two
1594
        //since GL_UNPACK_ROW_LENGTH counts in component and we moved the set 2 bytes per comp on 10 bits
1595
        //no need to further divide
1596
#if !defined(GPAC_GL_NO_STRIDE)
1597
        uv_stride = stride_luma/scaler/2;
1598
#endif
1599
        use_stride = GF_TRUE;
1600
      }
1601
#if !defined(GPAC_GL_NO_STRIDE)
1602
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, uv_stride);
1603
#endif
1604
      if (tx->first_tx_load) {
1605
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, pY);
1606
        tx->first_tx_load = GF_FALSE;
1607
      } else {
1608
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width/2, tx->height, GL_RGBA, tx->memory_format, pY);
1609
      }
1610
    }
1611
1612
#if !defined(GPAC_GL_NO_STRIDE)
1613
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1614
#endif
1615
1616
  }
1617
  else if (tx->first_tx_load) {
1618
    glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1619
#if !defined(GPAC_GL_NO_STRIDE)
1620
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1621
#endif
1622
    glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pY);
1623
1624
    glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1625
#if !defined(GPAC_GL_NO_STRIDE)
1626
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2);
1627
#endif
1628
    glTexImage2D(GL_TEXTURE_2D, 0, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->uv_w, tx->uv_h, 0, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->memory_format, pU);
1629
1630
    if (pV) {
1631
      glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1632
#if !defined(GPAC_GL_NO_STRIDE)
1633
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix);
1634
#endif
1635
      glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, pV);
1636
    }
1637
1638
    if (pA) {
1639
      glBindTexture(GL_TEXTURE_2D, tx->textures[3] );
1640
#if !defined(GPAC_GL_NO_STRIDE)
1641
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1642
#endif
1643
      glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pA);
1644
    }
1645
1646
#if !defined(GPAC_GL_NO_STRIDE)
1647
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1648
#endif
1649
    tx->first_tx_load = GF_FALSE;
1650
  }
1651
  else {
1652
    glBindTexture(GL_TEXTURE_2D, tx->textures[0] );
1653
#if !defined(GPAC_GL_NO_STRIDE)
1654
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1655
#endif
1656
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pY);
1657
    glBindTexture(GL_TEXTURE_2D, 0);
1658
1659
    glBindTexture(GL_TEXTURE_2D, tx->textures[1] );
1660
#if !defined(GPAC_GL_NO_STRIDE)
1661
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2);
1662
#endif
1663
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->memory_format, pU);
1664
    glBindTexture(GL_TEXTURE_2D, 0);
1665
1666
    if (pV) {
1667
      glBindTexture(GL_TEXTURE_2D, tx->textures[2] );
1668
#if !defined(GPAC_GL_NO_STRIDE)
1669
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix);
1670
#endif
1671
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, tx->gl_format, tx->memory_format, pV);
1672
      glBindTexture(GL_TEXTURE_2D, 0);
1673
    }
1674
1675
    if (pA) {
1676
      glBindTexture(GL_TEXTURE_2D, tx->textures[3] );
1677
#if !defined(GPAC_GL_NO_STRIDE)
1678
      if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix);
1679
#endif
1680
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pA);
1681
      glBindTexture(GL_TEXTURE_2D, 0);
1682
    }
1683
1684
#if !defined(GPAC_GL_NO_STRIDE)
1685
    if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1686
#endif
1687
  }
1688
1689
  //restore red/alpha scale
1690
  if (tx->scale_10bit) {
1691
#if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2)
1692
    glPixelTransferi(GL_RED_SCALE, 1);
1693
    glPixelTransferi(GL_ALPHA_SCALE, 1);
1694
    glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
1695
#endif
1696
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1697
  }
1698
1699
  return GF_TRUE;
1700
}
1701
1702
1703
struct yuv_coefs {
1704
  u32 cicp;
1705
  Double Kr, Kb;
1706
} YUVMatrices[] = {
1707
  {GF_CICP_MX_BT709, 0.2126, 0.0722},
1708
  {GF_CICP_MX_FCC47, 0.3, 0.11},
1709
  {GF_CICP_MX_BT601_625, 0.299, 0.114},
1710
  {GF_CICP_MX_SMPTE170, 0.299, 0.114},
1711
  {GF_CICP_MX_SMPTE240, 0.212, 0.087},
1712
  {GF_CICP_MX_BT2020, 0.2627, 0.0593},
1713
  {GF_CICP_MX_BT2020_CL, 0.2627, 0.0593}
1714
};
1715
1716
static void get_yuv_color_matrix(GF_GLTextureWrapper *tx, GF_Matrix *mx)
1717
{
1718
  Double Kg;
1719
  struct yuv_coefs *yc = NULL;
1720
1721
  //setup YUV->RGB matrix, in row-major
1722
  gf_mx_init(*mx);
1723
1724
  if (tx->mx_cicp>=0) {
1725
    u32 i, count=GF_ARRAY_LENGTH(YUVMatrices);
1726
    u32 mx_code = (u32) tx->mx_cicp;
1727
1728
    if (mx_code==GF_CICP_MX_IDENTITY) {
1729
      return;
1730
    }
1731
1732
    if (mx_code==GF_CICP_MX_YCgCo) {
1733
      GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YCgCo matrix not supported, will use BT709\n"));
1734
      yc = &YUVMatrices[1];
1735
    }
1736
    else if (mx_code==GF_CICP_MX_YDzDx) {
1737
      GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YDxDy matrix not supported, will use BT709\n"));
1738
      yc = &YUVMatrices[1];
1739
    } else {
1740
      for (i=0; i<count; i++) {
1741
        if (YUVMatrices[i].cicp == mx_code) {
1742
          yc = &YUVMatrices[i];
1743
          break;
1744
        }
1745
      }
1746
      if (!yc) {
1747
        GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GL] Unrecognized matrix coefficient value %d, will use BT709\n", mx_code));
1748
        yc = &YUVMatrices[1];
1749
      }
1750
    }
1751
  } else {
1752
    yc = &YUVMatrices[1];
1753
  }
1754
1755
  Kg = 1.0 - yc->Kr - yc->Kb;
1756
1757
  mx->m[0] = 1.0f;
1758
  mx->m[2] = (Float) (2.0 * (1.0 - yc->Kr) );
1759
1760
  mx->m[4] = 1.0;
1761
  mx->m[5] = (Float) ( - 2.0 * (1.0 - yc->Kb) * yc->Kb / Kg );
1762
  mx->m[6] = (Float) ( - 2.0 * (1.0 - yc->Kr) * yc->Kr / Kg );
1763
1764
  mx->m[8] = 1.0f;
1765
  mx->m[9] = (Float) (2.0 * (1.0 - yc->Kb) );
1766
  mx->m[10] = 0.0;
1767
1768
  //move to column major
1769
  gf_mx_transpose(mx);
1770
1771
  if (tx->fullrange) {
1772
    gf_mx_add_translation(mx, 0, FLT2FIX(-0.5), FLT2FIX(-0.5));
1773
  } else {
1774
    gf_mx_add_scale(mx, FLT2FIX(255.0/216.0), FLT2FIX(255.0/224.0), FLT2FIX(255.0/224.0) );
1775
    gf_mx_add_translation(mx, FLT2FIX(-0.0625), FLT2FIX(-0.5), FLT2FIX(-0.5));
1776
  }
1777
1778
  GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[GL] YUV2RGB matrix is (column-major):\n"
1779
    "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1780
    "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1781
    "\t%.4f\t%.4f\t%.4f\t%.4f\n"
1782
    "\t%.4f\t%.4f\t%.4f\t%.4f\n",
1783
      mx->m[0], mx->m[1], mx->m[2], mx->m[3],
1784
      mx->m[4], mx->m[5], mx->m[6], mx->m[7],
1785
      mx->m[8], mx->m[9], mx->m[10], mx->m[11],
1786
      mx->m[12], mx->m[13], mx->m[14], mx->m[15]
1787
  ));
1788
1789
}
1790
1791
1792
Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit)
1793
{
1794
  if (!texture_unit)
1795
    texture_unit = GL_TEXTURE0;
1796
1797
  if (gl_program && (gl_program != tx->last_program)) {
1798
    tx->last_program = gl_program;
1799
    tx->uniform_setup = GF_FALSE;
1800
  }
1801
1802
#if !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X)
1803
  if ((!tx->uniform_setup || (tx->init_active_texture != texture_unit)) && gl_program) {
1804
    char szName[100];
1805
    u32 i;
1806
    u32 start_idx = texture_unit - GL_TEXTURE0;
1807
    s32 loc;
1808
    tx->init_active_texture = texture_unit;
1809
    for (i=0; i<tx->nb_textures; i++) {
1810
      sprintf(szName, "_gf_%s_%d", tx_name, i+1);
1811
      loc = glGetUniformLocation(gl_program, szName);
1812
      if (!i && (loc == -1))
1813
        loc = glGetUniformLocation(gl_program, tx_name);
1814
1815
      GL_CHECK_ERR()
1816
      if (loc == -1) {
1817
        GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate texture %s in shader\n", szName));
1818
        return GF_FALSE;
1819
      }
1820
      glUniform1i(loc, start_idx + i);
1821
      GL_CHECK_ERR()
1822
    }
1823
    GL_CHECK_ERR()
1824
  }
1825
  if (!tx->uniform_setup && gl_program) {
1826
    s32 loc;
1827
    Bool needs_gpu_width = GF_FALSE;
1828
    char szName[100];
1829
    if (tx->is_yuv) {
1830
      GF_Matrix mx;
1831
      get_yuv_color_matrix(tx, &mx);
1832
      sprintf(szName, "_gf_%s_mx", tx_name);
1833
      loc = glGetUniformLocation(gl_program, szName);
1834
      if (loc == -1) {
1835
        GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate matrix coefficients %s in shader\n", szName));
1836
        return GF_FALSE;
1837
      }
1838
      glUniformMatrix4fv(loc, 1, GL_FALSE, mx.m);
1839
    }
1840
    switch (tx->pix_fmt) {
1841
    case GF_PIXEL_V210:
1842
      needs_gpu_width = GF_TRUE;
1843
    case GF_PIXEL_UYVY:
1844
    case GF_PIXEL_YUYV:
1845
    case GF_PIXEL_VYUY:
1846
    case GF_PIXEL_YVYU:
1847
    case GF_PIXEL_UYVY_10:
1848
    case GF_PIXEL_YUYV_10:
1849
    case GF_PIXEL_VYUY_10:
1850
    case GF_PIXEL_YVYU_10:
1851
      sprintf(szName, "_gf_%s_width", tx_name);
1852
      loc = glGetUniformLocation(gl_program, szName);
1853
      if (loc == -1) {
1854
        GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate uniform %s in shader\n", szName));
1855
        return GF_FALSE;
1856
      }
1857
      glUniform1f(loc, (GLfloat) tx->width);
1858
      if (needs_gpu_width) {
1859
        u32 gpu_width = tx->stride / 4;
1860
        sprintf(szName, "_gf_%s_gpu_width", tx_name);
1861
        loc = glGetUniformLocation(gl_program, szName);
1862
        if (loc == -1) {
1863
          GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate uniform %s in shader\n", szName));
1864
          return GF_FALSE;
1865
        }
1866
        glUniform1f(loc, (GLfloat) gpu_width);
1867
      }
1868
      break;
1869
    default:
1870
      break;
1871
    }
1872
    tx->uniform_setup = GF_TRUE;
1873
  }
1874
#endif // !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X)
1875
1876
  GL_CHECK_ERR()
1877
1878
  if (!tx->internal_textures) {
1879
    u32 i;
1880
    GF_Matrix txmx;
1881
1882
    gf_mx_init(txmx);
1883
    for (i=0; i<tx->nb_textures; i++) {
1884
      u32 gl_format = GL_TEXTURE_2D;
1885
      //everything we do is on this texture unit, including what the parent filter does when fetching the gl texture
1886
      glActiveTexture(texture_unit + i);
1887
      if (tx->frame_ifce && tx->frame_ifce->get_gl_texture(tx->frame_ifce, i, &gl_format, &tx->textures[i], &txmx) != GF_OK) {
1888
        if (!i) {
1889
          GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to get frame interface OpenGL texture ID for plane %d\n", i));
1890
          return GF_FALSE;
1891
        }
1892
        break;
1893
      }
1894
#ifndef GPAC_USE_GLES2
1895
      if (!gl_program)
1896
        glEnable(gl_format);
1897
#endif
1898
      if (!tx->textures[i])
1899
        break;
1900
1901
      glBindTexture(gl_format, tx->textures[i]);
1902
      glTexParameteri(gl_format, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1903
      glTexParameteri(gl_format, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1904
      glTexParameteri(gl_format, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1905
      glTexParameteri(gl_format, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1906
      /*todo pass matrix to shader !!*/
1907
    }
1908
    tx->flip = (txmx.m[5]<0) ? GF_TRUE : GF_FALSE;
1909
1910
    if (tx->nb_textures) {
1911
#ifndef GPAC_USE_GLES2
1912
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1913
      glClientActiveTexture(texture_unit);
1914
#endif
1915
    }
1916
    return GF_TRUE;
1917
  }
1918
  if (tx->nb_textures>3) {
1919
    glActiveTexture(texture_unit + 3);
1920
    glBindTexture(GL_TEXTURE_2D, tx->textures[3]);
1921
  }
1922
  if (tx->nb_textures>2) {
1923
    glActiveTexture(texture_unit + 2);
1924
    glBindTexture(GL_TEXTURE_2D, tx->textures[2]);
1925
  }
1926
  if (tx->nb_textures>1) {
1927
    glActiveTexture(texture_unit + 1);
1928
    glBindTexture(GL_TEXTURE_2D, tx->textures[1]);
1929
  }
1930
  if (tx->nb_textures) {
1931
    glActiveTexture(texture_unit);
1932
    glBindTexture(GL_TEXTURE_2D, tx->textures[0]);
1933
1934
#ifndef GPAC_USE_GLES2
1935
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1936
    glClientActiveTexture(texture_unit);
1937
#endif
1938
  }
1939
1940
#ifndef GPAC_USE_GLES2
1941
  glEnable(GL_TEXTURE_2D);
1942
#endif
1943
1944
  GL_CHECK_ERR()
1945
  return GF_TRUE;
1946
}
1947
1948
void gf_gl_txw_reset(GF_GLTextureWrapper *tx)
1949
{
1950
  if (tx->nb_textures) {
1951
    if (tx->internal_textures) {
1952
      glDeleteTextures(tx->nb_textures, tx->textures);
1953
      if (tx->pbo_state && tx->PBOs[0]) {
1954
        glDeleteBuffers(tx->nb_textures, tx->PBOs);
1955
      }
1956
    }
1957
    tx->nb_textures = 0;
1958
  }
1959
  tx->width = 0;
1960
  tx->height = 0;
1961
  tx->pix_fmt = 0;
1962
  tx->stride = 0;
1963
  tx->uv_stride = 0;
1964
  tx->internal_textures = GF_FALSE;
1965
  tx->uniform_setup = GF_FALSE;
1966
}
1967
1968
#else
1969
1970
void gf_opengl_init()
1971
0
{
1972
0
}
1973
1974
Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source, Bool y_flip)
1975
0
{
1976
0
  return GF_FALSE;
1977
0
}
1978
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)
1979
0
{
1980
0
  return GF_FALSE;
1981
0
}
1982
1983
Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce)
1984
0
{
1985
0
  return GF_FALSE;
1986
0
}
1987
1988
Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit)
1989
0
{
1990
0
  return GF_FALSE;
1991
0
}
1992
void gf_gl_txw_reset(GF_GLTextureWrapper *tx)
1993
0
{
1994
0
}
1995
1996
#endif //GPAC_DISABLE_3D