From 0150255a46da756f42e6f2e3776e2d39ed70dcec Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 14 Mar 2015 15:16:55 +0000 Subject: [PATCH] glimagesink: provide GstSample in client-draw signal Instead of prividing texture and size directly. And apply changes to examples. https://bugzilla.gnome.org/show_bug.cgi?id=739681 --- ext/gl/gstglimagesink.c | 25 ++++++++------ tests/examples/gl/generic/cube/Makefile.am | 2 +- tests/examples/gl/generic/cube/main.cpp | 25 ++++++++++---- tests/examples/gl/generic/cubeyuv/Makefile.am | 2 +- tests/examples/gl/generic/cubeyuv/main.cpp | 34 +++++++++++-------- .../gl/generic/doublecube/Makefile.am | 2 +- tests/examples/gl/generic/doublecube/main.cpp | 34 +++++++++++-------- .../gl/qt/mousevideooverlay/pipeline.cpp | 22 ++++++++++-- .../gl/qt/qglwidgetvideooverlay/pipeline.cpp | 22 ++++++++++-- 9 files changed, 112 insertions(+), 56 deletions(-) diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index 52f595a6af..89c2a69ded 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -180,12 +180,12 @@ _on_client_reshape (GstGLImageSink * sink, GstGLContext * context, static gboolean _on_client_draw (GstGLImageSink * sink, GstGLContext * context, - guint tex_id, guint width, guint height, gpointer data) + GstSample * sample, gpointer data) { gboolean ret; g_signal_emit (data, gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_DRAW], 0, - context, tex_id, width, height, &ret); + context, sample, &ret); return ret; } @@ -288,8 +288,7 @@ gst_gl_image_sink_bin_class_init (GstGLImageSinkBinClass * klass) gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_DRAW] = g_signal_new ("client-draw", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, - G_TYPE_BOOLEAN, 4, GST_GL_TYPE_CONTEXT, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + G_TYPE_BOOLEAN, 2, GST_GL_TYPE_CONTEXT, GST_TYPE_SAMPLE); gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_RESHAPE] = g_signal_new ("client-reshape", G_TYPE_FROM_CLASS (klass), @@ -516,8 +515,7 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass) gst_glimage_sink_signals[CLIENT_DRAW_SIGNAL] = g_signal_new ("client-draw", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, - G_TYPE_BOOLEAN, 4, GST_GL_TYPE_CONTEXT, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + G_TYPE_BOOLEAN, 2, GST_GL_TYPE_CONTEXT, GST_TYPE_SAMPLE); /** * GstGLImageSink::client-reshape: @@ -1472,8 +1470,9 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink) const GstGLFuncs *gl = NULL; GstGLWindow *window = NULL; - gboolean do_redisplay; - GstGLSyncMeta *sync_meta; + gboolean do_redisplay = FALSE; + GstGLSyncMeta *sync_meta = NULL; + GstSample *sample = NULL; g_return_if_fail (GST_IS_GLIMAGE_SINK (gl_sink)); @@ -1516,10 +1515,14 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink) gl->BindTexture (GL_TEXTURE_2D, 0); + sample = gst_sample_new (gl_sink->stored_buffer, + gst_video_info_to_caps (&gl_sink->info), + &GST_BASE_SINK (gl_sink)->segment, NULL); + g_signal_emit (gl_sink, gst_glimage_sink_signals[CLIENT_DRAW_SIGNAL], 0, - gl_sink->context, - gl_sink->redisplay_texture, GST_VIDEO_INFO_WIDTH (&gl_sink->info), - GST_VIDEO_INFO_HEIGHT (&gl_sink->info), &do_redisplay); + gl_sink->context, sample, &do_redisplay); + + gst_sample_unref (sample); if (!do_redisplay) { gfloat alpha = gl_sink->ignore_alpha ? 1.0f : 0.0f; diff --git a/tests/examples/gl/generic/cube/Makefile.am b/tests/examples/gl/generic/cube/Makefile.am index b6bd60b4e9..7262533e57 100644 --- a/tests/examples/gl/generic/cube/Makefile.am +++ b/tests/examples/gl/generic/cube/Makefile.am @@ -5,5 +5,5 @@ cube_SOURCES = main.cpp cube_CXXFLAGS=-I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \ $(GST_CXXFLAGS) $(GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -cube_LDADD=$(GST_LIBS) $(GL_LIBS) +cube_LDADD=$(GST_LIBS) -lgstvideo-$(GST_API_VERSION) $(GL_LIBS) diff --git a/tests/examples/gl/generic/cube/main.cpp b/tests/examples/gl/generic/cube/main.cpp index c671401747..c3ace9fbe2 100644 --- a/tests/examples/gl/generic/cube/main.cpp +++ b/tests/examples/gl/generic/cube/main.cpp @@ -18,11 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#include -#if __WIN32__ || _WIN32 -# include -#endif #include +#include #include #include @@ -75,7 +72,7 @@ static gboolean reshapeCallback (void *gl_sink, void *context, GLuint width, GLu } //client draw callback -static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLuint width, GLuint height, gpointer data) +static gboolean drawCallback (GstElement * gl_sink, GstGLContext *context, GstSample * sample, gpointer data) { static GLfloat xrot = 0; static GLfloat yrot = 0; @@ -84,6 +81,21 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu static glong last_sec = current_time.tv_sec; static gint nbFrames = 0; + GstVideoFrame v_frame; + GstVideoInfo v_info; + guint texture = 0; + GstBuffer *buf = gst_sample_get_buffer (sample); + GstCaps *caps = gst_sample_get_caps (sample); + + gst_video_info_from_caps (&v_info, caps); + + if (!gst_video_frame_map (&v_frame, &v_info, buf, (GstMapFlags) (GST_MAP_READ | GST_MAP_GL))) { + g_warning ("Failed to map the video buffer"); + return TRUE; + } + + texture = *(guint *) v_frame.data[0]; + g_get_current_time (¤t_time); nbFrames++ ; @@ -147,11 +159,12 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); + gst_video_frame_unmap (&v_frame); + xrot+=0.3f; yrot+=0.2f; zrot+=0.4f; - //return TRUE causes a postRedisplay return TRUE; } diff --git a/tests/examples/gl/generic/cubeyuv/Makefile.am b/tests/examples/gl/generic/cubeyuv/Makefile.am index 289cbd3f32..98697f002b 100644 --- a/tests/examples/gl/generic/cubeyuv/Makefile.am +++ b/tests/examples/gl/generic/cubeyuv/Makefile.am @@ -5,5 +5,5 @@ cubeyuv_SOURCES = main.cpp cubeyuv_CXXFLAGS=-I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \ $(GST_CXXFLAGS) $(GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -cubeyuv_LDADD=$(GST_LIBS) $(GL_LIBS) +cubeyuv_LDADD=$(GST_LIBS) $(GL_LIBS) -lgstvideo-$(GST_API_VERSION) diff --git a/tests/examples/gl/generic/cubeyuv/main.cpp b/tests/examples/gl/generic/cubeyuv/main.cpp index 75bc30afbc..9c4b2ccbdf 100644 --- a/tests/examples/gl/generic/cubeyuv/main.cpp +++ b/tests/examples/gl/generic/cubeyuv/main.cpp @@ -18,11 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#include -#if __WIN32__ || _WIN32 -# include -#endif #include +#include #include #include @@ -98,7 +95,7 @@ static gboolean reshapeCallback (void * gl_sink, void *context, GLuint width, GL //client draw callback -static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLuint width, GLuint height, gpointer data) +static gboolean drawCallback (GstElement * gl_sink, GstGLContext *context, GstSample * sample, gpointer data) { static GLfloat xrot = 0; static GLfloat yrot = 0; @@ -107,6 +104,21 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu static glong last_sec = current_time.tv_sec; static gint nbFrames = 0; + GstVideoFrame v_frame; + GstVideoInfo v_info; + guint texture = 0; + GstBuffer *buf = gst_sample_get_buffer (sample); + GstCaps *caps = gst_sample_get_caps (sample); + + gst_video_info_from_caps (&v_info, caps); + + if (!gst_video_frame_map (&v_frame, &v_info, buf, (GstMapFlags) (GST_MAP_READ | GST_MAP_GL))) { + g_warning ("Failed to map the video buffer"); + return TRUE; + } + + texture = *(guint *) v_frame.data[0]; + g_get_current_time (¤t_time); nbFrames++ ; @@ -170,20 +182,12 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); + gst_video_frame_unmap (&v_frame); + xrot+=0.03f; yrot+=0.02f; zrot+=0.04f; - //return TRUE causes a postRedisplay - //so you have to return FALSE to synchronise to have a graphic FPS - //equals to the input video frame rate - - //Usually, we will not always return TRUE (or FALSE) - //For example, if you want a fixed graphic FPS equals to 60 - //then you have to use the timeclock to return TRUE or FALSE - //in order to increase or decrease the FPS in real time - //to reach the 60. - return TRUE; } diff --git a/tests/examples/gl/generic/doublecube/Makefile.am b/tests/examples/gl/generic/doublecube/Makefile.am index 3f220de7a0..a13182906e 100644 --- a/tests/examples/gl/generic/doublecube/Makefile.am +++ b/tests/examples/gl/generic/doublecube/Makefile.am @@ -5,5 +5,5 @@ doublecube_SOURCES = main.cpp doublecube_CXXFLAGS=-I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \ $(GST_CXXFLAGS) $(GL_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -doublecube_LDADD=$(GST_LIBS) $(GL_LIBS) +doublecube_LDADD=$(GST_LIBS) $(GL_LIBS) -lgstvideo-$(GST_API_VERSION) diff --git a/tests/examples/gl/generic/doublecube/main.cpp b/tests/examples/gl/generic/doublecube/main.cpp index e72969904b..98d7825567 100644 --- a/tests/examples/gl/generic/doublecube/main.cpp +++ b/tests/examples/gl/generic/doublecube/main.cpp @@ -18,11 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#include -#if __WIN32__ || _WIN32 -# include -#endif #include +#include #include #include @@ -100,7 +97,7 @@ static gboolean reshapeCallback (void *gl_sink, void *context, GLuint width, GLu //client draw callback -static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLuint width, GLuint height) +static gboolean drawCallback (GstElement * gl_sink, GstGLContext *context, GstSample * sample, gpointer data) { static GLfloat xrot = 0; static GLfloat yrot = 0; @@ -109,6 +106,21 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu static glong last_sec = current_time.tv_sec; static gint nbFrames = 0; + GstVideoFrame v_frame; + GstVideoInfo v_info; + guint texture = 0; + GstBuffer *buf = gst_sample_get_buffer (sample); + GstCaps *caps = gst_sample_get_caps (sample); + + gst_video_info_from_caps (&v_info, caps); + + if (!gst_video_frame_map (&v_frame, &v_info, buf, (GstMapFlags) (GST_MAP_READ | GST_MAP_GL))) { + g_warning ("Failed to map the video buffer"); + return TRUE; + } + + texture = *(guint *) v_frame.data[0]; + g_get_current_time (¤t_time); nbFrames++ ; @@ -172,20 +184,12 @@ static gboolean drawCallback (void * gl_sink, void *context, GLuint texture, GLu glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); + gst_video_frame_unmap (&v_frame); + xrot+=0.03f; yrot+=0.02f; zrot+=0.04f; - //return TRUE causes a postRedisplay - //so you have to return FALSE to synchronise to have a graphic FPS - //equals to the input video frame rate - - //Usually, we will not always return TRUE (or FALSE) - //For example, if you want a fixed graphic FPS equals to 60 - //then you have to use the timeclock to return TRUE or FALSE - //in order to increase or decrease the FPS in real time - //to reach the 60. - return TRUE; } diff --git a/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp b/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp index 897b28c6bb..8ee60ffa54 100644 --- a/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp +++ b/tests/examples/gl/qt/mousevideooverlay/pipeline.cpp @@ -170,11 +170,26 @@ gboolean Pipeline::reshapeCallback (void *sink, void *context, guint width, guin } //client draw callback -gboolean Pipeline::drawCallback (void *sink, void *context, uint texture, uint width, uint height, gpointer data) +gboolean Pipeline::drawCallback (GstElement * gl_sink, GstGLContext *context, GstSample * sample, gpointer data) { static GTimeVal current_time; static glong last_sec = current_time.tv_sec; - static gint nbFrames = 0; + static gint nbFrames = 0; + + GstVideoFrame v_frame; + GstVideoInfo v_info; + guint texture = 0; + GstBuffer *buf = gst_sample_get_buffer (sample); + GstCaps *caps = gst_sample_get_caps (sample); + + gst_video_info_from_caps (&v_info, caps); + + if (!gst_video_frame_map (&v_frame, &v_info, buf, (GstMapFlags) (GST_MAP_READ | GST_MAP_GL))) { + g_warning ("Failed to map the video buffer"); + return TRUE; + } + + texture = *(guint *) v_frame.data[0]; g_get_current_time (¤t_time); nbFrames++ ; @@ -239,7 +254,8 @@ gboolean Pipeline::drawCallback (void *sink, void *context, uint texture, uint w glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); - //return TRUE causes a postRedisplay + gst_video_frame_unmap (&v_frame); + return TRUE; } diff --git a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp index 69e2774722..90c6be8c5a 100644 --- a/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp +++ b/tests/examples/gl/qt/qglwidgetvideooverlay/pipeline.cpp @@ -167,7 +167,7 @@ gboolean Pipeline::reshapeCallback (void *sink, void *context, guint width, guin } //client draw callback -gboolean Pipeline::drawCallback (void *sink, void *context, guint texture, guint width, guint height, gpointer data) +gboolean Pipeline::drawCallback (GstElement * gl_sink, GstGLContext *context, GstSample * sample, gpointer data) { static GLfloat xrot = 0; static GLfloat yrot = 0; @@ -176,6 +176,21 @@ gboolean Pipeline::drawCallback (void *sink, void *context, guint texture, guint static glong last_sec = current_time.tv_sec; static gint nbFrames = 0; + GstVideoFrame v_frame; + GstVideoInfo v_info; + guint texture = 0; + GstBuffer *buf = gst_sample_get_buffer (sample); + GstCaps *caps = gst_sample_get_caps (sample); + + gst_video_info_from_caps (&v_info, caps); + + if (!gst_video_frame_map (&v_frame, &v_info, buf, (GstMapFlags) (GST_MAP_READ | GST_MAP_GL))) { + g_warning ("Failed to map the video buffer"); + return TRUE; + } + + texture = *(guint *) v_frame.data[0]; + g_get_current_time (¤t_time); nbFrames++ ; @@ -237,13 +252,14 @@ gboolean Pipeline::drawCallback (void *sink, void *context, guint texture, guint glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); - glEnd(); + glEnd(); + + gst_video_frame_unmap (&v_frame); xrot+=0.03f; yrot+=0.02f; zrot+=0.04f; - //return TRUE causes a postRedisplay return TRUE; }