[590/906] up/download: fix scaling on transfer

i.e. uploading from a 10x10 video frame to a 20x20 texture into another 30x30 videoframe
This commit is contained in:
Matthew Waters 2012-09-25 15:20:21 +10:00
parent 17425aaaac
commit 4716682c55
6 changed files with 247 additions and 231 deletions

View file

@ -174,11 +174,8 @@ gst_gl_display_init (GstGLDisplay * display)
display->gen_shader = NULL; display->gen_shader = NULL;
display->del_shader = NULL; display->del_shader = NULL;
display->uploads = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, display->uploads = NULL;
g_object_unref); display->downloads = NULL;
display->downloads =
g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free,
g_object_unref);
#ifdef OPENGL_ES2 #ifdef OPENGL_ES2
display->redisplay_vertex_shader_str = display->redisplay_vertex_shader_str =
@ -267,11 +264,11 @@ gst_gl_display_finalize (GObject * object)
display->error_message = NULL; display->error_message = NULL;
} }
if (display->uploads) { if (display->uploads) {
g_hash_table_destroy (display->uploads); g_slist_free_full (display->uploads, g_object_unref);
display->uploads = NULL; display->uploads = NULL;
} }
if (display->downloads) { if (display->downloads) {
g_hash_table_destroy (display->downloads); g_slist_free_full (display->downloads, g_object_unref);
display->downloads = NULL; display->downloads = NULL;
} }
} }

View file

@ -129,8 +129,8 @@ struct _GstGLDisplay
GstGLDisplayConversion colorspace_conversion; GstGLDisplayConversion colorspace_conversion;
GHashTable *uploads; GSList *uploads;
GHashTable *downloads; GSList *downloads;
//foreign gl context //foreign gl context
gulong external_gl_context; gulong external_gl_context;

View file

