LCOV - code coverage report
Current view: top level - utils - gltools.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 337 570 59.1 %
Date: 2021-04-29 23:48:07 Functions: 7 7 100.0 %

          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

Generated by: LCOV version 1.13