+ // Use the xoverlay extension to tell gstreamer to play in our window
+#ifdef __WXGTK__
+ if(!GTK_WIDGET_REALIZED(m_ctrl->m_wxwindow))
+ {
+ // Not realized yet - set to connect at realization time
+ g_signal_connect (m_ctrl->m_wxwindow,
+ "realize",
+ G_CALLBACK (gtk_window_realize_callback),
+ this);
+ }
+ else
+ {
+ wxYield(); // see realize callback...
+ GdkWindow *window = GTK_PIZZA(m_ctrl->m_wxwindow)->bin_window;
+ wxASSERT(window);
+#endif
+
+ gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(m_xoverlay),
+#ifdef __WXGTK__
+ GDK_WINDOW_XWINDOW( window )
+#else
+ ctrl->GetHandle()
+#endif
+ );
+
+#ifdef __WXGTK__
+ g_signal_connect (m_ctrl->m_wxwindow,
+ // m_ctrl->m_wxwindow/*m_ctrl->m_widget*/,
+ "expose_event",
+ G_CALLBACK(gtk_window_expose_callback), this);
+ } // end if GtkPizza realized
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// wxGStreamerMediaBackend::SyncStateChange
+//
+// This function is rather complex - basically the idea is that we
+// poll the GstBus of m_playbin until it has reached desiredstate, an error
+// is reached, or there are no more messages left in the GstBus queue.
+//
+// Returns true if there are no messages left in the queue or
+// the current state reaches the disired state.
+//
+// PRECONDITION: Assumes m_asynclock is Lock()ed
+//-----------------------------------------------------------------------------
+#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
+bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
+ GstElementState desiredstate,
+ gint64 llTimeout)
+{
+ GstBus* bus = gst_element_get_bus(element);
+ GstMessage* message;
+ bool bBreak = false,
+ bSuccess = false;
+ gint64 llTimeWaited = 0;
+
+ do
+ {
+#if 1
+ // NB: The GStreamer gst_bus_poll is unfortunately broken and
+ // throws silly critical internal errors (for instance
+ // "message != NULL" when the whole point of it is to
+ // poll for the message in the first place!) so we implement
+ // our own "waiting mechinism"
+ if(gst_bus_have_pending(bus) == FALSE)
+ {
+ if(llTimeWaited >= llTimeout)
+ return true; // Reached timeout... assume success
+ llTimeWaited += 10*GST_MSECOND;
+ wxMilliSleep(10);
+ continue;
+ }
+
+ message = gst_bus_pop(bus);
+#else
+ message = gst_bus_poll(bus, (GstMessageType)
+ (GST_MESSAGE_STATE_CHANGED |
+ GST_MESSAGE_ERROR |
+ GST_MESSAGE_EOS), llTimeout);
+ if(!message)
+ return true;
+#endif
+ if(((GstElement*)GST_MESSAGE_SRC(message)) == element)
+ {
+ switch(GST_MESSAGE_TYPE(message))
+ {
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState oldstate, newstate, pendingstate;
+ gst_message_parse_state_changed(message, &oldstate,
+ &newstate, &pendingstate);
+ if(newstate == desiredstate)
+ {
+ bSuccess = bBreak = true;
+ }
+ break;
+ }
+ case GST_MESSAGE_ERROR:
+ {
+ GError* error;
+ gchar* debug;
+ gst_message_parse_error(message, &error, &debug);
+ gst_error_callback(NULL, NULL, error, debug, this);
+ bBreak = true;
+ break;
+ }
+ case GST_MESSAGE_EOS:
+ wxLogSysError(wxT("Reached end of stream prematurely"));
+ bBreak = true;
+ break;
+ default:
+ break; // not handled
+ }
+ }
+
+ gst_message_unref(message);
+ }while(!bBreak);
+
+ return bSuccess;
+}
+#else // 0.8 implementation
+bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
+ GstElementState desiredstate,
+ gint64 llTimeout)
+{
+ gint64 llTimeWaited = 0;
+ while(GST_STATE(element) != desiredstate)
+ {
+ if(llTimeWaited >= llTimeout)
+ break;
+ llTimeWaited += 10*GST_MSECOND;
+ wxMilliSleep(10);
+ }
+
+ return llTimeWaited != llTimeout;