@ -244,23 +244,23 @@ gst_gl_download_finalize (GObject * object)
static inline gboolean static inline gboolean
_init_format_pre (GstGLDownload * download, GstVideoFormat v_format, _init_format_pre (GstGLDownload * download, GstVideoFormat v_format,
guint width, guint height) guint out_width, guint out_height)
{ {
g_return_val_if_fail (download != NULL, FALSE); g_return_val_if_fail (download != NULL, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE);
g_return_val_if_fail (width > 0 && height > 0, FALSE); g_return_val_if_fail (out_width > 0 && out_height > 0, FALSE);
return TRUE; return TRUE;
} }
gboolean gboolean
gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format,
guint width, guint height) guint out_width, guint out_height)
{ {
GstVideoInfo info; GstVideoInfo info;
if (!_init_format_pre (download, v_format, width, height)) if (!_init_format_pre (download, v_format, out_width, out_height))
return FALSE; return FALSE;
g_mutex_lock (&download->lock); g_mutex_lock (&download->lock);
@ -272,7 +272,7 @@ gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format,
download->initted = TRUE; download->initted = TRUE;
} }
gst_video_info_set_format (&info, v_format, width, height); gst_video_info_set_format (&info, v_format, out_width, out_height);
download->info = info; download->info = info;
@ -286,11 +286,11 @@ gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format,
gboolean gboolean
gst_gl_download_init_format_thread (GstGLDownload * download, gst_gl_download_init_format_thread (GstGLDownload * download,
GstVideoFormat v_format, guint width, guint height) GstVideoFormat v_format, guint out_width, guint out_height)
{ {
GstVideoInfo info; GstVideoInfo info;
if (!_init_format_pre (download, v_format, width, height)) if (!_init_format_pre (download, v_format, out_width, out_height))
return FALSE; return FALSE;
g_mutex_lock (&download->lock); g_mutex_lock (&download->lock);
@ -302,7 +302,7 @@ gst_gl_download_init_format_thread (GstGLDownload * download,
download->initted = TRUE; download->initted = TRUE;
} }
gst_video_info_set_format (&info, v_format, width, height); gst_video_info_set_format (&info, v_format, out_width, out_height);
download->info = info; download->info = info;
@ -471,28 +471,31 @@ gst_gl_download_perform_with_data_unlocked_thread (GstGLDownload * download,
return TRUE; return TRUE;
} }
static inline guint64 * GstGLDownload *
_gen_key (GstVideoFormat v_format, guint width, guint height) gst_gl_display_find_download_unlocked (GstGLDisplay * display,
{ GstVideoFormat v_format, guint out_width, guint out_height)
guint64 *key;
/* this limits the width and the height to 2^29-1 = 536870911 */
key = g_malloc (sizeof (guint64 *));
*key = v_format | ((guint64) width << 6) | ((guint64) height << 35);
return key;
}
static inline GstGLDownload *
_find_download (GstGLDisplay * display, guint64 * key)
{ {
GstGLDownload *ret; GstGLDownload *ret;
GSList *walk;
ret = g_hash_table_lookup (display->downloads, key); walk = display->downloads;
while (walk) {
ret = walk->data;
if (ret && v_format == GST_VIDEO_INFO_FORMAT (&ret->info) &&
out_width == GST_VIDEO_INFO_WIDTH (&ret->info) &&
out_height == GST_VIDEO_INFO_HEIGHT (&ret->info))
break;
ret = NULL;
walk = g_slist_next (walk);
}
if (!ret) { if (!ret) {
ret = gst_gl_download_new (display); ret = gst_gl_download_new (display);
g_hash_table_insert (display->downloads, key, ret); display->downloads = g_slist_prepend (display->downloads, ret);
} }
return ret; return ret;
@ -500,45 +503,29 @@ _find_download (GstGLDisplay * display, guint64 * key)
GstGLDownload * GstGLDownload *
gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format,
guint width, guint height) guint out_width, guint out_height)
{ {
GstGLDownload *ret; GstGLDownload *ret;
guint64 *key;
key = _gen_key (v_format, width, height);
gst_gl_display_lock (display); gst_gl_display_lock (display);
ret = _find_download (display, key); ret = gst_gl_display_find_download_unlocked (display, v_format,
out_width, out_height);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
return ret; return ret;
} }
GstGLDownload *
gst_gl_display_find_download_thread (GstGLDisplay * display,
GstVideoFormat v_format, guint width, guint height)
{
GstGLDownload *ret;
guint64 *key;
key = _gen_key (v_format, width, height);
ret = _find_download (display, key);
return ret;
}
static void static void
_init_download (GstGLDisplay * display, GstGLDownload * download) _init_download (GstGLDisplay * display, GstGLDownload * download)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint out_width, out_height;
width = GST_VIDEO_INFO_WIDTH (&download->info);
height = GST_VIDEO_INFO_HEIGHT (&download->info);
v_format = GST_VIDEO_INFO_FORMAT (&download->info); v_format = GST_VIDEO_INFO_FORMAT (&download->info);
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
GST_TRACE ("initializing texture download for format %d", v_format); GST_TRACE ("initializing texture download for format %d", v_format);
@ -569,11 +556,11 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
*/ */
gst_gl_display_set_error (display, gst_gl_display_set_error (display,
"Context, EXT_framebuffer_object supported: no"); "Context, EXT_framebuffer_object supported: no");
return;
} }
GST_INFO ("Context, EXT_framebuffer_object supported: yes"); GST_INFO ("Context, EXT_framebuffer_object supported: yes");
/* setup FBO */ /* setup FBO */
if (!download->fbo && !download->depth_buffer) {
glGenFramebuffersEXT (1, &download->fbo); glGenFramebuffersEXT (1, &download->fbo);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo);
@ -582,20 +569,19 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, download->depth_buffer); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, download->depth_buffer);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
width, height); out_width, out_height);
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
width, height); out_width, out_height);
#else #else
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16,
width, height); out_width, out_height);
#endif #endif
}
/* setup a first texture to render to */ /* setup a first texture to render to */
glGenTextures (1, &download->out_texture[0]); glGenTextures (1, &download->out_texture[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[0]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); out_width, out_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
@ -615,7 +601,7 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
glGenTextures (1, &download->out_texture[1]); glGenTextures (1, &download->out_texture[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[1]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); out_width, out_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
@ -634,7 +620,7 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
glGenTextures (1, &download->out_texture[2]); glGenTextures (1, &download->out_texture[2]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[2]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); out_width, out_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
GL_LINEAR); GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
@ -901,14 +887,14 @@ static void
_do_download (GstGLDisplay * display, GstGLDownload * download) _do_download (GstGLDisplay * display, GstGLDownload * download)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint out_width, out_height;
width = GST_VIDEO_INFO_WIDTH (&download->info);
height = GST_VIDEO_INFO_HEIGHT (&download->info);
v_format = GST_VIDEO_INFO_FORMAT (&download->info); v_format = GST_VIDEO_INFO_FORMAT (&download->info);
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
GST_TRACE ("downloading texture:%u format:%d, dimensions:%ux%u", GST_TRACE ("downloading texture:%u format:%d, dimensions:%ux%u",
download->in_texture, v_format, width, height); download->in_texture, v_format, out_width, out_height);
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_RGBx:
@ -953,10 +939,10 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download)
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture);
#else #else
guint width, height; guint out_width, out_height;
width = GST_VIDEO_INFO_WIDTH (&download->info); out_width = GST_VIDEO_INFO_WIDTH (&download->info);
height = GST_VIDEO_INFO_HEIGHT (&download->info); out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f, const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f,
1.0f, 0.0f, 1.0f, 0.0f,
@ -970,7 +956,7 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download)
GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
glViewport (0, 0, width, height); glViewport (0, 0, out_width, out_height);
glClearColor (0.0, 0.0, 0.0, 0.0); glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -1003,7 +989,7 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download)
glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
GL_UNSIGNED_BYTE, download->data[0]); GL_UNSIGNED_BYTE, download->data[0]);
#else #else
glReadPixels (0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, glReadPixels (0, 0, out_width, out_height, GL_RGBA, GL_UNSIGNED_BYTE,
download->data[0]); download->data[0]);
#endif #endif
break; break;
@ -1019,10 +1005,10 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download)
#endif /* G_BYTE_ORDER */ #endif /* G_BYTE_ORDER */
#else /* OPENGL_ES2 */ #else /* OPENGL_ES2 */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN #if G_BYTE_ORDER == G_LITTLE_ENDIAN
glReadPixels (0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, glReadPixels (0, 0, out_width, out_eight, GL_BGRA,
download->data[0]); GL_UNSIGNED_INT_8_8_8_8, download->data[0]);
#else #else
glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_BGRA, glReadPixels (0, 0, out_width, out_eight, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]);
#endif /* G_BYTE_ORDER */ #endif /* G_BYTE_ORDER */
#endif /* !OPENGL_ES2 */ #endif /* !OPENGL_ES2 */
@ -1051,7 +1037,7 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download)
glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
GL_UNSIGNED_BYTE, download->data[0]); GL_UNSIGNED_BYTE, download->data[0]);
#else #else
glReadPixels (0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, glReadPixels (0, 0, out_width, out_height, GL_RGB, GL_UNSIGNED_BYTE,
download->data[0]); download->data[0]);
#endif #endif
break; break;
@ -1080,7 +1066,7 @@ static void
_do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint out_width, out_height;
GLenum multipleRT[] = { GLenum multipleRT[] = {
GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT0_EXT,
@ -1104,10 +1090,13 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
#endif #endif
width = GST_VIDEO_INFO_WIDTH (&download->info); out_width = GST_VIDEO_INFO_WIDTH (&download->info);
height = GST_VIDEO_INFO_HEIGHT (&download->info); out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
v_format = GST_VIDEO_INFO_FORMAT (&download->info); v_format = GST_VIDEO_INFO_FORMAT (&download->info);
GST_TRACE ("doing YUV download of texture:%u (%ux%u) using fbo:%u",
download->in_texture, out_width, out_height, download->fbo);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
@ -1116,7 +1105,7 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glPushMatrix (); glPushMatrix ();
glLoadIdentity (); glLoadIdentity ();
gluOrtho2D (0.0, width, 0.0, height); gluOrtho2D (0.0, out_width, 0.0, out_height);
glMatrixMode (GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
glPushMatrix (); glPushMatrix ();
@ -1125,7 +1114,7 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
glGetIntegerv (GL_VIEWPORT, viewport_dim); glGetIntegerv (GL_VIEWPORT, viewport_dim);
#endif #endif
glViewport (0, 0, width, height); glViewport (0, 0, out_width, out_height);
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
@ -1179,8 +1168,8 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
glActiveTextureARB (GL_TEXTURE0_ARB); glActiveTextureARB (GL_TEXTURE0_ARB);
gst_gl_shader_set_uniform_1i (download->shader, "tex", 0); gst_gl_shader_set_uniform_1i (download->shader, "tex", 0);
gst_gl_shader_set_uniform_1f (download->shader, "w", (gfloat) width); gst_gl_shader_set_uniform_1f (download->shader, "w", (gfloat) out_width);
gst_gl_shader_set_uniform_1f (download->shader, "h", (gfloat) height); gst_gl_shader_set_uniform_1f (download->shader, "h", (gfloat) out_height);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture);
} }
break; break;
@ -1196,11 +1185,11 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
glBegin (GL_QUADS); glBegin (GL_QUADS);
glTexCoord2i (0, 0); glTexCoord2i (0, 0);
glVertex2f (-1.0f, -1.0f); glVertex2f (-1.0f, -1.0f);
glTexCoord2i (width, 0); glTexCoord2i (out_width, 0);
glVertex2f (1.0f, -1.0f); glVertex2f (1.0f, -1.0f);
glTexCoord2i (width, height); glTexCoord2i (out_width, out_height);
glVertex2f (1.0f, 1.0f); glVertex2f (1.0f, 1.0f);
glTexCoord2i (0, height); glTexCoord2i (0, out_height);
glVertex2f (-1.0f, 1.0f); glVertex2f (-1.0f, 1.0f);
glEnd (); glEnd ();
@ -1229,8 +1218,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
gst_gl_display_check_framebuffer_status (); gst_gl_display_check_framebuffer_status ();
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
@ -1239,64 +1226,64 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download)
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_AYUV:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN #if G_BYTE_ORDER == G_LITTLE_ENDIAN
glReadPixels (0, 0, width, height, GL_BGRA, glReadPixels (0, 0, out_width, out_height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8, download->data[0]); GL_UNSIGNED_INT_8_8_8_8, download->data[0]);
#else #else
glReadPixels (0, 0, width, height, GL_BGRA, glReadPixels (0, 0, out_width, out_height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]);
#endif #endif
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY: case GST_VIDEO_FORMAT_UYVY:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN #if G_BYTE_ORDER == G_LITTLE_ENDIAN
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, height, GL_BGRA, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, out_height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]); GL_UNSIGNED_INT_8_8_8_8_REV, download->data[0]);
#else #else
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, height, GL_BGRA, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, out_height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8, download->data[0]); GL_UNSIGNED_INT_8_8_8_8, download->data[0]);
#endif #endif
break; break;
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
{ {
glReadPixels (0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[0]); download->data[0]);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
#endif #endif
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[1]); download->data[1]);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); glReadBuffer (GL_COLOR_ATTACHMENT2_EXT);
#endif #endif
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[2]); download->data[2]);
} }
break; break;
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
{ {
glReadPixels (0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, glReadPixels (0, 0, out_width, out_height, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[0]); download->data[0]);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
#endif #endif
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[2]); download->data[2]);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); glReadBuffer (GL_COLOR_ATTACHMENT2_EXT);
#endif #endif
glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[1]); download->data[1]);
} }
break; break;

