[gstreamer-bugs] [Bug 330598] New: [PATCH] crash in playbin and fix
GStreamer (bugzilla.gnome.org)
bugzilla-daemon at bugzilla.gnome.org
Thu Feb 9 15:26:23 PST 2006
Do not reply to this via email (we are currently unable to handle email
responses and they get discarded). You can add comments to this bug at
http://bugzilla.gnome.org/show_bug.cgi?id=330598
GStreamer | gst-plugins-base | Ver: 0.10.2
Summary: [PATCH] crash in playbin and fix
Product: GStreamer
Version: 0.10.2
Platform: Other
OS/Version: Linux
Status: UNCONFIRMED
Severity: normal
Priority: Normal
Component: gst-plugins-base
AssignedTo: gstreamer-bugs at lists.sourceforge.net
ReportedBy: wxprojects at comcast.net
QAContact: gstreamer-bugs at lists.sourceforge.net
GNOME version: Unspecified
GNOME milestone: Unspecified
Due to a change to set elements to GST_STATE_NULL in remove_sinks of playbin a
crash can be introduced. The frame member of playbin may be reliant upon the
xoverlay or another video element, so if that video element gets detroyed first
then when it tries to unref the frame member it could crash, and indeed does in
some instances depending on how the elements are layed out -in this case it is
because gst_ximagesink_ximage_destroy does not check ximagesink->xcontext for
NULL.
Program to reproduce crash in 10.2 (Note that I get this in anther actually
well-written application :)):
-----------
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#define TIMEOUT 100 * GST_MSECOND
GstXOverlay *x_overlay;
GtkWindow *window;
GtkWidget *videoarea;
Drawable xwindow_id;
static gboolean crashtime (GstElement * playbin)
{
gtk_main_quit();
return FALSE;
}
GstBusSyncReply sync_callback(GstBus *bus, GstMessage *message,
gpointer)
{
if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
return GST_BUS_PASS;
if (gst_structure_has_name (gst_message_get_structure(message),
"prepare-xwindow-id"))
{
gst_x_overlay_set_xwindow_id(
GST_X_OVERLAY(GST_MESSAGE_SRC(message)),
xwindow_id)
;
return GST_BUS_PASS;
}
return GST_BUS_DROP;
}
int main(int argc, char* argv[])
{
gtk_init (&argc, &argv);
g_thread_init(NULL);
gdk_threads_init();
gst_init(&argc, &argv);
if(argc > 1)
{
GtkWindow* window = (GtkWindow*)gtk_window_new
(GTK_WINDOW_TOPLEVEL);
videoarea = gtk_drawing_area_new ();
gtk_widget_set_size_request(videoarea, 320, 200);
GdkColor color;
gdk_color_parse ("black", &color);
gtk_widget_modify_bg (videoarea, GTK_STATE_NORMAL, &color);
gtk_container_add (GTK_CONTAINER (window), videoarea);
gtk_widget_show (videoarea);
gtk_widget_show ((GtkWidget*)window);
gtk_widget_set_double_buffered((GtkWidget*)window, FALSE);
Display *display;
display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
xwindow_id = GDK_DRAWABLE_XID((videoarea->window));
GstElement* playbin =
gst_element_factory_make ("playbin", "play");
gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (playbin)),
(GstBusSyncHandler)sync_callback, NULL);
GstElement* videosink =
gst_element_factory_make("ximagesink", "video-sink");
GstElement* audiosink =
gst_element_factory_make ("gconfaudiosink", "audio-sink");
if( GST_IS_BIN(videosink) )
x_overlay = (GstXOverlay*)
gst_bin_get_by_interface (GST_BIN (videosink),
GST_TYPE_X_OVERLAY);
else
x_overlay = (GstXOverlay*) videosink;
g_object_set (G_OBJECT (playbin),
"video-sink", videosink,
"audio-sink", audiosink,
NULL);
gst_element_set_state(playbin,
GST_STATE_READY);
gst_element_get_state(playbin, NULL, NULL, TIMEOUT);
GstElement* vis =
gst_element_factory_make ("goom", "vis");
g_object_set(playbin, "vis-plugin", vis, NULL);
g_object_set (G_OBJECT (playbin), "uri",
argv[1], NULL);
gst_element_set_state(playbin,
GST_STATE_PAUSED);
gst_element_get_state(playbin, NULL, NULL, TIMEOUT);
gst_element_set_state(playbin,
GST_STATE_PLAYING);
gst_element_get_state(playbin, NULL, NULL, TIMEOUT);
g_timeout_add (10000, (GSourceFunc) crashtime, playbin);
gtk_main ();
gst_element_set_state(playbin,
GST_STATE_READY); /* will crash here */
gst_element_get_state(playbin, NULL, NULL, TIMEOUT);
}
return 0;
}
---------
Backtrace:
---------
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1221330272 (LWP 18841)]
0xb7f30a35 in gst_ximage_buffer_finalize (ximage=0x8263b88) at ximagesink.c:491
491 if (ximagesink->xcontext->use_xshm) {
Current language: auto; currently c
(gdb) bt
#0 0xb7f30a35 in gst_ximage_buffer_finalize (ximage=0x8263b88)
at ximagesink.c:491
#1 0xb7e24ad9 in gst_mini_object_unref (mini_object=0x8263b88)
at gstminiobject.c:264
#2 0xb71a75b1 in remove_sinks (play_bin=0x80f9bc8) at gstplaybin.c:764
#3 0xb71a8311 in gst_play_bin_change_state (element=0x80f9bc8,
transition=GST_STATE_CHANGE_PAUSED_TO_READY) at gstplaybin.c:1055
#4 0xb7e17f4e in gst_element_change_state (element=0x80f9bc8,
transition=Variable "transition" is not available.
)
at gstelement.c:2151
#5 0xb7e1805b in gst_element_change_state (element=0x80f9bc8,
transition=Variable "transition" is not available.
)
at gstelement.c:2184
#6 0xb7e185aa in gst_element_set_state_func (element=0x80f9bc8,
state=GST_STATE_READY) at gstelement.c:2113
#7 0xb7e1727e in gst_element_set_state (element=0x80f9bc8,
state=GST_STATE_READY) at gstelement.c:2030
#8 0x080496aa in main (argc=2, argv=0xbfc49b34)
at junk.cpp:109
--------------
There are several solutions of which:
1) Make playbin unref the frame member before the sinks -
--- gst/playback/gstplaybinole.c 2006-02-09 11:15:12.000000000 -0800
+++ gst/playback/gstplaybin.c 2006-02-09 11:19:19.000000000 -0800
@@ -690,4 +690,12 @@
GST_DEBUG ("removesinks");
+
+ /* we need to dispose of the frame before the video
+ * sink as it may be a component of it */
+ if (play_bin->frame) {
+ gst_buffer_unref (play_bin->frame);
+ play_bin->frame = NULL;
+ }
+
element = g_hash_table_lookup (play_bin->cache, "abin");
if (element != NULL) {
@@ -761,9 +769,4 @@
}
- if (play_bin->frame) {
- gst_buffer_unref (play_bin->frame);
- play_bin->frame = NULL;
- }
-
play_bin->textoverlay_element = NULL;
}
-----------
2) Change ximagesink to check for NULL for ximagesink->xcontext in
gst_ximagesink_ximage_destroy
--- sys/ximage/ximagesinkole.c 2006-01-16 07:28:47.000000000 -0800
+++ sys/ximage/ximagesink.c 2006-02-09 11:32:47.000000000 -0800
@@ -489,5 +489,5 @@
#ifdef HAVE_XSHM
- if (ximagesink->xcontext->use_xshm) {
+ if (ximagesink->xcontext && ximagesink->xcontext->use_xshm) {
if (ximage->SHMInfo.shmaddr != ((void *) -1)) {
XShmDetach (ximagesink->xcontext->disp, &ximage->SHMInfo);
@@ -508,5 +508,7 @@
}
+ if(ximagesink->xcontext) {
XSync (ximagesink->xcontext->disp, FALSE);
+ }
g_mutex_unlock (ximagesink->x_lock);
-----------
3) Or, if this is desired behaviour perhaps a simple
g_return_if_fail (ximagesink->xcontext != NULL);
or similar could be added to the top of gst_ximagesink_ximage_destroy
--
Configure bugmail: http://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the Gstreamer-bugs
mailing list