support video crop for glimagesink

1.Add video crop meta copy in glupload
2.Calculate the new texture coordinate in vertices array and bind to buffer object
3.Make glimagesink only updating vertices array when video crop meta changed

Upstream-Status: Inappropriate [i.MX specific]

Signed-off-by: Haihua Hu <b55597@freescale.com>
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
index 43653bb..493c420 100644
--- a/ext/gl/gstglimagesink.c
+++ b/ext/gl/gstglimagesink.c
@@ -771,6 +771,8 @@
   glimage_sink->handle_events = TRUE;
   glimage_sink->ignore_alpha = TRUE;
   glimage_sink->overlay_compositor = NULL;
+  glimage_sink->cropmeta = NULL;
+  glimage_sink->prev_cropmeta = NULL;
 
   glimage_sink->mview_output_mode = DEFAULT_MULTIVIEW_MODE;
   glimage_sink->mview_output_flags = DEFAULT_MULTIVIEW_FLAGS;
@@ -1259,6 +1261,12 @@
         gst_object_unref (glimage_sink->display);
         glimage_sink->display = NULL;
       }
+
+      glimage_sink->cropmeta = NULL;
+      if (glimage_sink->prev_cropmeta)
+        g_slice_free(GstVideoCropMeta, glimage_sink->prev_cropmeta);
+      glimage_sink->prev_cropmeta = NULL;
+
       break;
     default:
       break;
@@ -1757,6 +1765,8 @@
       GST_VIDEO_SINK_WIDTH (glimage_sink),
       GST_VIDEO_SINK_HEIGHT (glimage_sink));
 
+  glimage_sink->cropmeta = gst_buffer_get_video_crop_meta (buf);
+
   /* Ask the underlying window to redraw its content */
   if (!gst_glimage_sink_redisplay (glimage_sink))
     goto redisplay_failed;
@@ -2242,6 +2252,54 @@
 
     gst_gl_shader_use (gl_sink->redisplay_shader);
 
+    if (gl_sink->cropmeta) {
+      gint width = GST_VIDEO_SINK_WIDTH (gl_sink);
+      gint height = GST_VIDEO_SINK_HEIGHT (gl_sink);
+
+      if (!gl_sink->prev_cropmeta){
+        /* Initialize the previous crop meta and set all memroy to zero */
+        gl_sink->prev_cropmeta = (GstVideoCropMeta *) g_slice_new0(GstVideoCropMeta);
+      }
+
+      /* If crop meta not equal to the previous, recalculate the vertices */
+      if (gl_sink->prev_cropmeta->x != gl_sink->cropmeta->x
+        || gl_sink->prev_cropmeta->y != gl_sink->cropmeta->y
+        || gl_sink->prev_cropmeta->width != gl_sink->cropmeta->width
+        || gl_sink->prev_cropmeta->height != gl_sink->cropmeta->height){
+
+	GLfloat crop_vertices[] = {
+	     1.0f,  1.0f, 0.0f, 1.0f, 0.0f,
+	    -1.0f,  1.0f, 0.0f, 0.0f, 0.0f,
+	    -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
+	     1.0f, -1.0f, 0.0f, 1.0f, 1.0f
+	};
+
+        crop_vertices[8] = (float)(gl_sink->cropmeta->x) / width;
+        crop_vertices[9] = (float)(gl_sink->cropmeta->y) / height;
+
+        crop_vertices[3] = (float)(gl_sink->cropmeta->width + gl_sink->cropmeta->x) / width;
+        crop_vertices[4] = crop_vertices[9];
+
+        crop_vertices[13] = crop_vertices[8];
+        crop_vertices[14] = (float)(gl_sink->cropmeta->height + gl_sink->cropmeta->y) / height;
+
+        crop_vertices[18] = crop_vertices[3];
+        crop_vertices[19] = crop_vertices[14];
+
+        gl->BindBuffer (GL_ARRAY_BUFFER, gl_sink->vertex_buffer);
+        gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), crop_vertices,
+            GL_STATIC_DRAW);
+
+        gl->BindBuffer (GL_ARRAY_BUFFER, 0);
+
+        /* Store the previous crop meta */
+        gl_sink->prev_cropmeta->x = gl_sink->cropmeta->x;
+        gl_sink->prev_cropmeta->y = gl_sink->cropmeta->y;
+        gl_sink->prev_cropmeta->width = gl_sink->cropmeta->width;
+        gl_sink->prev_cropmeta->height = gl_sink->cropmeta->height;
+      }
+    }
+
     if (gl->GenVertexArrays)
       gl->BindVertexArray (gl_sink->vao);
     _bind_buffer (gl_sink);
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
index 12166ec..839fbe4 100644
--- a/ext/gl/gstglimagesink.h
+++ b/ext/gl/gstglimagesink.h
@@ -121,6 +121,9 @@
     guint window_width;
     guint window_height;
 
+    GstVideoCropMeta *cropmeta;
+    GstVideoCropMeta *prev_cropmeta;
+
     GstVideoRectangle display_rect;
 
     GstGLShader *redisplay_shader;
diff --git a/ext/gl/gstgluploadelement.c b/ext/gl/gstgluploadelement.c
index f9e52f6..52bd76a 100644
--- a/ext/gl/gstgluploadelement.c
+++ b/ext/gl/gstgluploadelement.c
@@ -256,9 +256,19 @@
   /* basetransform doesn't unref if they're the same */
   if (buffer == *outbuf)
     gst_buffer_unref (*outbuf);
-  else
+  else {
+    GstVideoCropMeta *incropmeta, *outcropmeta;
+    /* add video crop meta to out buffer if need */
+    incropmeta = gst_buffer_get_video_crop_meta (buffer);
+    if (incropmeta) {
+      outcropmeta = gst_buffer_add_video_crop_meta (*outbuf);
+      outcropmeta->x = incropmeta->x;
+      outcropmeta->y = incropmeta->y;
+      outcropmeta->width = incropmeta->width;
+      outcropmeta->height = incropmeta->height;
+    }
     bclass->copy_metadata (bt, buffer, *outbuf);
-
+  }
   return GST_FLOW_OK;
 }