View file

@ -90,9 +90,9 @@ struct _GstGLDownloadClass
GstGLDownload * gst_gl_download_new (GstGLDisplay * display); GstGLDownload * gst_gl_download_new (GstGLDisplay * display);
gboolean gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, gboolean gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format,
guint width, guint height); guint out_width, guint out_height);
gboolean gst_gl_download_init_format_thread (GstGLDownload * download, GstVideoFormat v_format, gboolean gst_gl_download_init_format_thread (GstGLDownload * download, GstVideoFormat v_format,
guint width, guint height); guint out_width, guint out_height);
gboolean gst_gl_download_perform_with_memory_thread (GstGLDownload * download, GstGLMemory * gl_mem); gboolean gst_gl_download_perform_with_memory_thread (GstGLDownload * download, GstGLMemory * gl_mem);
gboolean gst_gl_download_perform_with_data_thread (GstGLDownload * download, GLuint texture_id, gboolean gst_gl_download_perform_with_data_thread (GstGLDownload * download, GLuint texture_id,
@ -102,10 +102,10 @@ gboolean gst_gl_download_perform_with_memory (GstGLDownload * download, G
gboolean gst_gl_download_perform_with_data (GstGLDownload * download, GLuint texture_id, gboolean gst_gl_download_perform_with_data (GstGLDownload * download, GLuint texture_id,
gpointer data[GST_VIDEO_MAX_PLANES]); gpointer data[GST_VIDEO_MAX_PLANES]);
GstGLDownload * gst_gl_display_find_download_thread (GstGLDisplay * display, GstVideoFormat v_format, GstGLDownload * gst_gl_display_find_download_unlocked (GstGLDisplay * display, GstVideoFormat v_format,
guint width, guint height); guint out_width, guint out_height);
GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format,
guint width, guint height); guint out_width, guint out_height);
G_END_DECLS G_END_DECLS

View file

@ -220,14 +220,15 @@ gst_gl_upload_finalize (GObject * object)
gboolean gboolean
gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format, gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format,
guint width, guint height) guint in_width, guint in_height, guint out_width, guint out_height)
{ {
GstVideoInfo info; GstVideoInfo info;
g_return_val_if_fail (upload != NULL, FALSE); g_return_val_if_fail (upload != NULL, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE);
g_return_val_if_fail (width > 0 && height > 0, FALSE); g_return_val_if_fail (in_width > 0 && in_height > 0, FALSE);
g_return_val_if_fail (out_width > 0 && out_height > 0, FALSE);
g_mutex_lock (&upload->lock); g_mutex_lock (&upload->lock);
@ -238,9 +239,11 @@ gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format,
upload->initted = TRUE; upload->initted = TRUE;
} }
gst_video_info_set_format (&info, v_format, width, height); gst_video_info_set_format (&info, v_format, out_width, out_height);
upload->info = info; upload->info = info;
upload->in_width = in_width;
upload->in_height = in_height;
gst_gl_display_thread_add (upload->display, gst_gl_display_thread_add (upload->display,
(GstGLDisplayThreadFunc) _init_upload, upload); (GstGLDisplayThreadFunc) _init_upload, upload);
@ -252,14 +255,15 @@ gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format,
gboolean gboolean
gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format, gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format,
guint width, guint height) guint in_width, guint in_height, guint out_width, guint out_height)
{ {
GstVideoInfo info; GstVideoInfo info;
g_return_val_if_fail (upload != NULL, FALSE); g_return_val_if_fail (upload != NULL, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE); g_return_val_if_fail (v_format != GST_VIDEO_FORMAT_ENCODED, FALSE);
g_return_val_if_fail (width > 0 && height > 0, FALSE); g_return_val_if_fail (in_width > 0 && in_height > 0, FALSE);
g_return_val_if_fail (out_width > 0 && out_height > 0, FALSE);
g_mutex_lock (&upload->lock); g_mutex_lock (&upload->lock);
@ -270,9 +274,11 @@ gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format,
upload->initted = TRUE; upload->initted = TRUE;
} }
gst_video_info_set_format (&info, v_format, width, height); gst_video_info_set_format (&info, v_format, out_width, out_height);
upload->info = info; upload->info = info;
upload->in_width = in_width;
upload->in_height = in_height;
_init_upload (upload->display, upload); _init_upload (upload->display, upload);
@ -298,6 +304,9 @@ gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem)
g_mutex_lock (&upload->lock); g_mutex_lock (&upload->lock);
upload->in_width = GST_VIDEO_INFO_WIDTH (&upload->info);
upload->in_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) { for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) {
data[i] = (guint8 *) gl_mem->data + data[i] = (guint8 *) gl_mem->data +
GST_VIDEO_INFO_PLANE_OFFSET (&upload->info, i); GST_VIDEO_INFO_PLANE_OFFSET (&upload->info, i);
@ -342,10 +351,6 @@ _perform_with_data_unlocked_pre (GstGLUpload * upload,
&& GST_VIDEO_INFO_FORMAT (&upload->info) != GST_VIDEO_FORMAT_ENCODED, && GST_VIDEO_INFO_FORMAT (&upload->info) != GST_VIDEO_FORMAT_ENCODED,
FALSE); FALSE);
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) {
g_return_val_if_fail (data[i] != NULL, FALSE);
}
upload->out_texture = texture_id; upload->out_texture = texture_id;
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) { for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) {
upload->data[i] = data[i]; upload->data[i] = data[i];
@ -432,28 +437,33 @@ gst_gl_upload_perform_with_data_unlocked_thread (GstGLUpload * upload,
return TRUE; return TRUE;
} }
static inline guint64 * GstGLUpload *
_gen_key (GstVideoFormat v_format, guint width, guint height) gst_gl_display_find_upload_unlocked (GstGLDisplay * display,
{ GstVideoFormat v_format, guint in_width, guint in_height,
guint64 *key; guint out_width, guint out_height)
/* this limits the width and the height to 2^29-1 = 536870911 */
key = g_malloc (sizeof (guint64 *));
*key = v_format | ((guint64) width << 6) | ((guint64) height << 35);
return key;
}
static inline GstGLUpload *
_find_upload (GstGLDisplay * display, guint64 * key)
{ {
GstGLUpload *ret; GstGLUpload *ret;
GSList *walk;
ret = g_hash_table_lookup (display->uploads, key); walk = display->uploads;
while (walk) {
ret = walk->data;
if (ret && v_format == GST_VIDEO_INFO_FORMAT (&ret->info) &&
out_width == GST_VIDEO_INFO_WIDTH (&ret->info) &&
out_height == GST_VIDEO_INFO_HEIGHT (&ret->info) &&
in_width == ret->in_width && in_height == ret->in_height)
break;
ret = NULL;
walk = g_slist_next (walk);
}
if (!ret) { if (!ret) {
ret = gst_gl_upload_new (display); ret = gst_gl_upload_new (display);
g_hash_table_insert (display->uploads, key, ret); display->uploads = g_slist_prepend (display->uploads, ret);
} }
return ret; return ret;
@ -461,43 +471,33 @@ _find_upload (GstGLDisplay * display, guint64 * key)
GstGLUpload * GstGLUpload *
gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format,
guint width, guint height) guint in_width, guint in_height, guint out_width, guint out_height)
{ {
GstGLUpload *ret; GstGLUpload *ret;
guint64 *key;
key = _gen_key (v_format, width, height);
gst_gl_display_lock (display); gst_gl_display_lock (display);
ret = _find_upload (display, key); ret =
gst_gl_display_find_upload_unlocked (display, v_format, in_width,
in_height, out_width, out_height);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
return ret; return ret;
} }
GstGLUpload *
gst_gl_display_find_upload_thread (GstGLDisplay * display,
GstVideoFormat v_format, guint width, guint height)
{
GstGLUpload *ret;
guint64 *key;
key = _gen_key (v_format, width, height);
ret = _find_upload (display, key);
return ret;
}
/* Called in the gl thread */ /* Called in the gl thread */
void void
_init_upload (GstGLDisplay * display, GstGLUpload * upload) _init_upload (GstGLDisplay * display, GstGLUpload * upload)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint in_width, in_height, out_width, out_height;
v_format = GST_VIDEO_INFO_FORMAT (&upload->info); v_format = GST_VIDEO_INFO_FORMAT (&upload->info);
in_width = upload->in_width;
in_height = upload->in_height;
out_width = GST_VIDEO_INFO_WIDTH (&upload->info);
out_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
GST_TRACE ("initializing texture upload for format:%d", v_format); GST_TRACE ("initializing texture upload for format:%d", v_format);
@ -512,6 +512,8 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
if (in_width != out_width || in_height != out_height)
_init_upload_fbo (display, upload);
/* color space conversion is not needed */ /* color space conversion is not needed */
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
@ -771,11 +773,11 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
void void
_init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload) _init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload)
{ {
guint width, height; guint out_width, out_height;
GLuint fake_texture = 0; /* a FBO must hava texture to init */ GLuint fake_texture = 0; /* a FBO must hava texture to init */
width = GST_VIDEO_INFO_WIDTH (&upload->info); out_width = GST_VIDEO_INFO_WIDTH (&upload->info);
height = GST_VIDEO_INFO_HEIGHT (&upload->info); out_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
if (!GLEW_EXT_framebuffer_object) { if (!GLEW_EXT_framebuffer_object) {
/* turn off the pipeline because Frame buffer object is a not present */ /* turn off the pipeline because Frame buffer object is a not present */
@ -795,18 +797,18 @@ _init_upload_fbo (GstGLDisplay * display, GstGLUpload * upload)
glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, upload->depth_buffer); glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, upload->depth_buffer);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
width, height); out_width, out_height);
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
width, height); out_width, out_height);
#else #else
glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16,
width, height); out_width, out_height);
#endif #endif
/* a fake texture is attached to the upload FBO (cannot init without it) */ /* a fake texture is attached to the upload FBO (cannot init without it) */
glGenTextures (1, &fake_texture); glGenTextures (1, &fake_texture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, out_width, out_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL); GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -847,14 +849,16 @@ void
_do_upload (GstGLDisplay * display, GstGLUpload * upload) _do_upload (GstGLDisplay * display, GstGLUpload * upload)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint in_width, in_height, out_width, out_height;
width = GST_VIDEO_INFO_WIDTH (&upload->info); out_width = GST_VIDEO_INFO_WIDTH (&upload->info);
height = GST_VIDEO_INFO_HEIGHT (&upload->info); out_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
v_format = GST_VIDEO_INFO_FORMAT (&upload->info); v_format = GST_VIDEO_INFO_FORMAT (&upload->info);
in_width = upload->in_width;
in_height = upload->in_height;
GST_TRACE ("uploading texture:%u dimensions: %ux%u", upload->out_texture, GST_TRACE ("uploading texture:%u dimensions: %ux%u", upload->out_texture,
width, height); out_width, out_height);
_do_upload_fill (display, upload); _do_upload_fill (display, upload);
@ -869,6 +873,8 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
if (in_width != out_width || in_height != out_height)
_do_upload_draw (display, upload);
/* color space conversion is not needed */ /* color space conversion is not needed */
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
@ -887,6 +893,8 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload)
/* not yet supported */ /* not yet supported */
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
if (in_width != out_width || in_height != out_height)
_do_upload_draw (display, upload);
/* color space conversion is not needed */ /* color space conversion is not needed */
break; break;
default: default:
@ -910,10 +918,10 @@ void
_do_upload_make (GstGLDisplay * display, GstGLUpload * upload) _do_upload_make (GstGLDisplay * display, GstGLUpload * upload)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint in_width, in_height;
width = GST_VIDEO_INFO_WIDTH (&upload->info); in_width = upload->in_width;
height = GST_VIDEO_INFO_HEIGHT (&upload->info); in_height = upload->in_height;
v_format = GST_VIDEO_INFO_FORMAT (&upload->info); v_format = GST_VIDEO_INFO_FORMAT (&upload->info);
glGenTextures (1, &upload->in_texture[0]); glGenTextures (1, &upload->in_texture[0]);
@ -929,31 +937,33 @@ _do_upload_make (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); in_width, in_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break; break;
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); in_width, in_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
break; break;
case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_AYUV:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NULL); in_width, in_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NULL);
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
switch (display->colorspace_conversion) { switch (display->colorspace_conversion) {
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); in_width, in_height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
NULL);
glGenTextures (1, &upload->in_texture[1]); glGenTextures (1, &upload->in_texture[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); in_width, in_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
NULL);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, in_width,
height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); in_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknown colorspace conversion %d", gst_gl_display_set_error (display, "Unknown colorspace conversion %d",
@ -967,15 +977,17 @@ _do_upload_make (GstGLDisplay * display, GstGLUpload * upload)
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA,
width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); in_width, in_height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
NULL);
glGenTextures (1, &upload->in_texture[1]); glGenTextures (1, &upload->in_texture[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); in_width, in_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
NULL);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, in_width,
height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); in_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknown colorspace conversion %d", gst_gl_display_set_error (display, "Unknown colorspace conversion %d",
@ -987,19 +999,21 @@ _do_upload_make (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); in_width, in_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &upload->in_texture[1]); glGenTextures (1, &upload->in_texture[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (in_width) / 2,
GST_ROUND_UP_2 (height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); GST_ROUND_UP_2 (in_height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
NULL);
glGenTextures (1, &upload->in_texture[2]); glGenTextures (1, &upload->in_texture[2]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (in_width) / 2,
GST_ROUND_UP_2 (height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); GST_ROUND_UP_2 (in_height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
NULL);
break; break;
default: default:
@ -1016,10 +1030,12 @@ void
_do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint in_width, in_height, out_width, out_height;
width = GST_VIDEO_INFO_WIDTH (&upload->info); in_width = upload->in_width;
height = GST_VIDEO_INFO_HEIGHT (&upload->info); in_height = upload->in_height;
out_width = GST_VIDEO_INFO_WIDTH (&upload->info);
out_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
v_format = GST_VIDEO_INFO_FORMAT (&upload->info); v_format = GST_VIDEO_INFO_FORMAT (&upload->info);
switch (v_format) { switch (v_format) {
@ -1034,6 +1050,9 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
/* color space conversion is not needed */ /* color space conversion is not needed */
if (in_width != out_width || in_height != out_height)
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]);
else
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture);
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
@ -1047,6 +1066,9 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
if (in_width != out_width || in_height != out_height)
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]);
else
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture);
break; break;
default: default:
@ -1065,49 +1087,50 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_RGB, GL_UNSIGNED_BYTE, upload->data[0]); GL_RGB, GL_UNSIGNED_BYTE, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_BGR, GL_UNSIGNED_BYTE, upload->data[0]); GL_BGR, GL_UNSIGNED_BYTE, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_RGBA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_RGBA, GL_UNSIGNED_BYTE, upload->data[0]); GL_RGBA, GL_UNSIGNED_BYTE, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_BGRA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_BGRA, GL_UNSIGNED_BYTE, upload->data[0]); GL_BGRA, GL_UNSIGNED_BYTE, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, upload->data[0]); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_xBGR: case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, upload->data[0]); GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, upload->data[0]);
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
switch (display->colorspace_conversion) { switch (display->colorspace_conversion) {
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); in_height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, height, GST_ROUND_UP_2 (in_width) / 2, in_height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, upload->data[0]); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, upload->data[0]);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, upload->data[0]); in_height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA,
upload->data[0]);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknow colorspace conversion %d", gst_gl_display_set_error (display, "Unknow colorspace conversion %d",
@ -1120,17 +1143,18 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
switch (display->colorspace_conversion) { switch (display->colorspace_conversion) {
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); in_height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, height, GST_ROUND_UP_2 (in_width) / 2, in_height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, upload->data[0]); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, upload->data[0]);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, upload->data[0]); in_height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA,
upload->data[0]);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknow colorspace conversion %d", gst_gl_display_set_error (display, "Unknow colorspace conversion %d",
@ -1141,33 +1165,33 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
break; break;
case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_I420:
{ {
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[0]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (in_width) / 2, GST_ROUND_UP_2 (in_height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[1]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (in_width) / 2, GST_ROUND_UP_2 (in_height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[2]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[2]);
} }
break; break;
case GST_VIDEO_FORMAT_YV12: /* same as I420 except plane 1+2 swapped */ case GST_VIDEO_FORMAT_YV12: /* same as I420 except plane 1+2 swapped */
{ {
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, in_height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[0]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (in_width) / 2, GST_ROUND_UP_2 (in_height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[1]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[1]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (in_width) / 2, GST_ROUND_UP_2 (in_height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[2]); GL_LUMINANCE, GL_UNSIGNED_BYTE, upload->data[2]);
} }
break; break;
@ -1190,7 +1214,7 @@ void
_do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload)
{ {
GstVideoFormat v_format; GstVideoFormat v_format;
guint width, height; guint in_width, in_height, out_width, out_height;
#ifdef OPENGL_ES2 #ifdef OPENGL_ES2
GLint viewport_dim[4]; GLint viewport_dim[4];
@ -1208,8 +1232,10 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload)
GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
#endif #endif
width = GST_VIDEO_INFO_WIDTH (&upload->info); in_width = upload->in_width;
height = GST_VIDEO_INFO_HEIGHT (&upload->info); in_height = upload->in_height;
out_width = GST_VIDEO_INFO_WIDTH (&upload->info);
out_height = GST_VIDEO_INFO_HEIGHT (&upload->info);
v_format = GST_VIDEO_INFO_FORMAT (&upload->info); v_format = GST_VIDEO_INFO_FORMAT (&upload->info);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, upload->fbo); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, upload->fbo);
@ -1233,7 +1259,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload)
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glPushMatrix (); glPushMatrix ();
glLoadIdentity (); glLoadIdentity ();
gluOrtho2D (0.0, width, 0.0, height); gluOrtho2D (0.0, out_width, 0.0, out_height);
glMatrixMode (GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
glPushMatrix (); glPushMatrix ();
@ -1242,7 +1268,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload)
glGetIntegerv (GL_VIEWPORT, viewport_dim); glGetIntegerv (GL_VIEWPORT, viewport_dim);
#endif #endif
glViewport (0, 0, width, height); glViewport (0, 0, out_width, out_height);
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
@ -1469,13 +1495,13 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload)
#ifndef OPENGL_ES2 #ifndef OPENGL_ES2
glBegin (GL_QUADS); glBegin (GL_QUADS);
glTexCoord2i (width, 0); glTexCoord2i (in_width, 0);
glVertex2f (1.0f, -1.0f); glVertex2f (1.0f, -1.0f);
glTexCoord2i (0, 0); glTexCoord2i (0, 0);
glVertex2f (-1.0f, -1.0f); glVertex2f (-1.0f, -1.0f);
glTexCoord2i (0, height); glTexCoord2i (0, in_height);
glVertex2f (-1.0f, 1.0f); glVertex2f (-1.0f, 1.0f);
glTexCoord2i (width, height); glTexCoord2i (in_width, in_height);
glVertex2f (1.0f, 1.0f); glVertex2f (1.0f, 1.0f);
glEnd (); glEnd ();

