summaryrefslogtreecommitdiffstats
path: root/sys/glsink/gstglupload.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/glsink/gstglupload.c')
-rw-r--r--sys/glsink/gstglupload.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/sys/glsink/gstglupload.c b/sys/glsink/gstglupload.c
index 116d9d44..81d73175 100644
--- a/sys/glsink/gstglupload.c
+++ b/sys/glsink/gstglupload.c
@@ -78,7 +78,7 @@ static GstStaticPadTemplate gst_gl_upload_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx)
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
);
enum
@@ -99,6 +99,9 @@ static void gst_gl_upload_get_property (GObject * object, guint prop_id,
static GstFlowReturn gst_gl_upload_chain (GstPad * pad, GstBuffer * buf);
static void gst_gl_upload_reset (GstGLUpload * upload);
+static GstStateChangeReturn
+gst_gl_upload_change_state (GstElement * element, GstStateChange transition);
+static gboolean gst_gl_upload_sink_setcaps (GstPad * pad, GstCaps * caps);
static void
@@ -123,11 +126,18 @@ gst_gl_upload_class_init (GstGLUploadClass * klass)
gobject_class->set_property = gst_gl_upload_set_property;
gobject_class->get_property = gst_gl_upload_get_property;
+ GST_ELEMENT_CLASS (klass)->change_state = gst_gl_upload_change_state;
}
static void
gst_gl_upload_init (GstGLUpload * upload, GstGLUploadClass * klass)
{
+ gst_element_create_all_pads (GST_ELEMENT (upload));
+
+ upload->sinkpad = gst_element_get_static_pad (GST_ELEMENT (upload), "sink");
+ upload->srcpad = gst_element_get_static_pad (GST_ELEMENT (upload), "src");
+
+ gst_pad_set_setcaps_function (upload->sinkpad, gst_gl_upload_sink_setcaps);
gst_pad_set_chain_function (upload->sinkpad, gst_gl_upload_chain);
gst_gl_upload_reset (upload);
@@ -162,6 +172,61 @@ gst_gl_upload_get_property (GObject * object, guint prop_id,
static void
gst_gl_upload_reset (GstGLUpload * upload)
{
+ if (upload->display) {
+ g_object_unref (upload->display);
+ upload->display = NULL;
+ }
+ upload->format = GST_VIDEO_FORMAT_BGRx;
+}
+
+static gboolean
+gst_gl_upload_start (GstGLUpload * upload)
+{
+ gboolean ret;
+
+ upload->format = GST_VIDEO_FORMAT_BGRx;
+ upload->display = gst_gl_display_new ();
+ ret = gst_gl_display_connect (upload->display, NULL);
+
+ return ret;
+}
+
+static gboolean
+gst_gl_upload_stop (GstGLUpload * upload)
+{
+ gst_gl_upload_reset (upload);
+
+ return TRUE;
+}
+
+static gboolean
+gst_gl_upload_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstGLUpload *upload;
+ GstVideoFormat format;
+ int height;
+ int width;
+ gboolean ret;
+ GstCaps *srccaps;
+
+ upload = GST_GL_UPLOAD (gst_pad_get_parent (pad));
+
+ ret = gst_video_format_parse_caps (caps, &format, &width, &height);
+ if (!ret)
+ return FALSE;
+
+ upload->format = format;
+ upload->width = width;
+ upload->height = height;
+
+ GST_ERROR ("setcaps %d %d %d", format, width, height);
+
+ srccaps = gst_caps_new_simple ("video/x-raw-gl",
+ "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
+ ret = gst_pad_set_caps (upload->srcpad, srccaps);
+ gst_caps_unref (srccaps);
+
+ return ret;
}
static GstFlowReturn
@@ -177,6 +242,10 @@ gst_gl_upload_chain (GstPad * pad, GstBuffer * buf)
gst_buffer_copy_metadata (GST_BUFFER (outbuf), buf,
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
+ gst_buffer_set_caps (GST_BUFFER (outbuf), GST_PAD_CAPS (upload->srcpad));
+
+ GST_DEBUG ("uploading %p size %d", GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf));
gst_gl_buffer_upload (outbuf, GST_BUFFER_DATA (buf));
gst_pad_push (upload->srcpad, GST_BUFFER (outbuf));
@@ -184,3 +253,44 @@ gst_gl_upload_chain (GstPad * pad, GstBuffer * buf)
gst_object_unref (upload);
return GST_FLOW_OK;
}
+
+static GstStateChangeReturn
+gst_gl_upload_change_state (GstElement * element, GstStateChange transition)
+{
+ GstGLUpload *upload;
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+
+ GST_DEBUG ("change state");
+
+ upload = GST_GL_UPLOAD (element);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ gst_gl_upload_start (upload);
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ return ret;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ gst_gl_upload_stop (upload);
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}