Initial pass at shader YV12 support - doesn't quite work yet.
1.1 --- a/include/SDL_pixels.h Fri Feb 11 23:02:35 2011 -0800
1.2 +++ b/include/SDL_pixels.h Sat Feb 12 00:25:02 2011 -0800
1.3 @@ -124,9 +124,7 @@
1.4 #define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF)
1.5 #define SDL_BYTESPERPIXEL(X) \
1.6 (SDL_ISPIXELFORMAT_FOURCC(X) ? \
1.7 - ((((X) == SDL_PIXELFORMAT_YV12) || \
1.8 - ((X) == SDL_PIXELFORMAT_IYUV) || \
1.9 - ((X) == SDL_PIXELFORMAT_YUY2) || \
1.10 + ((((X) == SDL_PIXELFORMAT_YUY2) || \
1.11 ((X) == SDL_PIXELFORMAT_UYVY) || \
1.12 ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
1.13
2.1 --- a/src/render/opengl/SDL_render_gl.c Fri Feb 11 23:02:35 2011 -0800
2.2 +++ b/src/render/opengl/SDL_render_gl.c Sat Feb 12 00:25:02 2011 -0800
2.3 @@ -119,6 +119,11 @@
2.4 void *pixels;
2.5 int pitch;
2.6 SDL_Rect locked_rect;
2.7 +
2.8 + /* YV12 texture support */
2.9 + SDL_bool yuv;
2.10 + GLuint utexture;
2.11 + GLuint vtexture;
2.12 } GL_TextureData;
2.13
2.14
2.15 @@ -292,12 +297,11 @@
2.16 SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
2.17 data->shaders ? "ENABLED" : "DISABLED");
2.18
2.19 -#if 0
2.20 /* We support YV12 textures using 3 textures and a shader */
2.21 if (data->shaders && data->num_texture_units >= 3) {
2.22 renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
2.23 + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
2.24 }
2.25 -#endif
2.26
2.27 /* Set up parameters for rendering */
2.28 data->blendMode = -1;
2.29 @@ -372,6 +376,12 @@
2.30 *format = GL_BGRA;
2.31 *type = GL_UNSIGNED_INT_8_8_8_8_REV;
2.32 break;
2.33 + case SDL_PIXELFORMAT_YV12:
2.34 + case SDL_PIXELFORMAT_IYUV:
2.35 + *internalFormat = GL_LUMINANCE;
2.36 + *format = GL_LUMINANCE;
2.37 + *type = GL_UNSIGNED_BYTE;
2.38 + break;
2.39 default:
2.40 return SDL_FALSE;
2.41 }
2.42 @@ -404,8 +414,15 @@
2.43 }
2.44
2.45 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
2.46 + size_t size;
2.47 data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
2.48 - data->pixels = SDL_malloc(texture->h * data->pitch);
2.49 + size = texture->h * data->pitch;
2.50 + if (texture->format == SDL_PIXELFORMAT_YV12 ||
2.51 + texture->format == SDL_PIXELFORMAT_IYUV) {
2.52 + /* Need to add size for the U and V planes */
2.53 + size += (2 * (texture->h * data->pitch) / 4);
2.54 + }
2.55 + data->pixels = SDL_malloc(size);
2.56 if (!data->pixels) {
2.57 SDL_OutOfMemory();
2.58 SDL_free(data);
2.59 @@ -478,6 +495,41 @@
2.60 GL_SetError("glTexImage2D()", result);
2.61 return -1;
2.62 }
2.63 +
2.64 + if (texture->format == SDL_PIXELFORMAT_YV12 ||
2.65 + texture->format == SDL_PIXELFORMAT_IYUV) {
2.66 + data->yuv = SDL_TRUE;
2.67 +
2.68 + renderdata->glGenTextures(1, &data->utexture);
2.69 + renderdata->glGenTextures(1, &data->vtexture);
2.70 + renderdata->glEnable(data->type);
2.71 +
2.72 + renderdata->glBindTexture(data->type, data->utexture);
2.73 + renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
2.74 + GL_LINEAR);
2.75 + renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
2.76 + GL_LINEAR);
2.77 + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
2.78 + GL_CLAMP_TO_EDGE);
2.79 + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
2.80 + GL_CLAMP_TO_EDGE);
2.81 + renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
2.82 + texture_h/2, 0, format, type, NULL);
2.83 +
2.84 + renderdata->glBindTexture(data->type, data->vtexture);
2.85 + renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
2.86 + GL_LINEAR);
2.87 + renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
2.88 + GL_LINEAR);
2.89 + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
2.90 + GL_CLAMP_TO_EDGE);
2.91 + renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
2.92 + GL_CLAMP_TO_EDGE);
2.93 + renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2,
2.94 + texture_h/2, 0, format, type, NULL);
2.95 +
2.96 + renderdata->glDisable(data->type);
2.97 + }
2.98 return 0;
2.99 }
2.100
2.101 @@ -500,6 +552,35 @@
2.102 renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
2.103 rect->h, data->format, data->formattype,
2.104 pixels);
2.105 + if (data->yuv) {
2.106 + /* Skip to the top of the next texture */
2.107 + const void *top = (const void*)((const Uint8*)pixels + (texture->h-rect->y) * pitch - rect->x);
2.108 +
2.109 + /* Skip to the correct offset into the next texture */
2.110 + pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
2.111 + if (texture->format == SDL_PIXELFORMAT_YV12) {
2.112 + renderdata->glBindTexture(data->type, data->vtexture);
2.113 + } else {
2.114 + renderdata->glBindTexture(data->type, data->utexture);
2.115 + }
2.116 + renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
2.117 + rect->w/2, rect->h/2,
2.118 + data->format, data->formattype, pixels);
2.119 +
2.120 + /* Skip to the top of the next texture */
2.121 + top = (const void*)((const Uint8*)top + (texture->h * pitch)/4);
2.122 +
2.123 + /* Skip to the correct offset into the next texture */
2.124 + pixels = (const void*)((const Uint8*)top + (rect->y / 2) * pitch + rect->x / 2);
2.125 + if (texture->format == SDL_PIXELFORMAT_YV12) {
2.126 + renderdata->glBindTexture(data->type, data->utexture);
2.127 + } else {
2.128 + renderdata->glBindTexture(data->type, data->vtexture);
2.129 + }
2.130 + renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
2.131 + rect->w/2, rect->h/2,
2.132 + data->format, data->formattype, pixels);
2.133 + }
2.134 renderdata->glDisable(data->type);
2.135 result = renderdata->glGetError();
2.136 if (result != GL_NO_ERROR) {
2.137 @@ -750,6 +831,13 @@
2.138 maxv *= texturedata->texh;
2.139
2.140 data->glEnable(texturedata->type);
2.141 + if (texturedata->yuv) {
2.142 + data->glActiveTextureARB(GL_TEXTURE2_ARB);
2.143 + data->glBindTexture(texturedata->type, texturedata->vtexture);
2.144 + data->glActiveTextureARB(GL_TEXTURE1_ARB);
2.145 + data->glBindTexture(texturedata->type, texturedata->utexture);
2.146 + data->glActiveTextureARB(GL_TEXTURE0_ARB);
2.147 + }
2.148 data->glBindTexture(texturedata->type, texturedata->texture);
2.149
2.150 if (texture->modMode) {
2.151 @@ -762,7 +850,11 @@
2.152 }
2.153
2.154 GL_SetBlendMode(data, texture->blendMode);
2.155 - GL_SelectShader(data->shaders, SHADER_RGB);
2.156 + if (texturedata->yuv) {
2.157 + GL_SelectShader(data->shaders, SHADER_YV12);
2.158 + } else {
2.159 + GL_SelectShader(data->shaders, SHADER_RGB);
2.160 + }
2.161
2.162 data->glBegin(GL_TRIANGLE_STRIP);
2.163 data->glTexCoord2f(minu, minv);
2.164 @@ -848,6 +940,10 @@
2.165 if (data->texture) {
2.166 renderdata->glDeleteTextures(1, &data->texture);
2.167 }
2.168 + if (data->yuv) {
2.169 + renderdata->glDeleteTextures(1, &data->utexture);
2.170 + renderdata->glDeleteTextures(1, &data->vtexture);
2.171 + }
2.172 if (data->pixels) {
2.173 SDL_free(data->pixels);
2.174 }
3.1 --- a/test/testoverlay2.c Fri Feb 11 23:02:35 2011 -0800
3.2 +++ b/test/testoverlay2.c Sat Feb 12 00:25:02 2011 -0800
3.3 @@ -360,7 +360,7 @@
3.4 int fps = 12;
3.5 int fpsdelay;
3.6 int nodelay = 0;
3.7 - int overlay_format = SDL_YUY2_OVERLAY;
3.8 + Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
3.9 int scale = 5;
3.10 SDL_bool done = SDL_FALSE;
3.11
3.12 @@ -397,15 +397,15 @@
3.13 } else if (strcmp(argv[1], "-format") == 0) {
3.14 if (argv[2]) {
3.15 if (!strcmp(argv[2], "YV12"))
3.16 - overlay_format = SDL_YV12_OVERLAY;
3.17 + pixel_format = SDL_PIXELFORMAT_YV12;
3.18 else if (!strcmp(argv[2], "IYUV"))
3.19 - overlay_format = SDL_IYUV_OVERLAY;
3.20 + pixel_format = SDL_PIXELFORMAT_IYUV;
3.21 else if (!strcmp(argv[2], "YUY2"))
3.22 - overlay_format = SDL_YUY2_OVERLAY;
3.23 + pixel_format = SDL_PIXELFORMAT_YUY2;
3.24 else if (!strcmp(argv[2], "UYVY"))
3.25 - overlay_format = SDL_UYVY_OVERLAY;
3.26 + pixel_format = SDL_PIXELFORMAT_UYVY;
3.27 else if (!strcmp(argv[2], "YVYU"))
3.28 - overlay_format = SDL_YVYU_OVERLAY;
3.29 + pixel_format = SDL_PIXELFORMAT_YVYU;
3.30 else {
3.31 fprintf(stderr,
3.32 "The -format option %s is not recognized, see help for info.\n",
3.33 @@ -490,7 +490,7 @@
3.34 quit(4);
3.35 }
3.36
3.37 - MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
3.38 + MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
3.39 if (!MooseTexture) {
3.40 fprintf(stderr, "Couldn't set create texture: %s\n", SDL_GetError());
3.41 free(RawMooseData);
3.42 @@ -569,7 +569,7 @@
3.43 if (!paused) {
3.44 i = (i + 1) % MOOSEFRAMES_COUNT;
3.45
3.46 - SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*2);
3.47 + SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
3.48 }
3.49 SDL_RenderClear(renderer);
3.50 SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);