Add support for GStreamer 1.x in Unix wxMediaCtrl implementation

Do it while keeping both 0.8 and 0.10 support, unlike the commit d0ef5d7,
which this is based on, that removed support for 0.8.

Closes https://github.com/wxWidgets/wxWidgets/pull/400
This commit is contained in:
Scott Talbert
2017-01-22 15:56:50 -05:00
committed by Vadim Zeitlin
parent c047751abf
commit 501b377435
3 changed files with 239 additions and 33 deletions

114
configure vendored
View File

@@ -37321,8 +37321,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
if test "$wxUSE_GSTREAMER8" = "no"; then
@@ -37331,6 +37331,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"
@@ -37386,16 +37473,14 @@ fi
echo "$GST_PKG_ERRORS" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&5
$as_echo "$as_me: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&2;}
GST_VERSION_MINOR=8
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&5
$as_echo "$as_me: WARNING: GStreamer 0.10 not available, falling back to 0.8" >&2;}
GST_VERSION_MINOR=8
else
@@ -37404,12 +37489,15 @@ 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
else
GST_VERSION_MINOR=8
GST_VERSION_MAJOR=0
GST_VERSION_MINOR=8
fi
if test $GST_VERSION_MINOR = "8"; then
@@ -37474,13 +37562,13 @@ fi
echo "$GST_PKG_ERRORS" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.8/0.10 not available." >&5
$as_echo "$as_me: WARNING: GStreamer 0.8/0.10 not available." >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.8/0.10/1.0 not available." >&5
$as_echo "$as_me: WARNING: GStreamer 0.8/0.10/1.0 not available." >&2;}
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.8/0.10 not available." >&5
$as_echo "$as_me: WARNING: GStreamer 0.8/0.10 not available." >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GStreamer 0.8/0.10/1.0 not available." >&5
$as_echo "$as_me: WARNING: GStreamer 0.8/0.10/1.0 not available." >&2;}
else
GST_CFLAGS=$pkg_cv_GST_CFLAGS

View File

@@ -7548,27 +7548,43 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$wxUSE_MEDIACTRL" = "auto"; then
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 So, we first check to see if 1.0 if available - if not we
dnl try the older 0.10 and 0.8 versions
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],
[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, falling back to 0.8])
GST_VERSION_MINOR=8
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, falling back to 0.8])
]
)
fi
else
dnl check only for 0.8
GST_VERSION_MAJOR=0
GST_VERSION_MINOR=8
fi
@@ -7578,7 +7594,7 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$wxUSE_MEDIACTRL" = "auto"; then
[gstreamer-$GST_VERSION gstreamer-interfaces-$GST_VERSION gstreamer-gconf-$GST_VERSION],
wxUSE_GSTREAMER="yes",
[
AC_MSG_WARN([GStreamer 0.8/0.10 not available.])
AC_MSG_WARN([GStreamer 0.8/0.10/1.0 not available.])
])
fi

View File

