diff --git a/configure b/configure index 217955794b..df2749f8ac 100755 --- a/configure +++ b/configure @@ -35698,8 +35698,8 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$wxUSE_MEDIACTRL" = "auto"; then if test "$wxUSE_GTK" = 1; then wxUSE_GSTREAMER="no" - GST_VERSION_MAJOR=0 - GST_VERSION_MINOR=10 + GST_VERSION_MAJOR=1 + GST_VERSION_MINOR=0 GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR @@ -35707,6 +35707,93 @@ pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GST" >&5 $as_echo_n "checking for GST... " >&6; } +if test -n "$PKG_CONFIG"; then + if test -n "$GST_CFLAGS"; then + pkg_cv_GST_CFLAGS="$GST_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-\$GST_VERSION gstreamer-video-\$GST_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GST_CFLAGS=`$PKG_CONFIG --cflags "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$GST_LIBS"; then + pkg_cv_GST_LIBS="$GST_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-\$GST_VERSION gstreamer-video-\$GST_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GST_LIBS=`$PKG_CONFIG --libs "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GST_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION"` + else + GST_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION"` + fi + # Put the nasty error message in config.log where it belongs + echo "$GST_PKG_ERRORS" >&5 + + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 1.0 not available, falling back to 0.10" >&5 +$as_echo "$as_me: WARNING: GStreamer 1.0 not available, falling back to 0.10" >&2;} + GST_VERSION_MAJOR=0 + GST_VERSION_MINOR=10 + GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR + + +elif test $pkg_failed = untried; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 1.0 not available, falling back to 0.10" >&5 +$as_echo "$as_me: WARNING: GStreamer 1.0 not available, falling back to 0.10" >&2;} + GST_VERSION_MAJOR=0 + GST_VERSION_MINOR=10 + GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR + + +else + GST_CFLAGS=$pkg_cv_GST_CFLAGS + GST_LIBS=$pkg_cv_GST_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + wxUSE_GSTREAMER="yes" + +fi + + if test $GST_VERSION_MINOR = "10"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GST" >&5 +$as_echo_n "checking for GST... " >&6; } + if test -n "$PKG_CONFIG"; then if test -n "$GST_CFLAGS"; then pkg_cv_GST_CFLAGS="$GST_CFLAGS" @@ -35762,13 +35849,13 @@ fi echo "$GST_PKG_ERRORS" >&5 - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available" >&5 $as_echo "$as_me: WARNING: GStreamer 0.10 not available" >&2;} elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available" >&5 $as_echo "$as_me: WARNING: GStreamer 0.10 not available" >&2;} @@ -35778,10 +35865,11 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - wxUSE_GSTREAMER="yes" - GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION" + wxUSE_GSTREAMER="yes" + GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION" fi + fi if test "$wxUSE_GSTREAMER" = "yes"; then CPPFLAGS="$GST_CFLAGS $CPPFLAGS" diff --git a/configure.in b/configure.in index 28ecf95d70..41244f8c41 100644 --- a/configure.in +++ b/configure.in @@ -7245,21 +7245,36 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$wxUSE_MEDIACTRL" = "auto"; then if test "$wxUSE_GTK" = 1; then wxUSE_GSTREAMER="no" - GST_VERSION_MAJOR=0 - GST_VERSION_MINOR=10 + GST_VERSION_MAJOR=1 + GST_VERSION_MINOR=0 GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR PKG_CHECK_MODULES(GST, - [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION], + [gstreamer-$GST_VERSION gstreamer-video-$GST_VERSION], [ wxUSE_GSTREAMER="yes" - GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION" ], [ - AC_MSG_WARN([GStreamer 0.10 not available]) + AC_MSG_WARN([GStreamer 1.0 not available, falling back to 0.10]) + GST_VERSION_MAJOR=0 + GST_VERSION_MINOR=10 + GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR ] ) + if test $GST_VERSION_MINOR = "10"; 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]) + ] + ) + fi + if test "$wxUSE_GSTREAMER" = "yes"; then CPPFLAGS="$GST_CFLAGS $CPPFLAGS" EXTRALIBS_MEDIA="$GST_LIBS" diff --git a/docs/changes.txt b/docs/changes.txt index 6a7d622b78..38f8fd5e49 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -63,6 +63,7 @@ All: - Add UTF-8 and ZIP 64 support to wxZip{Input,Output}Stream (Tobias Taschner). - Upgrade libpng to 1.6.21 fixing several security bugs (Paul Kulchenko). +- Support gstreamer 0.10 and 1.0 in wxMediaCtrl (Sebastian Dröge). - Fix handling of Unicode file names in wxFileSystem::FindFirst(). - Add wxStandardPaths::GetUserDir() (Tobias Taschner). - Allow calling wxItemContainer::Add() and similar with std::vector<> argument. diff --git a/src/unix/mediactrl.cpp b/src/unix/mediactrl.cpp index 9f8c60ecc8..81da7425b0 100644 --- a/src/unix/mediactrl.cpp +++ b/src/unix/mediactrl.cpp @@ -19,7 +19,11 @@ #include // main gstreamer header +#if GST_CHECK_VERSION(1,0,0) +#include +#else #include +#endif #ifndef WX_PRECOMP #include "wx/log.h" // wxLogDebug/wxLogSysError/wxLogTrace @@ -159,7 +163,11 @@ public: double m_dRate; // Current playback rate - // see GetPlaybackRate for notes wxLongLong m_llPausedPos; // Paused position - see Pause() +#if GST_CHECK_VERSION(1,0,0) + GstVideoOverlay* m_xoverlay; // X Overlay that contains the GST video +#else GstXOverlay* m_xoverlay; // X Overlay that contains the GST video +#endif wxMutex m_asynclock; // See "discussion of internals" class wxGStreamerMediaEventHandler* m_eventHandler; // see below @@ -250,7 +258,11 @@ expose_event(GtkWidget* widget, GdkEventExpose* event, wxGStreamerMediaBackend* // 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... +#if GST_CHECK_VERSION(1,0,0) + gst_video_overlay_expose(be->m_xoverlay); +#else gst_x_overlay_expose(be->m_xoverlay); +#endif } else { @@ -290,9 +302,15 @@ static gint gtk_window_realize_callback(GtkWidget* widget, GdkWindow* window = gtk_widget_get_window(widget); wxASSERT(window); +#if GST_CHECK_VERSION(1,0,0) + gst_video_overlay_set_window_handle(be->m_xoverlay, + GDK_WINDOW_XID(window) + ); +#else gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay), GDK_WINDOW_XID(window) ); +#endif GtkWidget* w = be->GetControl()->m_wxwindow; #ifdef __WXGTK3__ g_signal_connect(w, "draw", G_CALLBACK(draw), be); @@ -356,6 +374,7 @@ static void gst_notify_caps_callback(GstPad* pad, } } +#if !GST_CHECK_VERSION(1,0,0) //----------------------------------------------------------------------------- // "notify::stream-info" from m_playbin // @@ -377,6 +396,7 @@ static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element), be->QueryVideoSizeFromElement(be->m_playbin); } } +#endif //----------------------------------------------------------------------------- // gst_bus_async_callback [static] @@ -440,8 +460,12 @@ static GstBusSyncReply gst_bus_sync_callback(GstBus* bus, { // Pass a non-xwindowid-setting event on to the async handler where it // belongs +#if GST_CHECK_VERSION(1,0,0) + if (!gst_is_video_overlay_prepare_window_handle_message (message)) +#else if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT || !gst_structure_has_name (message->structure, "prepare-xwindow-id")) +#endif { // // NB: Unfortunately, the async callback can be quite @@ -505,6 +529,7 @@ void wxGStreamerMediaBackend::HandleStateChange(GstState oldstate, } } +#if !GST_CHECK_VERSION(1,0,0) //----------------------------------------------------------------------------- // wxGStreamerMediaBackend::QueryVideoSizeFromElement // @@ -566,6 +591,7 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element) return true; } +#endif //----------------------------------------------------------------------------- // wxGStreamerMediaBackend::QueryVideoSizeFromPad @@ -574,7 +600,11 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element) //----------------------------------------------------------------------------- bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad) { +#if GST_CHECK_VERSION(1,0,0) + GstCaps* caps = gst_pad_get_current_caps(pad); +#else const GstCaps* caps = GST_PAD_CAPS(pad); +#endif if ( caps ) { const GstStructure *s = gst_caps_get_structure (caps, 0); @@ -600,11 +630,21 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad) 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); +#if GST_CHECK_VERSION(1,0,0) + gst_caps_unref (caps); +#endif + + NotifyMovieSizeChanged (); + return true; } // end if caps + m_videoSize = wxSize(0,0); + + NotifyMovieSizeChanged (); + return false; // not ready/massive failure } @@ -633,7 +673,11 @@ void wxGStreamerMediaBackend::SetupXOverlay() GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow); wxASSERT(window); #endif +#if GST_CHECK_VERSION(1,0,0) + gst_video_overlay_set_window_handle(m_xoverlay, +#else gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_xoverlay), +#endif #ifdef __WXGTK__ GDK_WINDOW_XID(window) #else @@ -760,6 +804,31 @@ bool wxGStreamerMediaBackend::TryAudioSink(GstElement* audiosink) bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink) { +#if GST_CHECK_VERSION(1,0,0) + // Check if the video sink either is an xoverlay 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 + // (i.e. we NEED it!) - also connect to the natural video size change event + if( GST_IS_BIN(videosink) ) + m_xoverlay = (GstVideoOverlay*) + gst_bin_get_by_interface (GST_BIN (videosink), + GST_TYPE_VIDEO_OVERLAY); + else + m_xoverlay = (GstVideoOverlay*) videosink; + + if ( !GST_IS_VIDEO_OVERLAY(m_xoverlay) ) + { + g_object_unref(videosink); + return false; + } +#else // Check if the video sink either is an xoverlay or might contain one... if( !GST_IS_BIN(videosink) && !GST_IS_X_OVERLAY(videosink) ) { @@ -783,7 +852,7 @@ bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink) g_object_unref(videosink); return false; } - +#endif return true; } @@ -993,15 +1062,21 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, // handler as well so we can set the X window id of our xoverlay gst_bus_add_watch (gst_element_get_bus(m_playbin), (GstBusFunc) gst_bus_async_callback, this); +#if GST_CHECK_VERSION(1,0,0) + gst_bus_set_sync_handler(gst_element_get_bus(m_playbin), + (GstBusSyncHandler) gst_bus_sync_callback, this, NULL); +#else 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 // Get the audio sink - GstElement* audiosink = gst_element_factory_make ("gconfaudiosink", "audio-sink"); + GstElement* audiosink; +#if !GST_CHECK_VERSION(1,0,0) + audiosink = gst_element_factory_make ("gconfaudiosink", "audio-sink"); if( !TryAudioSink(audiosink) ) { +#endif // fallback to autodetection, then alsa, then oss as a stopgap audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink"); if( !TryAudioSink(audiosink) ) @@ -1017,13 +1092,18 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, } } } +#if !GST_CHECK_VERSION(1,0,0) } +#endif // Setup video sink - first try gconf, then auto, then xvimage and // then finally plain ximage - GstElement* videosink = gst_element_factory_make ("gconfvideosink", "video-sink"); + GstElement* videosink; +#if !GST_CHECK_VERSION(1,0,0) + videosink = gst_element_factory_make ("gconfvideosink", "video-sink"); if( !TryVideoSink(videosink) ) { +#endif videosink = gst_element_factory_make ("autovideosink", "video-sink"); if( !TryVideoSink(videosink) ) { @@ -1041,7 +1121,18 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, } } } +#if !GST_CHECK_VERSION(1,0,0) } +#endif + +#if GST_CHECK_VERSION(1,0,0) + 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); +#else + g_signal_connect(m_playbin, "notify::stream-info", + G_CALLBACK(gst_notify_stream_info_callback), this); +#endif // Tell GStreamer which window to draw to in 0.8 - 0.10 // sometimes needs this too... @@ -1078,6 +1169,7 @@ bool wxGStreamerMediaBackend::Load(const wxString& fileName) //----------------------------------------------------------------------------- bool wxGStreamerMediaBackend::Load(const wxURI& location) { +#if !GST_CHECK_VERSION(1,0,0) if(location.GetScheme().CmpNoCase(wxT("file")) == 0) { wxString uristring = location.BuildUnescapedURI(); @@ -1089,6 +1181,7 @@ bool wxGStreamerMediaBackend::Load(const wxURI& location) ); } else +#endif return DoLoad(location.BuildURI()); } @@ -1274,11 +1367,17 @@ wxLongLong wxGStreamerMediaBackend::GetPosition() else { gint64 pos; +#if GST_CHECK_VERSION(1,0,0) + if (!gst_element_query_position(m_playbin, GST_FORMAT_TIME, &pos) || + pos == -1) + return 0; +#else GstFormat fmtTime = GST_FORMAT_TIME; if (!gst_element_query_position(m_playbin, &fmtTime, &pos) || fmtTime != GST_FORMAT_TIME || pos == -1) return 0; +#endif return pos / GST_MSECOND ; } } @@ -1321,11 +1420,17 @@ bool wxGStreamerMediaBackend::SetPosition(wxLongLong where) wxLongLong wxGStreamerMediaBackend::GetDuration() { gint64 length; +#if GST_CHECK_VERSION(1,0,0) + if(!gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &length) || + length == -1) + return 0; +#else GstFormat fmtTime = GST_FORMAT_TIME; if(!gst_element_query_duration(m_playbin, &fmtTime, &length) || fmtTime != GST_FORMAT_TIME || length == -1) return 0; +#endif return length / GST_MSECOND ; } @@ -1423,11 +1528,17 @@ wxLongLong wxGStreamerMediaBackend::GetDownloadProgress() wxLongLong wxGStreamerMediaBackend::GetDownloadTotal() { gint64 length; +#if GST_CHECK_VERSION(1,0,0) + if (!gst_element_query_duration(m_playbin, GST_FORMAT_BYTES, &length) || + length == -1) + return 0; +#else GstFormat fmtBytes = GST_FORMAT_BYTES; if (!gst_element_query_duration(m_playbin, &fmtBytes, &length) || fmtBytes != GST_FORMAT_BYTES || length == -1) return 0; +#endif return length; }