From 458b4b47a7c5efa48ab60a732a8f04fd785df524 Mon Sep 17 00:00:00 2001 From: Jorn Baayen Date: Wed, 30 Aug 2006 13:48:48 +0000 Subject: [PATCH] 2006-08-30 Jorn Baayen * README: * clutter/Makefile.am: * clutter/clutter-audio.c: * clutter/clutter-audio.h: * clutter/clutter-main.c: (clutter_init): * clutter/clutter-media.c: * clutter/clutter-media.h: * clutter/clutter-video-texture.c: * clutter/clutter-video-texture.h: * clutter/clutter.h: * configure.ac: * examples/Makefile.am: * examples/README: * examples/video-cube.c: * examples/video-player.c: * gst/Makefile.am: * gst/clutterimagesink.: * gst/clutterimagesink.c: * gst/clutterimagesink.h: * gtk/Makefile.am: Remove gstreamer bits. There live in clutter-gst now. --- ChangeLog | 25 + README | 6 +- clutter/Makefile.am | 10 +- clutter/clutter-audio.c | 818 ------------------ clutter/clutter-audio.h | 87 -- clutter/clutter-main.c | 4 - clutter/clutter-media.c | 380 -------- clutter/clutter-media.h | 124 --- clutter/clutter-video-texture.c | 913 -------------------- clutter/clutter-video-texture.h | 89 -- clutter/clutter.h | 3 - configure.ac | 11 - doc/reference/ChangeLog | 4 + doc/reference/Makefile.am | 3 +- examples/Makefile.am | 30 +- examples/README | 13 - examples/media-actions-pause.png | Bin 6434 -> 0 bytes examples/media-actions-start.png | Bin 8053 -> 0 bytes examples/vid-panel.png | Bin 98180 -> 0 bytes examples/video-cube.c | 272 ------ examples/video-player.c | 381 -------- gst/Makefile.am | 17 - gst/clutterimagesink. | 703 --------------- gst/clutterimagesink.c | 1386 ------------------------------ gst/clutterimagesink.h | 122 --- gtk/Makefile.am | 7 +- 26 files changed, 42 insertions(+), 5366 deletions(-) delete mode 100644 clutter/clutter-audio.c delete mode 100644 clutter/clutter-audio.h delete mode 100644 clutter/clutter-media.c delete mode 100644 clutter/clutter-media.h delete mode 100644 clutter/clutter-video-texture.c delete mode 100644 clutter/clutter-video-texture.h delete mode 100644 examples/media-actions-pause.png delete mode 100644 examples/media-actions-start.png delete mode 100644 examples/vid-panel.png delete mode 100644 examples/video-cube.c delete mode 100644 examples/video-player.c delete mode 100644 gst/Makefile.am delete mode 100644 gst/clutterimagesink. delete mode 100644 gst/clutterimagesink.c delete mode 100644 gst/clutterimagesink.h diff --git a/ChangeLog b/ChangeLog index 18ed7688b..50c48dd77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2006-08-30 Jorn Baayen + + * README: + * clutter/Makefile.am: + * clutter/clutter-audio.c: + * clutter/clutter-audio.h: + * clutter/clutter-main.c: (clutter_init): + * clutter/clutter-media.c: + * clutter/clutter-media.h: + * clutter/clutter-video-texture.c: + * clutter/clutter-video-texture.h: + * clutter/clutter.h: + * configure.ac: + * examples/Makefile.am: + * examples/README: + * examples/video-cube.c: + * examples/video-player.c: + * gst/Makefile.am: + * gst/clutterimagesink.: + * gst/clutterimagesink.c: + * gst/clutterimagesink.h: + * gtk/Makefile.am: + + Remove gstreamer bits. There live in clutter-gst now. + 2006-08-30 Jorn Baayen * clutter/Makefile.am: diff --git a/README b/README index 86b6696aa..81a441c83 100644 --- a/README +++ b/README @@ -12,9 +12,9 @@ It currently uses fairly low end GL functionality with an aim to still work well on open source graphics drivers as well as possibly making an eventual GL ES port feasable. -Clutter currently requires GLib >= 2.8, GdkPixbuf, Gstreamer 0.10 and -OpenGL >= 1.2. Its also recommended you have some kind of working -hardware OpenGL on your target system. +Clutter currently requires GLib >= 2.8, GdkPixbuf and OpenGL >= 1.2. +Its also recommended you have some kind of working hardware OpenGL on +your target system. Clutter is LGPL licensed. diff --git a/clutter/Makefile.am b/clutter/Makefile.am index e7772b1b8..bbafe22eb 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -9,7 +9,6 @@ source_h = \ $(srcdir)/clutter-keysyms.h \ $(srcdir)/clutter-util.h \ $(srcdir)/clutter-fixed.h \ - $(srcdir)/clutter-media.h \ $(srcdir)/clutter-event.h \ $(srcdir)/clutter-color.h \ $(srcdir)/clutter-feature.h \ @@ -20,12 +19,10 @@ source_h = \ $(srcdir)/clutter-rectangle.h \ $(srcdir)/clutter-texture.h \ $(srcdir)/clutter-clone-texture.h \ - $(srcdir)/clutter-video-texture.h \ $(srcdir)/clutter-label.h \ $(srcdir)/clutter-behaviour.h \ $(srcdir)/clutter-behaviours.h \ $(srcdir)/clutter-alpha.h \ - $(srcdir)/clutter-audio.h \ $(srcdir)/clutter-main.h clutter-marshal.h: clutter-marshal.list @@ -76,7 +73,6 @@ CLEANFILES = $(BUILT_SOURCES) stamp-clutter-enum-types.h source_c = clutter-main.c \ clutter-util.c \ clutter-feature.c \ - clutter-media.c \ clutter-event.c \ clutter-color.c \ clutter-timeline.c \ @@ -85,13 +81,11 @@ source_c = clutter-main.c \ clutter-rectangle.c \ clutter-texture.c \ clutter-clone-texture.c \ - clutter-video-texture.c \ clutter-label.c \ clutter-actor.c \ clutter-behaviour.c \ clutter-behaviours.c \ clutter-alpha.c \ - clutter-audio.c \ clutter-enum-types.c source_h_priv = clutter-private.h @@ -101,11 +95,11 @@ libclutter_@CLUTTER_MAJORMINOR@_la_SOURCES = $(MARSHALFILES) \ $(source_h) \ $(source_h_priv) -INCLUDES = @GCC_FLAGS@ @CLUTTER_CFLAGS@ $(GST_CFLAGS) -I$(top_srcdir) +INCLUDES = @GCC_FLAGS@ @CLUTTER_CFLAGS@ -I$(top_srcdir) lib_LTLIBRARIES = libclutter-@CLUTTER_MAJORMINOR@.la -libclutter_@CLUTTER_MAJORMINOR@_la_LIBADD = @CLUTTER_LIBS@ $(GST_LIBS) +libclutter_@CLUTTER_MAJORMINOR@_la_LIBADD = @CLUTTER_LIBS@ libclutter_@CLUTTER_MAJORMINOR@_la_LDFLAGS = @CLUTTER_LT_LDFLAGS@ clutterheadersdir = $(includedir)/clutter-@CLUTTER_MAJORMINOR@/clutter diff --git a/clutter/clutter-audio.c b/clutter/clutter-audio.c deleted file mode 100644 index df595eb4d..000000000 --- a/clutter/clutter-audio.c +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:clutter-audio - * @short_description: Object for playback of audio files. - * - * #ClutterAudio is an object that plays audio files. - */ - -#include "clutter-audio.h" -#include "clutter-main.h" -#include "clutter-private.h" /* for DBG */ -#include "clutter-marshal.h" - -#include -#include - -#include - -struct _ClutterAudioPrivate -{ - GstElement *playbin; - char *uri; - gboolean can_seek; - int buffer_percent; - int duration; - guint tick_timeout_id; -}; - -enum { - PROP_0, - /* ClutterMedia proprs */ - PROP_URI, - PROP_PLAYING, - PROP_POSITION, - PROP_VOLUME, - PROP_CAN_SEEK, - PROP_BUFFER_PERCENT, - PROP_DURATION -}; - - -#define TICK_TIMEOUT 0.5 - -static void clutter_media_init (ClutterMediaInterface *iface); - -static gboolean tick_timeout (ClutterAudio *audio); - -G_DEFINE_TYPE_EXTENDED (ClutterAudio, \ - clutter_audio, \ - G_TYPE_OBJECT, \ - 0, \ - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_MEDIA, \ - clutter_media_init)); - -/* Interface implementation */ - -static void -set_uri (ClutterMedia *media, - const char *uri) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - GstState state, pending; - - g_return_if_fail (CLUTTER_IS_AUDIO (audio)); - - priv = audio->priv; - - if (!priv->playbin) - return; - - g_free (priv->uri); - - if (uri) - { - priv->uri = g_strdup (uri); - - /** - * Ensure the tick timeout is installed. - * - * We also have it installed in PAUSED state, because - * seeks etc may have a delayed effect on the position. - **/ - if (priv->tick_timeout_id == 0) - { - priv->tick_timeout_id = g_timeout_add (TICK_TIMEOUT * 1000, - (GSourceFunc) tick_timeout, - audio); - } - } - else - { - priv->uri = NULL; - - if (priv->tick_timeout_id > 0) - { - g_source_remove (priv->tick_timeout_id); - priv->tick_timeout_id = 0; - } - } - - priv->can_seek = FALSE; - priv->duration = 0; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - state = pending; - - gst_element_set_state (priv->playbin, GST_STATE_NULL); - - g_object_set (priv->playbin, - "uri", uri, - NULL); - - /** - * Restore state. - **/ - if (uri) - gst_element_set_state (priv->playbin, state); - - /* - * Emit notififications for all these to make sure UI is not showing - * any properties of the old URI. - */ - g_object_notify (G_OBJECT (audio), "uri"); - g_object_notify (G_OBJECT (audio), "can-seek"); - g_object_notify (G_OBJECT (audio), "duration"); - g_object_notify (G_OBJECT (audio), "position"); - -} - -static const char * -get_uri (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), NULL); - - priv = audio->priv; - - return priv->uri; -} - -static void -set_playing (ClutterMedia *media, - gboolean playing) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - - g_return_if_fail (CLUTTER_IS_AUDIO (audio)); - - priv = audio->priv; - - if (!priv->playbin) - return; - - if (priv->uri) - { - GstState state; - - if (playing) - state = GST_STATE_PLAYING; - else - state = GST_STATE_PAUSED; - - gst_element_set_state (audio->priv->playbin, state); - } - else - { - if (playing) - g_warning ("Tried to play, but no URI is loaded."); - } - - g_object_notify (G_OBJECT (audio), "playing"); - g_object_notify (G_OBJECT (audio), "position"); -} - -static gboolean -get_playing (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - GstState state, pending; - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), FALSE); - - priv = audio->priv; - - if (!priv->playbin) - return FALSE; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - return (pending == GST_STATE_PLAYING); - else - return (state == GST_STATE_PLAYING); -} - -static void -set_position (ClutterMedia *media, - int position) /* seconds */ -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - GstState state, pending; - - g_return_if_fail (CLUTTER_IS_AUDIO (audio)); - - priv = audio->priv; - - if (!priv->playbin) - return; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - state = pending; - - gst_element_set_state (priv->playbin, GST_STATE_PAUSED); - - gst_element_seek (priv->playbin, - 1.0, - GST_FORMAT_TIME, - GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, - position * GST_SECOND, - 0, 0); - - gst_element_set_state (priv->playbin, state); -} - -static int -get_position (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - GstQuery *query; - gint64 position; - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), -1); - - priv = audio->priv; - - if (!priv->playbin) - return -1; - - query = gst_query_new_position (GST_FORMAT_TIME); - - if (gst_element_query (priv->playbin, query)) - gst_query_parse_position (query, NULL, &position); - else - position = 0; - - gst_query_unref (query); - - return (position / GST_SECOND); -} - -static void -set_volume (ClutterMedia *media, - double volume) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - - g_return_if_fail (CLUTTER_IS_AUDIO (audio)); - // g_return_if_fail (volume >= 0.0 && volume <= GST_VOL_MAX); - - priv = audio->priv; - - if (!priv->playbin) - return; - - g_object_set (G_OBJECT (audio->priv->playbin), - "volume", volume, - NULL); - - g_object_notify (G_OBJECT (audio), "volume"); -} - -static double -get_volume (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - ClutterAudioPrivate *priv; - double volume; - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), 0.0); - - priv = audio->priv; - - if (!priv->playbin) - return 0.0; - - g_object_get (priv->playbin, - "volume", &volume, - NULL); - - return volume; -} - -static gboolean -can_seek (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), FALSE); - - return audio->priv->can_seek; -} - -static int -get_buffer_percent (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), -1); - - return audio->priv->buffer_percent; -} - -static int -get_duration (ClutterMedia *media) -{ - ClutterAudio *audio = CLUTTER_AUDIO(media); - - g_return_val_if_fail (CLUTTER_IS_AUDIO (audio), -1); - - return audio->priv->duration; -} - -static void -clutter_media_init (ClutterMediaInterface *iface) -{ - iface->set_uri = set_uri; - iface->get_uri = get_uri; - iface->set_playing = set_playing; - iface->get_playing = get_playing; - iface->set_position = set_position; - iface->get_position = get_position; - iface->set_volume = set_volume; - iface->get_volume = get_volume; - iface->can_seek = can_seek; - iface->get_buffer_percent = get_buffer_percent; - iface->get_duration = get_duration; -} - -static void -clutter_audio_dispose (GObject *object) -{ - ClutterAudio *self; - ClutterAudioPrivate *priv; - - self = CLUTTER_AUDIO(object); - priv = self->priv; - - /* FIXME: flush an errors off bus ? */ - /* gst_bus_set_flushing (priv->bus, TRUE); */ - - if (priv->playbin) - { - gst_element_set_state (priv->playbin, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (priv->playbin)); - priv->playbin = NULL; - } - - if (priv->tick_timeout_id > 0) - { - g_source_remove (priv->tick_timeout_id); - priv->tick_timeout_id = 0; - } - - G_OBJECT_CLASS (clutter_audio_parent_class)->dispose (object); -} - -static void -clutter_audio_finalize (GObject *object) -{ - ClutterAudio *self; - ClutterAudioPrivate *priv; - - self = CLUTTER_AUDIO(object); - priv = self->priv; - - if (priv->uri) - g_free(priv->uri); - - G_OBJECT_CLASS (clutter_audio_parent_class)->finalize (object); -} - -static void -clutter_audio_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterAudio *audio; - - audio = CLUTTER_AUDIO(object); - - switch (property_id) - { - case PROP_URI: - clutter_media_set_uri (CLUTTER_MEDIA(audio), - g_value_get_string (value)); - break; - case PROP_PLAYING: - clutter_media_set_playing (CLUTTER_MEDIA(audio), - g_value_get_boolean (value)); - break; - case PROP_POSITION: - clutter_media_set_position (CLUTTER_MEDIA(audio), - g_value_get_int (value)); - break; - case PROP_VOLUME: - clutter_media_set_volume (CLUTTER_MEDIA(audio), - g_value_get_double (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -clutter_audio_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterAudio *audio; - ClutterMedia *media; - - audio = CLUTTER_AUDIO (object); - media = CLUTTER_MEDIA (audio); - - switch (property_id) - { - case PROP_URI: - g_value_set_string (value, clutter_media_get_uri (media)); - break; - case PROP_PLAYING: - g_value_set_boolean (value, clutter_media_get_playing (media)); - break; - case PROP_POSITION: - g_value_set_int (value, clutter_media_get_position (media)); - break; - case PROP_VOLUME: - g_value_set_double (value, clutter_media_get_volume (media)); - break; - case PROP_CAN_SEEK: - g_value_set_boolean (value, clutter_media_get_can_seek (media)); - break; - case PROP_BUFFER_PERCENT: - g_value_set_int (value, clutter_media_get_buffer_percent (media)); - break; - case PROP_DURATION: - g_value_set_int (value, clutter_media_get_duration (media)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -clutter_audio_class_init (ClutterAudioClass *klass) -{ - GObjectClass *object_class; - - object_class = (GObjectClass*)klass; - - object_class->dispose = clutter_audio_dispose; - object_class->finalize = clutter_audio_finalize; - object_class->set_property = clutter_audio_set_property; - object_class->get_property = clutter_audio_get_property; - - /* Interface props */ - - g_object_class_override_property (object_class, PROP_URI, "uri"); - g_object_class_override_property (object_class, PROP_PLAYING, "playing"); - g_object_class_override_property (object_class, PROP_POSITION, "position"); - g_object_class_override_property (object_class, PROP_VOLUME, "volume"); - g_object_class_override_property (object_class, PROP_CAN_SEEK, "can-seek"); - g_object_class_override_property (object_class, PROP_DURATION, "duration"); - g_object_class_override_property (object_class, PROP_BUFFER_PERCENT, - "buffer-percent" ); -} - -static void -bus_message_error_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - GError *error; - - error = NULL; - gst_message_parse_error (message, &error, NULL); - - g_signal_emit_by_name (CLUTTER_MEDIA(audio), "error", error); - - g_error_free (error); -} - -static void -bus_message_eos_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - g_object_notify (G_OBJECT (audio), "position"); - - g_signal_emit_by_name (CLUTTER_MEDIA(audio), "eos"); -} - -static void -bus_message_tag_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - GstTagList *tag_list; - - gst_message_parse_tag (message, &tag_list); - - g_signal_emit_by_name (CLUTTER_MEDIA(audio), - "metadata-available", - tag_list); - - gst_tag_list_free (tag_list); -} - -static void -bus_message_buffering_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - const GstStructure *str; - - str = gst_message_get_structure (message); - if (!str) - return; - - if (!gst_structure_get_int (str, - "buffer-percent", - &audio->priv->buffer_percent)) - return; - - g_object_notify (G_OBJECT (audio), "buffer-percent"); -} - -static void -bus_message_duration_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - GstFormat format; - gint64 duration; - - gst_message_parse_duration (message, - &format, - &duration); - - if (format != GST_FORMAT_TIME) - return; - - audio->priv->duration = duration / GST_SECOND; - - g_object_notify (G_OBJECT (audio), "duration"); -} - -static void -bus_message_state_change_cb (GstBus *bus, - GstMessage *message, - ClutterAudio *audio) -{ - gpointer src; - GstState old_state, new_state; - - src = GST_MESSAGE_SRC (message); - - if (src != audio->priv->playbin) - return; - - gst_message_parse_state_changed (message, &old_state, &new_state, NULL); - - if (old_state == GST_STATE_READY && - new_state == GST_STATE_PAUSED) - { - GstQuery *query; - - /** - * Determine whether we can seek. - **/ - query = gst_query_new_seeking (GST_FORMAT_TIME); - - if (gst_element_query (audio->priv->playbin, query)) { - gst_query_parse_seeking (query, - NULL, - &audio->priv->can_seek, - NULL, - NULL); - } else { - /* - * Could not query for ability to seek. Determine - * using URI. - */ - - if (g_str_has_prefix (audio->priv->uri, - "http://")) { - audio->priv->can_seek = FALSE; - } else { - audio->priv->can_seek = TRUE; - } - } - - gst_query_unref (query); - - g_object_notify (G_OBJECT (audio), "can-seek"); - - /** - * Determine the duration. - **/ - query = gst_query_new_duration (GST_FORMAT_TIME); - - if (gst_element_query (audio->priv->playbin, query)) - { - gint64 duration; - - gst_query_parse_duration (query, NULL, &duration); - - audio->priv->duration = duration / GST_SECOND; - - g_object_notify (G_OBJECT (audio), "duration"); - } - - gst_query_unref (query); - } -} - -static gboolean -tick_timeout (ClutterAudio *audio) -{ - g_object_notify (G_OBJECT (audio), "position"); - - return TRUE; -} - -static void -fakesink_handoff_cb (GstElement *fakesrc, - GstBuffer *buffer, - GstPad *pad, - gpointer user_data) -{ - GstStructure *structure; - int width, height; - GdkPixbuf *pixb; - - structure = gst_caps_get_structure(GST_CAPS(buffer->caps), 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - /* FIXME: We really dont want to do this every time as gobject creation - * really need a clutter_texture_set_from_data call ? - */ - pixb = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer), - GDK_COLORSPACE_RGB, - FALSE, - 8, - width, - height, - (3 * width + 3) &~ 3, - NULL, - NULL); - - if (pixb) - { - clutter_texture_set_pixbuf (CLUTTER_TEXTURE(user_data), pixb); - g_object_unref(G_OBJECT(pixb)); - } -} - -static gboolean -lay_pipeline (ClutterAudio *audio) -{ - ClutterAudioPrivate *priv; - GstElement *audio_sink = NULL; - - priv = audio->priv; - - priv->playbin = gst_element_factory_make ("playbin", "playbin"); - - if (!priv->playbin) - { - g_warning ("Unable to create playbin GST element."); - return FALSE; - } - - audio_sink = gst_element_factory_make ("gconfaudiosink", "audio-sink"); - if (!audio_sink) - { - audio_sink = gst_element_factory_make ("autoaudiosink", "audio-sink"); - if (!audio_sink) - { - audio_sink = gst_element_factory_make ("alsasink", "audio-sink"); - g_warning ("Could not create a GST audio_sink. " - "Audio unavailable."); - - if (!audio_sink) /* Need to bother ? */ - audio_sink = gst_element_factory_make ("fakesink", "audio-sink"); - } - } - - g_object_set (G_OBJECT (priv->playbin), - "audio-sink", audio_sink, - NULL); - - return TRUE; -} - -static void -clutter_audio_init (ClutterAudio *audio) -{ - ClutterAudioPrivate *priv; - GstBus *bus; - - priv = g_new0 (ClutterAudioPrivate, 1); - audio->priv = priv; - - if (!lay_pipeline(audio)) - { - g_warning("Failed to initiate suitable playback pipeline."); - return; - } - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->playbin)); - - gst_bus_add_signal_watch (bus); - - g_signal_connect_object (bus, - "message::error", - G_CALLBACK (bus_message_error_cb), - audio, - 0); - - g_signal_connect_object (bus, - "message::eos", - G_CALLBACK (bus_message_eos_cb), - audio, - 0); - - g_signal_connect_object (bus, - "message::tag", - G_CALLBACK (bus_message_tag_cb), - audio, - 0); - - g_signal_connect_object (bus, - "message::buffering", - G_CALLBACK (bus_message_buffering_cb), - audio, - 0); - - g_signal_connect_object (bus, - "message::duration", - G_CALLBACK (bus_message_duration_cb), - audio, - 0); - - g_signal_connect_object (bus, - "message::state-changed", - G_CALLBACK (bus_message_state_change_cb), - audio, - 0); - - gst_object_unref (GST_OBJECT (bus)); - - return; -} - -/** - * clutter_audio_new: - * - * Creates #ClutterAudio object. - * - * Return value: A newly allocated #ClutterAudio object. - */ -ClutterAudio* -clutter_audio_new (void) -{ - return g_object_new (CLUTTER_TYPE_AUDIO, NULL); -} - diff --git a/clutter/clutter-audio.h b/clutter/clutter-audio.h deleted file mode 100644 index 99914d453..000000000 --- a/clutter/clutter-audio.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _HAVE_CLUTTER_AUDIO_H -#define _HAVE_CLUTTER_AUDIO_H - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_AUDIO clutter_audio_get_type() - -#define CLUTTER_AUDIO(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_AUDIO, ClutterAudio)) - -#define CLUTTER_AUDIO_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_AUDIO, ClutterAudioClass)) - -#define CLUTTER_IS_AUDIO(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_AUDIO)) - -#define CLUTTER_IS_AUDIO_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_AUDIO)) - -#define CLUTTER_AUDIO_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_AUDIO, ClutterAudioClass)) - -typedef struct _ClutterAudio ClutterAudio; -typedef struct _ClutterAudioClass ClutterAudioClass; -typedef struct _ClutterAudioPrivate ClutterAudioPrivate; - -/* #define CLUTTER_AUDIO_ERROR clutter_audio_error_quark() */ - -struct _ClutterAudio -{ - GObject parent; - ClutterAudioPrivate *priv; -}; - -struct _ClutterAudioClass -{ - GObjectClass parent_class; - - /* Future padding */ - void (* _clutter_reserved1) (void); - void (* _clutter_reserved2) (void); - void (* _clutter_reserved3) (void); - void (* _clutter_reserved4) (void); - void (* _clutter_reserved5) (void); - void (* _clutter_reserved6) (void); -}; - -GType clutter_audio_get_type (void) G_GNUC_CONST; -ClutterAudio *clutter_audio_new (void); - -G_END_DECLS - -#endif diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 5e20c0b8f..e611606c8 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -41,8 +41,6 @@ #include "clutter-stage.h" #include "clutter-private.h" -#include /* for gst_init() */ - typedef struct { GSource source; @@ -551,8 +549,6 @@ clutter_init (int *argc, char ***argv) XInitThreads(); - gst_init (argc, argv); - context->main_loops = NULL; context->main_loop_level = 0; diff --git a/clutter/clutter-media.c b/clutter/clutter-media.c deleted file mode 100644 index 49a664035..000000000 --- a/clutter/clutter-media.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:clutter-media - * @short_description: An interface for controlling playback of media data. - * - * #ClutterMedia is an interface for controlling playback of media data. - */ - -#include "config.h" - -#include "clutter-media.h" -#include "clutter-main.h" -#include "clutter-enum-types.h" -#include "clutter-private.h" /* for DBG */ - -static void clutter_media_base_init (gpointer g_class); - -GType -clutter_media_get_type (void) -{ - static GType media_type = 0; - - if (!media_type) - { - static const GTypeInfo media_info = - { - sizeof (ClutterMediaInterface), - clutter_media_base_init, - NULL, - }; - - media_type = g_type_register_static (G_TYPE_INTERFACE, "ClutterMedia", - &media_info, 0); - } - - return media_type; -} - -static void -clutter_media_base_init (gpointer g_iface) -{ - static gboolean initialized = FALSE; - - if (!initialized) - { - initialized = TRUE; - - /* props */ - - g_object_interface_install_property - (g_iface, - g_param_spec_string - ("uri", - "URI", - "The loaded URI.", - NULL, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boolean - ("playing", - "Playing", - "TRUE if playing.", - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("position", - "Position", - "The position in the current stream in seconds.", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_double - ("volume", - "Volume", - "The audio volume.", - 0, 100, 50, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boolean - ("can-seek", - "Can seek", - "TRUE if the current stream is seekable.", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("buffer-percent", - "Buffer percent", - "The percentage the current stream buffer is filled.", - 0, 100, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - g_object_interface_install_property - (g_iface, - g_param_spec_int - ("duration", - "Duration", - "The duration of the current stream in seconds.", - 0, G_MAXINT, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB)); - - /* signals */ - - g_signal_new ("metadata-available", - CLUTTER_TYPE_MEDIA, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaInterface, - metadata_available), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - g_signal_new ("eos", - CLUTTER_TYPE_MEDIA, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaInterface, - eos), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_signal_new ("error", - CLUTTER_TYPE_MEDIA, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaInterface, - error), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - } -} - -/** - * clutter_media_set_uri: - * @media: #ClutterMedia object - * @uri: Uri - * - * Sets the uri of @media to @uri. - */ -void -clutter_media_set_uri (ClutterMedia *media, - const char *uri) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - CLUTTER_MEDIA_GET_INTERFACE (media)->set_uri (media, uri); -} - -/** - * clutter_media_get_uri: - * @media: A #ClutterMedia object - * - * Retrieves the URI from @media. - * - * Return value: The URI as a string. - */ -const char* -clutter_media_get_uri (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_uri (media); -} - -/** - * clutter_media_set_playing: - * @media: A #ClutterMedia object - * @playing: TRUE to start playing, FALSE to stop. - * - * Starts or stops @media playing. - */ -void -clutter_media_set_playing (ClutterMedia *media, - gboolean playing) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - CLUTTER_MEDIA_GET_INTERFACE (media)->set_playing (media, playing); -} - -/** - * clutter_media_get_playing: - * @media: A #ClutterMedia object - * - * Retrieves the state of @media. - * - * Return value: TRUE if playing, FALSE if stopped. - */ -gboolean -clutter_media_get_playing (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), FALSE); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_playing (media); -} - -/** - * clutter_media_set_position: - * @media: A #ClutterMedia object - * @position: The desired position. - * - * Sets the playback position of @media to @position. - */ -void -clutter_media_set_position (ClutterMedia *media, - int position) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - CLUTTER_MEDIA_GET_INTERFACE (media)->set_position (media, position); -} - -/** - * clutter_media_get_position: - * @media: A #ClutterMedia object - * - * Retrieves the position of @media. - * - * Return value: The playback position. - */ -int -clutter_media_get_position (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_position (media); -} - -/** - * clutter_media_set_volume: - * @media: A #ClutterMedia object - * @volume: The volume as a double between 0.0 and 1.0 - * - * Sets the playback volume of @media to @volume. - */ -void -clutter_media_set_volume (ClutterMedia *media, - double volume) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - CLUTTER_MEDIA_GET_INTERFACE (media)->set_volume (media, volume); -} - -/** - * clutter_media_get_volume: - * @media: A #ClutterMedia object - * - * Retrieves the playback volume of @media. - * - * Return value: The playback volume between 0.0 and 1.0 - */ -double -clutter_media_get_volume (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0.0); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_volume (media); -} - -/** - * clutter_media_get_can_seek: - * @media: A #ClutterMedia object - * - * Retrieves whether @media is seekable or not. - * - * Return value: TRUE if @media can seek, FALSE otherwise. - */ -gboolean -clutter_media_get_can_seek (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), FALSE); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->can_seek (media); -} - -/** - * clutter_media_get_buffer_percent: - * @media: A #ClutterMedia object - * - * Retrieves the amount of the stream that is buffered. - * - * Return value: percentage value - */ -int -clutter_media_get_buffer_percent (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_buffer_percent (media); -} - -/** - * clutter_media_get_duration: - * @media: A #ClutterMedia object - * - * Retrieves the duration of the media stream that @media represents. - * - * Return value: The length of the media stream. - */ -int -clutter_media_get_duration (ClutterMedia *media) -{ - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); - - return CLUTTER_MEDIA_GET_INTERFACE (media)->get_duration (media); -} - -/* helper funcs */ - -/** - * clutter_media_set_filename: - * @media: A #ClutterMedia object - * @filename: A filename to media file. - * - * Converts a filesystem path to a uri and calls clutter_media_set_uri - */ -void -clutter_media_set_filename (ClutterMedia *media, const gchar *filename) -{ - gchar *uri; - - if (filename[0] != '/') - uri = g_strdup_printf ("file://%s/%s", g_get_current_dir (), filename); - else - uri = g_strdup_printf ("file://%s", filename); - - clutter_media_set_uri (media, uri); - - g_free(uri); -} diff --git a/clutter/clutter-media.h b/clutter/clutter-media.h deleted file mode 100644 index 293030b30..000000000 --- a/clutter/clutter-media.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _HAVE_CLUTTER_MEDIA_H -#define _HAVE_CLUTTER_MEDIA_H - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_MEDIA clutter_media_get_type() - -#define CLUTTER_MEDIA(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_MEDIA, ClutterMedia)) - -#define CLUTTER_IS_MEDIA(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_MEDIA)) - -#define CLUTTER_MEDIA_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((obj), \ - CLUTTER_TYPE_MEDIA, ClutterMediaInterface)) - -typedef struct _ClutterMedia ClutterMedia; -typedef struct _ClutterMediaInterface ClutterMediaInterface; - -struct _ClutterMediaInterface -{ - GTypeInterface base_iface; - void (*set_uri) (ClutterMedia *media, - const char *uri); - const char *(*get_uri) (ClutterMedia *media); - void (*set_playing) (ClutterMedia *media, - gboolean playing); - gboolean (*get_playing) (ClutterMedia *media); - void (*set_position) (ClutterMedia *media, - int position); - int (*get_position) (ClutterMedia *media); - void (*set_volume) (ClutterMedia *media, - double volume); - double (*get_volume) (ClutterMedia *media); - gboolean (*can_seek) (ClutterMedia *media); - int (*get_buffer_percent) (ClutterMedia *media); - int (*get_duration) (ClutterMedia *media); - - /* signals */ - - void (* metadata_available) (ClutterMedia *media, - GstTagList *tag_list); - void (* eos) (ClutterMedia *media); - void (* error) (ClutterMedia *media, - GError *error); -}; - - -GType clutter_media_get_type (void); - -void -clutter_media_set_uri (ClutterMedia *media, - const char *uri); -const char * -clutter_media_get_uri (ClutterMedia *media); - -void -clutter_media_set_playing (ClutterMedia *media, - gboolean playing); - -gboolean -clutter_media_get_playing (ClutterMedia *media); - -void -clutter_media_set_position (ClutterMedia *media, - int position); - -int -clutter_media_get_position (ClutterMedia *media); - -void -clutter_media_set_volume (ClutterMedia *media, - double volume); - -double -clutter_media_get_volume (ClutterMedia *media); - -gboolean -clutter_media_get_can_seek (ClutterMedia *media); - -int -clutter_media_get_buffer_percent (ClutterMedia *media); - -int -clutter_media_get_duration (ClutterMedia *media); - -void -clutter_media_set_filename (ClutterMedia *media, - const gchar *filename); - -G_END_DECLS - -#endif diff --git a/clutter/clutter-video-texture.c b/clutter/clutter-video-texture.c deleted file mode 100644 index b799c8471..000000000 --- a/clutter/clutter-video-texture.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:clutter-video-texture - * @short_description: Actor for playback of video files. - * - * #ClutterVideoTexture is a #ClutterTexture that plays video files. - */ - -#include "clutter-video-texture.h" -#include "clutter-main.h" -#include "clutter-private.h" /* for DBG */ -#include "clutter-marshal.h" - -#include -#include -#include - -#include -#include - -#include - -struct _ClutterVideoTexturePrivate -{ - GstElement *playbin; - char *uri; - gboolean can_seek; - int buffer_percent; - int duration; - gboolean force_aspect_ratio; - guint tick_timeout_id; -}; - -enum { - PROP_0, - /* ClutterMedia proprs */ - PROP_URI, - PROP_PLAYING, - PROP_POSITION, - PROP_VOLUME, - PROP_CAN_SEEK, - PROP_BUFFER_PERCENT, - PROP_DURATION, - - /* Extra texture props */ - PROP_FORCE_ASPECT_RATIO -}; - - -#define TICK_TIMEOUT 0.5 - -static void clutter_media_init (ClutterMediaInterface *iface); - -static gboolean tick_timeout (ClutterVideoTexture *video_texture); - -G_DEFINE_TYPE_EXTENDED (ClutterVideoTexture, \ - clutter_video_texture, \ - CLUTTER_TYPE_TEXTURE, \ - 0, \ - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_MEDIA, \ - clutter_media_init)); - -/* Interface implementation */ - -static void -set_uri (ClutterMedia *media, - const char *uri) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - GstState state, pending; - - g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); - - priv = video_texture->priv; - - if (!priv->playbin) - return; - - g_free (priv->uri); - - if (uri) - { - priv->uri = g_strdup (uri); - - /** - * Ensure the tick timeout is installed. - * - * We also have it installed in PAUSED state, because - * seeks etc may have a delayed effect on the position. - **/ - if (priv->tick_timeout_id == 0) - { - priv->tick_timeout_id = g_timeout_add (TICK_TIMEOUT * 1000, - (GSourceFunc) tick_timeout, - video_texture); - } - } - else - { - priv->uri = NULL; - - if (priv->tick_timeout_id > 0) - { - g_source_remove (priv->tick_timeout_id); - priv->tick_timeout_id = 0; - } - } - - priv->can_seek = FALSE; - priv->duration = 0; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - state = pending; - - gst_element_set_state (priv->playbin, GST_STATE_NULL); - - g_object_set (priv->playbin, - "uri", uri, - NULL); - - /** - * Restore state. - **/ - if (uri) - gst_element_set_state (priv->playbin, state); - - /* - * Emit notififications for all these to make sure UI is not showing - * any properties of the old URI. - */ - g_object_notify (G_OBJECT (video_texture), "uri"); - g_object_notify (G_OBJECT (video_texture), "can-seek"); - g_object_notify (G_OBJECT (video_texture), "duration"); - g_object_notify (G_OBJECT (video_texture), "position"); - -} - -static const char * -get_uri (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), NULL); - - priv = video_texture->priv; - - return priv->uri; -} - -static void -set_playing (ClutterMedia *media, - gboolean playing) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); - - priv = video_texture->priv; - - if (!priv->playbin) - return; - - if (priv->uri) - { - GstState state; - - if (playing) - state = GST_STATE_PLAYING; - else - state = GST_STATE_PAUSED; - - gst_element_set_state (video_texture->priv->playbin, state); - } - else - { - if (playing) - g_warning ("Tried to play, but no URI is loaded."); - } - - g_object_notify (G_OBJECT (video_texture), "playing"); - g_object_notify (G_OBJECT (video_texture), "position"); -} - -static gboolean -get_playing (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - GstState state, pending; - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); - - priv = video_texture->priv; - - if (!priv->playbin) - return FALSE; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - return (pending == GST_STATE_PLAYING); - else - return (state == GST_STATE_PLAYING); -} - -static void -set_position (ClutterMedia *media, - int position) /* seconds */ -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - GstState state, pending; - - g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); - - priv = video_texture->priv; - - if (!priv->playbin) - return; - - gst_element_get_state (priv->playbin, &state, &pending, 0); - - if (pending) - state = pending; - - gst_element_set_state (priv->playbin, GST_STATE_PAUSED); - - gst_element_seek (priv->playbin, - 1.0, - GST_FORMAT_TIME, - GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, - position * GST_SECOND, - 0, 0); - - gst_element_set_state (priv->playbin, state); -} - -static int -get_position (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - GstQuery *query; - gint64 position; - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); - - priv = video_texture->priv; - - if (!priv->playbin) - return -1; - - query = gst_query_new_position (GST_FORMAT_TIME); - - if (gst_element_query (priv->playbin, query)) - gst_query_parse_position (query, NULL, &position); - else - position = 0; - - gst_query_unref (query); - - return (position / GST_SECOND); -} - -static void -set_volume (ClutterMedia *media, - double volume) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture)); - // g_return_if_fail (volume >= 0.0 && volume <= GST_VOL_MAX); - - priv = video_texture->priv; - - if (!priv->playbin) - return; - - g_object_set (G_OBJECT (video_texture->priv->playbin), - "volume", volume, - NULL); - - g_object_notify (G_OBJECT (video_texture), "volume"); -} - -static double -get_volume (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - ClutterVideoTexturePrivate *priv; - double volume; - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), 0.0); - - priv = video_texture->priv; - - if (!priv->playbin) - return 0.0; - - g_object_get (priv->playbin, - "volume", &volume, - NULL); - - return volume; -} - -static gboolean -can_seek (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), FALSE); - - return video_texture->priv->can_seek; -} - -static int -get_buffer_percent (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); - - return video_texture->priv->buffer_percent; -} - -static int -get_duration (ClutterMedia *media) -{ - ClutterVideoTexture *video_texture = CLUTTER_VIDEO_TEXTURE(media); - - g_return_val_if_fail (CLUTTER_IS_VIDEO_TEXTURE (video_texture), -1); - - return video_texture->priv->duration; -} - -static void -clutter_media_init (ClutterMediaInterface *iface) -{ - iface->set_uri = set_uri; - iface->get_uri = get_uri; - iface->set_playing = set_playing; - iface->get_playing = get_playing; - iface->set_position = set_position; - iface->get_position = get_position; - iface->set_volume = set_volume; - iface->get_volume = get_volume; - iface->can_seek = can_seek; - iface->get_buffer_percent = get_buffer_percent; - iface->get_duration = get_duration; -} - -static void -clutter_video_texture_dispose (GObject *object) -{ - ClutterVideoTexture *self; - ClutterVideoTexturePrivate *priv; - - self = CLUTTER_VIDEO_TEXTURE(object); - priv = self->priv; - - /* FIXME: flush an errors off bus ? */ - /* gst_bus_set_flushing (priv->bus, TRUE); */ - - if (priv->playbin) - { - gst_element_set_state (priv->playbin, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (priv->playbin)); - priv->playbin = NULL; - } - - if (priv->tick_timeout_id > 0) - { - g_source_remove (priv->tick_timeout_id); - priv->tick_timeout_id = 0; - } - - G_OBJECT_CLASS (clutter_video_texture_parent_class)->dispose (object); -} - -static void -clutter_video_texture_finalize (GObject *object) -{ - ClutterVideoTexture *self; - ClutterVideoTexturePrivate *priv; - - self = CLUTTER_VIDEO_TEXTURE(object); - priv = self->priv; - - if (priv->uri) - g_free(priv->uri); - - G_OBJECT_CLASS (clutter_video_texture_parent_class)->finalize (object); -} - -static void -clutter_video_texture_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterVideoTexture *video_texture; - - video_texture = CLUTTER_VIDEO_TEXTURE(object); - - switch (property_id) - { - case PROP_URI: - clutter_media_set_uri (CLUTTER_MEDIA(video_texture), - g_value_get_string (value)); - break; - case PROP_PLAYING: - clutter_media_set_playing (CLUTTER_MEDIA(video_texture), - g_value_get_boolean (value)); - break; - case PROP_POSITION: - clutter_media_set_position (CLUTTER_MEDIA(video_texture), - g_value_get_int (value)); - break; - case PROP_VOLUME: - clutter_media_set_volume (CLUTTER_MEDIA(video_texture), - g_value_get_double (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -clutter_video_texture_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterVideoTexture *video_texture; - ClutterMedia *media; - - video_texture = CLUTTER_VIDEO_TEXTURE (object); - media = CLUTTER_MEDIA (video_texture); - - switch (property_id) - { - case PROP_URI: - g_value_set_string (value, clutter_media_get_uri (media)); - break; - case PROP_PLAYING: - g_value_set_boolean (value, clutter_media_get_playing (media)); - break; - case PROP_POSITION: - g_value_set_int (value, clutter_media_get_position (media)); - break; - case PROP_VOLUME: - g_value_set_double (value, clutter_media_get_volume (media)); - break; - case PROP_CAN_SEEK: - g_value_set_boolean (value, clutter_media_get_can_seek (media)); - break; - case PROP_BUFFER_PERCENT: - g_value_set_int (value, clutter_media_get_buffer_percent (media)); - break; - case PROP_DURATION: - g_value_set_int (value, clutter_media_get_duration (media)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -clutter_video_texture_class_init (ClutterVideoTextureClass *klass) -{ - GObjectClass *object_class; - ClutterActorClass *actor_class; - - object_class = (GObjectClass*)klass; - actor_class = (ClutterActorClass*)klass; - - object_class->dispose = clutter_video_texture_dispose; - object_class->finalize = clutter_video_texture_finalize; - object_class->set_property = clutter_video_texture_set_property; - object_class->get_property = clutter_video_texture_get_property; - - /* Interface props */ - - g_object_class_override_property (object_class, PROP_URI, "uri"); - g_object_class_override_property (object_class, PROP_PLAYING, "playing"); - g_object_class_override_property (object_class, PROP_POSITION, "position"); - g_object_class_override_property (object_class, PROP_VOLUME, "volume"); - g_object_class_override_property (object_class, PROP_CAN_SEEK, "can-seek"); - g_object_class_override_property (object_class, PROP_DURATION, "duration"); - g_object_class_override_property (object_class, PROP_BUFFER_PERCENT, - "buffer-percent" ); -} - -static void -bus_message_error_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - GError *error; - - error = NULL; - gst_message_parse_error (message, &error, NULL); - - g_signal_emit_by_name (CLUTTER_MEDIA(video_texture), "error", error); - - g_error_free (error); -} - -static void -bus_message_eos_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - g_object_notify (G_OBJECT (video_texture), "position"); - - g_signal_emit_by_name (CLUTTER_MEDIA(video_texture), "eos"); -} - -static void -bus_message_tag_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - GstTagList *tag_list; - - gst_message_parse_tag (message, &tag_list); - - g_signal_emit_by_name (CLUTTER_MEDIA(video_texture), - "metadata-available", - tag_list); - - gst_tag_list_free (tag_list); -} - -static void -bus_message_buffering_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - const GstStructure *str; - - str = gst_message_get_structure (message); - if (!str) - return; - - if (!gst_structure_get_int (str, - "buffer-percent", - &video_texture->priv->buffer_percent)) - return; - - g_object_notify (G_OBJECT (video_texture), "buffer-percent"); -} - -static void -bus_message_duration_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - GstFormat format; - gint64 duration; - - gst_message_parse_duration (message, - &format, - &duration); - - if (format != GST_FORMAT_TIME) - return; - - video_texture->priv->duration = duration / GST_SECOND; - - g_object_notify (G_OBJECT (video_texture), "duration"); -} - -static void -bus_message_actor_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - const GstStructure *str; - - str = gst_message_get_structure (message); - if (!str) - return; -} - -static void -bus_message_state_change_cb (GstBus *bus, - GstMessage *message, - ClutterVideoTexture *video_texture) -{ - gpointer src; - GstState old_state, new_state; - - src = GST_MESSAGE_SRC (message); - - if (src != video_texture->priv->playbin) - return; - - gst_message_parse_state_changed (message, &old_state, &new_state, NULL); - - if (old_state == GST_STATE_READY && - new_state == GST_STATE_PAUSED) - { - GstQuery *query; - - /** - * Determine whether we can seek. - **/ - query = gst_query_new_seeking (GST_FORMAT_TIME); - - if (gst_element_query (video_texture->priv->playbin, query)) { - gst_query_parse_seeking (query, - NULL, - &video_texture->priv->can_seek, - NULL, - NULL); - } else { - /* - * Could not query for ability to seek. Determine - * using URI. - */ - - if (g_str_has_prefix (video_texture->priv->uri, - "http://")) { - video_texture->priv->can_seek = FALSE; - } else { - video_texture->priv->can_seek = TRUE; - } - } - - gst_query_unref (query); - - g_object_notify (G_OBJECT (video_texture), "can-seek"); - - /** - * Determine the duration. - **/ - query = gst_query_new_duration (GST_FORMAT_TIME); - - if (gst_element_query (video_texture->priv->playbin, query)) - { - gint64 duration; - - gst_query_parse_duration (query, NULL, &duration); - - video_texture->priv->duration = duration / GST_SECOND; - - g_object_notify (G_OBJECT (video_texture), "duration"); - } - - gst_query_unref (query); - } -} - -static gboolean -tick_timeout (ClutterVideoTexture *video_texture) -{ - g_object_notify (G_OBJECT (video_texture), "position"); - - return TRUE; -} - -static void -fakesink_handoff_cb (GstElement *fakesrc, - GstBuffer *buffer, - GstPad *pad, - gpointer user_data) -{ - GstStructure *structure; - int width, height; - GdkPixbuf *pixb; - - structure = gst_caps_get_structure(GST_CAPS(buffer->caps), 0); - gst_structure_get_int(structure, "width", &width); - gst_structure_get_int(structure, "height", &height); - - /* FIXME: We really dont want to do this every time as gobject creation - * really need a clutter_texture_set_from_data call ? - */ - pixb = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer), - GDK_COLORSPACE_RGB, - FALSE, - 8, - width, - height, - (3 * width + 3) &~ 3, - NULL, - NULL); - - if (pixb) - { - clutter_texture_set_pixbuf (CLUTTER_TEXTURE(user_data), pixb); - g_object_unref(G_OBJECT(pixb)); - } -} - -static gboolean -lay_pipeline (ClutterVideoTexture *video_texture) -{ - ClutterVideoTexturePrivate *priv; - GstElement *audio_sink = NULL; - GstElement *video_sink, *video_bin, *video_capsfilter; - GstCaps *video_filtercaps; - GstPad *video_ghost_pad; - - priv = video_texture->priv; - - priv->playbin = gst_element_factory_make ("playbin", "playbin"); - - if (!priv->playbin) - { - g_warning ("Unable to create playbin GST actor."); - return FALSE; - } - - audio_sink = gst_element_factory_make ("gconfaudiosink", "audio-sink"); - if (!audio_sink) - { - audio_sink = gst_element_factory_make ("autoaudiosink", "audio-sink"); - if (!audio_sink) - { - audio_sink = gst_element_factory_make ("alsasink", "audio-sink"); - g_warning ("Could not create a GST audio_sink. " - "Audio unavailable."); - - if (!audio_sink) /* Need to bother ? */ - audio_sink = gst_element_factory_make ("fakesink", "audio-sink"); - } - } - - video_sink = gst_element_factory_make ("fakesink", "fakesink"); - - if (video_sink == NULL) - { - g_warning ("Could not create actor 'fakesink' for video playback"); - priv->playbin = NULL; - return FALSE; - } - - video_bin = gst_bin_new ("video-bin"); - - video_capsfilter = gst_element_factory_make ("capsfilter", - "video-capsfilter"); - - video_filtercaps - = gst_caps_new_simple("video/x-raw-rgb", - "bpp", G_TYPE_INT, 24, - "depth", G_TYPE_INT, 24, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - /* >> 8 for 24bpp */ - "red_mask", G_TYPE_INT, 0xff0000, - "green_mask", G_TYPE_INT, 0xff00, - "blue_mask", G_TYPE_INT, 0xff, - "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "framerate", GST_TYPE_FRACTION_RANGE, - 0, 1, G_MAXINT, 1, - NULL); - - g_object_set(G_OBJECT(video_capsfilter), - "caps", video_filtercaps, - NULL); - - gst_bin_add(GST_BIN(video_bin), video_capsfilter); - gst_bin_add(GST_BIN(video_bin), video_sink); - - gst_element_link (video_capsfilter, video_sink); - - video_ghost_pad = gst_ghost_pad_new ("sink", - gst_element_get_pad (video_capsfilter, - "sink")); - gst_element_add_pad (video_bin, video_ghost_pad); - - g_object_set (G_OBJECT(video_sink), - "signal-handoffs", TRUE, - "sync", TRUE, - /* Enable frame drops. FIXME: export setting in API ? */ - "qos", TRUE, - NULL); - - g_signal_connect(G_OBJECT (video_sink), - "handoff", - G_CALLBACK(fakesink_handoff_cb), - video_texture); - - g_object_set (G_OBJECT (priv->playbin), - "video-sink", video_bin, - "audio-sink", audio_sink, - NULL); - - return TRUE; -} - -static void -clutter_video_texture_init (ClutterVideoTexture *video_texture) -{ - ClutterVideoTexturePrivate *priv; - GstBus *bus; - - priv = g_new0 (ClutterVideoTexturePrivate, 1); - video_texture->priv = priv; - - if (!lay_pipeline(video_texture)) - { - g_warning("Failed to initiate suitable playback pipeline."); - return; - } - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->playbin)); - - gst_bus_add_signal_watch (bus); - - g_signal_connect_object (bus, - "message::error", - G_CALLBACK (bus_message_error_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::eos", - G_CALLBACK (bus_message_eos_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::tag", - G_CALLBACK (bus_message_tag_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::buffering", - G_CALLBACK (bus_message_buffering_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::duration", - G_CALLBACK (bus_message_duration_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::actor", - G_CALLBACK (bus_message_actor_cb), - video_texture, - 0); - - g_signal_connect_object (bus, - "message::state-changed", - G_CALLBACK (bus_message_state_change_cb), - video_texture, - 0); - - gst_object_unref (GST_OBJECT (bus)); - - return; -} - -/** - * clutter_video_texture_new: - * - * Creates a video texture. - * - * Return value: A #ClutterActor implementing a displaying a video texture. - */ -ClutterActor* -clutter_video_texture_new (void) -{ - ClutterVideoTexture *video_texture; - - video_texture = g_object_new (CLUTTER_TYPE_VIDEO_TEXTURE, - "tiled", FALSE, - "pixel-format", GL_RGB, - /* As RGB below needed for Big Endian */ - "pixel-type", GL_UNSIGNED_BYTE, - NULL); - - return CLUTTER_ACTOR(video_texture); -} - diff --git a/clutter/clutter-video-texture.h b/clutter/clutter-video-texture.h deleted file mode 100644 index f258a02e5..000000000 --- a/clutter/clutter-video-texture.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _HAVE_CLUTTER_VIDEO_TEXTURE_H -#define _HAVE_CLUTTER_VIDEO_TEXTURE_H - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_VIDEO_TEXTURE clutter_video_texture_get_type() - -#define CLUTTER_VIDEO_TEXTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTexture)) - -#define CLUTTER_VIDEO_TEXTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass)) - -#define CLUTTER_IS_VIDEO_TEXTURE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE)) - -#define CLUTTER_IS_VIDEO_TEXTURE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_VIDEO_TEXTURE)) - -#define CLUTTER_VIDEO_TEXTURE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE, ClutterVideoTextureClass)) - -typedef struct _ClutterVideoTexture ClutterVideoTexture; -typedef struct _ClutterVideoTextureClass ClutterVideoTextureClass; -typedef struct _ClutterVideoTexturePrivate ClutterVideoTexturePrivate; - -/* #define CLUTTER_VIDEO_TEXTURE_ERROR clutter_video_texture_error_quark() */ - -struct _ClutterVideoTexture -{ - ClutterTexture parent; - ClutterVideoTexturePrivate *priv; -}; - -struct _ClutterVideoTextureClass -{ - ClutterTextureClass parent_class; - - /* Future padding */ - void (* _clutter_reserved1) (void); - void (* _clutter_reserved2) (void); - void (* _clutter_reserved3) (void); - void (* _clutter_reserved4) (void); - void (* _clutter_reserved5) (void); - void (* _clutter_reserved6) (void); -}; - -GType clutter_video_texture_get_type (void) G_GNUC_CONST; -ClutterActor *clutter_video_texture_new (void); - -G_END_DECLS - -#endif diff --git a/clutter/clutter.h b/clutter/clutter.h index 164bd0129..c73a33904 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -3,7 +3,6 @@ #include "clutter-keysyms.h" #include "clutter-main.h" -#include "clutter-media.h" #include "clutter-color.h" #include "clutter-util.h" #include "clutter-event.h" @@ -16,10 +15,8 @@ #include "clutter-group.h" #include "clutter-texture.h" #include "clutter-clone-texture.h" -#include "clutter-video-texture.h" #include "clutter-label.h" #include "clutter-alpha.h" -#include "clutter-audio.h" #include "clutter-enum-types.h" #endif diff --git a/configure.ac b/configure.ac index 339c06753..9ebb6975c 100644 --- a/configure.ac +++ b/configure.ac @@ -94,15 +94,6 @@ PKG_CHECK_MODULES(CLUTTER_DEPS, [$pkg_modules]) dnl ======================================================================== -GST_MAJORMINOR=0.10 - -pkg_modules="gstreamer-$GST_MAJORMINOR gstreamer-plugins-base-$GST_MAJORMINOR" -PKG_CHECK_MODULES(GST, [$pkg_modules]) - -GST_LIBS="$GST_LIBS -lgstinterfaces-$GST_MAJORMINOR -lgstvideo-$GST_MAJORMINOR -lgstaudio-$GST_MAJORMINOR" - -dnl ======================================================================== - AC_ARG_ENABLE(gtk, [AC_HELP_STRING([--enable-gtk], [Buld Gtk+ Clutter widget])],enable_gtk="$enableval",enable_gtk=no) @@ -125,8 +116,6 @@ GTK_DOC_CHECK([1.0]) dnl ======================================================================== AC_SUBST(GCC_FLAGS) -AC_SUBST(GST_CFLAGS) -AC_SUBST(GST_LIBS) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) diff --git a/doc/reference/ChangeLog b/doc/reference/ChangeLog index 1a4b5d30a..c34a98493 100644 --- a/doc/reference/ChangeLog +++ b/doc/reference/ChangeLog @@ -1,3 +1,7 @@ +2006-08-30 Jorn Baayen + + * Makefile.am: + 2006-07-06 Emmanuele Bassi * clutter-sections.txt: Add clutter_actor_has_clip() and diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 24bda45ab..778c4b660 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -72,8 +72,7 @@ expand_content_files= # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -# FIXME: $(GST_CFLAGS) needed for clutter_media metadata - togo.. -INCLUDES=-I$(top_srcdir) $(CLUTTER_CFLAGS) $(GST_CFLAGS) +INCLUDES=-I$(top_srcdir) $(CLUTTER_CFLAGS) GTKDOC_LIBS=$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la $(CLUTTER_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. diff --git a/examples/Makefile.am b/examples/Makefile.am index 64ede2554..89bb3df93 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,51 +1,29 @@ -noinst_PROGRAMS = test video-player video-cube super-oh behave +noinst_PROGRAMS = test super-oh behave INCLUDES = -I$(top_srcdir)/ test_SOURCES = test.c -test_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +test_CFLAGS = $(CLUTTER_CFLAGS) $(GCONF_CFLAGS) test_LDFLAGS = \ $(CLUTTER_LIBS) \ - $(GST_LIBS) \ - $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la - -video_player_SOURCES = video-player.c -video_player_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -video_player_LDFLAGS = \ - $(CLUTTER_LIBS) \ - $(GST_LIBS) \ - $(GCONF_LIBS) \ - $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la - -video_cube_SOURCES = video-cube.c -video_cube_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) -video_cube_LDFLAGS = \ - $(CLUTTER_LIBS) \ - $(GST_LIBS) \ $(GCONF_LIBS) \ $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la super_oh_SOURCES = super-oh.c -super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GCONF_CFLAGS) super_oh_LDFLAGS = \ $(CLUTTER_LIBS) \ - $(GST_LIBS) \ $(GCONF_LIBS) \ $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la behave_SOURCES = behave.c -behave_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS) +behave_CFLAGS = $(CLUTTER_CFLAGS) $(GCONF_CFLAGS) behave_LDFLAGS = \ $(CLUTTER_LIBS) \ - $(GST_LIBS) \ $(GCONF_LIBS) \ $(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la EXTRA_DIST = redhand.png \ clutter-logo-800x600.png \ - media-actions-pause.png \ - media-actions-start.png \ - vid-panel.png \ README diff --git a/examples/README b/examples/README index 1e2e3895e..f62ead674 100644 --- a/examples/README +++ b/examples/README @@ -18,19 +18,6 @@ There are: Spinning OH logos. Click to dissapear. - o video-player. - - Simple fullscreen video player. - - - Move mouse to see controls. - - Hit q or Esc to exit, p to toggle pause state. - - Has some useless cheesy effects built in. - - Hit e to flip the video. - - o video-cube. - - Pure evil. A nasty hack to do a video cube with clutter. - Could be done much nicer. Also see http://svn.o-hand.com/repos/misc/trunk/opt for a simple diff --git a/examples/media-actions-pause.png b/examples/media-actions-pause.png deleted file mode 100644 index 38614e1c7a9719357549b2e5f7590290febc76ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6434 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 diff --git a/examples/media-actions-start.png b/examples/media-actions-start.png deleted file mode 100644 index b3c6170bf638824c63abe4900d531c9403b7357f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8053 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 D9};(B diff --git a/examples/vid-panel.png b/examples/vid-panel.png deleted file mode 100644 index d7c3e18ee7cdc87022f6e0ce089d6808035398b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98180 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

