diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index 5a4267a020..a1de98ebda 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -170,7 +170,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->upload_height = 0; display->upload_video_format = 0; display->colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MESA; - display->upload_data_with = 0; + display->upload_data_width = 0; display->upload_data_height = 0; display->upload_data = NULL; @@ -1139,6 +1139,9 @@ gst_gl_display_thread_init_upload (GstGLDisplay *display) g_assert_not_reached (); } + //alloc texture (related to upload) memory only on time + gst_gl_display_thread_do_upload_make (display); + g_cond_signal (display->cond_init_upload); } @@ -1149,8 +1152,6 @@ gst_gl_display_thread_do_upload (GstGLDisplay *display) { glutSetWindow (display->glutWinId); - //FIXME:call upload_make function in thread_init_upload instead of calling it here - gst_gl_display_thread_do_upload_make (display); gst_gl_display_thread_do_upload_fill (display); gst_gl_display_thread_do_upload_draw (display); @@ -2001,12 +2002,15 @@ gst_gl_display_del_texture (GstGLDisplay* display, GLuint texture, GLint width, /* Called by the first gl element of a video/x-raw-gl flow */ void gst_gl_display_init_upload (GstGLDisplay* display, GstVideoFormat video_format, - guint gl_width, guint gl_height) + guint gl_width, guint gl_height, + gint video_width, gint video_height) { gst_gl_display_lock (display); display->upload_video_format = video_format; display->upload_width = gl_width; display->upload_height = gl_height; + display->upload_data_width = video_width; + display->upload_data_height = video_height; gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_INIT_UPLOAD, display); g_cond_wait (display->cond_init_upload, display->mutex); gst_gl_display_unlock (display); @@ -2026,7 +2030,7 @@ gst_gl_display_do_upload (GstGLDisplay *display, GLuint texture, if (isAlive) { display->upload_outtex = texture; - display->upload_data_with = data_width; + display->upload_data_width = data_width; display->upload_data_height = data_height; display->upload_data = data; gst_gl_display_post_message (GST_GL_DISPLAY_ACTION_DO_UPLOAD, display); @@ -2225,116 +2229,112 @@ gst_gl_display_set_client_draw_callback (GstGLDisplay * display, CDCB cb) /* called by gst_gl_display_thread_do_upload (in the gl thread) */ void gst_gl_display_thread_do_upload_make (GstGLDisplay *display) { - gint width = display->upload_data_with; + gint width = display->upload_data_width; gint height = display->upload_data_height; - //FIXME:remove the next check then call this function in thread_init_upload - if (display->upload_intex == 0) + glGenTextures (1, &display->upload_intex); + + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex); + switch (display->upload_video_format) { - glGenTextures (1, &display->upload_intex); + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_AYUV: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + break; - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex); - switch (display->upload_video_format) + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, + width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + break; + + case GST_VIDEO_FORMAT_YUY2: + switch (display->colorspace_conversion) { - case GST_VIDEO_FORMAT_RGBx: - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_xBGR: - case GST_VIDEO_FORMAT_RGBA: - case GST_VIDEO_FORMAT_BGRA: - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_ABGR: - case GST_VIDEO_FORMAT_AYUV: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - break; - - case GST_VIDEO_FORMAT_RGB: - case GST_VIDEO_FORMAT_BGR: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, - width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - break; - - case GST_VIDEO_FORMAT_YUY2: - switch (display->colorspace_conversion) - { - case GST_GL_DISPLAY_CONVERSION_GLSL: - case GST_GL_DISPLAY_CONVERSION_MATRIX: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, - width, height, - 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); - - if (display->upload_intex_u == 0) { - glGenTextures (1, &display->upload_intex_u); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, - width, height, - 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - } - break; - case GST_GL_DISPLAY_CONVERSION_MESA: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, - width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); - break; - default: - g_assert_not_reached (); - } - break; - case GST_VIDEO_FORMAT_UYVY: - switch (display->colorspace_conversion) - { - case GST_GL_DISPLAY_CONVERSION_GLSL: - case GST_GL_DISPLAY_CONVERSION_MATRIX: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, - width, height, - 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); - if (display->upload_intex_u == 0) { - glGenTextures (1, &display->upload_intex_u); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, - width, height, - 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - break; - } - case GST_GL_DISPLAY_CONVERSION_MESA: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, - width, height, - 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); - break; - default: - g_assert_not_reached (); - } - break; - - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, - width, height, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); - - if (display->upload_intex_u == 0) { - glGenTextures (1, &display->upload_intex_u); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, - GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); - } - - if (display->upload_intex_v == 0) { - glGenTextures (1, &display->upload_intex_v); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_v); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, - GST_ROUND_UP_2 (width) / 2, - GST_ROUND_UP_2 (height) / 2, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); - } - break; + case GST_GL_DISPLAY_CONVERSION_GLSL: + case GST_GL_DISPLAY_CONVERSION_MATRIX: +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, + width, height, + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); +if (display->upload_intex_u == 0) { + glGenTextures (1, &display->upload_intex_u); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, + width, height, + 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); +} +break; + case GST_GL_DISPLAY_CONVERSION_MESA: +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, + width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); +break; default: - g_assert_not_reached (); +g_assert_not_reached (); } + break; + case GST_VIDEO_FORMAT_UYVY: + switch (display->colorspace_conversion) + { + case GST_GL_DISPLAY_CONVERSION_GLSL: + case GST_GL_DISPLAY_CONVERSION_MATRIX: +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE_ALPHA, + width, height, + 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); +if (display->upload_intex_u == 0) { + glGenTextures (1, &display->upload_intex_u); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, + width, height, + 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + break; +} + case GST_GL_DISPLAY_CONVERSION_MESA: +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, + width, height, + 0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, NULL); +break; + default: +g_assert_not_reached (); + } + break; + + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, + width, height, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + + if (display->upload_intex_u == 0) { +glGenTextures (1, &display->upload_intex_u); +glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, + GST_ROUND_UP_2 (width) / 2, + GST_ROUND_UP_2 (height) / 2, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + } + + if (display->upload_intex_v == 0) { +glGenTextures (1, &display->upload_intex_v); +glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_v); +glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, + GST_ROUND_UP_2 (width) / 2, + GST_ROUND_UP_2 (height) / 2, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + } + break; + + default: + g_assert_not_reached (); } } @@ -2343,7 +2343,7 @@ void gst_gl_display_thread_do_upload_make (GstGLDisplay *display) void gst_gl_display_thread_do_upload_fill (GstGLDisplay *display) { - gint width = display->upload_data_with; + gint width = display->upload_data_width; gint height = display->upload_data_height; gpointer data = display->upload_data; @@ -2615,13 +2615,13 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay *display) }//end switch display->currentVideo_format glBegin (GL_QUADS); - glTexCoord2i (display->upload_data_with, 0); + glTexCoord2i (display->upload_data_width, 0); glVertex2f (1.0f, -1.0f); glTexCoord2i (0, 0); glVertex2f (-1.0f, -1.0f); glTexCoord2i (0, display->upload_data_height); glVertex2f (-1.0f, 1.0f); - glTexCoord2i (display->upload_data_with, display->upload_data_height); + glTexCoord2i (display->upload_data_width, display->upload_data_height); glVertex2f (1.0f, 1.0f); glEnd (); diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index bc364dc314..cd65dcf858 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -175,7 +175,7 @@ struct _GstGLDisplay { GLuint upload_height; GstVideoFormat upload_video_format; GstGLDisplayConversion colorspace_conversion; - gint upload_data_with; + gint upload_data_width; gint upload_data_height; gpointer upload_data; @@ -278,7 +278,8 @@ void gst_gl_display_gen_texture (GstGLDisplay* display, GLuint* pTexture, GLint void gst_gl_display_del_texture (GstGLDisplay* display, GLuint texture, GLint width, GLint height); void gst_gl_display_init_upload (GstGLDisplay* display, GstVideoFormat video_format, - guint gl_width, guint gl_height); + guint gl_width, guint gl_height, + gint video_width, gint video_height); gboolean gst_gl_display_do_upload (GstGLDisplay* display, GLuint texture, gint data_width, gint data_height, gpointer data); diff --git a/gst/gl/gstglcolorscale.c b/gst/gl/gstglcolorscale.c index 9f435a7074..dae92af6cb 100644 --- a/gst/gl/gstglcolorscale.c +++ b/gst/gl/gstglcolorscale.c @@ -396,7 +396,8 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps, //blocking call, init colorspace conversion if needed gst_gl_display_init_upload (colorscale->display, colorscale->input_video_format, - colorscale->output_video_width, colorscale->output_video_height); + colorscale->output_video_width, colorscale->output_video_height, + colorscale->input_video_width, colorscale->input_video_height); //blocking call, init colorspace conversion if needed gst_gl_display_init_download (colorscale->display, colorscale->output_video_format, diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index c71e64828e..236f4301d3 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -1,4 +1,4 @@ -/* +/* * GStreamer * Copyright (C) 2008 Julien Isorce * @@ -88,7 +88,7 @@ GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink, static void gst_glimage_sink_init_interfaces (GType type) { - + static const GInterfaceInfo implements_info = { (GInterfaceInitFunc) gst_glimage_sink_implements_init, NULL, @@ -139,12 +139,12 @@ gst_glimage_sink_class_init (GstGLImageSinkClass* klass) g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", - "Define a custom reshape callback in a client code", + "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", - "Define a custom draw callback in a client code", + "Define a custom draw callback in a client code", G_PARAM_WRITABLE)); gobject_class->finalize = gst_glimage_sink_finalize; @@ -182,7 +182,7 @@ gst_glimage_sink_set_property (GObject* object, guint prop_id, glimage_sink = GST_GLIMAGE_SINK (object); - switch (prop_id) + switch (prop_id) { case ARG_DISPLAY: { @@ -215,7 +215,7 @@ gst_glimage_sink_finalize (GObject* object) glimage_sink = GST_GLIMAGE_SINK (object); - if (glimage_sink->caps) + if (glimage_sink->caps) gst_caps_unref (glimage_sink->caps); g_free (glimage_sink->display_name); @@ -231,7 +231,7 @@ gst_glimage_sink_get_property (GObject* object, guint prop_id, glimage_sink = GST_GLIMAGE_SINK (object); - switch (prop_id) + switch (prop_id) { case ARG_DISPLAY: g_value_set_string (value, glimage_sink->display_name); @@ -256,7 +256,7 @@ gst_glimage_sink_change_state (GstElement* element, GstStateChange transition) glimage_sink = GST_GLIMAGE_SINK (element); - switch (transition) + switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; @@ -272,7 +272,7 @@ gst_glimage_sink_change_state (GstElement* element, GstStateChange transition) if (ret == GST_STATE_CHANGE_FAILURE) return ret; - switch (transition) + switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; @@ -314,12 +314,12 @@ gst_glimage_sink_stop (GstBaseSink* bsink) glimage_sink = GST_GLIMAGE_SINK (bsink); - if (glimage_sink->stored_buffer) + if (glimage_sink->stored_buffer) { gst_buffer_unref (glimage_sink->stored_buffer); glimage_sink->stored_buffer = NULL; } - if (glimage_sink->display) + if (glimage_sink->display) { g_object_unref (glimage_sink->display); glimage_sink->display = NULL; @@ -346,12 +346,12 @@ gst_glimage_sink_get_times (GstBaseSink* bsink, GstBuffer* buf, glimagesink = GST_GLIMAGE_SINK (bsink); - if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) + if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { *start = GST_BUFFER_TIMESTAMP (buf); - if (GST_BUFFER_DURATION_IS_VALID (buf)) + if (GST_BUFFER_DURATION_IS_VALID (buf)) *end = *start + GST_BUFFER_DURATION (buf); - else + else { if (glimagesink->fps_n > 0) { *end = *start + @@ -422,57 +422,58 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) glimage_sink = GST_GLIMAGE_SINK (bsink); //is gl - if (glimage_sink->is_gl) + if (glimage_sink->is_gl) { //increment gl buffer ref before storage gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); //if glimagesink has not the display yet - if (glimage_sink->display == NULL) + if (glimage_sink->display == NULL) { glimage_sink->display = g_object_ref (gl_buffer->display); if (glimage_sink->window_id) gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id); - gst_gl_display_set_client_reshape_callback (glimage_sink->display, + gst_gl_display_set_client_reshape_callback (glimage_sink->display, glimage_sink->clientReshapeCallback); - - gst_gl_display_set_client_draw_callback (glimage_sink->display, + + gst_gl_display_set_client_draw_callback (glimage_sink->display, glimage_sink->clientDrawCallback); gst_gl_display_resize_context (glimage_sink->display, glimage_sink->width, glimage_sink->height); gst_gl_display_set_visible_context (glimage_sink->display, TRUE); - } - } + } + } //is not gl - else - { + else + { //if glimagesink has not the display yet - if (glimage_sink->display == NULL) + if (glimage_sink->display == NULL) { - + //do not stack when multiple windows static gint y_pos = 0; - + //create a display glimage_sink->display = gst_gl_display_new (); //init opengl context - gst_gl_display_create_context (glimage_sink->display, - 50, y_pos++ * (glimage_sink->height+50) + 50, - glimage_sink->width, glimage_sink->height, + gst_gl_display_create_context (glimage_sink->display, + 50, y_pos++ * (glimage_sink->height+50) + 50, + glimage_sink->width, glimage_sink->height, glimage_sink->window_id, TRUE); //init colorspace conversion if needed - gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, + gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, + glimage_sink->width, glimage_sink->height, glimage_sink->width, glimage_sink->height); - gst_gl_display_set_client_reshape_callback (glimage_sink->display, + gst_gl_display_set_client_reshape_callback (glimage_sink->display, glimage_sink->clientReshapeCallback); - - gst_gl_display_set_client_draw_callback (glimage_sink->display, + + gst_gl_display_set_client_draw_callback (glimage_sink->display, glimage_sink->clientDrawCallback); gst_gl_display_resize_context (glimage_sink->display, glimage_sink->width, glimage_sink->height); @@ -490,7 +491,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) } //the buffer is cleared when an other comes in - if (glimage_sink->stored_buffer) + if (glimage_sink->stored_buffer) { gst_buffer_unref (glimage_sink->stored_buffer); glimage_sink->stored_buffer = NULL; @@ -501,7 +502,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) //redisplay opengl scene if (gl_buffer->texture && - gst_gl_display_redisplay (glimage_sink->display, + gst_gl_display_redisplay (glimage_sink->display, gl_buffer->texture, gl_buffer->width, gl_buffer->height)) return GST_FLOW_OK; else @@ -526,7 +527,7 @@ gst_glimage_sink_set_xwindow_id (GstXOverlay* overlay, gulong window_id) GST_DEBUG ("set_xwindow_id %ld", window_id); - if (glimage_sink->window_id == window_id) + if (glimage_sink->window_id == window_id) return; if (window_id) diff --git a/gst/gl/gstglupload.c b/gst/gl/gstglupload.c index caadbd9e68..3759e8bb18 100644 --- a/gst/gl/gstglupload.c +++ b/gst/gl/gstglupload.c @@ -403,7 +403,8 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps, //init colorspace conversion if needed gst_gl_display_init_upload (upload->display, upload->video_format, - upload->gl_width, upload->gl_height); + upload->gl_width, upload->gl_height, + upload->video_width, upload->video_height); return ret; }