From 752357e283519b4a5ed1b0e9c81e71b1e986e064 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Tue, 10 Jun 2008 19:07:43 +0000 Subject: [PATCH] [087/906] glfilter can accept to have an input size different than the out put size : video/x-raw-gl, width=w1, height=w1 ! glfilter ! video/x-raw-gl, width=w2, height=w2 ! (fix every examples) git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@499 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstglbuffer.c | 8 +- gst-libs/gst/gl/gstglbuffer.h | 12 +- gst-libs/gst/gl/gstgldisplay.c | 202 ++++++++++++++++++++------------- gst-libs/gst/gl/gstgldisplay.h | 9 +- gst/gl/gstglfilter.c | 42 +++++-- gst/gl/gstglfilterapp.c | 110 ++++++------------ gst/gl/gstglfilterapp.h | 3 +- gst/gl/gstglfiltercube.c | 4 +- gst/gl/gstglimagesink.c | 4 +- gst/gl/gstglvideomaker.c | 3 + 10 files changed, 222 insertions(+), 175 deletions(-) diff --git a/gst-libs/gst/gl/gstglbuffer.c b/gst-libs/gst/gl/gstglbuffer.c index bdfd1799b0..2dcfe81d6a 100644 --- a/gst-libs/gst/gl/gstglbuffer.c +++ b/gst-libs/gst/gl/gstglbuffer.c @@ -44,12 +44,14 @@ gst_gl_buffer_init (GstGLBuffer* buffer, gpointer g_class) { buffer->display = NULL; buffer->video_format = 0; + buffer->width = 0; + buffer->height = 0; buffer->texture = 0; buffer->texture_u = 0; buffer->texture_v = 0; + buffer->widthGL = 0; + buffer->heightGL = 0; buffer->textureGL = 0; - buffer->width = 0; - buffer->height = 0; } static void @@ -107,6 +109,8 @@ gst_gl_buffer_new_from_video_format (GstGLDisplay* display, buffer->width = width; buffer->height = height; buffer->video_format = video_format; + buffer->widthGL = context_width; + buffer->heightGL = context_height; GST_BUFFER_SIZE (buffer) = gst_gl_buffer_format_get_size (video_format, context_width, context_height); //blocking call, init texture diff --git a/gst-libs/gst/gl/gstglbuffer.h b/gst-libs/gst/gl/gstglbuffer.h index 2c24b09a42..a86b0326f4 100644 --- a/gst-libs/gst/gl/gstglbuffer.h +++ b/gst-libs/gst/gl/gstglbuffer.h @@ -42,13 +42,15 @@ struct _GstGLBuffer { GstVideoFormat video_format; + gint width; + gint height; GLuint texture; GLuint texture_u; GLuint texture_v; - GLuint textureGL; - gint width; - gint height; + gint widthGL; + gint heightGL; + GLuint textureGL; }; GType gst_gl_buffer_get_type (void); @@ -66,8 +68,8 @@ gboolean gst_gl_buffer_format_parse_caps (GstCaps* caps, GstVideoFormat* format, #define GST_GL_VIDEO_CAPS \ "video/x-raw-gl," \ - "width=(int)[1,1920]," \ - "height=(int)[1,1080]," \ + "width=(int)[1,8000]," \ + "height=(int)[1,6000]," \ "pixel-aspect-ratio=(fraction)1/1," \ "framerate=(fraction)[0/1,100/1]" diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index 4bf10c668c..71d5b7faca 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -28,11 +28,13 @@ static void gst_gl_display_finalize (GObject * object); static gpointer gst_gl_display_glutThreadFunc (GstGLDisplay* display); static void gst_gl_display_glutCreateWindow (GstGLDisplay* display); +static void gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display); static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display); static void gst_gl_display_glutUseFBO (GstGLDisplay *display); static void gst_gl_display_glutDestroyFBO (GstGLDisplay *display); static void gst_gl_display_glutDestroyWindow (GstGLDisplay* display); static void gst_gl_display_glutSetVisibleWindow (GstGLDisplay* display); +static void gst_gl_display_glutReshapeWindow (GstGLDisplay* display); static void gst_gl_display_glutPrepareTexture (GstGLDisplay* display); static void gst_gl_display_glutUpdateTexture (GstGLDisplay* display); static void gst_gl_display_glutCleanTexture (GstGLDisplay* display); @@ -101,6 +103,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->cond_destroyFBO = g_cond_new (); display->cond_create = g_cond_new (); display->cond_destroy = g_cond_new (); + display->cond_download = g_cond_new (); display->fbo = 0; display->depthBuffer = 0; @@ -221,7 +224,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) "void main(void) {\n" " float r,g,b,y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" - " y=texture2DRect(Ytex,nxy*).r;\n" + " y=texture2DRect(Ytex,nxy).r;\n" " u=texture2DRect(Utex,nxy*0.5).r;\n" " v=texture2DRect(Vtex,nxy*0.5).r;\n" " y=1.1643*(y-0.0625);\n" @@ -358,6 +361,10 @@ gst_gl_display_finalize (GObject *object) g_cond_free (display->cond_video); display->cond_video = NULL; } + if (display->cond_download) { + g_cond_free (display->cond_download); + display->cond_download = NULL; + } if (display->cond_generateFBO) { g_cond_free (display->cond_generateFBO); display->cond_generateFBO = NULL; @@ -519,6 +526,70 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display) //unbind the FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + else + { + GST_DEBUG ("Context %d, EXT_framebuffer_object supported: no", glutWinId); + g_assert_not_reached (); + } + + //check if fragment program is available, then load them + if (GLEW_ARB_vertex_program) + { + gchar program[2048]; + + GST_DEBUG ("Context %d, ARB_fragment_program supported: yes", glutWinId); + + //from video to texture + + sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a'); + + display->GLSLProgram_YUY2 = gst_gl_display_loadGLSLprogram (program); + + sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r'); + + display->GLSLProgram_UYVY = gst_gl_display_loadGLSLprogram (program); + + display->GLSLProgram_I420_YV12 = gst_gl_display_loadGLSLprogram (display->textFProgram_I420_YV12); + + display->GLSLProgram_AYUV = gst_gl_display_loadGLSLprogram (display->textFProgram_AYUV); + } + else + { + GST_DEBUG ("Context %d, ARB_fragment_program supported: no", glutWinId); + g_assert_not_reached (); + } + + //setup callbacks + glutReshapeFunc (gst_gl_display_onReshape); + glutDisplayFunc (gst_gl_display_draw); + glutCloseFunc (gst_gl_display_onClose); + + //insert glut context to the map + display->glutWinId = glutWinId; + g_hash_table_insert (gst_gl_display_map, GUINT_TO_POINTER (glutWinId), display); + + //check glut id validity + g_assert (glutGetWindow() == glutWinId); + GST_DEBUG ("Context %d initialized", display->glutWinId); + + //release display constructor + g_cond_signal (display->cond_create); +} + + +/* Called by the idle funtion */ +static void +gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display) +{ + glutSetWindow (display->glutWinId); + + + if (GLEW_EXT_framebuffer_object) + { + GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", display->glutWinId); + + //-- init graphic frame buffer object (GL texture -> GL scene) //setup FBO @@ -627,35 +698,17 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display) display->multipleRT[0] = GL_COLOR_ATTACHMENT0_EXT; display->multipleRT[1] = GL_COLOR_ATTACHMENT1_EXT; display->multipleRT[2] = GL_COLOR_ATTACHMENT2_EXT; - } else { - GST_DEBUG ("Context %d, EXT_framebuffer_object supported: no", glutWinId); + GST_DEBUG ("Context %d, EXT_framebuffer_object supported: no", display->glutWinId); g_assert_not_reached (); } - //check if fragment program is available, then load them - if (GLEW_ARB_vertex_program) + if (GLEW_ARB_vertex_program) { gchar program[2048]; - GST_DEBUG ("Context %d, ARB_fragment_program supported: yes", glutWinId); - - //from video to texture - - sprintf (program, display->textFProgram_YUY2_UYVY, 'r', 'g', 'a'); - - display->GLSLProgram_YUY2 = gst_gl_display_loadGLSLprogram (program); - - sprintf (program, display->textFProgram_YUY2_UYVY, 'a', 'b', 'r'); - - display->GLSLProgram_UYVY = gst_gl_display_loadGLSLprogram (program); - - display->GLSLProgram_I420_YV12 = gst_gl_display_loadGLSLprogram (display->textFProgram_I420_YV12); - - display->GLSLProgram_AYUV = gst_gl_display_loadGLSLprogram (display->textFProgram_AYUV); - //from texture to video sprintf (program, display->textFProgram_to_YUY2_UYVY, "y2,u,y1,v"); @@ -667,28 +720,14 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display) display->GLSLProgram_to_I420_YV12 = gst_gl_display_loadGLSLprogram (display->textFProgram_to_I420_YV12); display->GLSLProgram_to_AYUV = gst_gl_display_loadGLSLprogram (display->textFProgram_to_AYUV); - } - else + } + else { - GST_DEBUG ("Context %d, ARB_fragment_program supported: no", glutWinId); + GST_DEBUG ("Context %d, ARB_fragment_program supported: no", display->glutWinId); g_assert_not_reached (); } - //setup callbacks - glutReshapeFunc (gst_gl_display_onReshape); - glutDisplayFunc (gst_gl_display_draw); - glutCloseFunc (gst_gl_display_onClose); - - //insert glut context to the map - display->glutWinId = glutWinId; - g_hash_table_insert (gst_gl_display_map, GUINT_TO_POINTER (glutWinId), display); - - //check glut id validity - g_assert (glutGetWindow() == glutWinId); - GST_DEBUG ("Context %d initialized", display->glutWinId); - - //release display constructor - g_cond_signal (display->cond_create); + g_cond_signal (display->cond_download); } @@ -877,6 +916,16 @@ gst_gl_display_glutSetVisibleWindow (GstGLDisplay *display) } +/* Called by the idle function */ +static void +gst_gl_display_glutReshapeWindow (GstGLDisplay* display) +{ + glutSetWindow (display->glutWinId); + glutReshapeWindow (display->glcontext_width, display->glcontext_height); + //should reset glcontext_width and height +} + + /* Called by the idle function */ static void gst_gl_display_glutPrepareTexture (GstGLDisplay * display) @@ -985,6 +1034,9 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg) case GST_GL_DISPLAY_ACTION_VISIBLE: gst_gl_display_glutSetVisibleWindow (msg->display); break; + case GST_GL_DISPLAY_ACTION_RESHAPE: + gst_gl_display_glutReshapeWindow (msg->display); + break; case GST_GL_DISPLAY_ACTION_PREPARE: gst_gl_display_glutPrepareTexture (msg->display); break; @@ -1009,6 +1061,9 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg) case GST_GL_DISPLAY_ACTION_USEFBO: gst_gl_display_glutUseFBO (msg->display); break; + case GST_GL_DISPLAY_ACTION_OVFBO: + gst_gldisplay_glutGenerateOutputVideoFBO (msg->display); + break; default: g_assert_not_reached (); } @@ -1029,7 +1084,8 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg) valid = TRUE; break; case GST_GL_DISPLAY_ACTION_DESTROY: - case GST_GL_DISPLAY_ACTION_VISIBLE: + case GST_GL_DISPLAY_ACTION_VISIBLE: + case GST_GL_DISPLAY_ACTION_RESHAPE: case GST_GL_DISPLAY_ACTION_PREPARE: case GST_GL_DISPLAY_ACTION_CHANGE: case GST_GL_DISPLAY_ACTION_CLEAR: @@ -1038,6 +1094,7 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg) case GST_GL_DISPLAY_ACTION_GENFBO: case GST_GL_DISPLAY_ACTION_DELFBO: case GST_GL_DISPLAY_ACTION_USEFBO: + case GST_GL_DISPLAY_ACTION_OVFBO: //msg is out of date if the associated display is not in the map if (!g_hash_table_lookup (gst_gl_display_map, GINT_TO_POINTER (msg->glutWinId))) valid = FALSE; @@ -1148,7 +1205,7 @@ gst_gl_display_setClientDrawCallback (GstGLDisplay * display, CDCB cb) /* Called by gst gl elements */ void -gst_gl_display_setVisibleWindow (GstGLDisplay * display, gboolean visible) +gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible) { gst_gl_display_lock (display); if (display->visible != visible) @@ -1160,11 +1217,23 @@ gst_gl_display_setVisibleWindow (GstGLDisplay * display, gboolean visible) } +/* Called by gst gl elements */ +void +gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height) +{ + gst_gl_display_lock (display); + display->glcontext_width = width; + display->glcontext_height = height; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_RESHAPE, display); + gst_gl_display_unlock (display); +} + + /* Called by gstglbuffer */ void -gst_gl_display_textureRequested (GstGLDisplay * display, GstVideoFormat video_format, - gint width, gint height, guint *texture, - guint *texture_u, guint *texture_v) +gst_gl_display_textureRequested (GstGLDisplay* display, GstVideoFormat video_format, + gint width, gint height, guint* texture, + guint* texture_u, guint* texture_v) { gst_gl_display_lock (display); display->requestedVideo_format = video_format; @@ -1311,6 +1380,19 @@ gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, } +/* Called by gst_gl elements */ +void +gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height) +{ + gst_gl_display_lock (display); + display->glcontext_width = width; + display->glcontext_height = height; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_OVFBO, display); + g_cond_wait (display->cond_download, display->mutex); + gst_gl_display_unlock (display); +} + + /* Called by gst_gl elements */ void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) @@ -1342,38 +1424,6 @@ gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) } -/* Called by gst_gl elements */ -void -gst_gl_display_resetGLcontext (GstGLDisplay* display, - gint glcontext_width, gint glcontext_height) -{ - static gint glheight = 0; - - gst_gl_display_lock (display); - gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DESTROY, display); - g_cond_wait (display->cond_destroy, display->mutex); - gst_gl_display_unlock (display); - - if (g_hash_table_size (gst_gl_display_map) == 0) - { - g_thread_join (gst_gl_display_glutThread); - g_print ("Glut thread joined when setting winId\n"); - gst_gl_display_glutThread = NULL; - g_async_queue_unref (gst_gl_display_messageQueue); - g_hash_table_unref (gst_gl_display_map); - gst_gl_display_map = NULL; - } - - //init opengl context - gst_gl_display_initGLContext (display, - 50, glheight++ * (glcontext_height+50) + 50, - glcontext_width, glcontext_height, - display->textureFBOWidth, display->textureFBOHeight, - display->winId, - FALSE); -} - - /* glutReshapeFunc callback */ void gst_gl_display_onReshape(gint width, gint height) diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 24969235a7..530769cba9 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -46,6 +46,7 @@ typedef enum { GST_GL_DISPLAY_ACTION_CREATE, GST_GL_DISPLAY_ACTION_DESTROY, GST_GL_DISPLAY_ACTION_VISIBLE, + GST_GL_DISPLAY_ACTION_RESHAPE, GST_GL_DISPLAY_ACTION_PREPARE, GST_GL_DISPLAY_ACTION_CHANGE, GST_GL_DISPLAY_ACTION_CLEAR, @@ -53,7 +54,8 @@ typedef enum { GST_GL_DISPLAY_ACTION_REDISPLAY, GST_GL_DISPLAY_ACTION_GENFBO, GST_GL_DISPLAY_ACTION_DELFBO, - GST_GL_DISPLAY_ACTION_USEFBO + GST_GL_DISPLAY_ACTION_USEFBO, + GST_GL_DISPLAY_ACTION_OVFBO } GstGLDisplayAction; @@ -95,6 +97,7 @@ struct _GstGLDisplay { GCond* cond_generateFBO; GCond* cond_useFBO; GCond* cond_destroyFBO; + GCond* cond_download; GCond* cond_create; GCond* cond_destroy; @@ -237,6 +240,7 @@ void gst_gl_display_initGLContext (GstGLDisplay* display, void gst_gl_display_setClientReshapeCallback (GstGLDisplay* display, CRCB cb); void gst_gl_display_setClientDrawCallback (GstGLDisplay* display, CDCB cb); void gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible); +void gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height); void gst_gl_display_textureRequested (GstGLDisplay* display, GstVideoFormat format, gint width, gint height, guint* texture, guint* texture_u, guint* texture_v); @@ -256,8 +260,7 @@ void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint te guint inputTextureWidth, guint inputTextureHeight, guint inputTexture); void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, guint depthbuffer, guint texture); +void gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height); void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId); -void gst_gl_display_resetGLcontext (GstGLDisplay* display, - gint glcontext_width, gint glcontext_height); #endif diff --git a/gst/gl/gstglfilter.c b/gst/gl/gstglfilter.c index a2cc3ad3cc..66ad5e2c91 100644 --- a/gst/gl/gstglfilter.c +++ b/gst/gl/gstglfilter.c @@ -90,8 +90,8 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) gobject_class->set_property = gst_gl_filter_set_property; gobject_class->get_property = gst_gl_filter_get_property; - /*GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = - gst_gl_filter_transform_caps;*/ + GST_BASE_TRANSFORM_CLASS (klass)->transform_caps = + gst_gl_filter_transform_caps; GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_filter_transform; GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_filter_start; GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_stop; @@ -183,7 +183,31 @@ static GstCaps* gst_gl_filter_transform_caps (GstBaseTransform* bt, GstPadDirection direction, GstCaps* caps) { - return NULL; + GstGLFilter* filter = GST_GL_FILTER (bt); + GstStructure* structure = gst_caps_get_structure (caps, 0); + GstCaps* ret = gst_caps_copy (caps); + const GValue* par = NULL; + + structure = gst_structure_copy (gst_caps_get_structure (ret, 0)); + + gst_structure_set (structure, + "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + + gst_caps_merge_structure (ret, gst_structure_copy (structure)); + + if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) + { + gst_structure_set (structure, + "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + gst_caps_merge_structure (ret, structure); + } + else + gst_structure_free (structure); + + GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, ret); + + return ret; } @@ -218,9 +242,11 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); filter->display = g_object_ref (gl_inbuf->display); + //blocking call, generate a FBO gst_gl_display_requestFBO (filter->display, filter->width, filter->height, &filter->fbo, &filter->depthbuffer, &filter->texture); + if (filter_class->onInitFBO) filter_class->onInitFBO (filter); } @@ -228,7 +254,7 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform* trans, gl_outbuf = gst_gl_buffer_new_from_video_format (filter->display, filter->video_format, filter->width, filter->height, - filter->width, filter->height); + gl_inbuf->width, gl_inbuf->height); *buf = GST_BUFFER (gl_outbuf); gst_buffer_set_caps (*buf, caps); @@ -244,18 +270,18 @@ gst_gl_filter_set_caps (GstBaseTransform* bt, GstCaps* incaps, gboolean ret = FALSE; GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); - ret = gst_gl_buffer_format_parse_caps (incaps, &filter->video_format, + ret = gst_gl_buffer_format_parse_caps (outcaps, &filter->video_format, &filter->width, &filter->height); + if (filter_class->set_caps) + filter_class->set_caps (filter, incaps, outcaps); + if (!ret) { GST_DEBUG ("bad caps"); return FALSE; } - if (filter_class->set_caps) - filter_class->set_caps (filter, incaps, outcaps); - GST_ERROR ("set_caps %d %d", filter->width, filter->height); return ret; diff --git a/gst/gl/gstglfilterapp.c b/gst/gl/gstglfilterapp.c index 4bcd61f457..c680bbad0c 100644 --- a/gst/gl/gstglfilterapp.c +++ b/gst/gl/gstglfilterapp.c @@ -36,8 +36,6 @@ static const GstElementDetails element_details = enum { PROP_0, - PROP_GLCONTEXT_WIDTH, - PROP_GLCONTEXT_HEIGHT, PROP_CLIENT_RESHAPE_CALLBACK, PROP_CLIENT_DRAW_CALLBACK }; @@ -48,16 +46,16 @@ enum GST_BOILERPLATE_FULL (GstGLFilterApp, gst_gl_filter_app, GstGLFilter, GST_TYPE_GL_FILTER, DEBUG_INIT); -static void gst_gl_filter_app_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_gl_filter_app_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_gl_filter_app_set_property (GObject* object, guint prop_id, + const GValue* value, GParamSpec* pspec); +static void gst_gl_filter_app_get_property (GObject* object, guint prop_id, + GValue* value, GParamSpec * pspec); static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps); static void gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter); -static gboolean gst_gl_filter_app_filter (GstGLFilter * filter, - GstGLBuffer * inbuf, GstGLBuffer * outbuf); +static gboolean gst_gl_filter_app_filter (GstGLFilter* filter, + GstGLBuffer* inbuf, GstGLBuffer* outbuf); static void gst_gl_filter_app_callback (guint width, guint height, guint texture); @@ -70,36 +68,26 @@ gst_gl_filter_app_base_init (gpointer klass) } static void -gst_gl_filter_app_class_init (GstGLFilterAppClass * klass) +gst_gl_filter_app_class_init (GstGLFilterAppClass* klass) { - GObjectClass* gobject_class; + GObjectClass* gobject_class; - gobject_class = (GObjectClass *) klass; - gobject_class->set_property = gst_gl_filter_app_set_property; - gobject_class->get_property = gst_gl_filter_app_get_property; + gobject_class = (GObjectClass *) klass; + gobject_class->set_property = gst_gl_filter_app_set_property; + gobject_class->get_property = gst_gl_filter_app_get_property; - GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_app_set_caps; - GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_app_filter; - GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_app_setClientCallbacks; - - g_object_class_install_property (gobject_class, PROP_GLCONTEXT_WIDTH, - g_param_spec_int ("glcontext_width", "OpenGL context width", - "Change the opengl context width", 0, INT_MAX, 0, - G_PARAM_WRITABLE)); - - g_object_class_install_property (gobject_class, PROP_GLCONTEXT_HEIGHT, - g_param_spec_int ("glcontext_height", "OpenGL context height", - "Change the opengl context height", 0, INT_MAX, 0, - G_PARAM_WRITABLE)); + GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_app_set_caps; + GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_app_filter; + GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_app_setClientCallbacks; g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", - "Executed in next glut loop iteration when window size is changed", + "Define a custom reshape callback in a client code", G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, g_param_spec_pointer ("client_draw_callback", "Client draw callback", - "Executed in next glut loop iteration when glutPostRedisplay is called", + "Define a custom draw callback in a client code", G_PARAM_WRITABLE)); } @@ -107,8 +95,6 @@ static void gst_gl_filter_app_init (GstGLFilterApp* filter, GstGLFilterAppClass* klass) { - filter->glcontext_width = 0; - filter->glcontext_height = 0; filter->clientReshapeCallback = NULL; filter->clientDrawCallback = NULL; } @@ -120,29 +106,19 @@ gst_gl_filter_app_set_property (GObject* object, guint prop_id, GstGLFilterApp* filter = GST_GL_FILTER_APP (object); switch (prop_id) { - case PROP_GLCONTEXT_WIDTH: - { - filter->glcontext_width = g_value_get_int (value); - break; - } - case PROP_GLCONTEXT_HEIGHT: - { - filter->glcontext_height = g_value_get_int (value); - break; - } - case PROP_CLIENT_RESHAPE_CALLBACK: - { - filter->clientReshapeCallback = g_value_get_pointer (value); - break; - } - case PROP_CLIENT_DRAW_CALLBACK: - { - filter->clientDrawCallback = g_value_get_pointer (value); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + case PROP_CLIENT_RESHAPE_CALLBACK: + { + filter->clientReshapeCallback = g_value_get_pointer (value); + break; + } + case PROP_CLIENT_DRAW_CALLBACK: + { + filter->clientDrawCallback = g_value_get_pointer (value); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -164,24 +140,8 @@ static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps) { - GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); + //GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); - g_print ("app_filter: gst_gl_filter_set_caps\n"); - - /*if (graphicmaker->glcontext_width != 0 && graphicmaker->glcontext_height != 0) - { - GValue value_w = { 0 }; - GValue value_h = { 0 }; - g_value_init (&value_w, G_TYPE_INT); - g_value_init (&value_h, G_TYPE_INT); - g_value_set_int (&value_w, graphicmaker->glcontext_width); - g_value_set_int (&value_h, graphicmaker->glcontext_height); - gst_structure_set_value (newstruct, "width", &value_w); - gst_structure_set_value (newstruct, "height", &value_h); - g_value_unset (&value_w); - g_value_unset (&value_h); - } - else*/ return TRUE; } @@ -197,10 +157,6 @@ gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter) //set the client draw callback gst_gl_display_setClientDrawCallback (filter->display, app_filter->clientDrawCallback); - - if (app_filter->glcontext_width != 0 && app_filter->glcontext_height != 0) - gst_gl_display_resetGLcontext (filter->display, - app_filter->glcontext_width, app_filter->glcontext_height); } static gboolean @@ -209,11 +165,13 @@ gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, { GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); - outbuf->width = filter->width; - outbuf->height = filter->height; + outbuf->width = inbuf->width; + outbuf->height = inbuf->height; outbuf->texture = inbuf->texture; outbuf->texture_u = inbuf->texture_u; outbuf->texture_v = inbuf->texture_v; + outbuf->widthGL = inbuf->widthGL; + outbuf->heightGL = inbuf->heightGL; outbuf->textureGL = inbuf->textureGL; return TRUE; diff --git a/gst/gl/gstglfilterapp.h b/gst/gl/gstglfilterapp.h index cd60402899..95c24dbe9f 100644 --- a/gst/gl/gstglfilterapp.h +++ b/gst/gl/gstglfilterapp.h @@ -37,8 +37,7 @@ typedef struct _GstGLFilterAppClass GstGLFilterAppClass; struct _GstGLFilterApp { GstGLFilter filter; - gint glcontext_width; - gint glcontext_height; + CRCB clientReshapeCallback; CDCB clientDrawCallback; }; diff --git a/gst/gl/gstglfiltercube.c b/gst/gl/gstglfiltercube.c index 2348c168c5..7a8652af50 100644 --- a/gst/gl/gstglfiltercube.c +++ b/gst/gl/gstglfiltercube.c @@ -119,8 +119,8 @@ gst_gl_filter_cube_filter (GstGLFilter* filter, GstGLBuffer* inbuf, filter->fbo, filter->depthbuffer, filter->texture, gst_gl_filter_cube_callback, inbuf->width, inbuf->height, inbuf->textureGL); - outbuf->width = filter->width; - outbuf->height = filter->height; + outbuf->width = inbuf->width; + outbuf->height = inbuf->height; outbuf->texture = inbuf->texture; outbuf->texture_u = inbuf->texture_u; outbuf->texture_v = inbuf->texture_v; diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index d75ddec8d8..000e7e139d 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -412,6 +412,8 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) if (glimage_sink->window_id) gst_gl_display_set_windowId (glimage_sink->display, glimage_sink->window_id); + gst_gl_display_resizeWindow (glimage_sink->display, glimage_sink->width, glimage_sink->height); + gst_gl_display_setVisibleWindow (glimage_sink->display, TRUE); } } @@ -466,7 +468,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) //redisplay opengl scene isAlive = gst_gl_display_postRedisplay (glimage_sink->display, - gl_buffer->textureGL, gl_buffer->width, gl_buffer->height); + gl_buffer->textureGL, gl_buffer->widthGL, gl_buffer->heightGL); if (isAlive) return GST_FLOW_OK; diff --git a/gst/gl/gstglvideomaker.c b/gst/gl/gstglvideomaker.c index d9809bb5c2..63efe7532a 100644 --- a/gst/gl/gstglvideomaker.c +++ b/gst/gl/gstglvideomaker.c @@ -297,7 +297,10 @@ gst_gl_videomaker_transform (GstBaseTransform* trans, GstBuffer* inbuf, videomaker = GST_GL_VIDEOMAKER (trans); if (videomaker->display == NULL) + { videomaker->display = g_object_ref (gl_inbuf->display); + gst_gl_display_initDonwloadFBO (videomaker->display, videomaker->width, videomaker->height); + } else g_assert (videomaker->display == gl_inbuf->display);