150 lines
5.5 KiB
Diff
150 lines
5.5 KiB
Diff
From 226e80315925bb722cfdd5716e078832f3f6b3c4 Mon Sep 17 00:00:00 2001
|
|
From: Haihua Hu <b55597@freescale.com>
|
|
Date: Fri, 13 Nov 2015 10:51:25 +0800
|
|
Subject: [PATCH] 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>
|
|
Signed-off-by: Lyon Wang <lyon.wang@freescale.com>
|
|
---
|
|
ext/gl/gstglimagesink.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
|
|
ext/gl/gstglimagesink.h | 3 +++
|
|
ext/gl/gstgluploadelement.c | 14 +++++++++--
|
|
3 files changed, 73 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
|
|
index 0bac4fb1c118..196757adfbac 100644
|
|
--- a/ext/gl/gstglimagesink.c
|
|
+++ b/ext/gl/gstglimagesink.c
|
|
@@ -601,6 +601,8 @@ gst_glimage_sink_init (GstGLImageSink * glimage_sink)
|
|
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;
|
|
@@ -1062,6 +1064,12 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|
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;
|
|
@@ -1546,6 +1554,8 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
|
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;
|
|
@@ -2028,6 +2038,54 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
|
|
|
|
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);
|
|
else
|
|
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
|
|
index 6e9b98e74a88..317055a016ed 100644
|
|
--- a/ext/gl/gstglimagesink.h
|
|
+++ b/ext/gl/gstglimagesink.h
|
|
@@ -107,6 +107,9 @@ struct _GstGLImageSink
|
|
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 86e8b01e2407..1738c2f81c1d 100644
|
|
--- a/ext/gl/gstgluploadelement.c
|
|
+++ b/ext/gl/gstgluploadelement.c
|
|
@@ -232,9 +232,19 @@ gst_gl_upload_element_prepare_output_buffer (GstBaseTransform * bt,
|
|
/* 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;
|
|
}
|
|
|