lNr!L(IN+y((TeW&gE9CA-n(?n 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 diff --git a/examples/video-cube.c b/examples/video-cube.c deleted file mode 100644 index 87c4b9502..000000000 --- a/examples/video-cube.c +++ /dev/null @@ -1,272 +0,0 @@ -/* HACK HACK. HACK. - * This is just a quick hack to see if a 3D type video cube - * would be possible with clutter. It needs many hacks cleaning. - */ - -#include -#include - -#include /* for M_PI */ - -#define WINWIDTH 800 -#define WINHEIGHT 600 - -/* lazy globals */ -static float xrot, yrot, zrot; - -/* Avoid needing GLUT perspective call */ -static void -frustum (GLfloat left, - GLfloat right, - GLfloat bottom, - GLfloat top, - GLfloat nearval, - GLfloat farval) -{ - GLfloat x, y, a, b, c, d; - GLfloat m[16]; - - x = (2.0 * nearval) / (right - left); - y = (2.0 * nearval) / (top - bottom); - a = (right + left) / (right - left); - b = (top + bottom) / (top - bottom); - c = -(farval + nearval) / ( farval - nearval); - d = -(2.0 * farval * nearval) / (farval - nearval); - -#define M(row,col) m[col*4+row] - M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; - M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; - M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; - M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; -#undef M - - glMultMatrixf (m); -} - -static void -perspective (GLfloat fovy, - GLfloat aspect, - GLfloat zNear, - GLfloat zFar) -{ - GLfloat xmin, xmax, ymin, ymax; - - ymax = zNear * tan (fovy * M_PI / 360.0); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; - - frustum (xmin, xmax, ymin, ymax, zNear, zFar); -} - - -/* video texture subclass */ - -#define CLUTTER_TYPE_VIDEO_TEXTURE_CUBE clutter_video_texture_cube_get_type() - -#define CLUTTER_VIDEO_TEXTURE_CUBE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCube)) - -#define CLUTTER_VIDEO_TEXTURE_CUBE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCubeClass)) - -#define CLUTTER_IS_VIDEO_TEXTURE_CUBE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE_CUBE)) - -#define CLUTTER_IS_VIDEO_TEXTURE_CUBE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_VIDEO_TEXTURE_CUBE)) - -#define CLUTTER_VIDEO_TEXTURE_CUBE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, ClutterVideoTextureCubeClass)) - -typedef struct ClutterVideoTextureCubePrivate ClutterVideoTextureCubePrivate ; - -typedef struct ClutterVideoTextureCube -{ - ClutterVideoTexture parent; - ClutterVideoTextureCubePrivate *priv; - -} -ClutterVideoTextureCube; - -typedef struct ClutterVideoTextureCubeClass -{ - ClutterVideoTextureClass parent_class; -} -ClutterVideoTextureCubeClass; - -GType clutter_video_texture_cube_get_type (void); - -G_DEFINE_TYPE (ClutterVideoTextureCube, clutter_video_texture_cube, CLUTTER_TYPE_VIDEO_TEXTURE); - - -static void -clutter_video_texture_cube_paint (ClutterActor *self) -{ - if (clutter_texture_get_pixbuf (CLUTTER_TEXTURE(self)) == NULL) - return; - - if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR(self))) - clutter_actor_realize (CLUTTER_ACTOR(self)); - - if (!clutter_texture_has_generated_tiles (CLUTTER_TEXTURE(self))) - return; - - /* HACK: sets up a 3D tranform matrix other than regular 2D one */ - /* FIXME: figure out how to nicely combine both within clutter */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - perspective (45.0f, - (GLfloat)WINWIDTH/(GLfloat)WINHEIGHT, - 0.1f, - 100.0f); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - /* back camera out a little */ - glTranslatef(0.0f,0.0f,-3.0f); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - - glShadeModel(GL_SMOOTH); - glClearDepth(1.0f); - glDepthFunc(GL_LEQUAL); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glRotatef(xrot,1.0f,0.0f,0.0f); - glRotatef(yrot,0.0f,1.0f,0.0f); - glRotatef(zrot,0.0f,0.0f,1.0f); - - /* HACK: Cheat as just bind to first tiled as squared */ - clutter_texture_bind_tile (CLUTTER_TEXTURE(self), 0); - - glBegin(GL_QUADS); - // Front Face - glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); - glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); - // Back Face - glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); - glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); - // Top Face - glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); - glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); - glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); - // Bottom Face - glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); - glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); - glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); - // Right face - glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); - // Left Face - glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); - glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); - glEnd(); - - - /* HACK: reset to regular transform */ -#if 0 - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - glOrtho (0, WINWIDTH, WINHEIGHT, 0, -1, 1); - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); -#endif - - /* rotate */ - xrot+=1.0f; - yrot+=1.0f; - zrot+=1.0f; -} - -static void -clutter_video_texture_cube_class_init (ClutterVideoTextureCubeClass *klass) -{ - GObjectClass *gobject_class; - ClutterActorClass *actor_class; - - gobject_class = (GObjectClass*)klass; - actor_class = (ClutterActorClass*)klass; - - actor_class->paint = clutter_video_texture_cube_paint; -} - -static void -clutter_video_texture_cube_init (ClutterVideoTextureCube *self) -{ - -} - -ClutterActor* -clutter_video_texture_cube_new (GError **err) -{ - return CLUTTER_ACTOR(g_object_new (CLUTTER_TYPE_VIDEO_TEXTURE_CUBE, - /* "tiled", FALSE, */ - NULL)); -} - - -int -main (int argc, char *argv[]) -{ - ClutterActor *label, *texture, *vtexture; - ClutterActor *stage; - GdkPixbuf *pixbuf; - GError *err = NULL; - - if (argc < 2) - g_error("%s