summaryrefslogtreecommitdiff
path: root/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0010-support-video-crop-for-glimagesink.patch
blob: cf2a085655f5f904058160b77073e06452e9f7a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
From a90946b5890892f105bc89161f7c3b7b8f0b7f52 Mon Sep 17 00:00:00 2001
From: Haihua Hu <b55597@freescale.com>
Date: Fri, 13 Nov 2015 10:51:25 +0800
Subject: [PATCH 10/26] 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>
---
 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 f6a61ac..75d3214 100644
--- a/ext/gl/gstglimagesink.c
+++ b/ext/gl/gstglimagesink.c
@@ -764,6 +764,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;
@@ -1253,6 +1255,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;
@@ -1737,6 +1745,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;
@@ -2222,6 +2232,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);
     _bind_buffer (gl_sink);
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
index 8833103..0723e08 100644
--- a/ext/gl/gstglimagesink.h
+++ b/ext/gl/gstglimagesink.h
@@ -120,6 +120,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 f9e52f6..52bd76a 100644
--- a/ext/gl/gstgluploadelement.c
+++ b/ext/gl/gstgluploadelement.c
@@ -256,9 +256,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;
 }
 
-- 
1.9.1