[banshee/stable-1.6] [XOverlay] fix video embed bnc#585817, bgo#548635
- From: Aaron Bockover <abock src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee/stable-1.6] [XOverlay] fix video embed bnc#585817, bgo#548635
- Date: Sat, 1 May 2010 20:30:31 +0000 (UTC)
commit 9330060c208271bc0213bc13c94adae3ba275c4a
Author: Aaron Bockover <abockover novell com>
Date: Sat May 1 16:19:34 2010 -0400
[XOverlay] fix video embed bnc#585817, bgo#548635
GStreamer requires an X11 window handle to be set on the XOverlay
interface of the video sink in order to render video. If one is not set
in time, GStreamer will create its own X window. Closing this window
will result in a crash, since it becomes unrealized, after which
GStreamer will continue to try to render to it.
Before, the X11 video window was created when the Now Playing UI
was realized. The window is now created when the pipeline is created, by
raising the new PrepareVideoWindow event. Technically, this event should
be raised when the prepare-xwindow-id message is pushed onto the
pipeline bus, but this is raised out of the main thread.
libbanshee/banshee-player-private.h | 2 +
libbanshee/banshee-player-video.c | 10 ++++++
.../Banshee.GStreamer/PlayerEngine.cs | 13 +++++++
.../Banshee.MediaEngine/PlayerEngine.cs | 1 +
.../Banshee.MediaEngine/PlayerEngineService.cs | 3 +-
.../Banshee.MediaEngine/PlayerEvent.cs | 3 +-
.../Banshee.NowPlaying/NowPlayingContents.cs | 12 ++++++-
.../Banshee.NowPlaying/NowPlayingSource.cs | 7 ++++
.../Banshee.NowPlaying/XOverlayVideoDisplay.cs | 35 +++++++++++--------
9 files changed, 67 insertions(+), 19 deletions(-)
---
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index 7145b1f..1b69d6f 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -86,6 +86,7 @@ typedef void (* BansheePlayerVisDataCallback) (BansheePlayer *player, gint
typedef void (* BansheePlayerNextTrackStartingCallback) (BansheePlayer *player);
typedef void (* BansheePlayerAboutToFinishCallback) (BansheePlayer *player);
typedef GstElement * (* BansheePlayerVideoPipelineSetupCallback) (BansheePlayer *player, GstBus *bus);
+typedef void (* BansheePlayerVideoPrepareWindowCallback) (BansheePlayer *player);
typedef void (* BansheePlayerVolumeChangedCallback) (BansheePlayer *player, gdouble new_volume);
typedef enum {
@@ -106,6 +107,7 @@ struct BansheePlayer {
BansheePlayerNextTrackStartingCallback next_track_starting_cb;
BansheePlayerAboutToFinishCallback about_to_finish_cb;
BansheePlayerVideoPipelineSetupCallback video_pipeline_setup_cb;
+ BansheePlayerVideoPrepareWindowCallback video_prepare_window_cb;
BansheePlayerVolumeChangedCallback volume_changed_cb;
// Pipeline Elements
diff --git a/libbanshee/banshee-player-video.c b/libbanshee/banshee-player-video.c
index cb36fd6..f34dc21 100644
--- a/libbanshee/banshee-player-video.c
+++ b/libbanshee/banshee-player-video.c
@@ -178,6 +178,10 @@ _bp_video_pipeline_setup (BansheePlayer *player, GstBus *bus)
#endif
#endif
+
+ if (player->video_prepare_window_cb != NULL) {
+ player->video_prepare_window_cb (player);
+ }
}
P_INVOKE void
@@ -186,6 +190,12 @@ bp_set_video_pipeline_setup_callback (BansheePlayer *player, BansheePlayerVideoP
SET_CALLBACK (video_pipeline_setup_cb);
}
+P_INVOKE void
+bp_set_video_prepare_window_callback (BansheePlayer *player, BansheePlayerVideoPrepareWindowCallback cb)
+{
+ SET_CALLBACK (video_prepare_window_cb);
+}
+
// ---------------------------------------------------------------------------
// Public Functions
// ---------------------------------------------------------------------------
diff --git a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
index 8d2b979..f17812d 100644
--- a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
+++ b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
@@ -61,6 +61,7 @@ namespace Banshee.GStreamer
internal delegate void BansheePlayerNextTrackStartingCallback (IntPtr player);
internal delegate void BansheePlayerAboutToFinishCallback (IntPtr player);
internal delegate IntPtr VideoPipelineSetupHandler (IntPtr player, IntPtr bus);
+ internal delegate void VideoPrepareWindowHandler (IntPtr player);
internal delegate void BansheePlayerVolumeChangedCallback (IntPtr player, double newVolume);
internal delegate void GstTaggerTagFoundCallback (IntPtr player, string tagName, ref GLib.Value value);
@@ -85,6 +86,7 @@ namespace Banshee.GStreamer
private BansheePlayerBufferingCallback buffering_callback;
private BansheePlayerVisDataCallback vis_data_callback;
private VideoPipelineSetupHandler video_pipeline_setup_callback;
+ private VideoPrepareWindowHandler video_prepare_window_callback;
private GstTaggerTagFoundCallback tag_found_callback;
private BansheePlayerNextTrackStartingCallback next_track_starting_callback;
private BansheePlayerAboutToFinishCallback about_to_finish_callback;
@@ -149,6 +151,7 @@ namespace Banshee.GStreamer
buffering_callback = new BansheePlayerBufferingCallback (OnBuffering);
vis_data_callback = new BansheePlayerVisDataCallback (OnVisualizationData);
video_pipeline_setup_callback = new VideoPipelineSetupHandler (OnVideoPipelineSetup);
+ video_prepare_window_callback = new VideoPrepareWindowHandler (OnVideoPrepareWindow);
tag_found_callback = new GstTaggerTagFoundCallback (OnTagFound);
next_track_starting_callback = new BansheePlayerNextTrackStartingCallback (OnNextTrackStarting);
about_to_finish_callback = new BansheePlayerAboutToFinishCallback (OnAboutToFinish);
@@ -163,6 +166,7 @@ namespace Banshee.GStreamer
bp_set_tag_found_callback (handle, tag_found_callback);
bp_set_next_track_starting_callback (handle, next_track_starting_callback);
bp_set_video_pipeline_setup_callback (handle, video_pipeline_setup_callback);
+ bp_set_video_prepare_window_callback (handle, video_prepare_window_callback);
bp_set_volume_changed_callback (handle, volume_changed_callback);
next_track_set = new EventWaitHandle (false, EventResetMode.ManualReset);
@@ -686,6 +690,11 @@ namespace Banshee.GStreamer
return clutter_video_sink;
}
+ private void OnVideoPrepareWindow (IntPtr player)
+ {
+ OnEventChanged (PlayerEvent.PrepareVideoWindow);
+ }
+
#endregion
#region Preferences
@@ -785,6 +794,10 @@ namespace Banshee.GStreamer
GstTaggerTagFoundCallback cb);
[DllImport ("libbanshee.dll")]
+ private static extern void bp_set_video_prepare_window_callback (HandleRef player,
+ VideoPrepareWindowHandler cb);
+
+ [DllImport ("libbanshee.dll")]
private static extern void bp_set_next_track_starting_callback (HandleRef player,
BansheePlayerNextTrackStartingCallback cb);
diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
index d5006cb..2c1fd80 100644
--- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
+++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
@@ -220,6 +220,7 @@ namespace Banshee.MediaEngine
pending_track = null;
pending_uri = null;
}
+
if (ThreadAssist.InMainThread) {
RaiseEventChanged (args);
} else {
diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
index 79ec1f8..48652af 100644
--- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
+++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
@@ -691,7 +691,8 @@ namespace Banshee.MediaEngine
| PlayerEvent.Volume
| PlayerEvent.Metadata
| PlayerEvent.TrackInfoUpdated
- | PlayerEvent.RequestNextTrack;
+ | PlayerEvent.RequestNextTrack
+ | PlayerEvent.PrepareVideoWindow;
private const PlayerEvent event_default_mask = event_all_mask & ~PlayerEvent.Iterate;
diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEvent.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEvent.cs
index a5c714f..92f09da 100644
--- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEvent.cs
+++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEvent.cs
@@ -109,7 +109,8 @@ namespace Banshee.MediaEngine
Volume = 128,
Metadata = 256,
TrackInfoUpdated = 512,
- RequestNextTrack = 1024
+ RequestNextTrack = 1024,
+ PrepareVideoWindow = 2048
}
public enum PlayerState
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingContents.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingContents.cs
index f411eaf..04721af 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingContents.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingContents.cs
@@ -35,8 +35,16 @@ namespace Banshee.NowPlaying
{
public class NowPlayingContents : EventBox, IDisposable
{
+ private static Widget video_display;
+
+ public static void CreateVideoDisplay ()
+ {
+ if (video_display == null) {
+ video_display = new XOverlayVideoDisplay ();
+ }
+ }
+
private Table table;
- private Widget video_display;
private Widget substitute_audio_display;
private bool video_display_initial_shown = false;
@@ -49,7 +57,7 @@ namespace Banshee.NowPlaying
table.NoShowAll = true;
- video_display = new XOverlayVideoDisplay ();
+ CreateVideoDisplay ();
IVideoDisplay ivideo_display = video_display as IVideoDisplay;
if (ivideo_display != null) {
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
index 04ee475..c4d15bb 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
@@ -58,6 +58,13 @@ namespace Banshee.NowPlaying
ServiceManager.PlaybackController.Transition += OnPlaybackControllerTransition;
ServiceManager.PlaybackController.TrackStarted += OnPlaybackControllerTrackStarted;
ServiceManager.PlayerEngine.ConnectEvent (OnTrackInfoUpdated, PlayerEvent.TrackInfoUpdated);
+ ServiceManager.PlayerEngine.ConnectEvent (OnCreateVideoWindow, PlayerEvent.PrepareVideoWindow);
+ }
+
+ private void OnCreateVideoWindow (PlayerEventArgs args)
+ {
+ ServiceManager.PlayerEngine.DisconnectEvent (OnCreateVideoWindow);
+ NowPlayingContents.CreateVideoDisplay ();
}
public void Dispose ()
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/XOverlayVideoDisplay.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/XOverlayVideoDisplay.cs
index c365db5..de924f5 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/XOverlayVideoDisplay.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/XOverlayVideoDisplay.cs
@@ -44,31 +44,36 @@ namespace Banshee.NowPlaying
public XOverlayVideoDisplay () : base ()
{
WidgetFlags = WidgetFlags.NoWindow;
+ CreateVideoWindow ();
}
protected override void OnRealized ()
{
WidgetFlags |= WidgetFlags.Realized;
-
+ CreateVideoWindow ();
GdkWindow = Parent.GdkWindow;
+ video_window.Reparent (GdkWindow, 0, 0);
+ video_window.MoveResize (Allocation.X, Allocation.Y, Allocation.Width, Allocation.Height);
+ video_window.ShowUnraised ();
+ }
+ private void CreateVideoWindow ()
+ {
if (video_window != null) {
- video_window.Reparent (GdkWindow, 0, 0);
- video_window.MoveResize (Allocation.X, Allocation.Y, Allocation.Width, Allocation.Height);
- video_window.ShowUnraised ();
return;
}
- Gdk.WindowAttr attributes = new Gdk.WindowAttr ();
- attributes.WindowType = Gdk.WindowType.Child;
- attributes.X = 0;
- attributes.Y = 0;
- attributes.Width = Allocation.Width;
- attributes.Height = Allocation.Height;
- attributes.Visual = Visual;
- attributes.Wclass = Gdk.WindowClass.InputOutput;
- attributes.Colormap = Colormap;
- attributes.EventMask = (int)(Gdk.EventMask.ExposureMask | Gdk.EventMask.VisibilityNotifyMask);
+ var attributes = new Gdk.WindowAttr () {
+ WindowType = Gdk.WindowType.Child,
+ X = 0,
+ Y = 0,
+ Width = 0,
+ Height = 0,
+ Visual = Visual,
+ Wclass = Gdk.WindowClass.InputOutput,
+ Colormap = Colormap,
+ EventMask = (int)(Gdk.EventMask.ExposureMask | Gdk.EventMask.VisibilityNotifyMask)
+ };
Gdk.WindowAttributesType attributes_mask =
Gdk.WindowAttributesType.X |
@@ -76,7 +81,7 @@ namespace Banshee.NowPlaying
Gdk.WindowAttributesType.Visual |
Gdk.WindowAttributesType.Colormap;
- video_window = new Gdk.Window (GdkWindow, attributes, attributes_mask);
+ video_window = new Gdk.Window (null, attributes, attributes_mask);
video_window.UserData = Handle;
video_window.SetBackPixmap (null, false);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]