@@ -20,7 +20,9 @@
#include <gst/gst.h> // main gstreamer header
// xoverlay/video stuff, gst-gconf for 0.8
#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
#if GST_VERSION_MAJOR > 0
# include <gst/video/video.h>
#elif GST_VERSION_MINOR >= 10
# include <gst/interfaces/xoverlay.h>
#else
# include <gst/xoverlay/xoverlay.h>
@@ -48,8 +50,8 @@
//-----------------------------------------------------------------------------
/*
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 0.8, 0.10, or
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
@@ -203,7 +205,11 @@ public:
double m_dRate; // Current playback rate -
// see GetPlaybackRate for notes
wxLongLong m_llPausedPos; // Paused position - see Pause()
#if GST_VERSION_MAJOR > 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
@@ -294,7 +300,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_VERSION_MAJOR > 0
gst_video_overlay_expose(be->m_xoverlay);
#else
gst_x_overlay_expose(be->m_xoverlay);
#endif
}
else
{
@@ -334,9 +344,15 @@ static gint gtk_window_realize_callback(GtkWidget* widget,
GdkWindow* window = gtk_widget_get_window(widget);
wxASSERT(window);
#if GST_VERSION_MAJOR > 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);
@@ -436,7 +452,7 @@ static void gst_notify_caps_callback(GstPad* pad,
//
// (Undocumented?)
//-----------------------------------------------------------------------------
#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR >= 10
extern "C" {
static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element),
GParamSpec* WXUNUSED(pspec),
@@ -537,8 +553,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_VERSION_MAJOR > 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
@@ -603,6 +623,7 @@ void wxGStreamerMediaBackend::HandleStateChange(GstElementState oldstate,
}
}
#if GST_VERSION_MAJOR == 0
//-----------------------------------------------------------------------------
// wxGStreamerMediaBackend::QueryVideoSizeFromElement
//
@@ -672,6 +693,7 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element)
return true;
}
#endif
//-----------------------------------------------------------------------------
// wxGStreamerMediaBackend::QueryVideoSizeFromPad
@@ -680,7 +702,11 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element)
//-----------------------------------------------------------------------------
bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad)
{
#if GST_VERSION_MAJOR > 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);
@@ -706,11 +732,15 @@ 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_VERSION_MAJOR > 0
gst_caps_unref (caps);
#endif
return true;
} // end if caps
m_videoSize = wxSize(0,0);
return false; // not ready/massive failure
}
@@ -739,7 +769,11 @@ void wxGStreamerMediaBackend::SetupXOverlay()
GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow);
wxASSERT(window);
#endif
#if GST_VERSION_MAJOR > 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
@@ -884,6 +918,31 @@ bool wxGStreamerMediaBackend::TryAudioSink(GstElement* audiosink)
bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink)
{
#if GST_VERSION_MAJOR > 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) )
{
@@ -907,7 +966,7 @@ bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink)
g_object_unref(videosink);
return false;
}
#endif
return true;
}
@@ -1130,16 +1189,22 @@ 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);
#endif
#if GST_VERSION_MAJOR > 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_gconf_get_default_audio_sink();
GstElement* audiosink;
#if GST_VERSION_MAJOR == 0
audiosink = gst_gconf_get_default_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) )
@@ -1155,13 +1220,18 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
}
}
}
#if GST_VERSION_MAJOR == 0
}
#endif
// 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;
#if GST_VERSION_MAJOR == 0
videosink = gst_gconf_get_default_video_sink();
if( !TryVideoSink(videosink) )
{
#endif
videosink = gst_element_factory_make ("autovideosink", "video-sink");
if( !TryVideoSink(videosink) )
{
@@ -1179,13 +1249,25 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
}
}
}
#if GST_VERSION_MAJOR == 0
}
#endif
#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
#if GST_VERSION_MAJOR > 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...
SetupXOverlay();
@@ -1221,6 +1303,7 @@ bool wxGStreamerMediaBackend::Load(const wxString& fileName)
//-----------------------------------------------------------------------------
bool wxGStreamerMediaBackend::Load(const wxURI& location)
{
#if GST_VERSION_MAJOR == 0
if(location.GetScheme().CmpNoCase(wxT("file")) == 0)
{
wxString uristring = location.BuildUnescapedURI();
@@ -1232,6 +1315,7 @@ bool wxGStreamerMediaBackend::Load(const wxURI& location)
);
}
else
#endif
return DoLoad(location.BuildURI());
}
@@ -1417,11 +1501,17 @@ wxLongLong wxGStreamerMediaBackend::GetPosition()
else
{
gint64 pos;
#if GST_VERSION_MAJOR > 0
if (!gst_element_query_position(m_playbin, GST_FORMAT_TIME, &pos) ||
pos == -1)
return 0;
#else
GstFormat fmtTime = GST_FORMAT_TIME;
if (!wxGst_element_query_position(m_playbin, &fmtTime, &pos) ||
fmtTime != GST_FORMAT_TIME || pos == -1)
return 0;
#endif
return pos / GST_MSECOND ;
}
}
@@ -1487,11 +1577,17 @@ bool wxGStreamerMediaBackend::SetPosition(wxLongLong where)
wxLongLong wxGStreamerMediaBackend::GetDuration()
{
gint64 length;
#if GST_VERSION_MAJOR > 0
if(!gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &length) ||
length == -1)
return 0;
#else
GstFormat fmtTime = GST_FORMAT_TIME;
if(!wxGst_element_query_duration(m_playbin, &fmtTime, &length) ||
fmtTime != GST_FORMAT_TIME || length == -1)
return 0;
#endif
return length / GST_MSECOND ;
}
@@ -1593,11 +1689,17 @@ wxLongLong wxGStreamerMediaBackend::GetDownloadProgress()
wxLongLong wxGStreamerMediaBackend::GetDownloadTotal()
{
gint64 length;
#if GST_VERSION_MAJOR > 0
if (!gst_element_query_duration(m_playbin, GST_FORMAT_BYTES, &length) ||
length == -1)
return 0;
#else
GstFormat fmtBytes = GST_FORMAT_BYTES;
if (!wxGst_element_query_duration(m_playbin, &fmtBytes, &length) ||
fmtBytes != GST_FORMAT_BYTES || length == -1)
return 0;
#endif
return length;
}