Ticket #14976: gst1.0.2.patch

File gst1.0.2.patch, 36.6 KB (added by slomo, 4 years ago)

gst1.0.patch (updated)

  • wxwidgets3.0-3.0.2+dfsg

    old new if test "$wxUSE_MEDIACTRL" = "yes" -o "$ 
    75437543        wxUSE_GSTREAMER="no"
    75447544
    75457545        dnl -------------------------------------------------------------------
    7546         dnl Test for at least 0.8 gstreamer module from pkg-config
    7547         dnl Even totem doesn't accept 0.9 evidently.
    7548         dnl
    7549         dnl So, we first check to see if 0.10 if available - if not we
    7550         dnl try the older 0.8 version
     7546        dnl Test for at least gstreamer 1.0 module from pkg-config
    75517547        dnl -------------------------------------------------------------------
    7552         GST_VERSION_MAJOR=0
    7553         GST_VERSION_MINOR=10
     7548        GST_VERSION_MAJOR=1
     7549        GST_VERSION_MINOR=0
    75547550        GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
    75557551
    7556         if test "$wxUSE_GSTREAMER8" = "no"; then
    7557             PKG_CHECK_MODULES(GST,
    7558                 [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION],
    7559                 [
    7560                     wxUSE_GSTREAMER="yes"
    7561                     GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION"
    7562                 ],
    7563                 [
    7564                     AC_MSG_WARN([GStreamer 0.10 not available, falling back to 0.8])
    7565                     GST_VERSION_MINOR=8
    7566                 ]
    7567             )
    7568         else
    7569             dnl check only for 0.8
    7570             GST_VERSION_MINOR=8
    7571         fi
    7572 
    7573         if test $GST_VERSION_MINOR = "8"; then
    7574             GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
    7575             PKG_CHECK_MODULES(GST,
    7576                 [gstreamer-$GST_VERSION gstreamer-interfaces-$GST_VERSION gstreamer-gconf-$GST_VERSION],
    7577                 wxUSE_GSTREAMER="yes",
    7578                 [
    7579                     AC_MSG_WARN([GStreamer 0.8/0.10 not available.])
    7580                 ])
    7581         fi
    7582 
     7552        PKG_CHECK_MODULES(GST,
     7553            [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION],
     7554            [
     7555                wxUSE_GSTREAMER="yes"
     7556                GST_LIBS="$GST_LIBS -lgstvideo-$GST_VERSION"
     7557            ],
     7558            [
     7559                AC_MSG_WARN([GStreamer 1.0 not available])
     7560            ]
     7561        )
    75837562
    75847563        if test "$wxUSE_GSTREAMER" = "yes"; then
    75857564            CPPFLAGS="$GST_CFLAGS $CPPFLAGS"
  • src/unix/mediactrl.cpp

    old new  
    1919
    2020#include <gst/gst.h>                // main gstreamer header
    2121
    22 // xoverlay/video stuff, gst-gconf for 0.8
    23 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    24 #   include <gst/interfaces/xoverlay.h>
    25 #else
    26 #   include <gst/xoverlay/xoverlay.h>
    27 #   include <gst/gconf/gconf.h>        // gstreamer glib configuration
    28 #endif
     22#include <gst/video/videooverlay.h>
    2923
    3024#ifndef  WX_PRECOMP
    3125    #include "wx/log.h"             // wxLogDebug/wxLogSysError/wxLogTrace
     
    4842//-----------------------------------------------------------------------------
    4943
    5044/*
    51    This is the GStreamer backend for unix. Currently we require 0.8 or
    52    0.10. Here we use the "playbin" GstElement for ease of use.
     45   This is the GStreamer backend for unix. Currently we require 1.0.
     46   Here we use the "playbin" GstElement for ease of use.
    5347
    54    Note that now we compare state change functions to GST_STATE_FAILURE
    55    now rather than GST_STATE_SUCCESS as newer gstreamer versions return
     48   Note that now we compare state change functions to GST_STATE_CHANGE_FAILURE
     49   now rather than GST_STATE_CHANGE_SUCCESS as newer gstreamer versions return
    5650   non-success values for returns that are otherwise successful but not
    5751   immediate.
    5852
     
    6054   moment but with a tad bit of work it could theorectically work in
    6155   straight wxX11 et al.
    6256
    63    One last note is that resuming from pausing/seeking can result
    64    in erratic video playback (GStreamer-based bug, happens in totem as well)
    65    - this is better in 0.10, however. One thing that might make it worse
    66    here is that we don't preserve the aspect ratio of the video and stretch
    67    it to the whole window.
     57   One last note is that we don't preserve the aspect ratio of the video and
     58   stretch it to the whole window.
    6859
    6960   Note that there are some things used here that could be undocumented -
    7061   for reference see the media player Kiss and Totem as well as some
     
    7263   that attempted thread-safety...
    7364
    7465   Then there is the issue of m_asynclock. This serves several purposes:
    75    1) It prevents the C callbacks from sending wx state change events
    76       so that we don't get duplicate ones in 0.8
    77    2) It makes the sync and async handlers in 0.10 not drop any
     66   1) It makes the sync and async handlers not drop any
    7867      messages so that while we are polling it we get the messages in
    7968      SyncStateChange instead of the queue.
    80    3) Keeps the pausing in Stop() synchronous
     69   2) Keeps the pausing in Stop() synchronous
    8170
    8271   RN: Note that I've tried to follow the wxGTK conventions here as close
    8372   as possible. In the implementation the C Callbacks come first, then
     
    9079//=============================================================================
    9180
    9281//-----------------------------------------------------------------------------
    93 //  GStreamer (most version compatibility) macros
     82//  GStreamer macros
    9483//-----------------------------------------------------------------------------
    9584
    96 // In 0.9 there was a HUGE change to GstQuery and the
    97 // gst_element_query function changed dramatically and split off
    98 // into two separate ones
    99 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8
    100 #    define wxGst_element_query_duration(e, f, p) \
    101                 gst_element_query(e, GST_QUERY_TOTAL, f, p)
    102 #    define wxGst_element_query_position(e, f, p) \
    103                 gst_element_query(e, GST_QUERY_POSITION, f, p)
    104 #elif GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 9
    105 // However, the actual 0.9 version has a slightly different definition
    106 // and instead of gst_element_query_duration it has two parameters to
    107 // gst_element_query_position instead
    108 #    define wxGst_element_query_duration(e, f, p) \
    109                 gst_element_query_position(e, f, 0, p)
    110 #    define wxGst_element_query_position(e, f, p) \
    111                 gst_element_query_position(e, f, p, 0)
    112 #else
    113 #    define wxGst_element_query_duration \
    114                 gst_element_query_duration
    115 #    define wxGst_element_query_position \
    116                 gst_element_query_position
    117 #endif
    118 
    119 // Other 0.10 macros
    120 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    121 #   define GST_STATE_FAILURE GST_STATE_CHANGE_FAILURE
    122 #   define GST_STATE_SUCCESS GST_STATE_CHANGE_SUCCESS
    123 #   define GstElementState GstState
    124 #   define gst_gconf_get_default_video_sink() \
    125         gst_element_factory_make ("gconfvideosink", "video-sink");
    126 #   define gst_gconf_get_default_audio_sink() \
    127         gst_element_factory_make ("gconfaudiosink", "audio-sink");
    128 #endif
    129 
    13085// Max wait time for element state waiting - GST_CLOCK_TIME_NONE for inf
    13186#define wxGSTREAMER_TIMEOUT (100 * GST_MSECOND) // Max 100 milliseconds
    13287
    public: 
    189144    bool CheckForErrors();
    190145    bool DoLoad(const wxString& locstring);
    191146    wxMediaCtrl* GetControl() { return m_ctrl; } // for C Callbacks
    192     void HandleStateChange(GstElementState oldstate, GstElementState newstate);
     147    void HandleStateChange(GstState oldstate, GstState newstate);
    193148    bool QueryVideoSizeFromElement(GstElement* element);
    194149    bool QueryVideoSizeFromPad(GstPad* caps);
    195     void SetupXOverlay();
    196     bool SyncStateChange(GstElement* element, GstElementState state,
     150    void SetupVideoOverlay();
     151    bool SyncStateChange(GstElement* element, GstState state,
    197152                         gint64 llTimeout = wxGSTREAMER_TIMEOUT);
    198153    bool TryAudioSink(GstElement* audiosink);
    199154    bool TryVideoSink(GstElement* videosink);
    public: 
    203158    double          m_dRate;        // Current playback rate -
    204159                                    // see GetPlaybackRate for notes
    205160    wxLongLong      m_llPausedPos;  // Paused position - see Pause()
    206     GstXOverlay*    m_xoverlay;     // X Overlay that contains the GST video
     161    GstVideoOverlay*    m_videooverlay;     // Video Overlay that contains the GST video
    207162    wxMutex         m_asynclock;    // See "discussion of internals"
    208163    class wxGStreamerMediaEventHandler* m_eventHandler; // see below
    209164
    expose_event(GtkWidget* widget, GdkEvent 
    284239{
    285240    // I've seen this recommended somewhere...
    286241    // TODO: Is this needed? Maybe it is just cruft...
    287     // gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay),
     242    // gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay),
    288243    //                              GDK_WINDOW_XWINDOW( window ) );
    289244
    290245    // If we have actual video.....
    expose_event(GtkWidget* widget, GdkEvent 
    294249        // GST Doesn't redraw automatically while paused
    295250        // Plus, the video sometimes doesn't redraw when it looses focus
    296251        // or is painted over so we just tell it to redraw...
    297         gst_x_overlay_expose(be->m_xoverlay);
     252        gst_video_overlay_expose(be->m_videooverlay);
    298253    }
    299254    else
    300255    {
    static gint gtk_window_realize_callback( 
    334289    GdkWindow* window = gtk_widget_get_window(widget);
    335290    wxASSERT(window);
    336291
    337     gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay),
     292    gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay),
    338293                                GDK_WINDOW_XID(window)
    339294                                );
    340295    GtkWidget* w = be->GetControl()->m_wxwindow;
    static gint gtk_window_realize_callback( 
    349304#endif // wxGTK
    350305
    351306//-----------------------------------------------------------------------------
    352 // "state-change" from m_playbin/GST_MESSAGE_STATE_CHANGE
    353 //
    354 // Called by gstreamer when the state changes - here we
    355 // send the appropriate corresponding wx event.
    356 //
    357 // 0.8 only as HandleStateChange does this in both versions
    358 //-----------------------------------------------------------------------------
    359 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
    360 extern "C" {
    361 static void gst_state_change_callback(GstElement *play,
    362                                       GstElementState oldstate,
    363                                       GstElementState newstate,
    364                                       wxGStreamerMediaBackend* be)
    365 {
    366     if(be->m_asynclock.TryLock() == wxMUTEX_NO_ERROR)
    367     {
    368         be->HandleStateChange(oldstate, newstate);
    369         be->m_asynclock.Unlock();
    370     }
    371 }
    372 }
    373 #endif // <0.10
    374 
    375 //-----------------------------------------------------------------------------
    376307// "eos" from m_playbin/GST_MESSAGE_EOS
    377308//
    378309// Called by gstreamer when the media is done playing ("end of stream")
    static void gst_notify_caps_callback(Gst 
    425356}
    426357
    427358//-----------------------------------------------------------------------------
    428 // "notify::stream-info" from m_playbin
    429 //
    430 // Run through the stuff in "stream-info" of m_playbin for a valid
    431 // video pad, and then attempt to query the video size from it - if not
    432 // set up an event to do so when ready.
    433 //
    434 // Currently unused - now we just query it directly using
    435 // QueryVideoSizeFromElement.
    436 //
    437 // (Undocumented?)
    438 //-----------------------------------------------------------------------------
    439 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    440 extern "C" {
    441 static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element),
    442                                             GParamSpec* WXUNUSED(pspec),
    443                                             wxGStreamerMediaBackend* be)
    444 {
    445     wxLogTrace(wxTRACE_GStreamer, wxT("gst_notify_stream_info_callback"));
    446     be->QueryVideoSizeFromElement(be->m_playbin);
    447 }
    448 }
    449 #endif
    450 
    451 //-----------------------------------------------------------------------------
    452 // "desired-size-changed" from m_xoverlay
    453 //
    454 // 0.8-specific this provides us with the video size when it changes -
    455 // even though we get the caps as well this seems to come before the
    456 // caps notification does...
    457 //
    458 // Note it will return 16,16 for an early-bird value or for audio
    459 //-----------------------------------------------------------------------------
    460 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
    461 extern "C" {
    462 static void gst_desired_size_changed_callback(GstElement * play,
    463                                               guint width, guint height,
    464                                               wxGStreamerMediaBackend* be)
    465 {
    466     if(!(width == 16 && height == 16))
    467     {
    468         be->m_videoSize.x = width;
    469         be->m_videoSize.y = height;
    470     }
    471     else
    472         be->QueryVideoSizeFromElement(be->m_playbin);
    473 }
    474 }
    475 #endif
    476 
    477 //-----------------------------------------------------------------------------
    478359// gst_bus_async_callback [static]
    479360// gst_bus_sync_callback [static]
    480361//
    481 // Called by m_playbin for notifications such as end-of-stream in 0.10 -
    482 // in previous versions g_signal notifications were used. Because everything
     362// Called by m_playbin for notifications such as end-of-stream. Because everything
    483363// in centered in one switch statement though it reminds one of old WinAPI
    484364// stuff.
    485365//
    486366// gst_bus_sync_callback is that sync version that is called on the main GUI
    487367// thread before the async version that we use to set the xwindow id of the
    488 // XOverlay (NB: This isn't currently used - see CreateControl()).
     368// VideoOverlay (NB: This isn't currently used - see CreateControl()).
    489369//-----------------------------------------------------------------------------
    490 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    491370extern "C" {
    492371static gboolean gst_bus_async_callback(GstBus* WXUNUSED(bus),
    493372                                       GstMessage* message,
    static GstBusSyncReply gst_bus_sync_call 
    537416{
    538417    // Pass a non-xwindowid-setting event on to the async handler where it
    539418    // belongs
    540     if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT ||
    541         !gst_structure_has_name (message->structure, "prepare-xwindow-id"))
     419    if (!gst_is_video_overlay_prepare_window_handle_message (message))
    542420    {
    543421        //
    544422        // NB: Unfortunately, the async callback can be quite
    static GstBusSyncReply gst_bus_sync_call 
    552430            return GST_BUS_DROP;
    553431    }
    554432
    555     wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-xwindow-id"));
    556     be->SetupXOverlay();
     433    wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-window-handle"));
     434    be->SetupVideoOverlay();
    557435    return GST_BUS_DROP; // We handled this message - drop from the queue
    558436}
    559437}
    560 #endif
    561438
    562439//-----------------------------------------------------------------------------
    563440//
    static GstBusSyncReply gst_bus_sync_call 
    569446// wxGStreamerMediaBackend::HandleStateChange
    570447//
    571448// Handles a state change event from our C Callback for "state-change" or
    572 // the async queue in 0.10. (Mostly this is here to avoid locking the
     449// the async queue . (Mostly this is here to avoid locking the
    573450// the mutex twice...)
    574451//-----------------------------------------------------------------------------
    575 void wxGStreamerMediaBackend::HandleStateChange(GstElementState oldstate,
    576                                                 GstElementState newstate)
     452void wxGStreamerMediaBackend::HandleStateChange(GstState oldstate,
     453                                                GstState newstate)
    577454{
    578455    switch(newstate)
    579456    {
    void wxGStreamerMediaBackend::HandleStat 
    604481}
    605482
    606483//-----------------------------------------------------------------------------
    607 // wxGStreamerMediaBackend::QueryVideoSizeFromElement
    608 //
    609 // Run through the stuff in "stream-info" of element for a valid
    610 // video pad, and then attempt to query the video size from it - if not
    611 // set up an event to do so when ready. Return true
    612 // if we got a valid video pad.
    613 //-----------------------------------------------------------------------------
    614 bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element)
    615 {
    616     const GList *list = NULL;
    617     g_object_get (G_OBJECT (element), "stream-info", &list, NULL);
    618 
    619     for ( ; list != NULL; list = list->next)
    620     {
    621         GObject *info = (GObject *) list->data;
    622         gint type;
    623         GParamSpec *pspec;
    624         GEnumValue *val;
    625         GstPad *pad = NULL;
    626 
    627         g_object_get (info, "type", &type, NULL);
    628         pspec = g_object_class_find_property (
    629                         G_OBJECT_GET_CLASS (info), "type");
    630         val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
    631 
    632         if (!strncasecmp(val->value_name, "video", 5) ||
    633             !strncmp(val->value_name, "GST_STREAM_TYPE_VIDEO", 21))
    634         {
    635             // Newer gstreamer 0.8+ plugins are SUPPOSED to have "object"...
    636             // but a lot of old plugins still use "pad" :)
    637             pspec = g_object_class_find_property (
    638                         G_OBJECT_GET_CLASS (info), "object");
    639 
    640             if (!pspec)
    641                 g_object_get (info, "pad", &pad, NULL);
    642             else
    643                 g_object_get (info, "object", &pad, NULL);
    644 
    645 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8
    646             // Killed in 0.9, presumely because events and such
    647             // should be pushed on pads regardless of whether they
    648             // are currently linked
    649             pad = (GstPad *) GST_PAD_REALIZE (pad);
    650             wxASSERT(pad);
    651 #endif
    652 
    653             if(!QueryVideoSizeFromPad(pad))
    654             {
    655                 // wait for those caps to get ready
    656                 g_signal_connect(
    657                 pad,
    658                 "notify::caps",
    659                 G_CALLBACK(gst_notify_caps_callback),
    660                 this);
    661             }
    662             break;
    663         }// end if video
    664     }// end searching through info list
    665 
    666     // no video (or extremely delayed stream-info)
    667     if(list == NULL)
    668     {
    669         m_videoSize = wxSize(0,0);
    670         return false;
    671     }
    672 
    673     return true;
    674 }
    675 
    676 //-----------------------------------------------------------------------------
    677484// wxGStreamerMediaBackend::QueryVideoSizeFromPad
    678485//
    679486// Gets the size of our video (in wxSize) from a GstPad
    680487//-----------------------------------------------------------------------------
    681488bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad)
    682489{
    683     const GstCaps* caps = GST_PAD_CAPS(pad);
     490    GstCaps* caps = gst_pad_get_current_caps(pad);
    684491    if ( caps )
    685492    {
    686493        const GstStructure *s = gst_caps_get_structure (caps, 0);
    bool wxGStreamerMediaBackend::QueryVideo 
    706513                m_videoSize.y = (int) ((float) den * m_videoSize.y / num);
    707514        }
    708515
    709          wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"),
    710                      m_videoSize.x, m_videoSize.y);
     516        wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"),
     517                    m_videoSize.x, m_videoSize.y);
     518
     519        gst_caps_unref (caps);
    711520        return true;
    712521    } // end if caps
    713522
     523    m_videoSize = wxSize(0,0);
    714524    return false; // not ready/massive failure
    715525}
    716526
    717527//-----------------------------------------------------------------------------
    718 // wxGStreamerMediaBackend::SetupXOverlay
     528// wxGStreamerMediaBackend::SetupVideoOverlay
    719529//
    720 // Attempts to set the XWindow id of our GstXOverlay to tell it which
     530// Attempts to set the XWindow id of our GstVideoOverlay to tell it which
    721531// window to play video in.
    722532//-----------------------------------------------------------------------------
    723 void wxGStreamerMediaBackend::SetupXOverlay()
     533void wxGStreamerMediaBackend::SetupVideoOverlay()
    724534{
    725     // Use the xoverlay extension to tell gstreamer to play in our window
     535    // Use the videooverlay extension to tell gstreamer to play in our window
    726536#ifdef __WXGTK__
    727537    if (!gtk_widget_get_realized(m_ctrl->m_wxwindow))
    728538    {
    void wxGStreamerMediaBackend::SetupXOver 
    739549        GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow);
    740550        wxASSERT(window);
    741551#endif
    742         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_xoverlay),
     552        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videooverlay),
    743553#ifdef __WXGTK__
    744554                        GDK_WINDOW_XID(window)
    745555#else
    void wxGStreamerMediaBackend::SetupXOver 
    769579//
    770580// PRECONDITION: Assumes m_asynclock is Lock()ed
    771581//-----------------------------------------------------------------------------
    772 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    773582bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
    774                                               GstElementState desiredstate,
     583                                              GstState desiredstate,
    775584                                              gint64 llTimeout)
    776585{
    777586    GstBus* bus = gst_element_get_bus(element);
    bool wxGStreamerMediaBackend::SyncStateC 
    844653
    845654    return bSuccess;
    846655}
    847 #else // 0.8 implementation
    848 bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
    849                                               GstElementState desiredstate,
    850                                               gint64 llTimeout)
    851 {
    852     gint64 llTimeWaited = 0;
    853     while(GST_STATE(element) != desiredstate)
    854     {
    855         if(llTimeWaited >= llTimeout)
    856             break;
    857         llTimeWaited += 10*GST_MSECOND;
    858         wxMilliSleep(10);
    859     }
    860 
    861     return llTimeWaited != llTimeout;
    862 }
    863 #endif
    864656
    865657//-----------------------------------------------------------------------------
    866658// wxGStreamerMediaBackend::TryAudioSink
    bool wxGStreamerMediaBackend::TryAudioSi 
    884676
    885677bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink)
    886678{
    887     // Check if the video sink either is an xoverlay or might contain one...
    888     if( !GST_IS_BIN(videosink) && !GST_IS_X_OVERLAY(videosink) )
     679    // Check if the video sink either is an videooverlay or might contain one...
     680    if( !GST_IS_BIN(videosink) && !GST_IS_VIDEO_OVERLAY(videosink) )
    889681    {
    890682        if(G_IS_OBJECT(videosink))
    891683            g_object_unref(videosink);
    892684        return false;
    893685    }
    894686
    895     // Make our video sink and make sure it supports the x overlay interface
    896     // the x overlay enables us to put the video in our control window
     687    // Make our video sink and make sure it supports the video overlay interface
     688    // the video overlay enables us to put the video in our control window
    897689    // (i.e. we NEED it!) - also connect to the natural video size change event
    898690    if( GST_IS_BIN(videosink) )
    899         m_xoverlay = (GstXOverlay*)
     691        m_videooverlay = (GstVideoOverlay*)
    900692                        gst_bin_get_by_interface (GST_BIN (videosink),
    901                                                   GST_TYPE_X_OVERLAY);
     693                                                  GST_TYPE_VIDEO_OVERLAY);
    902694    else
    903         m_xoverlay = (GstXOverlay*) videosink;
     695        m_videooverlay = (GstVideoOverlay*) videosink;
    904696
    905     if ( !GST_IS_X_OVERLAY(m_xoverlay) )
     697    if ( !GST_IS_VIDEO_OVERLAY(m_videooverlay) )
    906698    {
    907699        g_object_unref(videosink);
    908700        return false;
    bool wxGStreamerMediaBackend::CreateCont 
    1046838    //Really init gstreamer
    1047839    gboolean bInited;
    1048840    GError* error = NULL;
    1049 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    1050841    bInited = gst_init_check(&argcGST, &argvGST, &error);
    1051 #else
    1052     bInited = gst_init_check(&argcGST, &argvGST);
    1053 #endif
    1054842
    1055843    // Cleanup arguments for unicode case
    1056844#if wxUSE_UNICODE
    bool wxGStreamerMediaBackend::CreateCont 
    1117905        return false;
    1118906    }
    1119907
    1120 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
    1121     // Connect the glib events/callbacks we want to our playbin
    1122     g_signal_connect(m_playbin, "eos",
    1123                      G_CALLBACK(gst_finish_callback), this);
    1124     g_signal_connect(m_playbin, "error",
    1125                      G_CALLBACK(gst_error_callback), this);
    1126     g_signal_connect(m_playbin, "state-change",
    1127                      G_CALLBACK(gst_state_change_callback), this);
    1128 #else
    1129     // GStreamer 0.10+ uses GstBus for this now, connect to the sync
    1130     // handler as well so we can set the X window id of our xoverlay
     908    // GStreamer uses GstBus for this now, connect to the sync
     909    // handler as well so we can set the video window id of our videooverlay
    1131910    gst_bus_add_watch (gst_element_get_bus(m_playbin),
    1132911                       (GstBusFunc) gst_bus_async_callback, this);
    1133912    gst_bus_set_sync_handler(gst_element_get_bus(m_playbin),
    1134                              (GstBusSyncHandler) gst_bus_sync_callback, this);
    1135     g_signal_connect(m_playbin, "notify::stream-info",
    1136                      G_CALLBACK(gst_notify_stream_info_callback), this);
    1137 #endif
     913                             (GstBusSyncHandler) gst_bus_sync_callback, this, NULL);
    1138914
    1139915    // Get the audio sink
    1140     GstElement* audiosink = gst_gconf_get_default_audio_sink();
     916    // Use autodetection, then alsa, then oss as a stopgap
     917    GstElement* audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink");
    1141918    if( !TryAudioSink(audiosink) )
    1142919    {
    1143         // fallback to autodetection, then alsa, then oss as a stopgap
    1144         audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink");
     920        audiosink = gst_element_factory_make ("alsasink", "alsa-output");
    1145921        if( !TryAudioSink(audiosink) )
    1146922        {
    1147             audiosink = gst_element_factory_make ("alsasink", "alsa-output");
     923            audiosink = gst_element_factory_make ("osssink", "play_audio");
    1148924            if( !TryAudioSink(audiosink) )
    1149925            {
    1150                 audiosink = gst_element_factory_make ("osssink", "play_audio");
    1151                 if( !TryAudioSink(audiosink) )
    1152                 {
    1153                     wxLogSysError(wxT("Could not find a valid audiosink"));
    1154                     return false;
    1155                 }
     926                wxLogSysError(wxT("Could not find a valid audiosink"));
     927                return false;
    1156928            }
    1157929        }
    1158930    }
    1159931
    1160932    // Setup video sink - first try gconf, then auto, then xvimage and
    1161933    // then finally plain ximage
    1162     GstElement* videosink = gst_gconf_get_default_video_sink();
     934    GstElement* videosink = gst_element_factory_make ("autovideosink", "video-sink");
    1163935    if( !TryVideoSink(videosink) )
    1164936    {
    1165         videosink = gst_element_factory_make ("autovideosink", "video-sink");
     937        videosink = gst_element_factory_make ("xvimagesink", "video-sink");
    1166938        if( !TryVideoSink(videosink) )
    1167939        {
    1168             videosink = gst_element_factory_make ("xvimagesink", "video-sink");
     940            // finally, do a final fallback to ximagesink
     941            videosink =
     942                gst_element_factory_make ("ximagesink", "video-sink");
    1169943            if( !TryVideoSink(videosink) )
    1170944            {
    1171                 // finally, do a final fallback to ximagesink
    1172                 videosink =
    1173                     gst_element_factory_make ("ximagesink", "video-sink");
    1174                 if( !TryVideoSink(videosink) )
    1175                 {
    1176                     g_object_unref(audiosink);
    1177                     wxLogSysError(wxT("Could not find a suitable video sink"));
    1178                     return false;
    1179                 }
     945                g_object_unref(audiosink);
     946                wxLogSysError(wxT("Could not find a suitable video sink"));
     947                return false;
    1180948            }
    1181949        }
    1182950    }
    1183951
    1184 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
    1185     // Not on 0.10... called when video size changes
    1186     g_signal_connect(m_xoverlay, "desired-size-changed",
    1187                      G_CALLBACK(gst_desired_size_changed_callback), this);
    1188 #endif
    1189     // Tell GStreamer which window to draw to in 0.8 - 0.10
    1190     // sometimes needs this too...
    1191     SetupXOverlay();
     952    // Tell GStreamer which window to draw to
     953    SetupVideoOverlay();
    1192954
    1193955    // Now that we know (or, rather think) our video and audio sink
    1194956    // are valid set our playbin to use them
    bool wxGStreamerMediaBackend::CreateCont 
    1197959                  "audio-sink", audiosink,
    1198960                   NULL);
    1199961
     962    GstPad *video_sinkpad = gst_element_get_static_pad (videosink, "sink");
     963    g_signal_connect (video_sinkpad, "notify::caps", G_CALLBACK (gst_notify_caps_callback), this);
     964    gst_object_unref (video_sinkpad);
     965
    1200966    m_eventHandler = new wxGStreamerMediaEventHandler(this);
    1201967    return true;
    1202968}
    bool wxGStreamerMediaBackend::Load(const 
    1213979
    1214980//-----------------------------------------------------------------------------
    1215981// wxGStreamerMediaBackend::Load (URI version)
    1216 //
    1217 // In the case of a file URI passes it unencoded -
    1218 // also, as of 0.10.3 and earlier GstURI (the uri parser for gstreamer)
    1219 // is sort of broken and only accepts uris with at least two slashes
    1220 // after the scheme (i.e. file: == not ok, file:// == ok)
    1221982//-----------------------------------------------------------------------------
    1222983bool wxGStreamerMediaBackend::Load(const wxURI& location)
    1223984{
    1224     if(location.GetScheme().CmpNoCase(wxT("file")) == 0)
    1225     {
    1226         wxString uristring = location.BuildUnescapedURI();
    1227 
    1228         //Workaround GstURI leading "//" problem and make sure it leads
    1229         //with that
    1230         return DoLoad(wxString(wxT("file://")) +
    1231                       uristring.Right(uristring.length() - 5)
    1232                      );
    1233     }
    1234     else
    1235         return DoLoad(location.BuildURI());
     985    return DoLoad(location.BuildURI());
    1236986}
    1237987
    1238988//-----------------------------------------------------------------------------
    bool wxGStreamerMediaBackend::DoLoad(con 
    12581008
    12591009    // Set playbin to ready to stop the current media...
    12601010    if( gst_element_set_state (m_playbin,
    1261                                GST_STATE_READY) == GST_STATE_FAILURE ||
     1011                               GST_STATE_READY) == GST_STATE_CHANGE_FAILURE ||
    12621012        !SyncStateChange(m_playbin, GST_STATE_READY))
    12631013    {
    12641014        CheckForErrors();
    bool wxGStreamerMediaBackend::DoLoad(con 
    12811031    // Try to pause media as gstreamer won't let us query attributes
    12821032    // such as video size unless it is paused or playing
    12831033    if( gst_element_set_state (m_playbin,
    1284                                GST_STATE_PAUSED) == GST_STATE_FAILURE ||
     1034                               GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE ||
    12851035        !SyncStateChange(m_playbin, GST_STATE_PAUSED))
    12861036    {
    12871037        CheckForErrors();
    bool wxGStreamerMediaBackend::DoLoad(con 
    13071057//
    13081058// Sets the stream to a playing state
    13091059//
    1310 // THREAD-UNSAFE in 0.8, maybe in 0.10 as well
    13111060//-----------------------------------------------------------------------------
    13121061bool wxGStreamerMediaBackend::Play()
    13131062{
    13141063    if (gst_element_set_state (m_playbin,
    1315                                GST_STATE_PLAYING) == GST_STATE_FAILURE)
     1064                               GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE)
    13161065    {
    13171066        CheckForErrors();
    13181067        return false;
    bool wxGStreamerMediaBackend::Play() 
    13261075//
    13271076// Marks where we paused and pauses the stream
    13281077//
    1329 // THREAD-UNSAFE in 0.8, maybe in 0.10 as well
    13301078//-----------------------------------------------------------------------------
    13311079bool wxGStreamerMediaBackend::Pause()
    13321080{
    13331081    m_llPausedPos = wxGStreamerMediaBackend::GetPosition();
    13341082    if (gst_element_set_state (m_playbin,
    1335                                GST_STATE_PAUSED) == GST_STATE_FAILURE)
     1083                               GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE)
    13361084    {
    13371085        CheckForErrors();
    13381086        return false;
    bool wxGStreamerMediaBackend::Stop() 
    13531101    {   // begin state lock
    13541102        wxMutexLocker lock(m_asynclock);
    13551103        if(gst_element_set_state (m_playbin,
    1356                                   GST_STATE_PAUSED) == GST_STATE_FAILURE ||
     1104                                  GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE ||
    13571105          !SyncStateChange(m_playbin, GST_STATE_PAUSED))
    13581106        {
    13591107            CheckForErrors();
    wxLongLong wxGStreamerMediaBackend::GetP 
    14171165    else
    14181166    {
    14191167        gint64 pos;
    1420         GstFormat fmtTime = GST_FORMAT_TIME;
    14211168
    1422         if (!wxGst_element_query_position(m_playbin, &fmtTime, &pos) ||
    1423             fmtTime != GST_FORMAT_TIME || pos == -1)
     1169        if (!gst_element_query_position(m_playbin, GST_FORMAT_TIME, &pos) || pos == -1)
    14241170            return 0;
    14251171        return pos / GST_MSECOND ;
    14261172    }
    wxLongLong wxGStreamerMediaBackend::GetP 
    14381184// This is also an exceedingly ugly function due to the three implementations
    14391185// (or, rather two plus one implementation without a seek function).
    14401186//
    1441 // This is asynchronous and thread-safe on both 0.8 and 0.10.
    1442 //
    14431187// NB: This fires both a stop and play event if the media was previously
    14441188// playing... which in some ways makes sense. And yes, this makes the video
    14451189// go all haywire at times - a gstreamer bug...
    14461190//-----------------------------------------------------------------------------
    14471191bool wxGStreamerMediaBackend::SetPosition(wxLongLong where)
    14481192{
    1449 #if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 8 \
    1450                            && GST_VERSION_MICRO == 0
    1451     // 0.8.0 has no gst_element_seek according to official docs!!!
    1452     wxLogSysError(wxT("GStreamer 0.8.0 does not have gst_element_seek")
    1453                   wxT(" according to official docs"));
    1454     return false;
    1455 #else // != 0.8.0
    1456 
    1457 #   if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    1458         gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME,
     1193    if ( gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME,
    14591194           (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),
    14601195                          GST_SEEK_TYPE_SET, where.GetValue() * GST_MSECOND,
    1461                           GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
    1462 #   else
    1463         // NB: Some gstreamer versions return false basically all the time
    1464         // here - even totem doesn't bother to check the return value here
    1465         // so I guess we'll just assume it worked -
    1466         // TODO: maybe check the gst error callback???
    1467         gst_element_seek (m_playbin, (GstSeekType) (GST_SEEK_METHOD_SET |
    1468             GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH),
    1469             where.GetValue() * GST_MSECOND );
    1470 
    1471 #   endif // GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    1472 
     1196                          GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE ) )
    14731197    {
    14741198        m_llPausedPos = where;
    14751199        return true;
    14761200    }
    1477     return true;
    1478 #endif //== 0.8.0
     1201    return false;
    14791202}
    14801203
    14811204//-----------------------------------------------------------------------------
    bool wxGStreamerMediaBackend::SetPositio 
    14871210wxLongLong wxGStreamerMediaBackend::GetDuration()
    14881211{
    14891212    gint64 length;
    1490     GstFormat fmtTime = GST_FORMAT_TIME;
    14911213
    1492     if(!wxGst_element_query_duration(m_playbin, &fmtTime, &length) ||
    1493        fmtTime != GST_FORMAT_TIME || length == -1)
     1214    if(!gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &length) || length == -1)
    14941215        return 0;
    14951216    return length / GST_MSECOND ;
    14961217}
    void wxGStreamerMediaBackend::Move(int W 
    15121233// wxGStreamerMediaBackend::GetVideoSize
    15131234//
    15141235// Returns our cached video size from Load/gst_notify_caps_callback
    1515 // gst_x_overlay_get_desired_size also does this in 0.8...
     1236// gst_video_overlay_get_desired_size also does this in 0.8...
    15161237//-----------------------------------------------------------------------------
    15171238wxSize wxGStreamerMediaBackend::GetVideoSize() const
    15181239{
    wxSize wxGStreamerMediaBackend::GetVideo 
    15391260//TODO: forcing frame/samplerates, see audioscale and videorate. Audioscale is
    15401261//TODO: part of playbin.
    15411262//
    1542 // In 0.10 GStreamer has new gst_element_seek API that might
    1543 // support this - and I've got an attempt to do so but it is untested
    1544 // but it would appear to work...
     1263// In has new gst_element_seek API that supports this - and I've got an attempt
     1264// to do so but it is untested but it would appear to work...
    15451265//-----------------------------------------------------------------------------
    15461266double wxGStreamerMediaBackend::GetPlaybackRate()
    15471267{
    double wxGStreamerMediaBackend::GetPlayb 
    15521272
    15531273bool wxGStreamerMediaBackend::SetPlaybackRate(double dRate)
    15541274{
    1555 #if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
    15561275#if 0 // not tested enough
    15571276    if( gst_element_seek (m_playbin, dRate, GST_FORMAT_TIME,
    15581277                 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),
    bool wxGStreamerMediaBackend::SetPlaybac 
    15651284#else
    15661285    wxUnusedVar(dRate);
    15671286#endif
    1568 #endif
    15691287
    15701288    // failure
    15711289    return false;
    wxLongLong wxGStreamerMediaBackend::GetD 
    15931311wxLongLong wxGStreamerMediaBackend::GetDownloadTotal()
    15941312{
    15951313    gint64 length;
    1596     GstFormat fmtBytes = GST_FORMAT_BYTES;
    15971314
    1598     if (!wxGst_element_query_duration(m_playbin, &fmtBytes, &length) ||
    1599           fmtBytes != GST_FORMAT_BYTES || length == -1)
     1315    if (!gst_element_query_duration(m_playbin, GST_FORMAT_BYTES, &length) || length == -1)
    16001316        return 0;
    16011317    return length;
    16021318}