Merge branch 'drop-gstreamer-0.8' of https://github.com/plaes/wxWidgets

Drop support for ancient gstreamer 0.8.
This commit is contained in:
Vadim Zeitlin
2016-02-01 04:48:48 +01:00
4 changed files with 43 additions and 354 deletions

View File

@@ -19,13 +19,7 @@
#include <gst/gst.h> // main gstreamer header
// xoverlay/video stuff, gst-gconf for 0.8
#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
# include <gst/interfaces/xoverlay.h>
#else
# include <gst/xoverlay/xoverlay.h>
# include <gst/gconf/gconf.h> // gstreamer glib configuration
#endif
#include <gst/interfaces/xoverlay.h>
#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 0.10.
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.
@@ -89,44 +83,6 @@
// Declarations
//=============================================================================
//-----------------------------------------------------------------------------
// GStreamer (most version compatibility) 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 +145,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,
bool SyncStateChange(GstElement* element, GstState state,
gint64 llTimeout = wxGSTREAMER_TIMEOUT);
bool TryAudioSink(GstElement* audiosink);
bool TryVideoSink(GstElement* videosink);
@@ -348,30 +304,6 @@ static gint gtk_window_realize_callback(GtkWidget* widget,
}
#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
//
@@ -436,7 +368,6 @@ static void gst_notify_caps_callback(GstPad* pad,
//
// (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),
@@ -446,33 +377,6 @@ static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element),
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]
@@ -487,7 +391,6 @@ static void gst_desired_size_changed_callback(GstElement * play,
// thread before the async version that we use to set the xwindow id of the
// XOverlay (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,
@@ -557,7 +460,6 @@ static GstBusSyncReply gst_bus_sync_callback(GstBus* bus,
return GST_BUS_DROP; // We handled this message - drop from the queue
}
}
#endif
//-----------------------------------------------------------------------------
//
@@ -572,8 +474,8 @@ static GstBusSyncReply gst_bus_sync_callback(GstBus* bus,
// the async queue in 0.10. (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)
{
@@ -642,14 +544,6 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element)
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
@@ -769,9 +663,8 @@ void wxGStreamerMediaBackend::SetupXOverlay()
//
// 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 +737,6 @@ bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
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
@@ -1046,11 +922,7 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
//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,15 +989,6 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
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
gst_bus_add_watch (gst_element_get_bus(m_playbin),
@@ -1134,10 +997,9 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
(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 = gst_element_factory_make ("gconfaudiosink", "audio-sink");
if( !TryAudioSink(audiosink) )
{
// fallback to autodetection, then alsa, then oss as a stopgap
@@ -1159,7 +1021,7 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
// 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 ("gconfvideosink", "video-sink");
if( !TryVideoSink(videosink) )
{
videosink = gst_element_factory_make ("autovideosink", "video-sink");
@@ -1181,11 +1043,6 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
}
}
#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();
@@ -1258,7 +1115,7 @@ bool wxGStreamerMediaBackend::DoLoad(const wxString& locstring)
// 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 +1138,7 @@ bool wxGStreamerMediaBackend::DoLoad(const wxString& locstring)
// 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();
@@ -1312,7 +1169,7 @@ bool wxGStreamerMediaBackend::DoLoad(const wxString& locstring)
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;
@@ -1332,7 +1189,7 @@ 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 +1210,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();
@@ -1419,7 +1276,7 @@ wxLongLong wxGStreamerMediaBackend::GetPosition()
gint64 pos;
GstFormat fmtTime = GST_FORMAT_TIME;
if (!wxGst_element_query_position(m_playbin, &fmtTime, &pos) ||
if (!gst_element_query_position(m_playbin, &fmtTime, &pos) ||
fmtTime != GST_FORMAT_TIME || pos == -1)
return 0;
return pos / GST_MSECOND ;
@@ -1446,33 +1303,13 @@ wxLongLong wxGStreamerMediaBackend::GetPosition()
//-----------------------------------------------------------------------------
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,
(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_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 );
m_llPausedPos = where;
return true;
#endif //== 0.8.0
}
//-----------------------------------------------------------------------------
@@ -1486,7 +1323,7 @@ wxLongLong wxGStreamerMediaBackend::GetDuration()
gint64 length;
GstFormat fmtTime = GST_FORMAT_TIME;
if(!wxGst_element_query_duration(m_playbin, &fmtTime, &length) ||
if(!gst_element_query_duration(m_playbin, &fmtTime, &length) ||
fmtTime != GST_FORMAT_TIME || length == -1)
return 0;
return length / GST_MSECOND ;
@@ -1549,7 +1386,6 @@ double wxGStreamerMediaBackend::GetPlaybackRate()
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),
@@ -1559,9 +1395,6 @@ bool wxGStreamerMediaBackend::SetPlaybackRate(double dRate)
m_dRate = dRate;
return true;
}
#else
wxUnusedVar(dRate);
#endif
#endif
// failure
@@ -1592,7 +1425,7 @@ wxLongLong wxGStreamerMediaBackend::GetDownloadTotal()
gint64 length;
GstFormat fmtBytes = GST_FORMAT_BYTES;
if (!wxGst_element_query_duration(m_playbin, &fmtBytes, &length) ||
if (!gst_element_query_duration(m_playbin, &fmtBytes, &length) ||
fmtBytes != GST_FORMAT_BYTES || length == -1)
return 0;
return length;