From 4716682c558bb57808382cdf4dffae48e862fa87 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Tue, 25 Sep 2012 15:20:21 +1000 Subject: [PATCH] [590/906] up/download: fix scaling on transfer i.e. uploading from a 10x10 video frame to a 20x20 texture into another 30x30 videoframe --- gst-libs/gst/gl/gstgldisplay.c | 11 +- gst-libs/gst/gl/gstgldisplay.h | 4 +- gst-libs/gst/gl/gstgldownload.c | 187 ++++++++++++------------ gst-libs/gst/gl/gstgldownload.h | 12 +- gst-libs/gst/gl/gstglupload.c | 244 ++++++++++++++++++-------------- gst-libs/gst/gl/gstglupload.h | 20 ++- 6 files changed, 247 insertions(+), 231 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index e65234fa5c..aeac4ebd5e 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -174,11 +174,8 @@ gst_gl_display_init (GstGLDisplay * display) display->gen_shader = NULL; display->del_shader = NULL; - display->uploads = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, - g_object_unref); - display->downloads = - g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, - g_object_unref); + display->uploads = NULL; + display->downloads = NULL; #ifdef OPENGL_ES2 display->redisplay_vertex_shader_str = @@ -267,11 +264,11 @@ gst_gl_display_finalize (GObject * object) display->error_message = NULL; } if (display->uploads) { - g_hash_table_destroy (display->uploads); + g_slist_free_full (display->uploads, g_object_unref); display->uploads = NULL; } if (display->downloads) { - g_hash_table_destroy (display->downloads); + g_slist_free_full (display->downloads, g_object_unref); display->downloads = NULL; } } diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 5103ede9ea..8e4b82047b 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -129,8 +129,8 @@ struct _GstGLDisplay GstGLDisplayConversion colorspace_conversion; - GHashTable *uploads; - GHashTable *downloads; + GSList *uploads; + GSList *downloads; //foreign gl context gulong external_gl_context; diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c index d193d0a62d..4126dc6ca6 100644 --- a/gst-libs/gst/gl/gstgldownload.c +++ b/gst-libs/gst/gl/gstgldownload.c @@ -244,23 +244,23 @@ gst_gl_download_finalize (GObject * object) static inline gboolean _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 (v_format != GST_VIDEO_FORMAT_UNKNOWN, 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; } gboolean gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, - guint width, guint height) + guint out_width, guint out_height) { GstVideoInfo info; - if (!_init_format_pre (download, v_format, width, height)) + if (!_init_format_pre (download, v_format, out_width, out_height)) return FALSE; g_mutex_lock (&download->lock); @@ -272,7 +272,7 @@ gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, 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; @@ -286,11 +286,11 @@ gst_gl_download_init_format (GstGLDownload * download, GstVideoFormat v_format, gboolean 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; - if (!_init_format_pre (download, v_format, width, height)) + if (!_init_format_pre (download, v_format, out_width, out_height)) return FALSE; g_mutex_lock (&download->lock); @@ -302,7 +302,7 @@ gst_gl_download_init_format_thread (GstGLDownload * download, 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; @@ -471,28 +471,31 @@ gst_gl_download_perform_with_data_unlocked_thread (GstGLDownload * download, return TRUE; } -static inline guint64 * -_gen_key (GstVideoFormat v_format, guint width, guint 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 * +gst_gl_display_find_download_unlocked (GstGLDisplay * display, + GstVideoFormat v_format, guint out_width, guint out_height) { 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) { ret = gst_gl_download_new (display); - g_hash_table_insert (display->downloads, key, ret); + display->downloads = g_slist_prepend (display->downloads, ret); } return ret; @@ -500,45 +503,29 @@ _find_download (GstGLDisplay * display, guint64 * key) GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height) + guint out_width, guint out_height) { GstGLDownload *ret; - guint64 *key; - - key = _gen_key (v_format, width, height); 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); 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 _init_download (GstGLDisplay * display, GstGLDownload * download) { 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); + 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); @@ -569,33 +556,32 @@ _init_download (GstGLDisplay * display, GstGLDownload * download) */ gst_gl_display_set_error (display, "Context, EXT_framebuffer_object supported: no"); + return; } GST_INFO ("Context, EXT_framebuffer_object supported: yes"); /* setup FBO */ - if (!download->fbo && !download->depth_buffer) { - glGenFramebuffersEXT (1, &download->fbo); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); + glGenFramebuffersEXT (1, &download->fbo); + glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); - /* setup the render buffer for depth */ - glGenRenderbuffersEXT (1, &download->depth_buffer); - glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, download->depth_buffer); + /* setup the render buffer for depth */ + glGenRenderbuffersEXT (1, &download->depth_buffer); + glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, download->depth_buffer); #ifndef OPENGL_ES2 - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - width, height); - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, - width, height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + out_width, out_height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, + out_width, out_height); #else - glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - width, height); + glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + out_width, out_height); #endif - } /* setup a first texture to render to */ glGenTextures (1, &download->out_texture[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[0]); 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, GL_LINEAR); 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[1]); 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, GL_LINEAR); 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->out_texture[2]); 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, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, @@ -901,14 +887,14 @@ static void _do_download (GstGLDisplay * display, GstGLDownload * download) { 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); + 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", - download->in_texture, v_format, width, height); + download->in_texture, v_format, out_width, out_height); switch (v_format) { case GST_VIDEO_FORMAT_RGBx: @@ -953,10 +939,10 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) glEnable (GL_TEXTURE_RECTANGLE_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); #else - guint width, height; + guint out_width, out_height; - width = GST_VIDEO_INFO_WIDTH (&download->info); - height = GST_VIDEO_INFO_HEIGHT (&download->info); + out_width = GST_VIDEO_INFO_WIDTH (&download->info); + out_height = GST_VIDEO_INFO_HEIGHT (&download->info); const GLfloat vVertices[] = { 1.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 }; - glViewport (0, 0, width, height); + glViewport (0, 0, out_width, out_height); glClearColor (0.0, 0.0, 0.0, 0.0); 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, GL_UNSIGNED_BYTE, download->data[0]); #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]); #endif break; @@ -1019,10 +1005,10 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) #endif /* G_BYTE_ORDER */ #else /* OPENGL_ES2 */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN - glReadPixels (0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, - download->data[0]); + glReadPixels (0, 0, out_width, out_eight, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8, download->data[0]); #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]); #endif /* G_BYTE_ORDER */ #endif /* !OPENGL_ES2 */ @@ -1051,7 +1037,7 @@ _do_download_draw_rgb (GstGLDisplay * display, GstGLDownload * download) glGetTexImage (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, GL_UNSIGNED_BYTE, download->data[0]); #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]); #endif break; @@ -1080,7 +1066,7 @@ static void _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) { GstVideoFormat v_format; - guint width, height; + guint out_width, out_height; GLenum multipleRT[] = { GL_COLOR_ATTACHMENT0_EXT, @@ -1104,10 +1090,13 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; #endif - width = GST_VIDEO_INFO_WIDTH (&download->info); - height = GST_VIDEO_INFO_HEIGHT (&download->info); + out_width = GST_VIDEO_INFO_WIDTH (&download->info); + out_height = GST_VIDEO_INFO_HEIGHT (&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); #ifndef OPENGL_ES2 @@ -1116,7 +1105,7 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); - gluOrtho2D (0.0, width, 0.0, height); + gluOrtho2D (0.0, out_width, 0.0, out_height); glMatrixMode (GL_MODELVIEW); glPushMatrix (); @@ -1125,7 +1114,7 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glGetIntegerv (GL_VIEWPORT, viewport_dim); #endif - glViewport (0, 0, width, height); + glViewport (0, 0, out_width, out_height); switch (v_format) { case GST_VIDEO_FORMAT_YUY2: @@ -1179,8 +1168,8 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glActiveTextureARB (GL_TEXTURE0_ARB); 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, "h", (gfloat) height); + gst_gl_shader_set_uniform_1f (download->shader, "w", (gfloat) out_width); + gst_gl_shader_set_uniform_1f (download->shader, "h", (gfloat) out_height); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, download->in_texture); } break; @@ -1196,11 +1185,11 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) glBegin (GL_QUADS); glTexCoord2i (0, 0); glVertex2f (-1.0f, -1.0f); - glTexCoord2i (width, 0); + glTexCoord2i (out_width, 0); glVertex2f (1.0f, -1.0f); - glTexCoord2i (width, height); + glTexCoord2i (out_width, out_height); glVertex2f (1.0f, 1.0f); - glTexCoord2i (0, height); + glTexCoord2i (0, out_height); glVertex2f (-1.0f, 1.0f); glEnd (); @@ -1229,8 +1218,6 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) gst_gl_display_check_framebuffer_status (); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, download->fbo); #ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); @@ -1239,64 +1226,64 @@ _do_download_draw_yuv (GstGLDisplay * display, GstGLDownload * download) switch (v_format) { case GST_VIDEO_FORMAT_AYUV: #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]); #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]); #endif break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: #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]); #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]); #endif break; 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]); #ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); #endif - glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[1]); #ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); #endif - glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[2]); } break; 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]); #ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT1_EXT); #endif - glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[2]); #ifndef OPENGL_ES2 glReadBuffer (GL_COLOR_ATTACHMENT2_EXT); #endif - glReadPixels (0, 0, GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, + glReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2, + GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE, download->data[1]); } break; diff --git a/gst-libs/gst/gl/gstgldownload.h b/gst-libs/gst/gl/gstgldownload.h index 81d2f9792d..ef672a4399 100644 --- a/gst-libs/gst/gl/gstgldownload.h +++ b/gst-libs/gst/gl/gstgldownload.h @@ -90,9 +90,9 @@ struct _GstGLDownloadClass GstGLDownload * gst_gl_download_new (GstGLDisplay * display); 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, - 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_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, gpointer data[GST_VIDEO_MAX_PLANES]); -GstGLDownload * gst_gl_display_find_download_thread (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height); -GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height); +GstGLDownload * gst_gl_display_find_download_unlocked (GstGLDisplay * display, GstVideoFormat v_format, + guint out_width, guint out_height); +GstGLDownload * gst_gl_display_find_download (GstGLDisplay * display, GstVideoFormat v_format, + guint out_width, guint out_height); G_END_DECLS diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index 61a999d9a7..2ae2c4858e 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -220,14 +220,15 @@ gst_gl_upload_finalize (GObject * object) 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) { GstVideoInfo info; 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_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); @@ -238,9 +239,11 @@ gst_gl_upload_init_format (GstGLUpload * upload, GstVideoFormat v_format, 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->in_width = in_width; + upload->in_height = in_height; gst_gl_display_thread_add (upload->display, (GstGLDisplayThreadFunc) _init_upload, upload); @@ -252,14 +255,15 @@ gst_gl_upload_init_format (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) { GstVideoInfo info; 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_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); @@ -270,9 +274,11 @@ gst_gl_upload_init_format_thread (GstGLUpload * upload, GstVideoFormat v_format, 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->in_width = in_width; + upload->in_height = in_height; _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); + 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++) { data[i] = (guint8 *) gl_mem->data + 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, 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; for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) { upload->data[i] = data[i]; @@ -432,28 +437,33 @@ gst_gl_upload_perform_with_data_unlocked_thread (GstGLUpload * upload, return TRUE; } -static inline guint64 * -_gen_key (GstVideoFormat v_format, guint width, guint 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 GstGLUpload * -_find_upload (GstGLDisplay * display, guint64 * key) +GstGLUpload * +gst_gl_display_find_upload_unlocked (GstGLDisplay * display, + GstVideoFormat v_format, guint in_width, guint in_height, + guint out_width, guint out_height) { 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) { ret = gst_gl_upload_new (display); - g_hash_table_insert (display->uploads, key, ret); + display->uploads = g_slist_prepend (display->uploads, ret); } return ret; @@ -461,43 +471,33 @@ _find_upload (GstGLDisplay * display, guint64 * key) GstGLUpload * 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; - guint64 *key; - - key = _gen_key (v_format, width, height); 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); 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 */ void _init_upload (GstGLDisplay * display, GstGLUpload * upload) { GstVideoFormat v_format; + guint in_width, in_height, out_width, out_height; 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); @@ -512,6 +512,8 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGB: 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 */ break; case GST_VIDEO_FORMAT_YUY2: @@ -771,11 +773,11 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload) void _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 */ - width = GST_VIDEO_INFO_WIDTH (&upload->info); - height = GST_VIDEO_INFO_HEIGHT (&upload->info); + out_width = GST_VIDEO_INFO_WIDTH (&upload->info); + out_height = GST_VIDEO_INFO_HEIGHT (&upload->info); if (!GLEW_EXT_framebuffer_object) { /* 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); #ifndef OPENGL_ES2 glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - width, height); + out_width, out_height); glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, - width, height); + out_width, out_height); #else glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, - width, height); + out_width, out_height); #endif /* a fake texture is attached to the upload FBO (cannot init without it) */ glGenTextures (1, &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); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_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) { GstVideoFormat v_format; - guint width, height; + guint in_width, in_height, out_width, out_height; - width = GST_VIDEO_INFO_WIDTH (&upload->info); - height = GST_VIDEO_INFO_HEIGHT (&upload->info); + out_width = GST_VIDEO_INFO_WIDTH (&upload->info); + out_height = GST_VIDEO_INFO_HEIGHT (&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, - width, height); + out_width, out_height); _do_upload_fill (display, upload); @@ -869,6 +873,8 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_RGB: 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 */ break; case GST_VIDEO_FORMAT_YUY2: @@ -887,6 +893,8 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload) /* not yet supported */ break; 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 */ break; default: @@ -910,10 +918,10 @@ void _do_upload_make (GstGLDisplay * display, GstGLUpload * upload) { GstVideoFormat v_format; - guint width, height; + guint in_width, in_height; - width = GST_VIDEO_INFO_WIDTH (&upload->info); - height = GST_VIDEO_INFO_HEIGHT (&upload->info); + in_width = upload->in_width; + in_height = upload->in_height; v_format = GST_VIDEO_INFO_FORMAT (&upload->info); 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_ABGR: 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; case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: 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; case GST_VIDEO_FORMAT_AYUV: 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; case GST_VIDEO_FORMAT_YUY2: switch (display->colorspace_conversion) { case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_MATRIX: 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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; case GST_GL_DISPLAY_CONVERSION_MESA: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, - height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, in_width, + in_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); break; default: 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_MATRIX: 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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; case GST_GL_DISPLAY_CONVERSION_MESA: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, - height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, in_width, + in_height, 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); break; default: 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_YV12: 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, - GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + GST_ROUND_UP_2 (in_width) / 2, + GST_ROUND_UP_2 (in_height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, + NULL); glGenTextures (1, &upload->in_texture[2]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, - GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + GST_ROUND_UP_2 (in_width) / 2, + GST_ROUND_UP_2 (in_height) / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, + NULL); break; default: @@ -1016,10 +1030,12 @@ void _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) { GstVideoFormat v_format; - guint width, height; + guint in_width, in_height, out_width, out_height; - width = GST_VIDEO_INFO_WIDTH (&upload->info); - height = GST_VIDEO_INFO_HEIGHT (&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); v_format = GST_VIDEO_INFO_FORMAT (&upload->info); switch (v_format) { @@ -1034,7 +1050,10 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: /* color space conversion is not needed */ - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); + 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); break; case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_UYVY: @@ -1047,7 +1066,10 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); break; case GST_GL_DISPLAY_CONVERSION_MESA: - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); + 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); break; default: gst_gl_display_set_error (display, "Unknown colorspace conversion %d", @@ -1065,49 +1087,50 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) switch (v_format) { 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]); break; 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]); break; case GST_VIDEO_FORMAT_RGBx: 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]); break; case GST_VIDEO_FORMAT_BGRx: 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]); break; case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_xRGB: 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]); break; case GST_VIDEO_FORMAT_xBGR: 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]); break; case GST_VIDEO_FORMAT_YUY2: switch (display->colorspace_conversion) { case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_MATRIX: - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, + in_height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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]); break; case GST_GL_DISPLAY_CONVERSION_MESA: - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, upload->data[0]); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, + in_height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, + upload->data[0]); break; default: 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) { case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_MATRIX: - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, + in_height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, upload->data[0]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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]); break; case GST_GL_DISPLAY_CONVERSION_MESA: - glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, - GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, upload->data[0]); + glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, in_width, + in_height, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, + upload->data[0]); break; default: gst_gl_display_set_error (display, "Unknow colorspace conversion %d", @@ -1141,33 +1165,33 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload) break; 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); 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]); } break; 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[2]); 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]); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[1]); 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]); } break; @@ -1190,7 +1214,7 @@ void _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) { GstVideoFormat v_format; - guint width, height; + guint in_width, in_height, out_width, out_height; #ifdef OPENGL_ES2 GLint viewport_dim[4]; @@ -1208,8 +1232,10 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; #endif - width = GST_VIDEO_INFO_WIDTH (&upload->info); - height = GST_VIDEO_INFO_HEIGHT (&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); v_format = GST_VIDEO_INFO_FORMAT (&upload->info); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, upload->fbo); @@ -1233,7 +1259,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); - gluOrtho2D (0.0, width, 0.0, height); + gluOrtho2D (0.0, out_width, 0.0, out_height); glMatrixMode (GL_MODELVIEW); glPushMatrix (); @@ -1242,7 +1268,7 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) glGetIntegerv (GL_VIEWPORT, viewport_dim); #endif - glViewport (0, 0, width, height); + glViewport (0, 0, out_width, out_height); #ifndef OPENGL_ES2 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); @@ -1469,13 +1495,13 @@ _do_upload_draw (GstGLDisplay * display, GstGLUpload * upload) #ifndef OPENGL_ES2 glBegin (GL_QUADS); - glTexCoord2i (width, 0); + glTexCoord2i (in_width, 0); glVertex2f (1.0f, -1.0f); glTexCoord2i (0, 0); glVertex2f (-1.0f, -1.0f); - glTexCoord2i (0, height); + glTexCoord2i (0, in_height); glVertex2f (-1.0f, 1.0f); - glTexCoord2i (width, height); + glTexCoord2i (in_width, in_height); glVertex2f (1.0f, 1.0f); glEnd (); diff --git a/gst-libs/gst/gl/gstglupload.h b/gst-libs/gst/gl/gstglupload.h index a8a2dab769..cc1bfbad6e 100644 --- a/gst-libs/gst/gl/gstglupload.h +++ b/gst-libs/gst/gl/gstglupload.h @@ -60,13 +60,15 @@ struct _GstGLUpload GLuint depth_buffer; GLuint out_texture; GLuint in_texture[GST_VIDEO_MAX_PLANES]; + guint in_width; + guint in_height; GstGLShader *shader; #ifdef OPENGL_ES2 GLint shader_attr_position_loc; GLint shader_attr_texture_loc; #endif - /* output data */ + /* input data */ GstVideoInfo info; /* */ @@ -90,9 +92,11 @@ struct _GstGLUploadClass GstGLUpload * gst_gl_upload_new (GstGLDisplay * display); 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, - 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_data (GstGLUpload * upload, GLuint texture_id, @@ -101,10 +105,12 @@ gboolean gst_gl_upload_perform_with_memory_thread (GstGLUpload * upload, GstGLMe gboolean gst_gl_upload_perform_with_data_thread (GstGLUpload * upload, GLuint texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); -GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height); -GstGLUpload * gst_gl_display_find_upload_thread (GstGLDisplay * display, GstVideoFormat v_format, - guint width, guint height); +GstGLUpload * gst_gl_display_find_upload (GstGLDisplay * display, GstVideoFormat v_format, + guint in_width, guint in_height, + guint out_width, guint out_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