diff --git a/wxGTK3-3.0.3-gst1.0.patch b/wxGTK3-3.0.3-gst1.0.patch new file mode 100644 index 0000000..63f793a --- /dev/null +++ b/wxGTK3-3.0.3-gst1.0.patch @@ -0,0 +1,886 @@ +Index: wxwidgets3.0-3.0.2+dfsg/configure.in +=================================================================== +--- wxwidgets3.0-3.0.2+dfsg.orig/configure.in ++++ wxwidgets3.0-3.0.2+dfsg/configure.in +@@ -7543,43 +7543,22 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$ + wxUSE_GSTREAMER="no" + + dnl ------------------------------------------------------------------- +- dnl Test for at least 0.8 gstreamer module from pkg-config +- dnl Even totem doesn't accept 0.9 evidently. +- dnl +- dnl So, we first check to see if 0.10 if available - if not we +- dnl try the older 0.8 version ++ dnl Test for at least gstreamer 1.0 module from pkg-config + dnl ------------------------------------------------------------------- +- GST_VERSION_MAJOR=0 +- GST_VERSION_MINOR=10 ++ GST_VERSION_MAJOR=1 ++ GST_VERSION_MINOR=0 + GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR + +- if test "$wxUSE_GSTREAMER8" = "no"; then +- PKG_CHECK_MODULES(GST, +- [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION], +- [ +- wxUSE_GSTREAMER="yes" +- GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION" +- ], +- [ +- AC_MSG_WARN([GStreamer 0.10 not available, falling back to 0.8]) +- GST_VERSION_MINOR=8 +- ] +- ) +- else +- dnl check only for 0.8 +- GST_VERSION_MINOR=8 +- fi +- +- if test $GST_VERSION_MINOR = "8"; then +- GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR +- PKG_CHECK_MODULES(GST, +- [gstreamer-$GST_VERSION gstreamer-interfaces-$GST_VERSION gstreamer-gconf-$GST_VERSION], +- wxUSE_GSTREAMER="yes", +- [ +- AC_MSG_WARN([GStreamer 0.8/0.10 not available.]) +- ]) +- fi +- ++ PKG_CHECK_MODULES(GST, ++ [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION], ++ [ ++ wxUSE_GSTREAMER="yes" ++ GST_LIBS="$GST_LIBS -lgstvideo-$GST_VERSION" ++ ], ++ [ ++ AC_MSG_WARN([GStreamer 1.0 not available]) ++ ] ++ ) + + if test "$wxUSE_GSTREAMER" = "yes"; then + CPPFLAGS="$GST_CFLAGS $CPPFLAGS" +Index: wxwidgets3.0-3.0.2+dfsg/src/unix/mediactrl.cpp +=================================================================== +--- wxwidgets3.0-3.0.2+dfsg.orig/src/unix/mediactrl.cpp ++++ wxwidgets3.0-3.0.2+dfsg/src/unix/mediactrl.cpp +@@ -19,13 +19,7 @@ + + #include // main gstreamer header + +-// xoverlay/video stuff, gst-gconf for 0.8 +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 +-# include +-#else +-# include +-# include // gstreamer glib configuration +-#endif ++#include + + #ifndef WX_PRECOMP + #include "wx/log.h" // wxLogDebug/wxLogSysError/wxLogTrace +@@ -48,11 +42,11 @@ + //----------------------------------------------------------------------------- + + /* +- This is the GStreamer backend for unix. Currently we require 0.8 or +- 0.10. Here we use the "playbin" GstElement for ease of use. ++ This is the GStreamer backend for unix. Currently we require 1.0. ++ Here we use the "playbin" GstElement for ease of use. + +- Note that now we compare state change functions to GST_STATE_FAILURE +- now rather than GST_STATE_SUCCESS as newer gstreamer versions return ++ Note that now we compare state change functions to GST_STATE_CHANGE_FAILURE ++ now rather than GST_STATE_CHANGE_SUCCESS as newer gstreamer versions return + non-success values for returns that are otherwise successful but not + immediate. + +@@ -60,11 +54,8 @@ + moment but with a tad bit of work it could theorectically work in + straight wxX11 et al. + +- One last note is that resuming from pausing/seeking can result +- in erratic video playback (GStreamer-based bug, happens in totem as well) +- - this is better in 0.10, however. One thing that might make it worse +- here is that we don't preserve the aspect ratio of the video and stretch +- it to the whole window. ++ One last note is that we don't preserve the aspect ratio of the video and ++ stretch it to the whole window. + + Note that there are some things used here that could be undocumented - + for reference see the media player Kiss and Totem as well as some +@@ -72,12 +63,10 @@ + that attempted thread-safety... + + Then there is the issue of m_asynclock. This serves several purposes: +- 1) It prevents the C callbacks from sending wx state change events +- so that we don't get duplicate ones in 0.8 +- 2) It makes the sync and async handlers in 0.10 not drop any ++ 1) It makes the sync and async handlers not drop any + messages so that while we are polling it we get the messages in + SyncStateChange instead of the queue. +- 3) Keeps the pausing in Stop() synchronous ++ 2) Keeps the pausing in Stop() synchronous + + RN: Note that I've tried to follow the wxGTK conventions here as close + as possible. In the implementation the C Callbacks come first, then +@@ -90,43 +79,9 @@ + //============================================================================= + + //----------------------------------------------------------------------------- +-// GStreamer (most version compatibility) macros ++// GStreamer macros + //----------------------------------------------------------------------------- + +-// In 0.9 there was a HUGE change to GstQuery and the +-// gst_element_query function changed dramatically and split off +-// into two separate ones +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8 +-# define wxGst_element_query_duration(e, f, p) \ +- gst_element_query(e, GST_QUERY_TOTAL, f, p) +-# define wxGst_element_query_position(e, f, p) \ +- gst_element_query(e, GST_QUERY_POSITION, f, p) +-#elif GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 9 +-// However, the actual 0.9 version has a slightly different definition +-// and instead of gst_element_query_duration it has two parameters to +-// gst_element_query_position instead +-# define wxGst_element_query_duration(e, f, p) \ +- gst_element_query_position(e, f, 0, p) +-# define wxGst_element_query_position(e, f, p) \ +- gst_element_query_position(e, f, p, 0) +-#else +-# define wxGst_element_query_duration \ +- gst_element_query_duration +-# define wxGst_element_query_position \ +- gst_element_query_position +-#endif +- +-// Other 0.10 macros +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 +-# define GST_STATE_FAILURE GST_STATE_CHANGE_FAILURE +-# define GST_STATE_SUCCESS GST_STATE_CHANGE_SUCCESS +-# define GstElementState GstState +-# define gst_gconf_get_default_video_sink() \ +- gst_element_factory_make ("gconfvideosink", "video-sink"); +-# define gst_gconf_get_default_audio_sink() \ +- gst_element_factory_make ("gconfaudiosink", "audio-sink"); +-#endif +- + // Max wait time for element state waiting - GST_CLOCK_TIME_NONE for inf + #define wxGSTREAMER_TIMEOUT (100 * GST_MSECOND) // Max 100 milliseconds + +@@ -189,11 +144,11 @@ public: + bool CheckForErrors(); + bool DoLoad(const wxString& locstring); + wxMediaCtrl* GetControl() { return m_ctrl; } // for C Callbacks +- void HandleStateChange(GstElementState oldstate, GstElementState newstate); ++ void HandleStateChange(GstState oldstate, GstState newstate); + bool QueryVideoSizeFromElement(GstElement* element); + bool QueryVideoSizeFromPad(GstPad* caps); +- void SetupXOverlay(); +- bool SyncStateChange(GstElement* element, GstElementState state, ++ void SetupVideoOverlay(); ++ bool SyncStateChange(GstElement* element, GstState state, + gint64 llTimeout = wxGSTREAMER_TIMEOUT); + bool TryAudioSink(GstElement* audiosink); + bool TryVideoSink(GstElement* videosink); +@@ -203,7 +158,7 @@ public: + double m_dRate; // Current playback rate - + // see GetPlaybackRate for notes + wxLongLong m_llPausedPos; // Paused position - see Pause() +- GstXOverlay* m_xoverlay; // X Overlay that contains the GST video ++ GstVideoOverlay* m_videooverlay; // Video Overlay that contains the GST video + wxMutex m_asynclock; // See "discussion of internals" + class wxGStreamerMediaEventHandler* m_eventHandler; // see below + +@@ -284,7 +239,7 @@ expose_event(GtkWidget* widget, GdkEvent + { + // I've seen this recommended somewhere... + // TODO: Is this needed? Maybe it is just cruft... +- // gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay), ++ // gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay), + // GDK_WINDOW_XWINDOW( window ) ); + + // If we have actual video..... +@@ -294,7 +249,7 @@ expose_event(GtkWidget* widget, GdkEvent + // GST Doesn't redraw automatically while paused + // Plus, the video sometimes doesn't redraw when it looses focus + // or is painted over so we just tell it to redraw... +- gst_x_overlay_expose(be->m_xoverlay); ++ gst_video_overlay_expose(be->m_videooverlay); + } + else + { +@@ -334,7 +289,7 @@ static gint gtk_window_realize_callback( + GdkWindow* window = gtk_widget_get_window(widget); + wxASSERT(window); + +- gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay), ++ gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay), + GDK_WINDOW_XID(window) + ); + GtkWidget* w = be->GetControl()->m_wxwindow; +@@ -349,30 +304,6 @@ static gint gtk_window_realize_callback( + #endif // wxGTK + + //----------------------------------------------------------------------------- +-// "state-change" from m_playbin/GST_MESSAGE_STATE_CHANGE +-// +-// Called by gstreamer when the state changes - here we +-// send the appropriate corresponding wx event. +-// +-// 0.8 only as HandleStateChange does this in both versions +-//----------------------------------------------------------------------------- +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10 +-extern "C" { +-static void gst_state_change_callback(GstElement *play, +- GstElementState oldstate, +- GstElementState newstate, +- wxGStreamerMediaBackend* be) +-{ +- if(be->m_asynclock.TryLock() == wxMUTEX_NO_ERROR) +- { +- be->HandleStateChange(oldstate, newstate); +- be->m_asynclock.Unlock(); +- } +-} +-} +-#endif // <0.10 +- +-//----------------------------------------------------------------------------- + // "eos" from m_playbin/GST_MESSAGE_EOS + // + // Called by gstreamer when the media is done playing ("end of stream") +@@ -425,69 +356,17 @@ static void gst_notify_caps_callback(Gst + } + + //----------------------------------------------------------------------------- +-// "notify::stream-info" from m_playbin +-// +-// Run through the stuff in "stream-info" of m_playbin for a valid +-// video pad, and then attempt to query the video size from it - if not +-// set up an event to do so when ready. +-// +-// Currently unused - now we just query it directly using +-// QueryVideoSizeFromElement. +-// +-// (Undocumented?) +-//----------------------------------------------------------------------------- +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 +-extern "C" { +-static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element), +- GParamSpec* WXUNUSED(pspec), +- wxGStreamerMediaBackend* be) +-{ +- wxLogTrace(wxTRACE_GStreamer, wxT("gst_notify_stream_info_callback")); +- be->QueryVideoSizeFromElement(be->m_playbin); +-} +-} +-#endif +- +-//----------------------------------------------------------------------------- +-// "desired-size-changed" from m_xoverlay +-// +-// 0.8-specific this provides us with the video size when it changes - +-// even though we get the caps as well this seems to come before the +-// caps notification does... +-// +-// Note it will return 16,16 for an early-bird value or for audio +-//----------------------------------------------------------------------------- +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10 +-extern "C" { +-static void gst_desired_size_changed_callback(GstElement * play, +- guint width, guint height, +- wxGStreamerMediaBackend* be) +-{ +- if(!(width == 16 && height == 16)) +- { +- be->m_videoSize.x = width; +- be->m_videoSize.y = height; +- } +- else +- be->QueryVideoSizeFromElement(be->m_playbin); +-} +-} +-#endif +- +-//----------------------------------------------------------------------------- + // gst_bus_async_callback [static] + // gst_bus_sync_callback [static] + // +-// Called by m_playbin for notifications such as end-of-stream in 0.10 - +-// in previous versions g_signal notifications were used. Because everything ++// Called by m_playbin for notifications such as end-of-stream. Because everything + // in centered in one switch statement though it reminds one of old WinAPI + // stuff. + // + // gst_bus_sync_callback is that sync version that is called on the main GUI + // thread before the async version that we use to set the xwindow id of the +-// XOverlay (NB: This isn't currently used - see CreateControl()). ++// VideoOverlay (NB: This isn't currently used - see CreateControl()). + //----------------------------------------------------------------------------- +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 + extern "C" { + static gboolean gst_bus_async_callback(GstBus* WXUNUSED(bus), + GstMessage* message, +@@ -537,8 +416,7 @@ static GstBusSyncReply gst_bus_sync_call + { + // Pass a non-xwindowid-setting event on to the async handler where it + // belongs +- if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT || +- !gst_structure_has_name (message->structure, "prepare-xwindow-id")) ++ if (!gst_is_video_overlay_prepare_window_handle_message (message)) + { + // + // NB: Unfortunately, the async callback can be quite +@@ -552,12 +430,11 @@ static GstBusSyncReply gst_bus_sync_call + return GST_BUS_DROP; + } + +- wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-xwindow-id")); +- be->SetupXOverlay(); ++ wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-window-handle")); ++ be->SetupVideoOverlay(); + return GST_BUS_DROP; // We handled this message - drop from the queue + } + } +-#endif + + //----------------------------------------------------------------------------- + // +@@ -569,11 +446,11 @@ static GstBusSyncReply gst_bus_sync_call + // wxGStreamerMediaBackend::HandleStateChange + // + // Handles a state change event from our C Callback for "state-change" or +-// the async queue in 0.10. (Mostly this is here to avoid locking the ++// the async queue . (Mostly this is here to avoid locking the + // the mutex twice...) + //----------------------------------------------------------------------------- +-void wxGStreamerMediaBackend::HandleStateChange(GstElementState oldstate, +- GstElementState newstate) ++void wxGStreamerMediaBackend::HandleStateChange(GstState oldstate, ++ GstState newstate) + { + switch(newstate) + { +@@ -604,83 +481,13 @@ void wxGStreamerMediaBackend::HandleStat + } + + //----------------------------------------------------------------------------- +-// wxGStreamerMediaBackend::QueryVideoSizeFromElement +-// +-// Run through the stuff in "stream-info" of element for a valid +-// video pad, and then attempt to query the video size from it - if not +-// set up an event to do so when ready. Return true +-// if we got a valid video pad. +-//----------------------------------------------------------------------------- +-bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element) +-{ +- const GList *list = NULL; +- g_object_get (G_OBJECT (element), "stream-info", &list, NULL); +- +- for ( ; list != NULL; list = list->next) +- { +- GObject *info = (GObject *) list->data; +- gint type; +- GParamSpec *pspec; +- GEnumValue *val; +- GstPad *pad = NULL; +- +- g_object_get (info, "type", &type, NULL); +- pspec = g_object_class_find_property ( +- G_OBJECT_GET_CLASS (info), "type"); +- val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type); +- +- if (!strncasecmp(val->value_name, "video", 5) || +- !strncmp(val->value_name, "GST_STREAM_TYPE_VIDEO", 21)) +- { +- // Newer gstreamer 0.8+ plugins are SUPPOSED to have "object"... +- // but a lot of old plugins still use "pad" :) +- pspec = g_object_class_find_property ( +- G_OBJECT_GET_CLASS (info), "object"); +- +- if (!pspec) +- g_object_get (info, "pad", &pad, NULL); +- else +- g_object_get (info, "object", &pad, NULL); +- +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8 +- // Killed in 0.9, presumely because events and such +- // should be pushed on pads regardless of whether they +- // are currently linked +- pad = (GstPad *) GST_PAD_REALIZE (pad); +- wxASSERT(pad); +-#endif +- +- if(!QueryVideoSizeFromPad(pad)) +- { +- // wait for those caps to get ready +- g_signal_connect( +- pad, +- "notify::caps", +- G_CALLBACK(gst_notify_caps_callback), +- this); +- } +- break; +- }// end if video +- }// end searching through info list +- +- // no video (or extremely delayed stream-info) +- if(list == NULL) +- { +- m_videoSize = wxSize(0,0); +- return false; +- } +- +- return true; +-} +- +-//----------------------------------------------------------------------------- + // wxGStreamerMediaBackend::QueryVideoSizeFromPad + // + // Gets the size of our video (in wxSize) from a GstPad + //----------------------------------------------------------------------------- + bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad) + { +- const GstCaps* caps = GST_PAD_CAPS(pad); ++ GstCaps* caps = gst_pad_get_current_caps(pad); + if ( caps ) + { + const GstStructure *s = gst_caps_get_structure (caps, 0); +@@ -706,23 +513,26 @@ bool wxGStreamerMediaBackend::QueryVideo + m_videoSize.y = (int) ((float) den * m_videoSize.y / num); + } + +- wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"), +- m_videoSize.x, m_videoSize.y); ++ wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"), ++ m_videoSize.x, m_videoSize.y); ++ ++ gst_caps_unref (caps); + return true; + } // end if caps + ++ m_videoSize = wxSize(0,0); + return false; // not ready/massive failure + } + + //----------------------------------------------------------------------------- +-// wxGStreamerMediaBackend::SetupXOverlay ++// wxGStreamerMediaBackend::SetupVideoOverlay + // +-// Attempts to set the XWindow id of our GstXOverlay to tell it which ++// Attempts to set the XWindow id of our GstVideoOverlay to tell it which + // window to play video in. + //----------------------------------------------------------------------------- +-void wxGStreamerMediaBackend::SetupXOverlay() ++void wxGStreamerMediaBackend::SetupVideoOverlay() + { +- // Use the xoverlay extension to tell gstreamer to play in our window ++ // Use the videooverlay extension to tell gstreamer to play in our window + #ifdef __WXGTK__ + if (!gtk_widget_get_realized(m_ctrl->m_wxwindow)) + { +@@ -739,7 +549,7 @@ void wxGStreamerMediaBackend::SetupXOver + GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow); + wxASSERT(window); + #endif +- gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_xoverlay), ++ gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videooverlay), + #ifdef __WXGTK__ + GDK_WINDOW_XID(window) + #else +@@ -769,9 +579,8 @@ void wxGStreamerMediaBackend::SetupXOver + // + // PRECONDITION: Assumes m_asynclock is Lock()ed + //----------------------------------------------------------------------------- +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 + bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element, +- GstElementState desiredstate, ++ GstState desiredstate, + gint64 llTimeout) + { + GstBus* bus = gst_element_get_bus(element); +@@ -844,23 +653,6 @@ bool wxGStreamerMediaBackend::SyncStateC + + 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; +-} +-#endif + + //----------------------------------------------------------------------------- + // wxGStreamerMediaBackend::TryAudioSink +@@ -884,25 +676,25 @@ bool wxGStreamerMediaBackend::TryAudioSi + + bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink) + { +- // Check if the video sink either is an xoverlay or might contain one... +- if( !GST_IS_BIN(videosink) && !GST_IS_X_OVERLAY(videosink) ) ++ // Check if the video sink either is an videooverlay or might contain one... ++ if( !GST_IS_BIN(videosink) && !GST_IS_VIDEO_OVERLAY(videosink) ) + { + if(G_IS_OBJECT(videosink)) + g_object_unref(videosink); + return false; + } + +- // Make our video sink and make sure it supports the x overlay interface +- // the x overlay enables us to put the video in our control window ++ // Make our video sink and make sure it supports the video overlay interface ++ // the video overlay enables us to put the video in our control window + // (i.e. we NEED it!) - also connect to the natural video size change event + if( GST_IS_BIN(videosink) ) +- m_xoverlay = (GstXOverlay*) ++ m_videooverlay = (GstVideoOverlay*) + gst_bin_get_by_interface (GST_BIN (videosink), +- GST_TYPE_X_OVERLAY); ++ GST_TYPE_VIDEO_OVERLAY); + else +- m_xoverlay = (GstXOverlay*) videosink; ++ m_videooverlay = (GstVideoOverlay*) videosink; + +- if ( !GST_IS_X_OVERLAY(m_xoverlay) ) ++ if ( !GST_IS_VIDEO_OVERLAY(m_videooverlay) ) + { + g_object_unref(videosink); + return false; +@@ -1046,11 +838,7 @@ bool wxGStreamerMediaBackend::CreateCont + //Really init gstreamer + gboolean bInited; + GError* error = NULL; +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 + bInited = gst_init_check(&argcGST, &argvGST, &error); +-#else +- bInited = gst_init_check(&argcGST, &argvGST); +-#endif + + // Cleanup arguments for unicode case + #if wxUSE_UNICODE +@@ -1117,78 +905,52 @@ bool wxGStreamerMediaBackend::CreateCont + return false; + } + +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10 +- // Connect the glib events/callbacks we want to our playbin +- g_signal_connect(m_playbin, "eos", +- G_CALLBACK(gst_finish_callback), this); +- g_signal_connect(m_playbin, "error", +- G_CALLBACK(gst_error_callback), this); +- g_signal_connect(m_playbin, "state-change", +- G_CALLBACK(gst_state_change_callback), this); +-#else +- // GStreamer 0.10+ uses GstBus for this now, connect to the sync +- // handler as well so we can set the X window id of our xoverlay ++ // GStreamer uses GstBus for this now, connect to the sync ++ // handler as well so we can set the video window id of our videooverlay + gst_bus_add_watch (gst_element_get_bus(m_playbin), + (GstBusFunc) gst_bus_async_callback, this); + gst_bus_set_sync_handler(gst_element_get_bus(m_playbin), +- (GstBusSyncHandler) gst_bus_sync_callback, this); +- g_signal_connect(m_playbin, "notify::stream-info", +- G_CALLBACK(gst_notify_stream_info_callback), this); +-#endif ++ (GstBusSyncHandler) gst_bus_sync_callback, this, NULL); + + // Get the audio sink +- GstElement* audiosink = gst_gconf_get_default_audio_sink(); ++ // Use autodetection, then alsa, then oss as a stopgap ++ GstElement* audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink"); + if( !TryAudioSink(audiosink) ) + { +- // fallback to autodetection, then alsa, then oss as a stopgap +- audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink"); ++ audiosink = gst_element_factory_make ("alsasink", "alsa-output"); + if( !TryAudioSink(audiosink) ) + { +- audiosink = gst_element_factory_make ("alsasink", "alsa-output"); ++ audiosink = gst_element_factory_make ("osssink", "play_audio"); + if( !TryAudioSink(audiosink) ) + { +- audiosink = gst_element_factory_make ("osssink", "play_audio"); +- if( !TryAudioSink(audiosink) ) +- { +- wxLogSysError(wxT("Could not find a valid audiosink")); +- return false; +- } ++ wxLogSysError(wxT("Could not find a valid audiosink")); ++ return false; + } + } + } + + // Setup video sink - first try gconf, then auto, then xvimage and + // then finally plain ximage +- GstElement* videosink = gst_gconf_get_default_video_sink(); ++ GstElement* videosink = gst_element_factory_make ("autovideosink", "video-sink"); + if( !TryVideoSink(videosink) ) + { +- videosink = gst_element_factory_make ("autovideosink", "video-sink"); ++ videosink = gst_element_factory_make ("xvimagesink", "video-sink"); + if( !TryVideoSink(videosink) ) + { +- videosink = gst_element_factory_make ("xvimagesink", "video-sink"); ++ // finally, do a final fallback to ximagesink ++ videosink = ++ gst_element_factory_make ("ximagesink", "video-sink"); + if( !TryVideoSink(videosink) ) + { +- // finally, do a final fallback to ximagesink +- videosink = +- gst_element_factory_make ("ximagesink", "video-sink"); +- if( !TryVideoSink(videosink) ) +- { +- g_object_unref(audiosink); +- wxLogSysError(wxT("Could not find a suitable video sink")); +- return false; +- } ++ g_object_unref(audiosink); ++ wxLogSysError(wxT("Could not find a suitable video sink")); ++ return false; + } + } + } + +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10 +- // Not on 0.10... called when video size changes +- g_signal_connect(m_xoverlay, "desired-size-changed", +- G_CALLBACK(gst_desired_size_changed_callback), this); +-#endif +- // Tell GStreamer which window to draw to in 0.8 - 0.10 +- // sometimes needs this too... +- SetupXOverlay(); ++ // Tell GStreamer which window to draw to ++ SetupVideoOverlay(); + + // Now that we know (or, rather think) our video and audio sink + // are valid set our playbin to use them +@@ -1197,6 +959,10 @@ bool wxGStreamerMediaBackend::CreateCont + "audio-sink", audiosink, + NULL); + ++ GstPad *video_sinkpad = gst_element_get_static_pad (videosink, "sink"); ++ g_signal_connect (video_sinkpad, "notify::caps", G_CALLBACK (gst_notify_caps_callback), this); ++ gst_object_unref (video_sinkpad); ++ + m_eventHandler = new wxGStreamerMediaEventHandler(this); + return true; + } +@@ -1213,26 +979,10 @@ bool wxGStreamerMediaBackend::Load(const + + //----------------------------------------------------------------------------- + // wxGStreamerMediaBackend::Load (URI version) +-// +-// In the case of a file URI passes it unencoded - +-// also, as of 0.10.3 and earlier GstURI (the uri parser for gstreamer) +-// is sort of broken and only accepts uris with at least two slashes +-// after the scheme (i.e. file: == not ok, file:// == ok) + //----------------------------------------------------------------------------- + bool wxGStreamerMediaBackend::Load(const wxURI& location) + { +- if(location.GetScheme().CmpNoCase(wxT("file")) == 0) +- { +- wxString uristring = location.BuildUnescapedURI(); +- +- //Workaround GstURI leading "//" problem and make sure it leads +- //with that +- return DoLoad(wxString(wxT("file://")) + +- uristring.Right(uristring.length() - 5) +- ); +- } +- else +- return DoLoad(location.BuildURI()); ++ return DoLoad(location.BuildURI()); + } + + //----------------------------------------------------------------------------- +@@ -1258,7 +1008,7 @@ bool wxGStreamerMediaBackend::DoLoad(con + + // Set playbin to ready to stop the current media... + if( gst_element_set_state (m_playbin, +- GST_STATE_READY) == GST_STATE_FAILURE || ++ GST_STATE_READY) == GST_STATE_CHANGE_FAILURE || + !SyncStateChange(m_playbin, GST_STATE_READY)) + { + CheckForErrors(); +@@ -1281,7 +1031,7 @@ bool wxGStreamerMediaBackend::DoLoad(con + // Try to pause media as gstreamer won't let us query attributes + // such as video size unless it is paused or playing + if( gst_element_set_state (m_playbin, +- GST_STATE_PAUSED) == GST_STATE_FAILURE || ++ GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE || + !SyncStateChange(m_playbin, GST_STATE_PAUSED)) + { + CheckForErrors(); +@@ -1307,12 +1057,11 @@ bool wxGStreamerMediaBackend::DoLoad(con + // + // Sets the stream to a playing state + // +-// THREAD-UNSAFE in 0.8, maybe in 0.10 as well + //----------------------------------------------------------------------------- + bool wxGStreamerMediaBackend::Play() + { + if (gst_element_set_state (m_playbin, +- GST_STATE_PLAYING) == GST_STATE_FAILURE) ++ GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) + { + CheckForErrors(); + return false; +@@ -1326,13 +1075,12 @@ bool wxGStreamerMediaBackend::Play() + // + // Marks where we paused and pauses the stream + // +-// THREAD-UNSAFE in 0.8, maybe in 0.10 as well + //----------------------------------------------------------------------------- + bool wxGStreamerMediaBackend::Pause() + { + m_llPausedPos = wxGStreamerMediaBackend::GetPosition(); + if (gst_element_set_state (m_playbin, +- GST_STATE_PAUSED) == GST_STATE_FAILURE) ++ GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) + { + CheckForErrors(); + return false; +@@ -1353,7 +1101,7 @@ bool wxGStreamerMediaBackend::Stop() + { // begin state lock + wxMutexLocker lock(m_asynclock); + if(gst_element_set_state (m_playbin, +- GST_STATE_PAUSED) == GST_STATE_FAILURE || ++ GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE || + !SyncStateChange(m_playbin, GST_STATE_PAUSED)) + { + CheckForErrors(); +@@ -1417,10 +1165,8 @@ wxLongLong wxGStreamerMediaBackend::GetP + else + { + gint64 pos; +- GstFormat fmtTime = GST_FORMAT_TIME; + +- if (!wxGst_element_query_position(m_playbin, &fmtTime, &pos) || +- fmtTime != GST_FORMAT_TIME || pos == -1) ++ if (!gst_element_query_position(m_playbin, GST_FORMAT_TIME, &pos) || pos == -1) + return 0; + return pos / GST_MSECOND ; + } +@@ -1438,44 +1184,21 @@ wxLongLong wxGStreamerMediaBackend::GetP + // This is also an exceedingly ugly function due to the three implementations + // (or, rather two plus one implementation without a seek function). + // +-// This is asynchronous and thread-safe on both 0.8 and 0.10. +-// + // NB: This fires both a stop and play event if the media was previously + // playing... which in some ways makes sense. And yes, this makes the video + // go all haywire at times - a gstreamer bug... + //----------------------------------------------------------------------------- + bool wxGStreamerMediaBackend::SetPosition(wxLongLong where) + { +-#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 8 \ +- && GST_VERSION_MICRO == 0 +- // 0.8.0 has no gst_element_seek according to official docs!!! +- wxLogSysError(wxT("GStreamer 0.8.0 does not have gst_element_seek") +- wxT(" according to official docs")); +- return false; +-#else // != 0.8.0 +- +-# if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 +- gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME, ++ if ( gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME, + (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, where.GetValue() * GST_MSECOND, +- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE ); +-# else +- // NB: Some gstreamer versions return false basically all the time +- // here - even totem doesn't bother to check the return value here +- // so I guess we'll just assume it worked - +- // TODO: maybe check the gst error callback??? +- gst_element_seek (m_playbin, (GstSeekType) (GST_SEEK_METHOD_SET | +- GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH), +- where.GetValue() * GST_MSECOND ); +- +-# endif // GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 +- ++ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE ) ) + { + m_llPausedPos = where; + return true; + } +- return true; +-#endif //== 0.8.0 ++ return false; + } + + //----------------------------------------------------------------------------- +@@ -1487,10 +1210,8 @@ bool wxGStreamerMediaBackend::SetPositio + wxLongLong wxGStreamerMediaBackend::GetDuration() + { + gint64 length; +- GstFormat fmtTime = GST_FORMAT_TIME; + +- if(!wxGst_element_query_duration(m_playbin, &fmtTime, &length) || +- fmtTime != GST_FORMAT_TIME || length == -1) ++ if(!gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &length) || length == -1) + return 0; + return length / GST_MSECOND ; + } +@@ -1512,7 +1233,7 @@ void wxGStreamerMediaBackend::Move(int W + // wxGStreamerMediaBackend::GetVideoSize + // + // Returns our cached video size from Load/gst_notify_caps_callback +-// gst_x_overlay_get_desired_size also does this in 0.8... ++// gst_video_overlay_get_desired_size also does this in 0.8... + //----------------------------------------------------------------------------- + wxSize wxGStreamerMediaBackend::GetVideoSize() const + { +@@ -1539,9 +1260,8 @@ wxSize wxGStreamerMediaBackend::GetVideo + //TODO: forcing frame/samplerates, see audioscale and videorate. Audioscale is + //TODO: part of playbin. + // +-// In 0.10 GStreamer has new gst_element_seek API that might +-// support this - and I've got an attempt to do so but it is untested +-// but it would appear to work... ++// In has new gst_element_seek API that supports this - and I've got an attempt ++// to do so but it is untested but it would appear to work... + //----------------------------------------------------------------------------- + double wxGStreamerMediaBackend::GetPlaybackRate() + { +@@ -1552,7 +1272,6 @@ double wxGStreamerMediaBackend::GetPlayb + + bool wxGStreamerMediaBackend::SetPlaybackRate(double dRate) + { +-#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10 + #if 0 // not tested enough + if( gst_element_seek (m_playbin, dRate, GST_FORMAT_TIME, + (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), +@@ -1565,7 +1284,6 @@ bool wxGStreamerMediaBackend::SetPlaybac + #else + wxUnusedVar(dRate); + #endif +-#endif + + // failure + return false; +@@ -1593,10 +1311,8 @@ wxLongLong wxGStreamerMediaBackend::GetD + wxLongLong wxGStreamerMediaBackend::GetDownloadTotal() + { + gint64 length; +- GstFormat fmtBytes = GST_FORMAT_BYTES; + +- if (!wxGst_element_query_duration(m_playbin, &fmtBytes, &length) || +- fmtBytes != GST_FORMAT_BYTES || length == -1) ++ if (!gst_element_query_duration(m_playbin, GST_FORMAT_BYTES, &length) || length == -1) + return 0; + return length; + } diff --git a/wxGTK3.spec b/wxGTK3.spec index d468515..03eae08 100644 --- a/wxGTK3.spec +++ b/wxGTK3.spec @@ -20,7 +20,7 @@ Name: %{wxgtkname} Version: 3.0.3 -Release: 0.2%{?usesnapshot:.git%{shortcommit0}}%{?dist} +Release: 0.3%{?usesnapshot:.git%{shortcommit0}}%{?dist} Summary: GTK port of the wxWidgets GUI library License: wxWidgets Group: System Environment/Libraries @@ -39,6 +39,8 @@ Source10: wx-config # remove abort when ABI check fails # Backport from wxGTK Patch0: %{name}-%{version}-abicheck.patch +# Switch to use GStreamer 1.0 - patch is from Debian +Patch1: %{name}-%{version}-gst1.0.patch BuildRequires: gtk%{gtkver}-devel #Note webkitgtk (GTK2) does not appear to be supported @@ -53,7 +55,7 @@ BuildRequires: expat-devel BuildRequires: SDL-devel BuildRequires: libGLU-devel BuildRequires: libSM-devel -BuildRequires: gstreamer-plugins-base-devel +BuildRequires: gstreamer1-plugins-base-devel BuildRequires: GConf2-devel BuildRequires: gettext BuildRequires: cppunit-devel @@ -355,6 +357,9 @@ fi %doc docs/doxygen/out/xml/* %changelog +* Fri Dec 30 2016 Scott Talbert - 3.0.3-0.3.gitf90b768 +- Switch to use GStreamer 1.0 (#1402628) + * Wed Dec 28 2016 Jeremy Newton - 3.0.3-0.2.gitf90b768 - Update to newer git snapshot