Skip to content

Commit

Permalink
Added support for Android video textures
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Dec 12, 2017
1 parent bed7fd8 commit e8bbbb3
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
4 changes: 3 additions & 1 deletion include/SDL_pixels.h
Expand Up @@ -287,7 +287,9 @@ enum
SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */
SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'),
SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */
SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1')
SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'),
SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */
SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ')
};

typedef struct SDL_Color
Expand Down
38 changes: 34 additions & 4 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -166,7 +166,8 @@ typedef enum
GLES2_IMAGESOURCE_TEXTURE_BGR,
GLES2_IMAGESOURCE_TEXTURE_YUV,
GLES2_IMAGESOURCE_TEXTURE_NV12,
GLES2_IMAGESOURCE_TEXTURE_NV21
GLES2_IMAGESOURCE_TEXTURE_NV21,
GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES
} GLES2_ImageSource;

typedef struct GLES2_DriverContext
Expand Down Expand Up @@ -593,17 +594,32 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
format = GL_LUMINANCE;
type = GL_UNSIGNED_BYTE;
break;
#ifdef GL_TEXTURE_EXTERNAL_OES
case SDL_PIXELFORMAT_EXTERNAL_OES:
format = GL_NONE;
type = GL_NONE;
break;
#endif
default:
return SDL_SetError("Texture format not supported");
}

if (texture->format == SDL_PIXELFORMAT_EXTERNAL_OES &&
texture->access != SDL_TEXTUREACCESS_STATIC) {
return SDL_SetError("Unsupported texture access for SDL_PIXELFORMAT_EXTERNAL_OES");
}

/* Allocate a texture struct */
data = (GLES2_TextureData *)SDL_calloc(1, sizeof(GLES2_TextureData));
if (!data) {
return SDL_OutOfMemory();
}
data->texture = 0;
#ifdef GL_TEXTURE_EXTERNAL_OES
data->texture_type = (texture->format == SDL_PIXELFORMAT_EXTERNAL_OES) ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
#else
data->texture_type = GL_TEXTURE_2D;
#endif
data->pixel_format = format;
data->pixel_type = type;
data->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
Expand Down Expand Up @@ -692,9 +708,11 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
return -1;
if (texture->format != SDL_PIXELFORMAT_EXTERNAL_OES) {
renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
return -1;
}
}

if (texture->access == SDL_TEXTUREACCESS_TARGET) {
Expand Down Expand Up @@ -1263,6 +1281,9 @@ GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, int w, int
goto fault;
}
break;
case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC;
break;
default:
goto fault;
}
Expand Down Expand Up @@ -1711,6 +1732,9 @@ GLES2_SetupCopy(SDL_Renderer *renderer, SDL_Texture *texture)
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
default:
return SDL_SetError("Unsupported texture format");
}
Expand Down Expand Up @@ -1741,6 +1765,9 @@ GLES2_SetupCopy(SDL_Renderer *renderer, SDL_Texture *texture)
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
default:
return SDL_SetError("Unsupported texture format");
}
Expand Down Expand Up @@ -2208,6 +2235,9 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
#ifdef GL_TEXTURE_EXTERNAL_OES
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES;
#endif

GLES2_ResetState(renderer);

Expand Down
31 changes: 31 additions & 0 deletions src/render/opengles2/SDL_shaders_gles2.c
Expand Up @@ -275,6 +275,21 @@ static const Uint8 GLES2_FragmentSrc_TextureNV21BT709Src_[] = \
NV21_SHADER_BODY \
;

/* Custom Android video format texture */
static const Uint8 GLES2_FragmentSrc_TextureExternalOESSrc_[] = " \
#extension GL_OES_EGL_image_external : require\n\
precision mediump float; \
uniform samplerExternalOES u_texture; \
uniform vec4 u_modulation; \
varying vec2 v_texCoord; \
\
void main() \
{ \
gl_FragColor = texture2D(u_texture, v_texCoord); \
gl_FragColor *= u_modulation; \
} \
";

static const GLES2_ShaderInstance GLES2_VertexSrc_Default = {
GL_VERTEX_SHADER,
GLES2_SOURCE_SHADER,
Expand Down Expand Up @@ -380,6 +395,13 @@ static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT709Src = {
GLES2_FragmentSrc_TextureNV12BT709Src_
};

static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureExternalOESSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureExternalOESSrc_),
GLES2_FragmentSrc_TextureExternalOESSrc_
};


/*************************************************************************************************
* Vertex/fragment shader definitions *
Expand Down Expand Up @@ -490,6 +512,13 @@ static GLES2_Shader GLES2_FragmentShader_TextureNV21BT709Src = {
}
};

static GLES2_Shader GLES2_FragmentShader_TextureExternalOESSrc = {
1,
{
&GLES2_FragmentSrc_TextureExternalOESSrc
}
};


/*************************************************************************************************
* Shader selector *
Expand Down Expand Up @@ -528,6 +557,8 @@ const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type)
return &GLES2_FragmentShader_TextureNV21BT601Src;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC:
return &GLES2_FragmentShader_TextureNV21BT709Src;
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC:
return &GLES2_FragmentShader_TextureExternalOESSrc;
default:
return NULL;
}
Expand Down
1 change: 1 addition & 0 deletions src/render/opengles2/SDL_shaders_gles2.h
Expand Up @@ -56,6 +56,7 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC,
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC
} GLES2_ShaderType;

#define GLES2_SOURCE_SHADER (GLenum)-1
Expand Down

0 comments on commit e8bbbb3

Please sign in to comment.