View file

@ -60,13 +60,15 @@ struct _GstGLUpload
GLuint depth_buffer; GLuint depth_buffer;
GLuint out_texture; GLuint out_texture;
GLuint in_texture[GST_VIDEO_MAX_PLANES]; GLuint in_texture[GST_VIDEO_MAX_PLANES];
guint in_width;
guint in_height;
GstGLShader *shader; GstGLShader *shader;
#ifdef OPENGL_ES2 #ifdef OPENGL_ES2
GLint shader_attr_position_loc; GLint shader_attr_position_loc;
GLint shader_attr_texture_loc; GLint shader_attr_texture_loc;
#endif #endif
/* output data */ /* input data */
GstVideoInfo info; GstVideoInfo info;
/* <private> */ /* <private> */
@ -90,9 +92,11 @@ struct _GstGLUploadClass
GstGLUpload * gst_gl_upload_new (GstGLDisplay * display); GstGLUpload * gst_gl_upload_new (GstGLDisplay * display);
gboolean gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format, gboolean gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format,
guint width, guint height); guint in_width, guint in_height,
guint out_width, guint out_height);
gboolean gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format, gboolean gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format,
guint width, guint height); guint in_width, guint in_height,
guint out_width, guint out_height);
gboolean gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem); gboolean gst_gl_upload_perform_with_memory (GstGLUpload * upload, GstGLMemory * gl_mem);
gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint texture_id, gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint texture_id,
@ -102,9 +106,11 @@ gboolean gst_gl_upload_perform_with_data_thread (GstGLUpload * upload, GLuint
gpointer data[GST_VIDEO_MAX_PLANES]); gpointer data[GST_VIDEO_MAX_PLANES]);
GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format,
guint width, guint height); guint in_width, guint in_height,
GstGLUpload * gst_gl_display_find_upload_thread (GstGLDisplay * display, GstVideoFormat v_format, guint out_width, guint out_height);
guint width, guint height); GstGLUpload * gst_gl_display_find_upload_unlocked (GstGLDisplay * display, GstVideoFormat v_format,
guint in_width, guint in_height,
guint out_width, guint out_height);
G_END_DECLS G_END_DECLS