1 Index: wxwidgets3.0-3.0.2+dfsg/configure.in
2 ===================================================================
3 --- wxwidgets3.0-3.0.2+dfsg.orig/configure.in
4 +++ wxwidgets3.0-3.0.2+dfsg/configure.in
5 @@ -7543,43 +7543,22 @@ if test "$wxUSE_MEDIACTRL" = "yes" -o "$
6 wxUSE_GSTREAMER="no"
7
8 dnl -------------------------------------------------------------------
9 - dnl Test for at least 0.8 gstreamer module from pkg-config
10 - dnl Even totem doesn't accept 0.9 evidently.
11 - dnl
12 - dnl So, we first check to see if 0.10 if available - if not we
13 - dnl try the older 0.8 version
14 + dnl Test for at least gstreamer 1.0 module from pkg-config
15 dnl -------------------------------------------------------------------
16 - GST_VERSION_MAJOR=0
17 - GST_VERSION_MINOR=10
18 + GST_VERSION_MAJOR=1
19 + GST_VERSION_MINOR=0
20 GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
21
22 - if test "$wxUSE_GSTREAMER8" = "no"; then
23 - PKG_CHECK_MODULES(GST,
24 - [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION],
25 - [
26 - wxUSE_GSTREAMER="yes"
27 - GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_VERSION"
28 - ],
29 - [
30 - AC_MSG_WARN([GStreamer 0.10 not available, falling back to 0.8])
31 - GST_VERSION_MINOR=8
32 - ]
33 - )
34 - else
35 - dnl check only for 0.8
36 - GST_VERSION_MINOR=8
37 - fi
38 -
39 - if test $GST_VERSION_MINOR = "8"; then
40 - GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR
41 - PKG_CHECK_MODULES(GST,
42 - [gstreamer-$GST_VERSION gstreamer-interfaces-$GST_VERSION gstreamer-gconf-$GST_VERSION],
43 - wxUSE_GSTREAMER="yes",
44 - [
45 - AC_MSG_WARN([GStreamer 0.8/0.10 not available.])
46 - ])
47 - fi
48 -
49 + PKG_CHECK_MODULES(GST,
50 + [gstreamer-$GST_VERSION gstreamer-plugins-base-$GST_VERSION],
51 + [
52 + wxUSE_GSTREAMER="yes"
53 + GST_LIBS="$GST_LIBS -lgstvideo-$GST_VERSION"
54 + ],
55 + [
56 + AC_MSG_WARN([GStreamer 1.0 not available])
57 + ]
58 + )
59
60 if test "$wxUSE_GSTREAMER" = "yes"; then
61 CPPFLAGS="$GST_CFLAGS $CPPFLAGS"
62 Index: wxwidgets3.0-3.0.2+dfsg/src/unix/mediactrl.cpp
63 ===================================================================
64 --- wxwidgets3.0-3.0.2+dfsg.orig/src/unix/mediactrl.cpp
65 +++ wxwidgets3.0-3.0.2+dfsg/src/unix/mediactrl.cpp
66 @@ -19,13 +19,7 @@
67
68 #include <gst/gst.h> // main gstreamer header
69
70 -// xoverlay/video stuff, gst-gconf for 0.8
71 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
72 -# include <gst/interfaces/xoverlay.h>
73 -#else
74 -# include <gst/xoverlay/xoverlay.h>
75 -# include <gst/gconf/gconf.h> // gstreamer glib configuration
76 -#endif
77 +#include <gst/video/videooverlay.h>
78
79 #ifndef WX_PRECOMP
80 #include "wx/log.h" // wxLogDebug/wxLogSysError/wxLogTrace
81 @@ -48,11 +42,11 @@
82 //-----------------------------------------------------------------------------
83
84 /*
85 - This is the GStreamer backend for unix. Currently we require 0.8 or
86 - 0.10. Here we use the "playbin" GstElement for ease of use.
87 + This is the GStreamer backend for unix. Currently we require 1.0.
88 + Here we use the "playbin" GstElement for ease of use.
89
90 - Note that now we compare state change functions to GST_STATE_FAILURE
91 - now rather than GST_STATE_SUCCESS as newer gstreamer versions return
92 + Note that now we compare state change functions to GST_STATE_CHANGE_FAILURE
93 + now rather than GST_STATE_CHANGE_SUCCESS as newer gstreamer versions return
94 non-success values for returns that are otherwise successful but not
95 immediate.
96
97 @@ -60,11 +54,8 @@
98 moment but with a tad bit of work it could theorectically work in
99 straight wxX11 et al.
100
101 - One last note is that resuming from pausing/seeking can result
102 - in erratic video playback (GStreamer-based bug, happens in totem as well)
103 - - this is better in 0.10, however. One thing that might make it worse
104 - here is that we don't preserve the aspect ratio of the video and stretch
105 - it to the whole window.
106 + One last note is that we don't preserve the aspect ratio of the video and
107 + stretch it to the whole window.
108
109 Note that there are some things used here that could be undocumented -
110 for reference see the media player Kiss and Totem as well as some
111 @@ -72,12 +63,10 @@
112 that attempted thread-safety...
113
114 Then there is the issue of m_asynclock. This serves several purposes:
115 - 1) It prevents the C callbacks from sending wx state change events
116 - so that we don't get duplicate ones in 0.8
117 - 2) It makes the sync and async handlers in 0.10 not drop any
118 + 1) It makes the sync and async handlers not drop any
119 messages so that while we are polling it we get the messages in
120 SyncStateChange instead of the queue.
121 - 3) Keeps the pausing in Stop() synchronous
122 + 2) Keeps the pausing in Stop() synchronous
123
124 RN: Note that I've tried to follow the wxGTK conventions here as close
125 as possible. In the implementation the C Callbacks come first, then
126 @@ -90,43 +79,9 @@
127 //=============================================================================
128
129 //-----------------------------------------------------------------------------
130 -// GStreamer (most version compatibility) macros
131 +// GStreamer macros
132 //-----------------------------------------------------------------------------
133
134 -// In 0.9 there was a HUGE change to GstQuery and the
135 -// gst_element_query function changed dramatically and split off
136 -// into two separate ones
137 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8
138 -# define wxGst_element_query_duration(e, f, p) \
139 - gst_element_query(e, GST_QUERY_TOTAL, f, p)
140 -# define wxGst_element_query_position(e, f, p) \
141 - gst_element_query(e, GST_QUERY_POSITION, f, p)
142 -#elif GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 9
143 -// However, the actual 0.9 version has a slightly different definition
144 -// and instead of gst_element_query_duration it has two parameters to
145 -// gst_element_query_position instead
146 -# define wxGst_element_query_duration(e, f, p) \
147 - gst_element_query_position(e, f, 0, p)
148 -# define wxGst_element_query_position(e, f, p) \
149 - gst_element_query_position(e, f, p, 0)
150 -#else
151 -# define wxGst_element_query_duration \
152 - gst_element_query_duration
153 -# define wxGst_element_query_position \
154 - gst_element_query_position
155 -#endif
156 -
157 -// Other 0.10 macros
158 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
159 -# define GST_STATE_FAILURE GST_STATE_CHANGE_FAILURE
160 -# define GST_STATE_SUCCESS GST_STATE_CHANGE_SUCCESS
161 -# define GstElementState GstState
162 -# define gst_gconf_get_default_video_sink() \
163 - gst_element_factory_make ("gconfvideosink", "video-sink");
164 -# define gst_gconf_get_default_audio_sink() \
165 - gst_element_factory_make ("gconfaudiosink", "audio-sink");
166 -#endif
167 -
168 // Max wait time for element state waiting - GST_CLOCK_TIME_NONE for inf
169 #define wxGSTREAMER_TIMEOUT (100 * GST_MSECOND) // Max 100 milliseconds
170
171 @@ -189,11 +144,11 @@ public:
172 bool CheckForErrors();
173 bool DoLoad(const wxString& locstring);
174 wxMediaCtrl* GetControl() { return m_ctrl; } // for C Callbacks
175 - void HandleStateChange(GstElementState oldstate, GstElementState newstate);
176 + void HandleStateChange(GstState oldstate, GstState newstate);
177 bool QueryVideoSizeFromElement(GstElement* element);
178 bool QueryVideoSizeFromPad(GstPad* caps);
179 - void SetupXOverlay();
180 - bool SyncStateChange(GstElement* element, GstElementState state,
181 + void SetupVideoOverlay();
182 + bool SyncStateChange(GstElement* element, GstState state,
183 gint64 llTimeout = wxGSTREAMER_TIMEOUT);
184 bool TryAudioSink(GstElement* audiosink);
185 bool TryVideoSink(GstElement* videosink);
186 @@ -203,7 +158,7 @@ public:
187 double m_dRate; // Current playback rate -
188 // see GetPlaybackRate for notes
189 wxLongLong m_llPausedPos; // Paused position - see Pause()
190 - GstXOverlay* m_xoverlay; // X Overlay that contains the GST video
191 + GstVideoOverlay* m_videooverlay; // Video Overlay that contains the GST video
192 wxMutex m_asynclock; // See "discussion of internals"
193 class wxGStreamerMediaEventHandler* m_eventHandler; // see below
194
195 @@ -284,7 +239,7 @@ expose_event(GtkWidget* widget, GdkEvent
196 {
197 // I've seen this recommended somewhere...
198 // TODO: Is this needed? Maybe it is just cruft...
199 - // gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay),
200 + // gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay),
201 // GDK_WINDOW_XWINDOW( window ) );
202
203 // If we have actual video.....
204 @@ -294,7 +249,7 @@ expose_event(GtkWidget* widget, GdkEvent
205 // GST Doesn't redraw automatically while paused
206 // Plus, the video sometimes doesn't redraw when it looses focus
207 // or is painted over so we just tell it to redraw...
208 - gst_x_overlay_expose(be->m_xoverlay);
209 + gst_video_overlay_expose(be->m_videooverlay);
210 }
211 else
212 {
213 @@ -334,7 +289,7 @@ static gint gtk_window_realize_callback(
214 GdkWindow* window = gtk_widget_get_window(widget);
215 wxASSERT(window);
216
217 - gst_x_overlay_set_xwindow_id( GST_X_OVERLAY(be->m_xoverlay),
218 + gst_video_overlay_set_window_handle( GST_VIDEO_OVERLAY(be->m_videooverlay),
219 GDK_WINDOW_XID(window)
220 );
221 GtkWidget* w = be->GetControl()->m_wxwindow;
222 @@ -349,30 +304,6 @@ static gint gtk_window_realize_callback(
223 #endif // wxGTK
224
225 //-----------------------------------------------------------------------------
226 -// "state-change" from m_playbin/GST_MESSAGE_STATE_CHANGE
227 -//
228 -// Called by gstreamer when the state changes - here we
229 -// send the appropriate corresponding wx event.
230 -//
231 -// 0.8 only as HandleStateChange does this in both versions
232 -//-----------------------------------------------------------------------------
233 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
234 -extern "C" {
235 -static void gst_state_change_callback(GstElement *play,
236 - GstElementState oldstate,
237 - GstElementState newstate,
238 - wxGStreamerMediaBackend* be)
239 -{
240 - if(be->m_asynclock.TryLock() == wxMUTEX_NO_ERROR)
241 - {
242 - be->HandleStateChange(oldstate, newstate);
243 - be->m_asynclock.Unlock();
244 - }
245 -}
246 -}
247 -#endif // <0.10
248 -
249 -//-----------------------------------------------------------------------------
250 // "eos" from m_playbin/GST_MESSAGE_EOS
251 //
252 // Called by gstreamer when the media is done playing ("end of stream")
253 @@ -425,69 +356,17 @@ static void gst_notify_caps_callback(Gst
254 }
255
256 //-----------------------------------------------------------------------------
257 -// "notify::stream-info" from m_playbin
258 -//
259 -// Run through the stuff in "stream-info" of m_playbin for a valid
260 -// video pad, and then attempt to query the video size from it - if not
261 -// set up an event to do so when ready.
262 -//
263 -// Currently unused - now we just query it directly using
264 -// QueryVideoSizeFromElement.
265 -//
266 -// (Undocumented?)
267 -//-----------------------------------------------------------------------------
268 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
269 -extern "C" {
270 -static void gst_notify_stream_info_callback(GstElement* WXUNUSED(element),
271 - GParamSpec* WXUNUSED(pspec),
272 - wxGStreamerMediaBackend* be)
273 -{
274 - wxLogTrace(wxTRACE_GStreamer, wxT("gst_notify_stream_info_callback"));
275 - be->QueryVideoSizeFromElement(be->m_playbin);
276 -}
277 -}
278 -#endif
279 -
280 -//-----------------------------------------------------------------------------
281 -// "desired-size-changed" from m_xoverlay
282 -//
283 -// 0.8-specific this provides us with the video size when it changes -
284 -// even though we get the caps as well this seems to come before the
285 -// caps notification does...
286 -//
287 -// Note it will return 16,16 for an early-bird value or for audio
288 -//-----------------------------------------------------------------------------
289 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
290 -extern "C" {
291 -static void gst_desired_size_changed_callback(GstElement * play,
292 - guint width, guint height,
293 - wxGStreamerMediaBackend* be)
294 -{
295 - if(!(width == 16 && height == 16))
296 - {
297 - be->m_videoSize.x = width;
298 - be->m_videoSize.y = height;
299 - }
300 - else
301 - be->QueryVideoSizeFromElement(be->m_playbin);
302 -}
303 -}
304 -#endif
305 -
306 -//-----------------------------------------------------------------------------
307 // gst_bus_async_callback [static]
308 // gst_bus_sync_callback [static]
309 //
310 -// Called by m_playbin for notifications such as end-of-stream in 0.10 -
311 -// in previous versions g_signal notifications were used. Because everything
312 +// Called by m_playbin for notifications such as end-of-stream. Because everything
313 // in centered in one switch statement though it reminds one of old WinAPI
314 // stuff.
315 //
316 // gst_bus_sync_callback is that sync version that is called on the main GUI
317 // thread before the async version that we use to set the xwindow id of the
318 -// XOverlay (NB: This isn't currently used - see CreateControl()).
319 +// VideoOverlay (NB: This isn't currently used - see CreateControl()).
320 //-----------------------------------------------------------------------------
321 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
322 extern "C" {
323 static gboolean gst_bus_async_callback(GstBus* WXUNUSED(bus),
324 GstMessage* message,
325 @@ -537,8 +416,7 @@ static GstBusSyncReply gst_bus_sync_call
326 {
327 // Pass a non-xwindowid-setting event on to the async handler where it
328 // belongs
329 - if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT ||
330 - !gst_structure_has_name (message->structure, "prepare-xwindow-id"))
331 + if (!gst_is_video_overlay_prepare_window_handle_message (message))
332 {
333 //
334 // NB: Unfortunately, the async callback can be quite
335 @@ -552,12 +430,11 @@ static GstBusSyncReply gst_bus_sync_call
336 return GST_BUS_DROP;
337 }
338
339 - wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-xwindow-id"));
340 - be->SetupXOverlay();
341 + wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-window-handle"));
342 + be->SetupVideoOverlay();
343 return GST_BUS_DROP; // We handled this message - drop from the queue
344 }
345 }
346 -#endif
347
348 //-----------------------------------------------------------------------------
349 //
350 @@ -569,11 +446,11 @@ static GstBusSyncReply gst_bus_sync_call
351 // wxGStreamerMediaBackend::HandleStateChange
352 //
353 // Handles a state change event from our C Callback for "state-change" or
354 -// the async queue in 0.10. (Mostly this is here to avoid locking the
355 +// the async queue . (Mostly this is here to avoid locking the
356 // the mutex twice...)
357 //-----------------------------------------------------------------------------
358 -void wxGStreamerMediaBackend::HandleStateChange(GstElementState oldstate,
359 - GstElementState newstate)
360 +void wxGStreamerMediaBackend::HandleStateChange(GstState oldstate,
361 + GstState newstate)
362 {
363 switch(newstate)
364 {
365 @@ -604,83 +481,13 @@ void wxGStreamerMediaBackend::HandleStat
366 }
367
368 //-----------------------------------------------------------------------------
369 -// wxGStreamerMediaBackend::QueryVideoSizeFromElement
370 -//
371 -// Run through the stuff in "stream-info" of element for a valid
372 -// video pad, and then attempt to query the video size from it - if not
373 -// set up an event to do so when ready. Return true
374 -// if we got a valid video pad.
375 -//-----------------------------------------------------------------------------
376 -bool wxGStreamerMediaBackend::QueryVideoSizeFromElement(GstElement* element)
377 -{
378 - const GList *list = NULL;
379 - g_object_get (G_OBJECT (element), "stream-info", &list, NULL);
380 -
381 - for ( ; list != NULL; list = list->next)
382 - {
383 - GObject *info = (GObject *) list->data;
384 - gint type;
385 - GParamSpec *pspec;
386 - GEnumValue *val;
387 - GstPad *pad = NULL;
388 -
389 - g_object_get (info, "type", &type, NULL);
390 - pspec = g_object_class_find_property (
391 - G_OBJECT_GET_CLASS (info), "type");
392 - val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
393 -
394 - if (!strncasecmp(val->value_name, "video", 5) ||
395 - !strncmp(val->value_name, "GST_STREAM_TYPE_VIDEO", 21))
396 - {
397 - // Newer gstreamer 0.8+ plugins are SUPPOSED to have "object"...
398 - // but a lot of old plugins still use "pad" :)
399 - pspec = g_object_class_find_property (
400 - G_OBJECT_GET_CLASS (info), "object");
401 -
402 - if (!pspec)
403 - g_object_get (info, "pad", &pad, NULL);
404 - else
405 - g_object_get (info, "object", &pad, NULL);
406 -
407 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR <= 8
408 - // Killed in 0.9, presumely because events and such
409 - // should be pushed on pads regardless of whether they
410 - // are currently linked
411 - pad = (GstPad *) GST_PAD_REALIZE (pad);
412 - wxASSERT(pad);
413 -#endif
414 -
415 - if(!QueryVideoSizeFromPad(pad))
416 - {
417 - // wait for those caps to get ready
418 - g_signal_connect(
419 - pad,
420 - "notify::caps",
421 - G_CALLBACK(gst_notify_caps_callback),
422 - this);
423 - }
424 - break;
425 - }// end if video
426 - }// end searching through info list
427 -
428 - // no video (or extremely delayed stream-info)
429 - if(list == NULL)
430 - {
431 - m_videoSize = wxSize(0,0);
432 - return false;
433 - }
434 -
435 - return true;
436 -}
437 -
438 -//-----------------------------------------------------------------------------
439 // wxGStreamerMediaBackend::QueryVideoSizeFromPad
440 //
441 // Gets the size of our video (in wxSize) from a GstPad
442 //-----------------------------------------------------------------------------
443 bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad)
444 {
445 - const GstCaps* caps = GST_PAD_CAPS(pad);
446 + GstCaps* caps = gst_pad_get_current_caps(pad);
447 if ( caps )
448 {
449 const GstStructure *s = gst_caps_get_structure (caps, 0);
450 @@ -706,23 +513,26 @@ bool wxGStreamerMediaBackend::QueryVideo
451 m_videoSize.y = (int) ((float) den * m_videoSize.y / num);
452 }
453
454 - wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"),
455 - m_videoSize.x, m_videoSize.y);
456 + wxLogTrace(wxTRACE_GStreamer, wxT("Adjusted video size: [%i,%i]"),
457 + m_videoSize.x, m_videoSize.y);
458 +
459 + gst_caps_unref (caps);
460 return true;
461 } // end if caps
462
463 + m_videoSize = wxSize(0,0);
464 return false; // not ready/massive failure
465 }
466
467 //-----------------------------------------------------------------------------
468 -// wxGStreamerMediaBackend::SetupXOverlay
469 +// wxGStreamerMediaBackend::SetupVideoOverlay
470 //
471 -// Attempts to set the XWindow id of our GstXOverlay to tell it which
472 +// Attempts to set the XWindow id of our GstVideoOverlay to tell it which
473 // window to play video in.
474 //-----------------------------------------------------------------------------
475 -void wxGStreamerMediaBackend::SetupXOverlay()
476 +void wxGStreamerMediaBackend::SetupVideoOverlay()
477 {
478 - // Use the xoverlay extension to tell gstreamer to play in our window
479 + // Use the videooverlay extension to tell gstreamer to play in our window
480 #ifdef __WXGTK__
481 if (!gtk_widget_get_realized(m_ctrl->m_wxwindow))
482 {
483 @@ -739,7 +549,7 @@ void wxGStreamerMediaBackend::SetupXOver
484 GdkWindow* window = gtk_widget_get_window(m_ctrl->m_wxwindow);
485 wxASSERT(window);
486 #endif
487 - gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_xoverlay),
488 + gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videooverlay),
489 #ifdef __WXGTK__
490 GDK_WINDOW_XID(window)
491 #else
492 @@ -769,9 +579,8 @@ void wxGStreamerMediaBackend::SetupXOver
493 //
494 // PRECONDITION: Assumes m_asynclock is Lock()ed
495 //-----------------------------------------------------------------------------
496 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
497 bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
498 - GstElementState desiredstate,
499 + GstState desiredstate,
500 gint64 llTimeout)
501 {
502 GstBus* bus = gst_element_get_bus(element);
503 @@ -844,23 +653,6 @@ bool wxGStreamerMediaBackend::SyncStateC
504
505 return bSuccess;
506 }
507 -#else // 0.8 implementation
508 -bool wxGStreamerMediaBackend::SyncStateChange(GstElement* element,
509 - GstElementState desiredstate,
510 - gint64 llTimeout)
511 -{
512 - gint64 llTimeWaited = 0;
513 - while(GST_STATE(element) != desiredstate)
514 - {
515 - if(llTimeWaited >= llTimeout)
516 - break;
517 - llTimeWaited += 10*GST_MSECOND;
518 - wxMilliSleep(10);
519 - }
520 -
521 - return llTimeWaited != llTimeout;
522 -}
523 -#endif
524
525 //-----------------------------------------------------------------------------
526 // wxGStreamerMediaBackend::TryAudioSink
527 @@ -884,25 +676,25 @@ bool wxGStreamerMediaBackend::TryAudioSi
528
529 bool wxGStreamerMediaBackend::TryVideoSink(GstElement* videosink)
530 {
531 - // Check if the video sink either is an xoverlay or might contain one...
532 - if( !GST_IS_BIN(videosink) && !GST_IS_X_OVERLAY(videosink) )
533 + // Check if the video sink either is an videooverlay or might contain one...
534 + if( !GST_IS_BIN(videosink) && !GST_IS_VIDEO_OVERLAY(videosink) )
535 {
536 if(G_IS_OBJECT(videosink))
537 g_object_unref(videosink);
538 return false;
539 }
540
541 - // Make our video sink and make sure it supports the x overlay interface
542 - // the x overlay enables us to put the video in our control window
543 + // Make our video sink and make sure it supports the video overlay interface
544 + // the video overlay enables us to put the video in our control window
545 // (i.e. we NEED it!) - also connect to the natural video size change event
546 if( GST_IS_BIN(videosink) )
547 - m_xoverlay = (GstXOverlay*)
548 + m_videooverlay = (GstVideoOverlay*)
549 gst_bin_get_by_interface (GST_BIN (videosink),
550 - GST_TYPE_X_OVERLAY);
551 + GST_TYPE_VIDEO_OVERLAY);
552 else
553 - m_xoverlay = (GstXOverlay*) videosink;
554 + m_videooverlay = (GstVideoOverlay*) videosink;
555
556 - if ( !GST_IS_X_OVERLAY(m_xoverlay) )
557 + if ( !GST_IS_VIDEO_OVERLAY(m_videooverlay) )
558 {
559 g_object_unref(videosink);
560 return false;
561 @@ -1046,11 +838,7 @@ bool wxGStreamerMediaBackend::CreateCont
562 //Really init gstreamer
563 gboolean bInited;
564 GError* error = NULL;
565 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
566 bInited = gst_init_check(&argcGST, &argvGST, &error);
567 -#else
568 - bInited = gst_init_check(&argcGST, &argvGST);
569 -#endif
570
571 // Cleanup arguments for unicode case
572 #if wxUSE_UNICODE
573 @@ -1117,78 +905,52 @@ bool wxGStreamerMediaBackend::CreateCont
574 return false;
575 }
576
577 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
578 - // Connect the glib events/callbacks we want to our playbin
579 - g_signal_connect(m_playbin, "eos",
580 - G_CALLBACK(gst_finish_callback), this);
581 - g_signal_connect(m_playbin, "error",
582 - G_CALLBACK(gst_error_callback), this);
583 - g_signal_connect(m_playbin, "state-change",
584 - G_CALLBACK(gst_state_change_callback), this);
585 -#else
586 - // GStreamer 0.10+ uses GstBus for this now, connect to the sync
587 - // handler as well so we can set the X window id of our xoverlay
588 + // GStreamer uses GstBus for this now, connect to the sync
589 + // handler as well so we can set the video window id of our videooverlay
590 gst_bus_add_watch (gst_element_get_bus(m_playbin),
591 (GstBusFunc) gst_bus_async_callback, this);
592 gst_bus_set_sync_handler(gst_element_get_bus(m_playbin),
593 - (GstBusSyncHandler) gst_bus_sync_callback, this);
594 - g_signal_connect(m_playbin, "notify::stream-info",
595 - G_CALLBACK(gst_notify_stream_info_callback), this);
596 -#endif
597 + (GstBusSyncHandler) gst_bus_sync_callback, this, NULL);
598
599 // Get the audio sink
600 - GstElement* audiosink = gst_gconf_get_default_audio_sink();
601 + // Use autodetection, then alsa, then oss as a stopgap
602 + GstElement* audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink");
603 if( !TryAudioSink(audiosink) )
604 {
605 - // fallback to autodetection, then alsa, then oss as a stopgap
606 - audiosink = gst_element_factory_make ("autoaudiosink", "audio-sink");
607 + audiosink = gst_element_factory_make ("alsasink", "alsa-output");
608 if( !TryAudioSink(audiosink) )
609 {
610 - audiosink = gst_element_factory_make ("alsasink", "alsa-output");
611 + audiosink = gst_element_factory_make ("osssink", "play_audio");
612 if( !TryAudioSink(audiosink) )
613 {
614 - audiosink = gst_element_factory_make ("osssink", "play_audio");
615 - if( !TryAudioSink(audiosink) )
616 - {
617 - wxLogSysError(wxT("Could not find a valid audiosink"));
618 - return false;
619 - }
620 + wxLogSysError(wxT("Could not find a valid audiosink"));
621 + return false;
622 }
623 }
624 }
625
626 // Setup video sink - first try gconf, then auto, then xvimage and
627 // then finally plain ximage
628 - GstElement* videosink = gst_gconf_get_default_video_sink();
629 + GstElement* videosink = gst_element_factory_make ("autovideosink", "video-sink");
630 if( !TryVideoSink(videosink) )
631 {
632 - videosink = gst_element_factory_make ("autovideosink", "video-sink");
633 + videosink = gst_element_factory_make ("xvimagesink", "video-sink");
634 if( !TryVideoSink(videosink) )
635 {
636 - videosink = gst_element_factory_make ("xvimagesink", "video-sink");
637 + // finally, do a final fallback to ximagesink
638 + videosink =
639 + gst_element_factory_make ("ximagesink", "video-sink");
640 if( !TryVideoSink(videosink) )
641 {
642 - // finally, do a final fallback to ximagesink
643 - videosink =
644 - gst_element_factory_make ("ximagesink", "video-sink");
645 - if( !TryVideoSink(videosink) )
646 - {
647 - g_object_unref(audiosink);
648 - wxLogSysError(wxT("Could not find a suitable video sink"));
649 - return false;
650 - }
651 + g_object_unref(audiosink);
652 + wxLogSysError(wxT("Could not find a suitable video sink"));
653 + return false;
654 }
655 }
656 }
657
658 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR < 10
659 - // Not on 0.10... called when video size changes
660 - g_signal_connect(m_xoverlay, "desired-size-changed",
661 - G_CALLBACK(gst_desired_size_changed_callback), this);
662 -#endif
663 - // Tell GStreamer which window to draw to in 0.8 - 0.10
664 - // sometimes needs this too...
665 - SetupXOverlay();
666 + // Tell GStreamer which window to draw to
667 + SetupVideoOverlay();
668
669 // Now that we know (or, rather think) our video and audio sink
670 // are valid set our playbin to use them
671 @@ -1197,6 +959,10 @@ bool wxGStreamerMediaBackend::CreateCont
672 "audio-sink", audiosink,
673 NULL);
674
675 + GstPad *video_sinkpad = gst_element_get_static_pad (videosink, "sink");
676 + g_signal_connect (video_sinkpad, "notify::caps", G_CALLBACK (gst_notify_caps_callback), this);
677 + gst_object_unref (video_sinkpad);
678 +
679 m_eventHandler = new wxGStreamerMediaEventHandler(this);
680 return true;
681 }
682 @@ -1213,26 +979,10 @@ bool wxGStreamerMediaBackend::Load(const
683
684 //-----------------------------------------------------------------------------
685 // wxGStreamerMediaBackend::Load (URI version)
686 -//
687 -// In the case of a file URI passes it unencoded -
688 -// also, as of 0.10.3 and earlier GstURI (the uri parser for gstreamer)
689 -// is sort of broken and only accepts uris with at least two slashes
690 -// after the scheme (i.e. file: == not ok, file:// == ok)
691 //-----------------------------------------------------------------------------
692 bool wxGStreamerMediaBackend::Load(const wxURI& location)
693 {
694 - if(location.GetScheme().CmpNoCase(wxT("file")) == 0)
695 - {
696 - wxString uristring = location.BuildUnescapedURI();
697 -
698 - //Workaround GstURI leading "//" problem and make sure it leads
699 - //with that
700 - return DoLoad(wxString(wxT("file://")) +
701 - uristring.Right(uristring.length() - 5)
702 - );
703 - }
704 - else
705 - return DoLoad(location.BuildURI());
706 + return DoLoad(location.BuildURI());
707 }
708
709 //-----------------------------------------------------------------------------
710 @@ -1258,7 +1008,7 @@ bool wxGStreamerMediaBackend::DoLoad(con
711
712 // Set playbin to ready to stop the current media...
713 if( gst_element_set_state (m_playbin,
714 - GST_STATE_READY) == GST_STATE_FAILURE ||
715 + GST_STATE_READY) == GST_STATE_CHANGE_FAILURE ||
716 !SyncStateChange(m_playbin, GST_STATE_READY))
717 {
718 CheckForErrors();
719 @@ -1281,7 +1031,7 @@ bool wxGStreamerMediaBackend::DoLoad(con
720 // Try to pause media as gstreamer won't let us query attributes
721 // such as video size unless it is paused or playing
722 if( gst_element_set_state (m_playbin,
723 - GST_STATE_PAUSED) == GST_STATE_FAILURE ||
724 + GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE ||
725 !SyncStateChange(m_playbin, GST_STATE_PAUSED))
726 {
727 CheckForErrors();
728 @@ -1307,12 +1057,11 @@ bool wxGStreamerMediaBackend::DoLoad(con
729 //
730 // Sets the stream to a playing state
731 //
732 -// THREAD-UNSAFE in 0.8, maybe in 0.10 as well
733 //-----------------------------------------------------------------------------
734 bool wxGStreamerMediaBackend::Play()
735 {
736 if (gst_element_set_state (m_playbin,
737 - GST_STATE_PLAYING) == GST_STATE_FAILURE)
738 + GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE)
739 {
740 CheckForErrors();
741 return false;
742 @@ -1326,13 +1075,12 @@ bool wxGStreamerMediaBackend::Play()
743 //
744 // Marks where we paused and pauses the stream
745 //
746 -// THREAD-UNSAFE in 0.8, maybe in 0.10 as well
747 //-----------------------------------------------------------------------------
748 bool wxGStreamerMediaBackend::Pause()
749 {
750 m_llPausedPos = wxGStreamerMediaBackend::GetPosition();
751 if (gst_element_set_state (m_playbin,
752 - GST_STATE_PAUSED) == GST_STATE_FAILURE)
753 + GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE)
754 {
755 CheckForErrors();
756 return false;
757 @@ -1353,7 +1101,7 @@ bool wxGStreamerMediaBackend::Stop()
758 { // begin state lock
759 wxMutexLocker lock(m_asynclock);
760 if(gst_element_set_state (m_playbin,
761 - GST_STATE_PAUSED) == GST_STATE_FAILURE ||
762 + GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE ||
763 !SyncStateChange(m_playbin, GST_STATE_PAUSED))
764 {
765 CheckForErrors();
766 @@ -1417,10 +1165,8 @@ wxLongLong wxGStreamerMediaBackend::GetP
767 else
768 {
769 gint64 pos;
770 - GstFormat fmtTime = GST_FORMAT_TIME;
771
772 - if (!wxGst_element_query_position(m_playbin, &fmtTime, &pos) ||
773 - fmtTime != GST_FORMAT_TIME || pos == -1)
774 + if (!gst_element_query_position(m_playbin, GST_FORMAT_TIME, &pos) || pos == -1)
775 return 0;
776 return pos / GST_MSECOND ;
777 }
778 @@ -1438,44 +1184,21 @@ wxLongLong wxGStreamerMediaBackend::GetP
779 // This is also an exceedingly ugly function due to the three implementations
780 // (or, rather two plus one implementation without a seek function).
781 //
782 -// This is asynchronous and thread-safe on both 0.8 and 0.10.
783 -//
784 // NB: This fires both a stop and play event if the media was previously
785 // playing... which in some ways makes sense. And yes, this makes the video
786 // go all haywire at times - a gstreamer bug...
787 //-----------------------------------------------------------------------------
788 bool wxGStreamerMediaBackend::SetPosition(wxLongLong where)
789 {
790 -#if GST_VERSION_MAJOR == 0 && GST_VERSION_MINOR == 8 \
791 - && GST_VERSION_MICRO == 0
792 - // 0.8.0 has no gst_element_seek according to official docs!!!
793 - wxLogSysError(wxT("GStreamer 0.8.0 does not have gst_element_seek")
794 - wxT(" according to official docs"));
795 - return false;
796 -#else // != 0.8.0
797 -
798 -# if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
799 - gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME,
800 + if ( gst_element_seek (m_playbin, m_dRate, GST_FORMAT_TIME,
801 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),
802 GST_SEEK_TYPE_SET, where.GetValue() * GST_MSECOND,
803 - GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE );
804 -# else
805 - // NB: Some gstreamer versions return false basically all the time
806 - // here - even totem doesn't bother to check the return value here
807 - // so I guess we'll just assume it worked -
808 - // TODO: maybe check the gst error callback???
809 - gst_element_seek (m_playbin, (GstSeekType) (GST_SEEK_METHOD_SET |
810 - GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH),
811 - where.GetValue() * GST_MSECOND );
812 -
813 -# endif // GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
814 -
815 + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE ) )
816 {
817 m_llPausedPos = where;
818 return true;
819 }
820 - return true;
821 -#endif //== 0.8.0
822 + return false;
823 }
824
825 //-----------------------------------------------------------------------------
826 @@ -1487,10 +1210,8 @@ bool wxGStreamerMediaBackend::SetPositio
827 wxLongLong wxGStreamerMediaBackend::GetDuration()
828 {
829 gint64 length;
830 - GstFormat fmtTime = GST_FORMAT_TIME;
831
832 - if(!wxGst_element_query_duration(m_playbin, &fmtTime, &length) ||
833 - fmtTime != GST_FORMAT_TIME || length == -1)
834 + if(!gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &length) || length == -1)
835 return 0;
836 return length / GST_MSECOND ;
837 }
838 @@ -1512,7 +1233,7 @@ void wxGStreamerMediaBackend::Move(int W
839 // wxGStreamerMediaBackend::GetVideoSize
840 //
841 // Returns our cached video size from Load/gst_notify_caps_callback
842 -// gst_x_overlay_get_desired_size also does this in 0.8...
843 +// gst_video_overlay_get_desired_size also does this in 0.8...
844 //-----------------------------------------------------------------------------
845 wxSize wxGStreamerMediaBackend::GetVideoSize() const
846 {
847 @@ -1539,9 +1260,8 @@ wxSize wxGStreamerMediaBackend::GetVideo
848 //TODO: forcing frame/samplerates, see audioscale and videorate. Audioscale is
849 //TODO: part of playbin.
850 //
851 -// In 0.10 GStreamer has new gst_element_seek API that might
852 -// support this - and I've got an attempt to do so but it is untested
853 -// but it would appear to work...
854 +// In has new gst_element_seek API that supports this - and I've got an attempt
855 +// to do so but it is untested but it would appear to work...
856 //-----------------------------------------------------------------------------
857 double wxGStreamerMediaBackend::GetPlaybackRate()
858 {
859 @@ -1552,7 +1272,6 @@ double wxGStreamerMediaBackend::GetPlayb
860
861 bool wxGStreamerMediaBackend::SetPlaybackRate(double dRate)
862 {
863 -#if GST_VERSION_MAJOR > 0 || GST_VERSION_MINOR >= 10
864 #if 0 // not tested enough
865 if( gst_element_seek (m_playbin, dRate, GST_FORMAT_TIME,
866 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT),
867 @@ -1565,7 +1284,6 @@ bool wxGStreamerMediaBackend::SetPlaybac
868 #else
869 wxUnusedVar(dRate);
870 #endif
871 -#endif
872
873 // failure
874 return false;
875 @@ -1593,10 +1311,8 @@ wxLongLong wxGStreamerMediaBackend::GetD
876 wxLongLong wxGStreamerMediaBackend::GetDownloadTotal()
877 {
878 gint64 length;
879 - GstFormat fmtBytes = GST_FORMAT_BYTES;
880
881 - if (!wxGst_element_query_duration(m_playbin, &fmtBytes, &length) ||
882 - fmtBytes != GST_FORMAT_BYTES || length == -1)
883 + if (!gst_element_query_duration(m_playbin, GST_FORMAT_BYTES, &length) || length == -1)
884 return 0;
885 return length;
886 }
|