[590/906] up/download: fix scaling on transfer
authorMatthew Waters <ystreet00@gmail.com>
Tue, 25 Sep 2012 05:20:21 +0000 (15:20 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:25 +0000 (19:31 +0000)
i.e. uploading from a 10x10 video frame to a 20x20 texture into another 30x30 videoframe

gst-libs/gst/gl/gstgldisplay.c
gst-libs/gst/gl/gstgldisplay.h
gst-libs/gst/gl/gstgldownload.c
gst-libs/gst/gl/gstgldownload.h
gst-libs/gst/gl/gstglupload.c
gst-libs/gst/gl/gstglupload.h

index e65234f..aeac4eb 100644 (file)
@@ -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;
   }
 }
index 5103ede..8e4b820 100644 (file)
@@ -129,8 +129,8 @@ struct _GstGLDisplay
 
   GstGLDisplayConversion colorspace_conversion;
 
-  GHashTable *uploads;
-  GHashTable *downloads;
+  GSList *uploads;
+  GSList *downloads;
 
   //foreign gl context
   gulong external_gl_context;
index d193d0a..4126dc6 100644 (file)
@@ -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)
+GstGLDownload *
+gst_gl_display_find_download_unlocked (GstGLDisplay * display,
+    GstVideoFormat v_format, guint out_width, guint out_height)
 {
-  guint64 *key;
+  GstGLDownload *ret;
+  GSList *walk;
 
-  /* 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;
-}
+  walk = display->downloads;
 
-static inline GstGLDownload *
-_find_download (GstGLDisplay * display, guint64 * key)
-{
-  GstGLDownload *ret;
+  while (walk) {
+    ret = walk->data;
 
-  ret = g_hash_table_lookup (display->downloads, key);
+    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;
index 81d2f97..ef672a4 100644 (file)
@@ -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
 
index 61a999d..2ae2c48 100644 (file)
@@ -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)
+GstGLUpload *
+gst_gl_display_find_upload_unlocked (GstGLDisplay * display,
+    GstVideoFormat v_format, guint in_width, guint in_height,
+    guint out_width, guint out_height)
 {
-  guint64 *key;
+  GstGLUpload *ret;
+  GSList *walk;
 
-  /* 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;
-}
+  walk = display->uploads;
 
-static inline GstGLUpload *
-_find_upload (GstGLDisplay * display, guint64 * key)
-{
-  GstGLUpload *ret;
+  while (walk) {
+    ret = walk->data;
 
-  ret = g_hash_table_lookup (display->uploads, key);
+    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 ();
 
index a8a2dab..cc1bfba 100644 (file)
@@ -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;
 
   /* <private> */
@@ -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