banshee r3632 - in trunk/banshee: . libbanshee src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Extensions
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3632 - in trunk/banshee: . libbanshee src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Extensions
- Date: Tue, 1 Apr 2008 00:36:24 +0100 (BST)
Author: abock
Date: Tue Apr 1 00:36:23 2008
New Revision: 3632
URL: http://svn.gnome.org/viewvc/banshee?rev=3632&view=rev
Log:
2008-03-31 Aaron Bockover <abock gnome org>
* libbanshee/banshee-player-cdda.c:
* libbanshee/banshee-player-cdda.h:
* libbanshee/banshee-player-equalizer.c:
* libbanshee/banshee-player-missing-elements.c:
* libbanshee/banshee-player-missing-elements.h:
* libbanshee/banshee-player-pipeline.c:
* libbanshee/banshee-player-pipeline.h:
* libbanshee/banshee-player-private.h:
* libbanshee/banshee-player-video.h:
* libbanshee/banshee-player.c:
* libbanshee/banshee-player.h: Hopefully the last big round of changes
to the player engine; moved the main pipeline and equalizer code into
separate modules so banshee-player is basically just the p/invokable
'public' API and doesn't contain much logic at all
* src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs:
Updated to reflect API changes in libbanshee
Added:
trunk/banshee/libbanshee/banshee-player-equalizer.c
trunk/banshee/libbanshee/banshee-player-pipeline.c
trunk/banshee/libbanshee/banshee-player-pipeline.h
trunk/banshee/libbanshee/banshee-player-private.h
- copied, changed from r3627, /trunk/banshee/libbanshee/banshee-player.h
Removed:
trunk/banshee/libbanshee/banshee-player.h
Modified:
trunk/banshee/ChangeLog
trunk/banshee/libbanshee/Makefile.am
trunk/banshee/libbanshee/banshee-player-cdda.c
trunk/banshee/libbanshee/banshee-player-cdda.h
trunk/banshee/libbanshee/banshee-player-missing-elements.c
trunk/banshee/libbanshee/banshee-player-missing-elements.h
trunk/banshee/libbanshee/banshee-player-video.h
trunk/banshee/libbanshee/banshee-player.c
trunk/banshee/libbanshee/libbanshee.mdp
trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
trunk/banshee/src/Extensions/Extensions.mds
Modified: trunk/banshee/libbanshee/Makefile.am
==============================================================================
--- trunk/banshee/libbanshee/Makefile.am (original)
+++ trunk/banshee/libbanshee/Makefile.am Tue Apr 1 00:36:23 2008
@@ -3,6 +3,7 @@
-Wall \
-ggdb3 \
-D_FORTIFY_SOURCE=2 \
+ -DINSIDE_LIBBANSHEE_I_SWEAR \
$(LIBBANSHEE_CFLAGS) \
$(GST_CFLAGS) \
$(LIBNAUTILUS_BURN_CFLAGS)
@@ -14,16 +15,19 @@
libbanshee_la_SOURCES = \
banshee-player.c \
banshee-player-cdda.c \
+ banshee-player-equalizer.c \
banshee-player-missing-elements.c \
+ banshee-player-pipeline.c \
banshee-player-video.c \
gst-cd-rip-0.10.c \
gst-misc-0.10.c \
gst-transcode-0.10.c
noinst_HEADERS = \
- banshee-player.h \
banshee-player-cdda.h \
banshee-player-missing-elements.h \
+ banshee-player-pipeline.h \
+ banshee-player-private.h \
banshee-player-video.h \
gst-cd-rip.h \
gst-misc.h \
Modified: trunk/banshee/libbanshee/banshee-player-cdda.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-cdda.c (original)
+++ trunk/banshee/libbanshee/banshee-player-cdda.c Tue Apr 1 00:36:23 2008
@@ -55,6 +55,36 @@
return source;
}
+static void
+bp_cdda_on_notify_source (GstElement *playbin, gpointer unknown, BansheePlayer *player)
+{
+ GstElement *cdda_src = NULL;
+
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ if (player->cdda_device == NULL) {
+ return;
+ }
+
+ cdda_src = bp_cdda_get_cdda_source (playbin);
+ if (cdda_src == NULL) {
+ return;
+ }
+
+ // Technically don't need to check the class, since GstCddaBaseSrc elements will always have this
+ if (G_LIKELY (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "device"))) {
+ bp_debug ("bp_cdda: setting device property on source (%s)", player->cdda_device);
+ g_object_set (cdda_src, "device", player->cdda_device, NULL);
+ }
+
+ // If the GstCddaBaseSrc is cdparanoia, it will have this property, so set it
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "paranoia-mode")) {
+ g_object_set (cdda_src, "paranoia-mode", 0, NULL);
+ }
+
+ g_object_unref (cdda_src);
+}
+
static gboolean
bp_cdda_source_seek_to_track (GstElement *playbin, guint track)
{
@@ -96,33 +126,11 @@
// ---------------------------------------------------------------------------
void
-_bp_cdda_on_notify_source (GstElement *playbin, gpointer unknown, BansheePlayer *player)
+_bp_cdda_pipeline_setup (BansheePlayer *player)
{
- GstElement *cdda_src = NULL;
-
- g_return_if_fail (IS_BANSHEE_PLAYER (player));
-
- if (player->cdda_device == NULL) {
- return;
- }
-
- cdda_src = bp_cdda_get_cdda_source (playbin);
- if (cdda_src == NULL) {
- return;
+ if (player != NULL && player->playbin != NULL) {
+ g_signal_connect (player->playbin, "notify::source", G_CALLBACK (bp_cdda_on_notify_source), player);
}
-
- // Technically don't need to check the class, since GstCddaBaseSrc elements will always have this
- if (G_LIKELY (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "device"))) {
- bp_debug ("bp_cdda: setting device property on source (%s)", player->cdda_device);
- g_object_set (cdda_src, "device", player->cdda_device, NULL);
- }
-
- // If the GstCddaBaseSrc is cdparanoia, it will have this property, so set it
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (cdda_src), "paranoia-mode")) {
- g_object_set (cdda_src, "paranoia-mode", 0, NULL);
- }
-
- g_object_unref (cdda_src);
}
gboolean
Modified: trunk/banshee/libbanshee/banshee-player-cdda.h
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-cdda.h (original)
+++ trunk/banshee/libbanshee/banshee-player-cdda.h Tue Apr 1 00:36:23 2008
@@ -29,9 +29,9 @@
#ifndef _BANSHEE_PLAYER_CDDA_H
#define _BANSHEE_PLAYER_CDDA_H
-#include "banshee-player.h"
+#include "banshee-player-private.h"
-void _bp_cdda_on_notify_source (GstElement *playbin, gpointer unknown, BansheePlayer *player);
+void _bp_cdda_pipeline_setup (BansheePlayer *player);
gboolean _bp_cdda_handle_uri (BansheePlayer *player, const gchar *uri);
#endif /* _BANSHEE_PLAYER_CDDA_H */
Added: trunk/banshee/libbanshee/banshee-player-equalizer.c
==============================================================================
--- (empty file)
+++ trunk/banshee/libbanshee/banshee-player-equalizer.c Tue Apr 1 00:36:23 2008
@@ -0,0 +1,123 @@
+//
+// banshee-player-equalizer.c
+//
+// Authors:
+// Alexander Hixon <hixon alexander mediati org>
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#include "banshee-player-private.h"
+
+// ---------------------------------------------------------------------------
+// Public Functions
+// ---------------------------------------------------------------------------
+
+P_INVOKE gboolean
+bp_equalizer_is_supported (BansheePlayer *player)
+{
+ return player != NULL && player->equalizer != NULL && player->preamp != NULL;
+}
+
+P_INVOKE void
+bp_equalizer_set_preamp_level (BansheePlayer *player, gdouble level)
+{
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ if (player->equalizer != NULL && player->preamp != NULL) {
+ g_object_set (player->preamp, "volume", level, NULL);
+ }
+}
+
+P_INVOKE void
+bp_equalizer_set_gain (BansheePlayer *player, guint bandnum, gdouble gain)
+{
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ if (player->equalizer != NULL) {
+ GstObject *band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), bandnum);
+ g_object_set (band, "gain", gain, NULL);
+ g_object_unref (band);
+ }
+}
+
+P_INVOKE void
+bp_equalizer_get_bandrange (BansheePlayer *player, gint *min, gint *max)
+{
+ // NOTE: This only refers to the newer version of the equalizer element.
+ //
+ // GStreamer's equalizer goes from -24 to +12, but -12 to +12 is much better:
+ // - Equal levels on both sides, which means we get a nice linear y=x
+ // - This also makes converting other eq presets easier.
+ // - We get a nice roud 0 dB in the middle of the band range, instead of -6, which is stupid
+ // since 0 dB gives us no gain, yet its not in the middle - less sense to the end user.
+
+ GParamSpecDouble *pspec;
+
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ if (player->equalizer == NULL) {
+ return;
+ }
+
+ // Fetch gain range of first band (since it should be the same for the rest)
+ pspec = (GParamSpecDouble*)g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0");
+ if (pspec != NULL) {
+ // Assume old equalizer.
+ *min = pspec->minimum;
+ *max = pspec->maximum;
+ return;
+ }
+
+ pspec = (GParamSpecDouble*)g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0::gain");
+ if (pspec != NULL && pspec->maximum == 12) {
+ // New equalizer - return even scale.
+ *min = -12;
+ *max = 12;
+ } else if (pspec != NULL) {
+ // Return just the ranges the equalizer supports
+ *min = pspec->minimum;
+ *max = pspec->maximum;
+ } else {
+ g_warning ("Could not find valid gain range for equalizer element");
+ }
+}
+
+P_INVOKE void
+bp_equalizer_get_frequencies (BansheePlayer *player, gdouble **freq)
+{
+ gint i;
+ gdouble bandfreq[10];
+
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ for (i = 0; i < 10; i++) {
+ GstObject *band;
+
+ band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), i);
+ g_object_get (G_OBJECT (band), "freq", &bandfreq[i], NULL);
+ g_object_unref (band);
+ }
+
+ *freq = bandfreq;
+}
Modified: trunk/banshee/libbanshee/banshee-player-missing-elements.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-missing-elements.c (original)
+++ trunk/banshee/libbanshee/banshee-player-missing-elements.c Tue Apr 1 00:36:23 2008
@@ -51,6 +51,10 @@
{
GSList *node = list;
+ if (node == NULL) {
+ return;
+ }
+
for (; node != NULL; node = node->next) {
g_free (node->data);
}
Modified: trunk/banshee/libbanshee/banshee-player-missing-elements.h
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-missing-elements.h (original)
+++ trunk/banshee/libbanshee/banshee-player-missing-elements.h Tue Apr 1 00:36:23 2008
@@ -29,7 +29,7 @@
#ifndef _BANSHEE_PLAYER_MISSING_ELEMENTS_H
#define _BANSHEE_PLAYER_MISSING_ELEMENTS_H
-#include "banshee-player.h"
+#include "banshee-player-private.h"
void _bp_missing_elements_destroy (BansheePlayer *player);
void _bp_missing_elements_process_message (BansheePlayer *player, GstMessage *message);
Added: trunk/banshee/libbanshee/banshee-player-pipeline.c
==============================================================================
--- (empty file)
+++ trunk/banshee/libbanshee/banshee-player-pipeline.c Tue Apr 1 00:36:23 2008
@@ -0,0 +1,281 @@
+//
+// banshee-player-pipeline.c
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#include "banshee-player-pipeline.h"
+#include "banshee-player-cdda.h"
+#include "banshee-player-video.h"
+#include "banshee-player-missing-elements.h"
+
+// ---------------------------------------------------------------------------
+// Private Functions
+// ---------------------------------------------------------------------------
+
+static void
+bp_pipeline_process_tag (const GstTagList *tag_list, const gchar *tag_name, BansheePlayer *player)
+{
+ const GValue *value;
+ gint value_count;
+
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ value_count = gst_tag_list_get_tag_size (tag_list, tag_name);
+ if (value_count < 1) {
+ return;
+ }
+
+ value = gst_tag_list_get_value_index (tag_list, tag_name, 0);
+
+ if (value != NULL && player->tag_found_cb != NULL) {
+ player->tag_found_cb (player, tag_name, value);
+ }
+}
+
+static gboolean
+bp_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer userdata)
+{
+ BansheePlayer *player = (BansheePlayer *)userdata;
+
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
+ g_return_val_if_fail (message != NULL, FALSE);
+
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS: {
+ if (player->eos_cb != NULL) {
+ player->eos_cb (player);
+ }
+ break;
+ }
+
+ case GST_MESSAGE_STATE_CHANGED: {
+ GstState old, new, pending;
+ gst_message_parse_state_changed (message, &old, &new, &pending);
+
+ _bp_missing_elements_handle_state_changed (player, old, new);
+
+ if (player->state_changed_cb != NULL) {
+ player->state_changed_cb (player, old, new, pending);
+ }
+ break;
+ }
+
+ case GST_MESSAGE_BUFFERING: {
+ const GstStructure *buffering_struct;
+ gint buffering_progress = 0;
+
+ buffering_struct = gst_message_get_structure (message);
+ if (!gst_structure_get_int (buffering_struct, "buffer-percent", &buffering_progress)) {
+ g_warning ("Could not get completion percentage from BUFFERING message");
+ break;
+ }
+
+ if (buffering_progress >= 100) {
+ player->buffering = FALSE;
+ if (player->target_state == GST_STATE_PLAYING) {
+ gst_element_set_state (player->playbin, GST_STATE_PLAYING);
+ }
+ } else if (!player->buffering && player->target_state == GST_STATE_PLAYING) {
+ GstState current_state;
+ gst_element_get_state (player->playbin, ¤t_state, NULL, 0);
+ if (current_state == GST_STATE_PLAYING) {
+ gst_element_set_state (player->playbin, GST_STATE_PAUSED);
+ }
+ player->buffering = TRUE;
+ }
+
+ if (player->buffering_cb != NULL) {
+ player->buffering_cb (player, buffering_progress);
+ }
+ break;
+ }
+
+ case GST_MESSAGE_TAG: {
+ GstTagList *tags;
+
+ if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_TAG) {
+ break;
+ }
+
+ gst_message_parse_tag (message, &tags);
+
+ if (GST_IS_TAG_LIST (tags)) {
+ gst_tag_list_foreach (tags, (GstTagForeachFunc)bp_pipeline_process_tag, player);
+ gst_tag_list_free (tags);
+ }
+ break;
+ }
+
+ case GST_MESSAGE_ERROR: {
+ GError *error;
+ gchar *debug;
+
+ // FIXME: This is to work around a bug in qtdemux in
+ // -good <= 0.10.6
+ if (message->src != NULL && message->src->name != NULL &&
+ strncmp (message->src->name, "qtdemux", 7) == 0) {
+ break;
+ }
+
+ _bp_pipeline_destroy (player);
+
+ if (player->error_cb != NULL) {
+ gst_message_parse_error (message, &error, &debug);
+ player->error_cb (player, error->domain, error->code, error->message, debug);
+ g_error_free (error);
+ g_free (debug);
+ }
+
+ break;
+ }
+
+ case GST_MESSAGE_ELEMENT: {
+ _bp_missing_elements_process_message (player, message);
+ break;
+ }
+
+ default: break;
+ }
+
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------
+// Internal Functions
+// ---------------------------------------------------------------------------
+
+gboolean
+_bp_pipeline_construct (BansheePlayer *player)
+{
+ GstBus *bus;
+ GstPad *teepad;
+ GstElement *audiosink;
+ GstElement *audiosinkqueue;
+ // GstElement *audioconvert;
+
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
+
+ // Playbin is the core element that handles autoplugging (finding the right
+ // source and decoder elements) based on source URI and stream content
+ player->playbin = gst_element_factory_make ("playbin", "playbin");
+ g_return_val_if_fail (player->playbin != NULL, FALSE);
+
+ // Try to find an audio sink, prefer gconf, which typically is set to auto these days,
+ // fall back on auto, which should work on windows, and as a last ditch, try alsa
+ audiosink = gst_element_factory_make ("gconfaudiosink", "audiosink");
+ if (audiosink == NULL) {
+ audiosink = gst_element_factory_make ("autoaudiosink", "audiosink");
+ if (audiosink == NULL) {
+ audiosink = gst_element_factory_make ("alsasink", "audiosink");
+ }
+ }
+
+ g_return_val_if_fail (audiosink != NULL, FALSE);
+
+ // Set the profile to "music and movies" (gst-plugins-good 0.10.3)
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (audiosink), "profile")) {
+ g_object_set (G_OBJECT (audiosink), "profile", 1, NULL);
+ }
+
+ // Create a custom audio sink bin that will hold the real primary sink
+ player->audiobin = gst_bin_new ("audiobin");
+ g_return_val_if_fail (player->audiobin != NULL, FALSE);
+
+ // Our audio sink is a tee, so plugins can attach their own pipelines
+ player->audiotee = gst_element_factory_make ("tee", "audiotee");
+ g_return_val_if_fail (player->audiotee != NULL, FALSE);
+
+ audiosinkqueue = gst_element_factory_make ("queue", "audiosinkqueue");
+ g_return_val_if_fail (audiosinkqueue != NULL, FALSE);
+
+ // FIXME: Make the equalizer work properly
+ // audioconvert = gst_element_factory_make("audioconvert", "audioconvert");
+ // player->equalizer = gst_element_factory_make("equalizer-10bands", "equalizer-10bands");
+ // player->preamp = gst_element_factory_make("volume", "preamp");
+
+ // Add elements to custom audio sink
+ gst_bin_add (GST_BIN (player->audiobin), player->audiotee);
+ // FIXME: Make the equalizer work properly
+ //if (player->equalizer != NULL) {
+ // gst_bin_add (GST_BIN (player->audiobin), audioconvert);
+ // gst_bin_add (GST_BIN (player->audiobin), player->equalizer);
+ // gst_bin_add (GST_BIN (player->audiobin), player->preamp);
+ //}
+ gst_bin_add (GST_BIN (player->audiobin), audiosinkqueue);
+ gst_bin_add (GST_BIN (player->audiobin), audiosink);
+
+ // Ghost pad the audio bin so audio is passed from the bin into the tee
+ teepad = gst_element_get_pad (player->audiotee, "sink");
+ gst_element_add_pad (player->audiobin, gst_ghost_pad_new ("sink", teepad));
+ gst_object_unref (teepad);
+
+ // Link the first tee pad to the primary audio sink queue
+ gst_pad_link (gst_element_get_request_pad (player->audiotee, "src0"),
+ gst_element_get_pad (audiosinkqueue, "sink"));
+
+ // Link the queue and the actual audio sink
+ // FIXME: Make the equalizer work properly
+ // if (player->equalizer != NULL) {
+ // // link in equalizer, preamp and audioconvert.
+ // gst_element_link_many (audiosinkqueue, player->preamp, player->equalizer, audioconvert, audiosink)
+ // } else {
+ // // link the queue with the real audio sink
+ // gst_element_link (audiosinkqueue, audiosink);
+ // }
+
+ gst_element_link (audiosinkqueue, audiosink);
+
+ // Now that our internal audio sink is constructed, tell playbin to use it
+ g_object_set (G_OBJECT (player->playbin), "audio-sink", player->audiobin, NULL);
+
+ // Connect to the bus to get messages
+ bus = gst_pipeline_get_bus (GST_PIPELINE (player->playbin));
+ gst_bus_add_watch (bus, bp_pipeline_bus_callback, player);
+
+ // Now allow specialized pipeline setups
+ _bp_cdda_pipeline_setup (player);
+ _bp_video_pipeline_setup (player, bus);
+
+ return TRUE;
+}
+
+void
+_bp_pipeline_destroy (BansheePlayer *player)
+{
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+ if (player->playbin == NULL) {
+ return;
+ }
+
+ if (GST_IS_ELEMENT (player->playbin)) {
+ player->target_state = GST_STATE_NULL;
+ gst_element_set_state (player->playbin, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT(player->playbin));
+ }
+
+ player->playbin = NULL;
+}
Added: trunk/banshee/libbanshee/banshee-player-pipeline.h
==============================================================================
--- (empty file)
+++ trunk/banshee/libbanshee/banshee-player-pipeline.h Tue Apr 1 00:36:23 2008
@@ -0,0 +1,37 @@
+//
+// banshee-player-pipeline.h
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#ifndef _BANSHEE_PLAYER_PIPELINE_H
+#define _BANSHEE_PLAYER_PIPELINE_H
+
+#include "banshee-player-private.h"
+
+gboolean _bp_pipeline_construct (BansheePlayer *player);
+void _bp_pipeline_destroy (BansheePlayer *player);
+
+#endif /* _BANSHEE_PLAYER_PIPELINE_H */
Copied: trunk/banshee/libbanshee/banshee-player-private.h (from r3627, /trunk/banshee/libbanshee/banshee-player.h)
==============================================================================
--- /trunk/banshee/libbanshee/banshee-player.h (original)
+++ trunk/banshee/libbanshee/banshee-player-private.h Tue Apr 1 00:36:23 2008
@@ -1,5 +1,37 @@
-#ifndef _BANSHEE_PLAYER_H
-#define _BANSHEE_PLAYER_H
+//
+// banshee-player-private.h
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#ifndef _BANSHEE_PLAYER_PRIVATE_H
+#define _BANSHEE_PLAYER_PRIVATE_H
+
+#ifndef INSIDE_LIBBANSHEE_I_SWEAR
+#error libbanshee is not a stable API and is not meant to be used by third party applications
+#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -74,4 +106,4 @@
#endif
};
-#endif /* _BANSHEE_PLAYER_H */
+#endif /* _BANSHEE_PLAYER_PRIVATE_H */
Modified: trunk/banshee/libbanshee/banshee-player-video.h
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-video.h (original)
+++ trunk/banshee/libbanshee/banshee-player-video.h Tue Apr 1 00:36:23 2008
@@ -29,7 +29,7 @@
#ifndef _BANSHEE_PLAYER_VIDEO_H
#define _BANSHEE_PLAYER_VIDEO_H
-#include "banshee-player.h"
+#include "banshee-player-private.h"
void _bp_video_pipeline_setup (BansheePlayer *player, GstBus *bus);
Modified: trunk/banshee/libbanshee/banshee-player.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-player.c (original)
+++ trunk/banshee/libbanshee/banshee-player.c Tue Apr 1 00:36:23 2008
@@ -1,329 +1,111 @@
-/***************************************************************************
- * gst-playback-0.10.c
- *
- * Copyright (C) 2005-2007 Novell, Inc.
- * Written by Aaron Bockover <aaron abock org>
- * Contributions by Alexander Hixon <hixon alexander mediati org>
- ****************************************************************************/
-
-/* THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
+//
+// banshee-player.c
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2005-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
-#include "banshee-player.h"
+#include "banshee-player-private.h"
+#include "banshee-player-pipeline.h"
#include "banshee-player-cdda.h"
-#include "banshee-player-video.h"
#include "banshee-player-missing-elements.h"
-static void
-bp_process_tag(const GstTagList *tag_list, const gchar *tag_name, BansheePlayer *player)
-{
- const GValue *value;
- gint value_count;
-
- value_count = gst_tag_list_get_tag_size(tag_list, tag_name);
- if(value_count < 1) {
- return;
- }
-
- value = gst_tag_list_get_value_index(tag_list, tag_name, 0);
-
- if(player != NULL && player->tag_found_cb != NULL) {
- player->tag_found_cb(player, tag_name, value);
- }
-}
-
-static void
-bp_destroy_pipeline(BansheePlayer *player)
-{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
-
- if(player->playbin == NULL) {
- return;
- }
-
- if(GST_IS_ELEMENT(player->playbin)) {
- player->target_state = GST_STATE_NULL;
- gst_element_set_state(player->playbin, GST_STATE_NULL);
- gst_object_unref(GST_OBJECT(player->playbin));
- }
-
- player->playbin = NULL;
-}
-
-static gboolean
-bp_bus_callback(GstBus *bus, GstMessage *message, gpointer data)
-{
- BansheePlayer *player = (BansheePlayer *)data;
-
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), FALSE);
-
- switch(GST_MESSAGE_TYPE(message)) {
- case GST_MESSAGE_ERROR: {
- GError *error;
- gchar *debug;
-
- // FIXME: This is to work around a bug in qtdemux in
- // -good <= 0.10.6
- if(message->src != NULL && message->src->name != NULL &&
- strncmp(message->src->name, "qtdemux", 0) == 0) {
- break;
- }
-
- bp_destroy_pipeline(player);
-
- if(player->error_cb != NULL) {
- gst_message_parse_error(message, &error, &debug);
- player->error_cb(player, error->domain, error->code, error->message, debug);
- g_error_free(error);
- g_free(debug);
- }
-
- break;
- }
-
- case GST_MESSAGE_ELEMENT: {
- _bp_missing_elements_process_message (player, message);
- break;
- }
-
- case GST_MESSAGE_EOS: {
- if(player->eos_cb != NULL) {
- player->eos_cb(player);
- }
- break;
- }
-
- case GST_MESSAGE_STATE_CHANGED: {
- GstState old, new, pending;
- gst_message_parse_state_changed (message, &old, &new, &pending);
-
- _bp_missing_elements_handle_state_changed (player, old, new);
-
- if (player->state_changed_cb != NULL) {
- player->state_changed_cb (player, old, new, pending);
- }
- break;
- }
-
- case GST_MESSAGE_BUFFERING: {
- const GstStructure *buffering_struct;
- gint buffering_progress = 0;
-
- buffering_struct = gst_message_get_structure(message);
- if(!gst_structure_get_int(buffering_struct, "buffer-percent", &buffering_progress)) {
- g_warning("Could not get completion percentage from BUFFERING message");
- break;
- }
-
- if(buffering_progress >= 100) {
- player->buffering = FALSE;
- if(player->target_state == GST_STATE_PLAYING) {
- gst_element_set_state(player->playbin, GST_STATE_PLAYING);
- }
- } else if(!player->buffering && player->target_state == GST_STATE_PLAYING) {
- GstState current_state;
- gst_element_get_state(player->playbin, ¤t_state, NULL, 0);
- if(current_state == GST_STATE_PLAYING) {
- gst_element_set_state(player->playbin, GST_STATE_PAUSED);
- }
- player->buffering = TRUE;
- }
-
- if(player->buffering_cb != NULL) {
- player->buffering_cb(player, buffering_progress);
- }
- }
- case GST_MESSAGE_TAG: {
- GstTagList *tags;
-
- if(GST_MESSAGE_TYPE(message) != GST_MESSAGE_TAG) {
- break;
- }
-
- gst_message_parse_tag(message, &tags);
-
- if(GST_IS_TAG_LIST(tags)) {
- gst_tag_list_foreach(tags, (GstTagForeachFunc)bp_process_tag, player);
- gst_tag_list_free(tags);
- }
- break;
- }
- default:
- break;
- }
-
- return TRUE;
-}
-
-static gboolean
-bp_construct(BansheePlayer *player)
-{
- GstBus *bus;
- GstElement *audiosink;
- GstElement *audiosinkqueue;
- //GstElement *audioconvert;
- GstPad *teepad;
-
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), FALSE);
-
- // create necessary elements
- player->playbin = gst_element_factory_make("playbin", "playbin");
- g_return_val_if_fail(player->playbin != NULL, FALSE);
-
- audiosink = gst_element_factory_make("gconfaudiosink", "audiosink");
- g_return_val_if_fail(audiosink != NULL, FALSE);
-
- /* Set the profile to "music and movies" (gst-plugins-good 0.10.3) */
- if(g_object_class_find_property(G_OBJECT_GET_CLASS(audiosink), "profile")) {
- g_object_set(G_OBJECT(audiosink), "profile", 1, NULL);
- }
-
- player->audiobin = gst_bin_new("audiobin");
- g_return_val_if_fail(player->audiobin != NULL, FALSE);
-
- player->audiotee = gst_element_factory_make("tee", "audiotee");
- g_return_val_if_fail(player->audiotee != NULL, FALSE);
-
- audiosinkqueue = gst_element_factory_make("queue", "audiosinkqueue");
- g_return_val_if_fail(audiosinkqueue != NULL, FALSE);
-
- //audioconvert = gst_element_factory_make("audioconvert", "audioconvert");
- //player->equalizer = gst_element_factory_make("equalizer-10bands", "equalizer-10bands");
- //player->preamp = gst_element_factory_make("volume", "preamp");
-
- // add elements to custom audio sink
- gst_bin_add(GST_BIN(player->audiobin), player->audiotee);
- //if(player->equalizer != NULL) {
- // gst_bin_add(GST_BIN(player->audiobin), audioconvert);
- // gst_bin_add(GST_BIN(player->audiobin), player->equalizer);
- // gst_bin_add(GST_BIN(player->audiobin), player->preamp);
- //}
- gst_bin_add(GST_BIN(player->audiobin), audiosinkqueue);
- gst_bin_add(GST_BIN(player->audiobin), audiosink);
-
- // ghost pad the audio bin
- teepad = gst_element_get_pad(player->audiotee, "sink");
- gst_element_add_pad(player->audiobin, gst_ghost_pad_new("sink", teepad));
- gst_object_unref(teepad);
-
- // link the tee/queue pads for the default
- gst_pad_link(gst_element_get_request_pad(player->audiotee, "src0"),
- gst_element_get_pad(audiosinkqueue, "sink"));
-
- //if (player->equalizer != NULL)
- //{
- // //link in equalizer, preamp and audioconvert.
- // gst_element_link(audiosinkqueue, player->preamp);
- // gst_element_link(player->preamp, player->equalizer);
- // gst_element_link(player->equalizer, audioconvert);
- // gst_element_link(audioconvert, audiosink);
- //} else {
- // // link the queue with the real audio sink
- gst_element_link(audiosinkqueue, audiosink);
- //}
-
- g_object_set (G_OBJECT (player->playbin), "audio-sink", player->audiobin, NULL);
-
- bus = gst_pipeline_get_bus (GST_PIPELINE (player->playbin));
- gst_bus_add_watch (bus, bp_bus_callback, player);
-
- g_signal_connect (player->playbin, "notify::source", G_CALLBACK (_bp_cdda_on_notify_source), player);
-
- _bp_video_pipeline_setup (player, bus);
-
- return TRUE;
-}
+// ---------------------------------------------------------------------------
+// Private Functions
+// ---------------------------------------------------------------------------
static gboolean
-bp_iterate_timeout(BansheePlayer *player)
+bp_iterate_timeout_handler (BansheePlayer *player)
{
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), FALSE);
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
if(player->iterate_cb != NULL) {
- player->iterate_cb(player);
+ player->iterate_cb (player);
}
return TRUE;
}
static void
-bp_start_iterate_timeout(BansheePlayer *player)
+bp_iterate_timeout_start (BansheePlayer *player)
{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
+ g_return_if_fail (IS_BANSHEE_PLAYER(player));
- if(player->iterate_timeout_id != 0) {
- return;
+ if (player->iterate_timeout_id == 0) {
+ player->iterate_timeout_id = g_timeout_add (200,
+ (GSourceFunc)bp_iterate_timeout_handler, player);
}
-
- player->iterate_timeout_id = g_timeout_add(200,
- (GSourceFunc)bp_iterate_timeout, player);
}
static void
-bp_stop_iterate_timeout(BansheePlayer *player)
+bp_iterate_timeout_stop (BansheePlayer *player)
{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
- if(player->iterate_timeout_id == 0) {
- return;
+ if (player->iterate_timeout_id != 0) {
+ g_source_remove (player->iterate_timeout_id);
+ player->iterate_timeout_id = 0;
}
-
- g_source_remove(player->iterate_timeout_id);
- player->iterate_timeout_id = 0;
}
-// public methods
-
-BansheePlayer *
-bp_new()
+static void
+bp_pipeline_set_state (BansheePlayer *player, GstState state)
{
- BansheePlayer *player = g_new0(BansheePlayer, 1);
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
- player->mutex = g_mutex_new ();
+ if (state == GST_STATE_NULL || state == GST_STATE_PAUSED) {
+ bp_iterate_timeout_stop (player);
+ }
- if(!bp_construct(player)) {
- g_free(player);
- return NULL;
+ if (GST_IS_ELEMENT (player->playbin)) {
+ player->target_state = state;
+ gst_element_set_state (player->playbin, state);
}
- return player;
+ if (state == GST_STATE_PLAYING) {
+ bp_iterate_timeout_start (player);
+ }
}
-void
-bp_free (BansheePlayer *player)
+// ---------------------------------------------------------------------------
+// Public Functions
+// ---------------------------------------------------------------------------
+
+P_INVOKE void
+bp_destroy (BansheePlayer *player)
{
g_return_if_fail (IS_BANSHEE_PLAYER (player));
- g_mutex_free (player->mutex);
-
- if (GST_IS_OBJECT (player->playbin)) {
- player->target_state = GST_STATE_NULL;
- gst_element_set_state (player->playbin, GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (player->playbin));
+ if (player->mutex != NULL) {
+ g_mutex_free (player->mutex);
}
if (player->cdda_device != NULL) {
g_free (player->cdda_device);
}
+ _bp_pipeline_destroy (player);
_bp_missing_elements_destroy (player);
memset (player, 0, sizeof (BansheePlayer));
@@ -334,192 +116,161 @@
bp_debug ("bp: disposed player");
}
-void
-bp_set_eos_callback(BansheePlayer *player,
- BansheePlayerEosCallback cb)
-{
- SET_CALLBACK(eos_cb);
-}
-
-void
-bp_set_error_callback(BansheePlayer *player,
- BansheePlayerErrorCallback cb)
+P_INVOKE BansheePlayer *
+bp_new ()
{
- SET_CALLBACK(error_cb);
-}
-
-void
-bp_set_state_changed_callback(BansheePlayer *player,
- BansheePlayerStateChangedCallback cb)
-{
- SET_CALLBACK(state_changed_cb);
-}
-
-void
-bp_set_iterate_callback(BansheePlayer *player,
- BansheePlayerIterateCallback cb)
-{
- SET_CALLBACK(iterate_cb);
-}
-
-void
-bp_set_buffering_callback(BansheePlayer *player,
- BansheePlayerBufferingCallback cb)
-{
- SET_CALLBACK(buffering_cb);
-}
-
-void
-bp_set_tag_found_callback(BansheePlayer *player,
- BansheePlayerTagFoundCallback cb)
-{
- SET_CALLBACK(tag_found_cb);
+ BansheePlayer *player = g_new0 (BansheePlayer, 1);
+
+ player->mutex = g_mutex_new ();
+
+ if (!_bp_pipeline_construct (player)) {
+ bp_destroy (player);
+ return NULL;
+ }
+
+ return player;
}
-void
-bp_open(BansheePlayer *player, const gchar *uri)
+P_INVOKE gboolean
+bp_open (BansheePlayer *player, const gchar *uri)
{
GstState state;
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
- if(player->playbin == NULL && !bp_construct(player)) {
- return;
+ // Build the pipeline if we need to
+ if (player->playbin == NULL && !_bp_pipeline_construct (player)) {
+ return FALSE;
}
+ // Give the CDDA code a chance to intercept the open request
+ // in case it is able to perform a fast seek to a track
if (_bp_cdda_handle_uri (player, uri)) {
- return;
+ return TRUE;
}
- gst_element_get_state(player->playbin, &state, NULL, 0);
- if(state >= GST_STATE_PAUSED) {
+ // Set the pipeline to the proper state
+ gst_element_get_state (player->playbin, &state, NULL, 0);
+ if (state >= GST_STATE_PAUSED) {
player->target_state = GST_STATE_READY;
- gst_element_set_state(player->playbin, GST_STATE_READY);
+ gst_element_set_state (player->playbin, GST_STATE_READY);
}
- g_object_set(G_OBJECT(player->playbin), "uri", uri, NULL);
-}
-
-void
-bp_stop(BansheePlayer *player, gboolean nullstate)
-{
- GstState state = nullstate ? GST_STATE_NULL : GST_STATE_PAUSED;
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
- bp_stop_iterate_timeout(player);
- if(GST_IS_ELEMENT(player->playbin)) {
- player->target_state = state;
- gst_element_set_state(player->playbin, state);
- }
+ // Pass the request off to playbin
+ g_object_set (G_OBJECT (player->playbin), "uri", uri, NULL);
+
+ return TRUE;
}
-void
-bp_pause(BansheePlayer *player)
+P_INVOKE void
+bp_stop (BansheePlayer *player, gboolean nullstate)
{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
- bp_stop_iterate_timeout(player);
- player->target_state = GST_STATE_PAUSED;
- gst_element_set_state(player->playbin, GST_STATE_PAUSED);
+ // Some times "stop" really means "pause", particularly with
+ // CDDA track transitioning; a NULL state will release resources
+ bp_pipeline_set_state (player, nullstate ? GST_STATE_NULL : GST_STATE_PAUSED);
}
-void
-bp_play(BansheePlayer *player)
+P_INVOKE void
+bp_pause (BansheePlayer *player)
{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
- player->target_state = GST_STATE_PLAYING;
- gst_element_set_state(player->playbin, GST_STATE_PLAYING);
- bp_start_iterate_timeout(player);
+ bp_pipeline_set_state (player, GST_STATE_PAUSED);
}
-void
-bp_set_volume(BansheePlayer *player, gint volume)
+P_INVOKE void
+bp_play (BansheePlayer *player)
{
- gdouble act_volume;
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
- act_volume = CLAMP(volume, 0, 100) / 100.0;
- g_object_set(G_OBJECT(player->playbin), "volume", act_volume, NULL);
+ bp_pipeline_set_state (player, GST_STATE_PLAYING);
}
-gint
-bp_get_volume(BansheePlayer *player)
-{
- gdouble volume = 0.0;
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), 0);
- g_object_get(player->playbin, "volume", &volume, NULL);
- return (gint)(volume * 100.0);
-}
-void
-bp_set_position(BansheePlayer *player, guint64 time_ms)
+P_INVOKE gboolean
+bp_set_position (BansheePlayer *player, guint64 time_ms)
{
- g_return_if_fail(IS_BANSHEE_PLAYER(player));
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
- if(!gst_element_seek(player->playbin, 1.0,
- GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
- GST_SEEK_TYPE_SET, time_ms * GST_MSECOND,
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
- g_warning("Could not seek in stream");
+ if (!gst_element_seek (player->playbin, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_TYPE_SET, time_ms * GST_MSECOND, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
+ g_warning ("Could not seek in stream");
+ return FALSE;
}
+
+ return TRUE;
}
-guint64
-bp_get_position(BansheePlayer *player)
+P_INVOKE guint64
+bp_get_position (BansheePlayer *player)
{
- GstFormat format = GST_FORMAT_TIME;
+ static GstFormat format = GST_FORMAT_TIME;
gint64 position;
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), 0);
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
- if(gst_element_query_position(player->playbin, &format, &position)) {
- return position / 1000000;
+ if (gst_element_query_position (player->playbin, &format, &position)) {
+ return position / GST_MSECOND;
}
return 0;
}
-guint64
-bp_get_duration(BansheePlayer *player)
+P_INVOKE guint64
+bp_get_duration (BansheePlayer *player)
{
- GstFormat format = GST_FORMAT_TIME;
+ static GstFormat format = GST_FORMAT_TIME;
gint64 duration;
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), 0);
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
- if(gst_element_query_duration(player->playbin, &format, &duration)) {
- return duration / 1000000;
+ if (gst_element_query_duration (player->playbin, &format, &duration)) {
+ return duration / GST_MSECOND;
}
return 0;
}
-gboolean
-bp_can_seek(BansheePlayer *player)
+P_INVOKE gboolean
+bp_can_seek (BansheePlayer *player)
{
GstQuery *query;
gboolean can_seek = TRUE;
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), FALSE);
- g_return_val_if_fail(player->playbin != NULL, FALSE);
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
+ g_return_val_if_fail (player->playbin != NULL, FALSE);
- query = gst_query_new_seeking(GST_FORMAT_TIME);
- if(!gst_element_query(player->playbin, query)) {
+ query = gst_query_new_seeking (GST_FORMAT_TIME);
+ if (!gst_element_query (player->playbin, query)) {
// This will probably fail, 100% of the time, because it's apparently
// very unimplemented in GStreamer... when it's fixed
// we will return FALSE here, and show the warning
- // g_warning("Could not query pipeline for seek ability");
- return bp_get_duration(player) > 0;
+ // g_warning ("Could not query pipeline for seek ability");
+ return bp_get_duration (player) > 0;
}
- gst_query_parse_seeking(query, NULL, &can_seek, NULL, NULL);
- gst_query_unref(query);
+ gst_query_parse_seeking (query, NULL, &can_seek, NULL, NULL);
+ gst_query_unref (query);
return can_seek;
}
-gboolean
-bp_get_pipeline_elements(BansheePlayer *player, GstElement **playbin, GstElement **audiobin,
- GstElement **audiotee)
+P_INVOKE void
+bp_set_volume (BansheePlayer *player, gint volume)
+{
+ g_return_if_fail (IS_BANSHEE_PLAYER (player));
+ g_object_set (G_OBJECT (player->playbin), "volume", CLAMP (volume, 0, 100) / 100.0, NULL);
+}
+
+P_INVOKE gint
+bp_get_volume (BansheePlayer *player)
{
- g_return_val_if_fail(IS_BANSHEE_PLAYER(player), FALSE);
+ gdouble volume = 0.0;
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
+ g_object_get (player->playbin, "volume", &volume, NULL);
+ return (gint)(volume * 100.0);
+}
+
+P_INVOKE gboolean
+bp_get_pipeline_elements (BansheePlayer *player, GstElement **playbin, GstElement **audiobin, GstElement **audiotee)
+{
+ g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
*playbin = player->playbin;
*audiobin = player->audiobin;
@@ -528,104 +279,53 @@
return TRUE;
}
-void
+P_INVOKE void
bp_set_application_gdk_window(BansheePlayer *player, GdkWindow *window)
{
player->window = window;
}
-void
-bp_get_error_quarks(GQuark *core, GQuark *library, GQuark *resource, GQuark *stream)
+P_INVOKE void
+bp_set_eos_callback (BansheePlayer *player, BansheePlayerEosCallback cb)
{
- *core = GST_CORE_ERROR;
- *library = GST_LIBRARY_ERROR;
- *resource = GST_RESOURCE_ERROR;
- *stream = GST_STREAM_ERROR;
+ SET_CALLBACK(eos_cb);
}
-/* Region Equalizer */
+P_INVOKE void
+bp_set_error_callback (BansheePlayer *player, BansheePlayerErrorCallback cb)
+{
+ SET_CALLBACK (error_cb);
+}
-gboolean
-gst_equalizer_is_supported(BansheePlayer *player)
+P_INVOKE void
+bp_set_state_changed_callback (BansheePlayer *player, BansheePlayerStateChangedCallback cb)
{
- return player != NULL && player->equalizer != NULL && player->preamp != NULL;
+ SET_CALLBACK (state_changed_cb);
}
-void
-gst_equalizer_set_preamp_level(BansheePlayer *player, gdouble level)
-{
- if (player->equalizer != NULL && player->preamp != NULL)
- g_object_set (player->preamp, "volume", level, NULL);
-}
-
-void
-gst_equalizer_set_gain(BansheePlayer *player, guint bandnum, gdouble gain)
-{
- if (player->equalizer != NULL) {
- GstObject *band;
- band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), bandnum);
- g_object_set (band, "gain", gain, NULL);
- g_object_unref (band);
- }
-}
-
-void
-gst_equalizer_get_bandrange(BansheePlayer *player, gint *min, gint *max)
-{
- /*
- * NOTE: This only refers to the newer version of the equalizer element.
- *
- * Yes, I know GStreamer's equalizer goes from -24 to +12, but -12 to +12 is much better for two reasons:
- * (x) Equal levels on both sides, which means we get a nice linear y=x
- * (x) This also makes converting other eq presets easier.
- * (x) We get a nice roud 0 dB in the middle of the band range, instead of -6, which is stupid
- * since 0 dB gives us no gain, yet its not in the middle - less sense to the end user.
- *
- * If that didn't make any sense, yay for late-night coding. :)
- */
-
- if (player->equalizer != NULL) {
- GParamSpecDouble *pspec;
-
- // Fetch gain range of first band (since it should be the same for the rest)
- pspec = (GParamSpecDouble*) g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0");
- if (pspec) {
- // Assume old equalizer.
- *min = pspec->minimum;
- *max = pspec->maximum;
- }
- else {
- pspec = (GParamSpecDouble*) g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0::gain");
- if (pspec && pspec->maximum == 12) {
- // New equalizer - return even scale.
- *min = -12;
- *max = 12;
- }
- else if (pspec) {
- // Return just the ranges the equalizer supports
- *min = pspec->minimum;
- *max = pspec->maximum;
- }
- else {
- g_warning("Could not find valid gain range for equalizer.");
- }
- }
- }
-}
-
-void
-gst_equalizer_get_frequencies(BansheePlayer *player, gdouble *freq[])
-{
- gint i;
- gdouble bandfreq[10];
-
- for(i = 0; i < 10; i++) {
- GstObject *band;
-
- band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), i);
- g_object_get (G_OBJECT (band), "freq", &bandfreq[i], NULL);
- g_object_unref (band);
- }
-
- *freq = bandfreq;
+P_INVOKE void
+bp_set_iterate_callback (BansheePlayer *player, BansheePlayerIterateCallback cb)
+{
+ SET_CALLBACK (iterate_cb);
+}
+
+P_INVOKE void
+bp_set_buffering_callback (BansheePlayer *player, BansheePlayerBufferingCallback cb)
+{
+ SET_CALLBACK(buffering_cb);
+}
+
+P_INVOKE void
+bp_set_tag_found_callback (BansheePlayer *player, BansheePlayerTagFoundCallback cb)
+{
+ SET_CALLBACK (tag_found_cb);
+}
+
+P_INVOKE void
+bp_get_error_quarks (GQuark *core, GQuark *library, GQuark *resource, GQuark *stream)
+{
+ *core = GST_CORE_ERROR;
+ *library = GST_LIBRARY_ERROR;
+ *resource = GST_RESOURCE_ERROR;
+ *stream = GST_STREAM_ERROR;
}
Modified: trunk/banshee/libbanshee/libbanshee.mdp
==============================================================================
--- trunk/banshee/libbanshee/libbanshee.mdp (original)
+++ trunk/banshee/libbanshee/libbanshee.mdp Tue Apr 1 00:36:23 2008
@@ -12,7 +12,7 @@
<File name="gst-misc-0.10.c" subtype="Code" buildaction="Compile" />
<File name="banshee-player.c" subtype="Code" buildaction="Compile" />
<File name="gst-transcode-0.10.c" subtype="Code" buildaction="Compile" />
- <File name="banshee-player.h" subtype="Code" buildaction="Nothing" />
+ <File name="banshee-player-private.h" subtype="Code" buildaction="Nothing" />
<File name="banshee-player-cdda.h" subtype="Code" buildaction="Nothing" />
<File name="gst-cd-rip.h" subtype="Code" buildaction="Nothing" />
<File name="gst-misc.h" subtype="Code" buildaction="Nothing" />
@@ -22,6 +22,9 @@
<File name="banshee-player-missing-elements.h" subtype="Code" buildaction="Nothing" />
<File name="banshee-player-video.c" subtype="Code" buildaction="Compile" />
<File name="banshee-player-video.h" subtype="Code" buildaction="Nothing" />
+ <File name="banshee-player-equalizer.c" subtype="Code" buildaction="Compile" />
+ <File name="banshee-player-pipeline.c" subtype="Code" buildaction="Compile" />
+ <File name="banshee-player-pipeline.h" subtype="Code" buildaction="Nothing" />
</Contents>
<compiler ctype="GccCompiler" />
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
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 Tue Apr 1 00:36:23 2008
@@ -120,7 +120,7 @@
public override void Dispose ()
{
base.Dispose ();
- bp_free (handle);
+ bp_destroy (handle);
}
public override void Close ()
@@ -321,7 +321,7 @@
public override bool SupportsEqualizer {
get {
if (supports_equalizer == null) {
- supports_equalizer = gst_equalizer_is_supported (handle);
+ supports_equalizer = bp_equalizer_is_supported (handle);
}
return supports_equalizer.Value;
@@ -346,7 +346,7 @@
public double AmplifierLevel {
set {
double db = Math.Pow (10.0, value / 20.0);
- gst_equalizer_set_preamp_level (handle, db);
+ bp_equalizer_set_preamp_level (handle, db);
}
}
@@ -355,7 +355,7 @@
int min = -1;
int max = -1;
- gst_equalizer_get_bandrange (handle, out min, out max);
+ bp_equalizer_get_bandrange (handle, out min, out max);
return new int [] { min, max };
}
@@ -364,7 +364,7 @@
public uint [] EqualizerFrequencies {
get {
double [] freq = new double[10];
- gst_equalizer_get_frequencies (handle, out freq);
+ bp_equalizer_get_frequencies (handle, out freq);
uint [] ret = new uint[freq.Length];
for (int i = 0; i < freq.Length; i++) {
@@ -377,7 +377,7 @@
public void SetEqualizerGain (uint band, double gain)
{
- gst_equalizer_set_gain (handle, band, gain);
+ bp_equalizer_set_gain (handle, band, gain);
}
private static string [] source_capabilities = { "file", "http", "cdda" };
@@ -394,7 +394,7 @@
private static extern IntPtr bp_new ();
[DllImport ("libbanshee")]
- private static extern void bp_free (HandleRef player);
+ private static extern void bp_destroy (HandleRef player);
[DllImport ("libbanshee")]
private static extern void bp_set_eos_callback (HandleRef player, BansheePlayerEosCallback cb);
@@ -419,7 +419,7 @@
GstTaggerTagFoundCallback cb);
[DllImport ("libbanshee")]
- private static extern void bp_open (HandleRef player, IntPtr uri);
+ private static extern bool bp_open (HandleRef player, IntPtr uri);
[DllImport ("libbanshee")]
private static extern void bp_stop (HandleRef player, bool nullstate);
@@ -440,7 +440,7 @@
private static extern bool bp_can_seek (HandleRef player);
[DllImport ("libbanshee")]
- private static extern void bp_set_position (HandleRef player, ulong time_ms);
+ private static extern bool bp_set_position (HandleRef player, ulong time_ms);
[DllImport ("libbanshee")]
private static extern ulong bp_get_position (HandleRef player);
@@ -469,19 +469,19 @@
out uint resource, out uint stream);
[DllImport ("libbanshee")]
- private static extern bool gst_equalizer_is_supported (HandleRef player);
+ private static extern bool bp_equalizer_is_supported (HandleRef player);
[DllImport ("libbanshee")]
- private static extern void gst_equalizer_set_preamp_level (HandleRef player, double level);
+ private static extern void bp_equalizer_set_preamp_level (HandleRef player, double level);
[DllImport ("libbanshee")]
- private static extern void gst_equalizer_set_gain (HandleRef player, uint bandnum, double gain);
+ private static extern void bp_equalizer_set_gain (HandleRef player, uint bandnum, double gain);
[DllImport ("libbanshee")]
- private static extern void gst_equalizer_get_bandrange (HandleRef player, out int min, out int max);
+ private static extern void bp_equalizer_get_bandrange (HandleRef player, out int min, out int max);
[DllImport ("libbanshee")]
- private static extern void gst_equalizer_get_frequencies (HandleRef player,
+ private static extern void bp_equalizer_get_frequencies (HandleRef player,
[MarshalAs (UnmanagedType.LPArray)] out double [] freq);
}
}
Modified: trunk/banshee/src/Extensions/Extensions.mds
==============================================================================
--- trunk/banshee/src/Extensions/Extensions.mds (original)
+++ trunk/banshee/src/Extensions/Extensions.mds Tue Apr 1 00:36:23 2008
@@ -30,4 +30,4 @@
<Entry filename="Banshee.Bookmarks/Banshee.Bookmarks.mdp" />
<Entry filename="Banshee.AudioCd/Banshee.AudioCd.mdp" />
</Entries>
-</Combine>
+</Combine>
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]