banshee r3483 - in trunk/banshee: . build/m4/banshee libbanshee src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3483 - in trunk/banshee: . build/m4/banshee libbanshee src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying
- Date: Wed, 19 Mar 2008 04:54:17 +0000 (GMT)
Author: abock
Date: Wed Mar 19 04:54:17 2008
New Revision: 3483
URL: http://svn.gnome.org/viewvc/banshee?rev=3483&view=rev
Log:
2008-03-19 Aaron Bockover <abock gnome org>
* build/m4/banshee/gstreamer.m4: Link gstinterfaces and gstvideo libraries
* libbanshee/gst-playback-0.10.c: First pass at hopefully properly
implementing the GstXOverlay stuff; adds video rough video support
to the pipeline/player engine
* src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs:
* src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs:
* src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs:
Implement a few video related features to allow setting/exposing to a
GdkWindow for video support
* src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs:
Send the GdkWindow/Video calls into the player engine - binds the
pipeline XOverlay to a window in the UI
* src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/VideoDisplay.cs:
Managed GdkWindow and video slab display widget thingy that can be
drawn on by an engine
Modified:
trunk/banshee/ChangeLog
trunk/banshee/build/m4/banshee/gstreamer.m4
trunk/banshee/libbanshee/gst-playback-0.10.c
trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/VideoDisplay.cs
Modified: trunk/banshee/build/m4/banshee/gstreamer.m4
==============================================================================
--- trunk/banshee/build/m4/banshee/gstreamer.m4 (original)
+++ trunk/banshee/build/m4/banshee/gstreamer.m4 Wed Mar 19 04:54:17 2008
@@ -9,7 +9,9 @@
gstreamer-plugins-base-0.10 >= $GSTREAMER_REQUIRED_VERSION
gstreamer-controller-0.10 >= $GSTREAMER_REQUIRED_VERSION
gstreamer-dataprotocol-0.10 >= $GSTREAMER_REQUIRED_VERSION)
-
+
+ GST_LIBS="$GST_LIBS -lgstvideo-0.10 -lgstinterfaces-0.10"
+
PKG_CHECK_MODULES(GST_PBUTILS, gstreamer-plugins-base-0.10 >= 0.10.12,
gst_pbutils=yes, gst_pbutils=no)
Modified: trunk/banshee/libbanshee/gst-playback-0.10.c
==============================================================================
--- trunk/banshee/libbanshee/gst-playback-0.10.c (original)
+++ trunk/banshee/libbanshee/gst-playback-0.10.c Wed Mar 19 04:54:17 2008
@@ -46,6 +46,7 @@
#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
+#include <gst/interfaces/xoverlay.h>
#endif
#include "gst-tagger.h"
@@ -71,6 +72,13 @@
GstElement *equalizer;
GstElement *preamp;
+ GMutex *mutex;
+
+ #ifdef GDK_WINDOWING_X11
+ GstXOverlay *xoverlay;
+ GdkWindow *video_window;
+ #endif
+
guint iterate_timeout_id;
gchar *cdda_device;
@@ -93,6 +101,10 @@
#endif
};
+#ifdef GDK_WINDOWING_X11
+static gboolean gst_playback_find_xoverlay (GstPlayback *engine);
+#endif
+
// private methods
static void
@@ -384,10 +396,47 @@
return FALSE;
}
+static void
+gst_playback_video_sink_element_added (GstBin *videosink, GstElement *element, GstPlayback *engine)
+{
+ g_return_if_fail (IS_GST_PLAYBACK (engine));
+
+ #ifdef GDK_WINDOWING_X11
+ g_mutex_lock (engine->mutex);
+ gst_playback_find_xoverlay (engine);
+ g_mutex_unlock (engine->mutex);
+ #endif
+}
+
+static void
+gst_playback_bus_element_sync_message (GstBus *bus, GstMessage *message, GstPlayback *engine)
+{
+ gboolean found_xoverlay;
+
+ g_return_if_fail (IS_GST_PLAYBACK (engine));
+
+ #ifdef GDK_WINDOWING_X11
+
+ if (message->structure == NULL || !gst_structure_has_name (message->structure, "prepare-xwindow-id")) {
+ return;
+ }
+
+ g_mutex_lock (engine->mutex);
+ found_xoverlay = gst_playback_find_xoverlay (engine);
+ g_mutex_unlock (engine->mutex);
+
+ if (found_xoverlay) {
+ gst_x_overlay_set_xwindow_id (engine->xoverlay, GDK_WINDOW_XWINDOW (engine->video_window));
+ }
+
+ #endif
+}
+
static gboolean
gst_playback_construct(GstPlayback *engine)
{
- GstElement *fakesink;
+ GstBus *bus;
+ GstElement *videosink;
GstElement *audiosink;
GstElement *audiosinkqueue;
GstElement *audioconvert;
@@ -446,23 +495,42 @@
gst_element_link(engine->preamp, engine->equalizer);
gst_element_link(engine->equalizer, audioconvert);
gst_element_link(audioconvert, audiosink);
- }
- else
- {
+ } else {
// link the queue with the real audio sink
gst_element_link(audiosinkqueue, audiosink);
}
- g_object_set(G_OBJECT(engine->playbin), "audio-sink", engine->audiobin, NULL);
+ g_object_set (G_OBJECT (engine->playbin), "audio-sink", engine->audiobin, NULL);
+
+ videosink = gst_element_factory_make ("gconfvideosink", "videosink");
+ if (videosink == NULL) {
+ videosink = gst_element_factory_make ("ximagesink", "videosink");
+ if (videosink == NULL) {
+ videosink = gst_element_factory_make ("fakesink", "videosink");
+ if (videosink != NULL) {
+ g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
+ }
+ }
+ }
+
+ g_object_set (G_OBJECT (engine->playbin), "video-sink", videosink, NULL);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (engine->playbin));
- fakesink = gst_element_factory_make("fakesink", "fakesink");
- g_object_set(G_OBJECT(engine->playbin), "video-sink", fakesink, NULL);
+ gst_bus_add_watch (bus, gst_playback_bus_callback, engine);
+ gst_bus_set_sync_handler (bus, gst_bus_sync_signal_handler, engine);
+
+ g_signal_connect (bus, "sync-message::element",
+ G_CALLBACK (gst_playback_bus_element_sync_message), engine);
+
+ g_signal_connect (engine->playbin, "notify::source",
+ G_CALLBACK (gst_playback_on_notify_source_cb), engine);
+
+ if (GST_IS_BIN (videosink)) {
+ g_signal_connect (videosink, "element-added",
+ G_CALLBACK (gst_playback_video_sink_element_added), engine);
+ }
- gst_bus_add_watch(gst_pipeline_get_bus(GST_PIPELINE(engine->playbin)),
- gst_playback_bus_callback, engine);
-
- g_signal_connect(engine->playbin, "notify::source", G_CALLBACK(gst_playback_on_notify_source_cb), engine);
-
return TRUE;
}
@@ -510,6 +578,9 @@
gst_playback_new()
{
GstPlayback *engine = g_new0(GstPlayback, 1);
+
+ engine->mutex = g_mutex_new ();
+
if(!gst_playback_construct(engine)) {
g_free(engine);
return NULL;
@@ -523,6 +594,8 @@
{
g_return_if_fail(IS_GST_PLAYBACK(engine));
+ g_mutex_free (engine->mutex);
+
if(GST_IS_OBJECT(engine->playbin)) {
engine->target_state = GST_STATE_NULL;
gst_element_set_state(engine->playbin, GST_STATE_NULL);
@@ -770,7 +843,7 @@
}
void
-gst_playback_set_gdk_window(GstPlayback *engine, GdkWindow *window)
+gst_playback_set_application_gdk_window(GstPlayback *engine, GdkWindow *window)
{
engine->window = window;
}
@@ -784,10 +857,116 @@
*stream = GST_STREAM_ERROR;
}
+/* Region XOverlay */
+
+#ifdef GDK_WINDOWING_X11
+
+gboolean
+gst_playback_video_is_supported (GstPlayback *engine)
+{
+ return TRUE; // gst_playback_find_xoverlay (engine);
+}
+
+static gboolean
+gst_playback_find_xoverlay (GstPlayback *engine)
+{
+ GstElement *video_sink = NULL;
+ GstElement *xoverlay;
+ GstXOverlay *previous_xoverlay;
+
+ previous_xoverlay = engine->xoverlay;
+
+ g_object_get (engine->playbin, "video-sink", &video_sink, NULL);
+
+ if (video_sink == NULL) {
+ engine->xoverlay = NULL;
+ if (previous_xoverlay != NULL) {
+ gst_object_unref (previous_xoverlay);
+ }
+
+ return FALSE;
+ }
+
+ xoverlay = GST_IS_BIN (video_sink)
+ ? gst_bin_get_by_interface (GST_BIN (video_sink), GST_TYPE_X_OVERLAY)
+ : video_sink;
+
+ engine->xoverlay = GST_IS_X_OVERLAY (xoverlay) ? GST_X_OVERLAY (xoverlay) : NULL;
+
+ if (previous_xoverlay != NULL) {
+ gst_object_unref (previous_xoverlay);
+ }
+
+ if (engine->xoverlay != NULL && g_object_class_find_property (
+ G_OBJECT_GET_CLASS (engine->xoverlay), "force-aspect-ratio")) {
+ g_object_set (G_OBJECT (engine->xoverlay), "force-aspect-ratio", TRUE, NULL);
+ }
+
+ gst_object_unref (video_sink);
+
+ return engine->xoverlay != NULL;
+}
+
+void
+gst_playback_set_video_window (GstPlayback *engine, GdkWindow *window)
+{
+ engine->video_window = window;
+}
+
+void
+gst_playback_expose_video_window (GstPlayback *engine, GdkWindow *window, gboolean direct)
+{
+ XID window_id;
+
+ if (direct && engine->xoverlay != NULL && GST_IS_X_OVERLAY (engine->xoverlay)) {
+ gst_x_overlay_expose (engine->xoverlay);
+ return;
+ }
+
+ g_mutex_lock (engine->mutex);
+
+ if (engine->xoverlay == NULL && !gst_playback_find_xoverlay (engine)) {
+ g_mutex_unlock (engine->mutex);
+ return;
+ }
+
+ gst_object_ref (engine->xoverlay);
+ g_mutex_unlock (engine->mutex);
+
+ window_id = GDK_WINDOW_XWINDOW (window);
+
+ gst_x_overlay_set_xwindow_id (engine->xoverlay, window_id);
+ gst_x_overlay_expose (engine->xoverlay);
+
+ gst_object_unref (engine->xoverlay);
+}
+
+#else
+
+gboolean
+gst_playback_video_is_supported (GstPlayback *engine)
+{
+ return FALSE;
+}
+
+void
+gst_playback_set_video_window (GstPlayback *engine, GdkWindow *window)
+{
+}
+
+void
+gst_playback_expose_video_window (GstPlayback *engine, GdkWindow *window, gboolean direct)
+{
+}
+
+#endif
+
+/* Region Equalizer */
+
gboolean
gst_equalizer_is_supported(GstPlayback *engine)
{
- return (engine != NULL && engine->equalizer != NULL && engine->preamp != NULL);
+ return engine != NULL && engine->equalizer != NULL && engine->preamp != NULL;
}
void
Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs (original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs Wed Mar 19 04:54:17 2008
@@ -137,7 +137,7 @@
IPropertyStoreExpose service = ServiceManager.Get<IService> ("GtkElementsService") as IPropertyStoreExpose;
if (service != null) {
- gst_playback_set_gdk_window (handle, service.PropertyStore.Get<IntPtr> ("PrimaryWindow.RawHandle"));
+ gst_playback_set_application_gdk_window (handle, service.PropertyStore.Get<IntPtr> ("PrimaryWindow.RawHandle"));
}
IntPtr uri_ptr = GLib.Marshaller.StringToPtrGStrdup (uri.AbsoluteUri);
@@ -156,6 +156,11 @@
gst_playback_pause (handle);
OnStateChanged (PlayerEngineState.Paused);
}
+
+ public override void VideoExpose (IntPtr window, bool direct)
+ {
+ gst_playback_expose_video_window (handle, window, direct);
+ }
public override IntPtr [] GetBaseElements ()
{
@@ -312,14 +317,35 @@
get { return "GStreamer 0.10"; }
}
+ private bool? supports_equalizer = null;
public override bool SupportsEqualizer {
- get { return gst_equalizer_is_supported (handle); }
+ get {
+ if (supports_equalizer == null) {
+ supports_equalizer = gst_equalizer_is_supported (handle);
+ }
+
+ return supports_equalizer.Value;
+ }
+ }
+
+ private bool? supports_video = null;
+ public override bool SupportsVideo {
+ get {
+ if (supports_video == null) {
+ supports_video = gst_playback_video_is_supported (handle);
+ }
+
+ return supports_video.Value;
+ }
}
-
+
+ public override IntPtr VideoWindow {
+ set { gst_playback_set_video_window (handle, value); }
+ }
+
public double AmplifierLevel {
set {
- double db = Math.Pow (10.0, value/20.0);
-
+ double db = Math.Pow (10.0, value / 20.0);
gst_equalizer_set_preamp_level (handle, db);
}
}
@@ -427,7 +453,16 @@
out IntPtr audiobin, out IntPtr audiotee);
[DllImport ("libbanshee")]
- private static extern void gst_playback_set_gdk_window (HandleRef engine, IntPtr window);
+ private static extern void gst_playback_set_application_gdk_window (HandleRef engine, IntPtr window);
+
+ [DllImport ("libbanshee")]
+ private static extern bool gst_playback_video_is_supported (HandleRef engine);
+
+ [DllImport ("libbanshee")]
+ private static extern void gst_playback_set_video_window (HandleRef engine, IntPtr window);
+
+ [DllImport ("libbanshee")]
+ private static extern void gst_playback_expose_video_window (HandleRef engine, IntPtr window, bool direct);
[DllImport ("libbanshee")]
private static extern void gst_playback_get_error_quarks (out uint core, out uint library,
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs Wed Mar 19 04:54:17 2008
@@ -62,6 +62,10 @@
get { return false; }
}
+ public override bool SupportsVideo {
+ get { return false; }
+ }
+
private static string [] source_capabilities = { "file", "http", "cdda" };
public override IEnumerable SourceCapabilities {
get { return source_capabilities; }
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs Wed Mar 19 04:54:17 2008
@@ -111,6 +111,11 @@
OnStateChanged (PlayerEngineState.Paused);
}
+ public virtual void VideoExpose (IntPtr window, bool direct)
+ {
+ throw new NotImplementedException ("Engine must implement VideoExpose since this method only gets called when SupportsVideo is true");
+ }
+
public virtual IntPtr [] GetBaseElements ()
{
return null;
@@ -273,5 +278,13 @@
public abstract bool SupportsEqualizer {
get;
}
+
+ public abstract bool SupportsVideo {
+ get;
+ }
+
+ public virtual IntPtr VideoWindow {
+ set { }
+ }
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs Wed Mar 19 04:54:17 2008
@@ -354,6 +354,15 @@
}
}
+ public void VideoExpose (IntPtr window, bool direct)
+ {
+ active_engine.VideoExpose (window, direct);
+ }
+
+ public IntPtr VideoWindow {
+ set { active_engine.VideoWindow = value; }
+ }
+
public void TrackInfoUpdated ()
{
active_engine.TrackInfoUpdated ();
@@ -435,6 +444,10 @@
get { return ((active_engine is IEqualizer) && active_engine.SupportsEqualizer); }
}
+ public bool SupportsVideo {
+ get { return active_engine.SupportsVideo; }
+ }
+
public uint Length {
get {
uint length = active_engine.Length;
Modified: trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/VideoDisplay.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/VideoDisplay.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/VideoDisplay.cs Wed Mar 19 04:54:17 2008
@@ -30,37 +30,31 @@
using Gtk;
using Banshee.Gui;
+using Banshee.MediaEngine;
+using Banshee.ServiceStack;
namespace Banshee.NowPlaying
{
public class VideoDisplay : Gtk.Widget
{
private Gdk.Pixbuf idle_pixbuf;
+ private Gdk.Window video_window;
public VideoDisplay ()
{
+ CreateVideoWindow ();
}
- protected override void OnRealized ()
+ private void CreateVideoWindow ()
{
- WidgetFlags |= WidgetFlags.Realized;
-
Gdk.WindowAttr attributes = new Gdk.WindowAttr ();
attributes.WindowType = Gdk.WindowType.Child;
- attributes.X = Allocation.X;
- attributes.Y = Allocation.Y;
- attributes.Width = Allocation.Width;
- attributes.Height = Allocation.Height;
attributes.Visual = Visual;
attributes.Wclass = Gdk.WindowClass.InputOutput;
attributes.Colormap = Colormap;
attributes.EventMask = (int)(
Gdk.EventMask.VisibilityNotifyMask |
- Gdk.EventMask.ExposureMask |
- Gdk.EventMask.PointerMotionMask |
- Gdk.EventMask.EnterNotifyMask |
- Gdk.EventMask.LeaveNotifyMask |
- Events);
+ Gdk.EventMask.ExposureMask);
Gdk.WindowAttributesType attributes_mask =
Gdk.WindowAttributesType.X |
@@ -68,11 +62,35 @@
Gdk.WindowAttributesType.Visual |
Gdk.WindowAttributesType.Colormap;
+ video_window = new Gdk.Window (null, attributes, attributes_mask);
+ video_window.UserData = Handle;
+
+ video_window.SetBackPixmap (null, false);
+ Style = Style.Attach (video_window);
+
+ ServiceManager.PlayerEngine.VideoWindow = video_window.Handle;
+ }
+
+ protected override void OnRealized ()
+ {
+ WidgetFlags |= WidgetFlags.Realized;
+
+ Gdk.WindowAttr attributes = new Gdk.WindowAttr ();
+ attributes.WindowType = Gdk.WindowType.Child;
+ attributes.X = Allocation.X;
+ attributes.Y = Allocation.Y;
+ attributes.Width = Allocation.Width;
+ attributes.Height = Allocation.Height;
+ attributes.Wclass = Gdk.WindowClass.InputOnly;
+
+ Gdk.WindowAttributesType attributes_mask =
+ Gdk.WindowAttributesType.X |
+ Gdk.WindowAttributesType.Y;
+
GdkWindow = new Gdk.Window (Parent.GdkWindow, attributes, attributes_mask);
GdkWindow.UserData = Handle;
- GdkWindow.SetBackPixmap (null, false);
- Style = Style.Attach (GdkWindow);
+ video_window.Reparent (Parent.GdkWindow, Allocation.X, Allocation.Y);
}
protected override void OnUnrealized ()
@@ -80,17 +98,20 @@
WidgetFlags ^= WidgetFlags.Realized;
GdkWindow.UserData = IntPtr.Zero;
GdkWindow.Destroy ();
+ video_window.Reparent (null, 0, 0);
}
protected override void OnMapped ()
{
WidgetFlags |= WidgetFlags.Mapped;
+ video_window.Show ();
GdkWindow.Show ();
}
protected override void OnUnmapped ()
{
WidgetFlags ^= WidgetFlags.Mapped;
+ video_window.Hide ();
GdkWindow.Hide ();
}
@@ -98,16 +119,31 @@
{
base.OnSizeAllocated (allocation);
- if (IsRealized) {
+ if (IsRealized && IsMapped) {
+ video_window.MoveResize (allocation);
GdkWindow.MoveResize (allocation);
}
QueueDraw ();
}
+ protected override bool OnConfigureEvent (Gdk.EventConfigure evnt)
+ {
+ if (ServiceManager.PlayerEngine.SupportsVideo) {
+ ServiceManager.PlayerEngine.VideoExpose (video_window.Handle, true);
+ }
+
+ return false;
+ }
+
protected override bool OnExposeEvent (Gdk.EventExpose evnt)
{
- if (!Visible || !IsMapped || GdkWindow == null) {
+ if (!Visible || !IsMapped || video_window == null) {
+ return true;
+ }
+
+ if (ServiceManager.PlayerEngine.SupportsVideo) {
+ ServiceManager.PlayerEngine.VideoExpose (video_window.Handle, false);
return true;
}
@@ -119,7 +155,7 @@
return true;
}
- GdkWindow.DrawPixbuf (Style.BackgroundGC (StateType.Normal), idle_pixbuf, 0, 0,
+ video_window.DrawPixbuf (Style.BackgroundGC (StateType.Normal), idle_pixbuf, 0, 0,
(Allocation.Width - idle_pixbuf.Width) / 2, (Allocation.Height - idle_pixbuf.Height) / 2,
idle_pixbuf.Width, idle_pixbuf.Height, Gdk.RgbDither.Normal, 0, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]