CVSROOT: /sources/gnash Module name: gnash Changes by: Bastiaan Jacques <bjacques> 08/02/20 21:39:45
Modified files: gui : gtk.cpp Removed files: libbase : gstgnashsrc.c gstgnashsrc.h libmedia/gst : sound_handler_gst.cpp sound_handler_gst.h Log message: Remove unused files. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gtk.cpp?cvsroot=gnash&r1=1.148&r2=1.149 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/gstgnashsrc.c?cvsroot=gnash&r1=1.5&r2=0 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/gstgnashsrc.h?cvsroot=gnash&r1=1.10&r2=0 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/sound_handler_gst.cpp?cvsroot=gnash&r1=1.11&r2=0 http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/sound_handler_gst.h?cvsroot=gnash&r1=1.9&r2=0 Patches: Index: gui/gtk.cpp =================================================================== RCS file: /sources/gnash/gnash/gui/gtk.cpp,v retrieving revision 1.148 retrieving revision 1.149 diff -u -b -r1.148 -r1.149 --- gui/gtk.cpp 20 Feb 2008 19:49:49 -0000 1.148 +++ gui/gtk.cpp 20 Feb 2008 21:39:44 -0000 1.149 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: gtk.cpp,v 1.148 2008/02/20 19:49:49 bjacques Exp $ */ +/* $Id: gtk.cpp,v 1.149 2008/02/20 21:39:44 bjacques Exp $ */ #ifdef HAVE_CONFIG_H #include "gnashconfig.h" @@ -117,6 +117,7 @@ log_debug (_("Created top level window")); } + // XXXbjacques: why do we need this? //gtk_container_set_reallocate_redraws(GTK_CONTAINER (_window), TRUE); @@ -161,6 +162,14 @@ setupEvents(); gtk_widget_realize(_window); + gdk_window_set_events(_window->window, + GdkEventMask(GDK_EXPOSURE_MASK | GDK_VISIBILITY_NOTIFY_MASK)); + + GdkWindow* parent = gdk_window_get_parent(_window->window); + gdk_window_set_events(parent, + GdkEventMask(GDK_EXPOSURE_MASK | GDK_VISIBILITY_NOTIFY_MASK)); + + gtk_widget_show(_drawingArea); gtk_widget_show(_window); @@ -392,7 +401,7 @@ G_CALLBACK (realize_event), NULL); g_signal_connect(G_OBJECT (_drawingArea), "configure_event", G_CALLBACK (configure_event), this); - g_signal_connect(G_OBJECT (_drawingArea), "expose_event", + g_signal_connect(G_OBJECT (_window), "expose_event", G_CALLBACK (expose_event), this); return true; @@ -1615,7 +1624,7 @@ GdkEventExpose *const event, const gpointer data) { -// GNASH_REPORT_FUNCTION; + GNASH_REPORT_FUNCTION; GtkGui* gui = static_cast<GtkGui*>(data); Index: libbase/gstgnashsrc.c =================================================================== RCS file: libbase/gstgnashsrc.c diff -N libbase/gstgnashsrc.c --- libbase/gstgnashsrc.c 1 Jul 2007 10:54:08 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,328 +0,0 @@ -// -// Copyright (C) 2005, 2006 Free Software Foundation, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Based on the filesrc and fdsrc element in Gstreamer-core. -// - -/* $Id: gstgnashsrc.c,v 1.5 2007/07/01 10:54:08 bjacques Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstgnashsrc.h" - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - - -GST_DEBUG_CATEGORY_STATIC (gst_gnash_src_debug); -#define GST_CAT_DEFAULT gst_gnash_src_debug - -static const GstElementDetails gst_gnash_src_details = -GST_ELEMENT_DETAILS ("Gnash source", - "Gnash", - "Use callback to read from Gnash", - "Gnash team"); - -/* GnashSrc signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -#define DEFAULT_BLOCKSIZE 4*1024 -#define DEFAULT_DATA NULL -#define DEFAULT_CALLBACKS NULL - -enum -{ - ARG_0, - ARG_DATA, - ARG_CALLBACKS -}; - -static void gst_gnash_src_finalize (GObject * object); - -static void gst_gnash_src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_gnash_src_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static gboolean gst_gnash_src_start (GstBaseSrc * basesrc); -static gboolean gst_gnash_src_stop (GstBaseSrc * basesrc); - -static gboolean gst_gnash_src_is_seekable (GstBaseSrc * src); -static gboolean gst_gnash_src_get_size (GstBaseSrc * src, guint64 * size); -static GstFlowReturn gst_gnash_src_create (GstPushSrc * src, GstBuffer ** buffer); -static gboolean gst_gnash_src_do_seek (GstBaseSrc * src, GstSegment * s); - -static void -_do_init (GType gnashsrc_type) -{ - UNUSEDPAR(gnashsrc_type); -/* static const GInterfaceInfo urihandler_info = { - gst_gnash_src_uri_handler_init, - NULL, - NULL - };*/ - - GST_DEBUG_CATEGORY_INIT (gst_gnash_src_debug, "gnashsrc", 0, "gnashsrc element"); -} - -GST_BOILERPLATE_FULL (GstGnashSrc, gst_gnash_src, GstElement, GST_TYPE_PUSH_SRC, _do_init); - -static void -gst_gnash_src_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - - gst_element_class_set_details (gstelement_class, &gst_gnash_src_details); -} - -static void -gst_gnash_src_class_init (GstGnashSrcClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseSrcClass *gstbasesrc_class; - GstPushSrcClass *gstpush_src_class; - - gobject_class = G_OBJECT_CLASS (klass); - gstelement_class = GST_ELEMENT_CLASS (klass); - gstbasesrc_class = GST_BASE_SRC_CLASS (klass); - gstpush_src_class = GST_PUSH_SRC_CLASS (klass); - - gobject_class->set_property = gst_gnash_src_set_property; - gobject_class->get_property = gst_gnash_src_get_property; - - g_object_class_install_property (gobject_class, ARG_DATA, - g_param_spec_pointer ("data", NULL, NULL, (GParamFlags)G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, ARG_CALLBACKS, - g_param_spec_pointer ("callbacks", NULL, NULL, (GParamFlags)G_PARAM_READWRITE)); - - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gnash_src_finalize); - - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnash_src_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnash_src_stop); - gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_gnash_src_is_seekable); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnash_src_get_size); - gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_gnash_src_do_seek); - - gstpush_src_class->create = GST_DEBUG_FUNCPTR (gst_gnash_src_create); -} - -static void -gst_gnash_src_init (GstGnashSrc * src, GstGnashSrcClass * g_class) -{ - UNUSEDPAR(g_class); - src->data = NULL; - src->callbacks = NULL; - src->read_position = 0; -} - -static void -gst_gnash_src_finalize (GObject * object) -{ - GstGnashSrc *src; - - src = GST_GNASH_SRC (object); - - free (src->callbacks); - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_gnash_src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstGnashSrc *src; - - g_return_if_fail (GST_IS_GNASH_SRC (object)); - - src = GST_GNASH_SRC (object); - - switch (prop_id) { - case ARG_DATA: - src->data = g_value_get_pointer (value); - break; - case ARG_CALLBACKS: - src->callbacks = g_value_get_pointer (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_gnash_src_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstGnashSrc *src; - UNUSEDPAR(value); - g_return_if_fail (GST_IS_GNASH_SRC (object)); - - src = GST_GNASH_SRC (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -// -// Below is the functions used get make this plugin work. -// - -// Used for seeking -static gboolean -gst_gnash_src_do_seek (GstBaseSrc * basesrc, GstSegment * seg) -{ - - GstGnashSrc *src; - off_t res; - src = GST_GNASH_SRC (basesrc); - - if (seg->format != GST_FORMAT_BYTES) return FALSE; - - struct gnashsrc_callback *gc; - gc = src->callbacks; - res = gc->seek (src->data, seg->start, SEEK_CUR); - return TRUE; - -} - -// Output the next buffer -static GstFlowReturn -gst_gnash_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) -{ - GstGnashSrc *src; - src = GST_GNASH_SRC (psrc); - int ret, blocksize; - GstBuffer *buf; - - struct gnashsrc_callback *gc; - gc = src->callbacks; - - blocksize = GST_BASE_SRC (src)->blocksize; - buf = gst_buffer_new_and_alloc (blocksize); - - GST_LOG_OBJECT (src, "Reading %d bytes", blocksize); - - ret = gc->read(src->data, (void*)GST_BUFFER_DATA(buf), blocksize); - - if (G_UNLIKELY (ret < 0)) goto could_not_read; - - /* other files should eos if they read 0 and more was requested */ - if (G_UNLIKELY (ret == 0 && blocksize > 0)) - goto eos; - - blocksize = ret; - - GST_BUFFER_SIZE (buf) = blocksize; - GST_BUFFER_OFFSET (buf) = src->read_position; - GST_BUFFER_OFFSET_END (buf) = src->read_position + blocksize; - - *outbuf = buf; - - src->read_position += blocksize; - - return GST_FLOW_OK; - - /* ERROR */ -could_not_read: - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } -eos: - { - GST_DEBUG ("non-regular file hits EOS"); - gst_buffer_unref (buf); - return GST_FLOW_UNEXPECTED; - } -} - -static gboolean -gst_gnash_src_is_seekable (GstBaseSrc * basesrc) -{ - GstGnashSrc *src = GST_GNASH_SRC (basesrc); - - return src->seekable; -} - -// Get size of the file. Not sure how we shall handles this... -static gboolean -gst_gnash_src_get_size (GstBaseSrc * basesrc, guint64 * size) -{ - GstGnashSrc *src; - - src = GST_GNASH_SRC (basesrc); - - if (!src->seekable) { - /* If it isn't seekable, we won't know the length (but fstat will still - * succeed, and wrongly say our length is zero. */ - return FALSE; - } - return FALSE; - - // Since it's a streamed video file we probably don't know the length, so we - // tell it's 50000. Maybe we should just return FALSE? - *size = 500000; - return TRUE; - -} - -/* open the file and mmap it, necessary to go to READY state */ -static gboolean -gst_gnash_src_start (GstBaseSrc * basesrc) -{ - GstGnashSrc *src = GST_GNASH_SRC (basesrc); - - if (src->data == NULL || src->callbacks == NULL) { - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,(("No data or callback struct supplied.")), (NULL)); - return FALSE; - } - - src->read_position = 0; - GST_INFO_OBJECT (src, "Ready for reading using callbacks"); - - // TODO: set seekable to false when real streaming - src->seekable = TRUE; - - return TRUE; - -} - -/* stop and free */ -static gboolean -gst_gnash_src_stop (GstBaseSrc * basesrc) -{ - GstGnashSrc *src = GST_GNASH_SRC (basesrc); - UNUSEDPAR(src); - return TRUE; -} - Index: libbase/gstgnashsrc.h =================================================================== RCS file: libbase/gstgnashsrc.h diff -N libbase/gstgnashsrc.h --- libbase/gstgnashsrc.h 21 Jan 2008 20:55:44 -0000 1.10 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,81 +0,0 @@ -// -// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Based on the filesrc and fdsrc element in Gstreamer-core -// - -/* $Id: gstgnashsrc.h,v 1.10 2008/01/21 20:55:44 rsavoye Exp $ */ - -#ifndef __GST_GNASH_SRC_H__ -#define __GST_GNASH_SRC_H__ - -#define UNUSEDPAR(x) { x = x; } - - -#include <gst/gst.h> -#include <gst/base/gstpushsrc.h> - -// Struct to contain the callback functions -struct gnashsrc_callback { - int (*read)(void* data, char* buf, int buf_size); - int (*seek)(void* data, int offset, int whence); -}; - -G_BEGIN_DECLS - -#define GST_TYPE_GNASH_SRC \ - (gst_gnash_src_get_type()) -#define GST_GNASH_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GNASH_SRC,GstGnashSrc)) -#define GST_GNASH_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GNASH_SRC,GstGnashSrcClass)) -#define GST_IS_GNASH_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GNASH_SRC)) -#define GST_IS_GNASH_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GNASH_SRC)) - -typedef struct _GstGnashSrc GstGnashSrc; -typedef struct _GstGnashSrcClass GstGnashSrcClass; - -/** - * GstGnashSrc: - * - * Opaque #GstGnashSrc structure. - */ -struct _GstGnashSrc { - GstPushSrc element; - - /*< private >*/ - - guint64 read_position; // position in the stream - - gpointer data; // data passes with the callbacks - gpointer callbacks; // struct with the callbacks - - gboolean seekable; // seekable or not - -}; - -struct _GstGnashSrcClass { - GstPushSrcClass parent_class; -}; - -GType gst_gnash_src_get_type (void); - -G_END_DECLS - -#endif /* __GST_GNASH_SRC_H__ */ Index: libmedia/gst/sound_handler_gst.cpp =================================================================== RCS file: libmedia/gst/sound_handler_gst.cpp diff -N libmedia/gst/sound_handler_gst.cpp --- libmedia/gst/sound_handler_gst.cpp 21 Jan 2008 23:10:15 -0000 1.11 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,906 +0,0 @@ -// sound_handler_gst.cpp: Audio output via GStreamer, for Gnash. -// -// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// - -// Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003 -// which has been donated to the Public Domain. - -/* $Id: sound_handler_gst.cpp,v 1.11 2008/01/21 23:10:15 rsavoye Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "gnashconfig.h" -#endif - -#include "utility.h" // for convert_raw_data - -#include <utility> // for std::make_pair - -// Assume people running --enable-media=gst know what they are doing -// (HAVE_GST_GST_H seems broken atm, specifically when an older glib -// install is around) -// - -#ifdef SOUND_GST - -#include "sound_handler_gst.h" -#include "gnash.h" -#include "log.h" -#include "types.h" // for IF_VERBOSE_* macros -#include <cmath> -#include <vector> - -#include <gst/gst.h> - -#define BUFFER_SIZE 5000 - -using namespace boost; - -namespace gnash { -namespace media { - -GST_sound_handler::GST_sound_handler() - : looping(false), - muted(false) -{ - // init gstreamer - gst_init(NULL, NULL); -} - -void -GST_sound_handler::delete_all_sounds() -{ - for (size_t i=0, e=m_sound_data.size(); i < e; ++i) { - stop_sound(i); - delete_sound(i); - } - m_sound_data.clear(); -} - -GST_sound_handler::~GST_sound_handler() -{ - delete_all_sounds(); -} - - -int GST_sound_handler::create_sound( - void* data_, - unsigned int data_bytes, - std::auto_ptr<SoundInfo> sinfo) -// Called to create a sample. We'll return a sample ID that -// can be use for playing it. -{ - - try_mutex::scoped_lock lock(_mutex); - - unsigned char* data = static_cast<unsigned char*>(data_); - - assert(sinfo.get()); - sound_data *sounddata = new sound_data; - if (!sounddata) { - log_error(_("could not allocate memory for sound data")); - return -1; - } - - sounddata->volume = 100; - sounddata->soundinfo = sinfo; - - switch (sounddata->soundinfo->getFormat()) - { - case AUDIO_CODEC_MP3: - case AUDIO_CODEC_RAW: - case AUDIO_CODEC_ADPCM: - case AUDIO_CODEC_UNCOMPRESSED: - case AUDIO_CODEC_NELLYMOSER: - case AUDIO_CODEC_NELLYMOSER_8HZ_MONO: - if ( data ) sounddata->append(data, data_bytes); - break; - - - default: - // Unhandled format. - log_error(_("Unknown sound format %d requested; gnash does not handle it"), (int)sounddata->soundinfo->getFormat()); - return -1; // Unhandled format, set to NULL. - } - - m_sound_data.push_back(sounddata); - - return m_sound_data.size()-1; -} - - -// this gets called when a stream gets more data -long GST_sound_handler::fill_stream_data(unsigned char* data, unsigned int data_bytes, unsigned int /*sample_count*/, int handle_id) -{ - try_mutex::scoped_lock lock(_mutex); - - // @@ does a negative handle_id have any meaning ? - // should we change it to unsigned instead ? - if (handle_id >= 0 && (unsigned int) handle_id < m_sound_data.size()) - { - sound_data* sounddata = m_sound_data[handle_id]; - - long startSize = sounddata->dataSize(); - - sounddata->append(data, data_bytes); - - // If playback has already started, we also update the active sounds - for (size_t i=0, e=sounddata->m_gst_elements.size(); i < e; ++i) { - gst_elements* sound = sounddata->m_gst_elements[i]; - sound->data_size = sounddata->dataSize(); - sound->set_data(sounddata->data()); - } - - return startSize; - } - else - { - delete [] data; - return 0; - } -} - -// This stops sounds when they are done playing -static gboolean sound_killer (gpointer user_data) -{ - gst_elements *gstelements = static_cast<gst_elements*>(user_data); - gst_element_set_state (GST_ELEMENT (gstelements->pipeline), GST_STATE_NULL); - return false; -} - -// The callback function which refills the buffer with data -void GST_sound_handler::callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data) -{ - gst_elements *gstelements = static_cast<gst_elements*>(user_data); - - try_mutex::scoped_try_lock lock(gstelements->handler->_mutex); - - // If we couldn't obtain a lock return to avoid a deadlock - if (!lock.locked()) { - - // We return nothing in this case to avoid noise being decoded and played - if (GST_BUFFER_SIZE(buffer) != 0 && GST_BUFFER_DATA(buffer)) { - GST_BUFFER_DATA(buffer) = 0; - GST_BUFFER_SIZE(buffer) = 0; - } - return; - } - - // First callback or after a couldn't-get-lock-return - if (GST_BUFFER_SIZE(buffer) == 0) { - if (gstelements->data_size > BUFFER_SIZE) { - GST_BUFFER_SIZE(buffer) = BUFFER_SIZE; - } else { - GST_BUFFER_SIZE(buffer) = gstelements->data_size; - } - - // Reallocate the required memory. - guint8* tmp_buf = new guint8[GST_BUFFER_SIZE(buffer)]; - memcpy(tmp_buf, GST_BUFFER_DATA(buffer), sizeof(buffer)); - - delete [] GST_BUFFER_DATA(buffer); - GST_BUFFER_DATA(buffer) = tmp_buf; - } - - // All the data has been given to the pipeline, so now we need to stop - // the pipeline. g_idle_add() makes sure sound_killer is called soon. - if (gstelements->position > gstelements->data_size) { - g_idle_add(sound_killer, user_data); - GST_BUFFER_SIZE(buffer) = 0; - GST_BUFFER_DATA(buffer) = 0; - return; - } - - const guint8* data_pos = gstelements->get_data_ptr(gstelements->position); - - // Last callback - the last re-fill - if (gstelements->position+BUFFER_SIZE > gstelements->data_size) { - - unsigned int chunk_size = gstelements->data_size-gstelements->position; - // Check if we should loop. If loop_count is 0 we have we just - // played the sound for the last (and perhaps first) time. - // If loop_count is anything else we continue to loop. - if (gstelements->loop_count == 0) { - GST_BUFFER_SIZE(buffer) = chunk_size; - memcpy(GST_BUFFER_DATA(buffer), data_pos, chunk_size); - gstelements->position += BUFFER_SIZE; - - gst_element_set_state (GST_ELEMENT (gstelements->input), GST_STATE_PAUSED); - - } else { - // Copy what's left of the data, and then fill the rest with "new" data. - memcpy(GST_BUFFER_DATA(buffer), data_pos, chunk_size); - memcpy(GST_BUFFER_DATA(buffer) + chunk_size, gstelements->get_data_ptr(0), GST_BUFFER_SIZE(buffer)- chunk_size); - gstelements->position = GST_BUFFER_SIZE(buffer) - chunk_size; - gstelements->loop_count--; - - } - - return; - - } - - // Standard re-fill - memcpy(GST_BUFFER_DATA(buffer), data_pos, BUFFER_SIZE); - gstelements->position += BUFFER_SIZE; - -} - - -void GST_sound_handler::play_sound(int sound_handle, int loop_count, int /*offset*/, long start_position, const std::vector<sound_envelope>* /*envelopes*/) -// Play the index'd sample. -{ - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists, or if audio is muted - if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size() || muted) - { - // Invalid handle, or audio is muted. - return; - } - - sound_data* sounddata = m_sound_data[sound_handle]; - - // If this is called from a streamsoundblocktag, we only start if this - // sound isn't already playing. - if (start_position > 0 && sounddata->m_gst_elements.size() > 0) { - return; - } - // Make sure sound actually got some data - if (sounddata->dataSize() < 1) { - IF_VERBOSE_MALFORMED_SWF( - log_swferror(_("Trying to play sound with size 0")); - ); - return; - } - - // Make a "gst_elements" for this sound which is latter placed on the vector of instances of this sound being played - gst_elements* gst_element = new gst_elements; - if (gst_element == NULL) { - log_error (_("Could not allocate memory for gst_element")); - return; - } - - // Set the handler - gst_element->handler = this; - - // Copy data-info to the "gst_elements" - gst_element->data_size = sounddata->dataSize(); - gst_element->set_data(sounddata->data()); - gst_element->position = start_position; - - // Set number of loop we should do. -1 is infinte loop, 0 plays it once, 1 twice etc. - gst_element->loop_count = loop_count; - - // create main pipeline - gst_element->pipeline = gst_pipeline_new (NULL); - - // create an audio sink - use oss, alsa or...? make a commandline option? - // we first try atudetect, then alsa, then oss, then esd, then...? -#if !defined(__NetBSD__) - gst_element->audiosink = gst_element_factory_make ("autoaudiosink", NULL); - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("alsasink", NULL); - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("osssink", NULL); -#endif - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("esdsink", NULL); - - // Check if the creation of the gstreamer pipeline, adder and audiosink was a succes - if (!gst_element->pipeline) { - log_error(_("The gstreamer pipeline element could not be created")); - } - if (!gst_element->audiosink) { - log_error(_("The gstreamer audiosink element could not be created")); - } - - // link adder and output to bin - gst_bin_add (GST_BIN (gst_element->pipeline), gst_element->audiosink); - - gst_element->bin = gst_bin_new(NULL); - gst_element->input = gst_element_factory_make ("fakesrc", NULL); - gst_element->capsfilter = gst_element_factory_make ("capsfilter", NULL); - gst_element->audioconvert = gst_element_factory_make ("audioconvert", NULL); - gst_element->audioresample = gst_element_factory_make ("audioresample", NULL); - gst_element->volume = gst_element_factory_make ("volume", NULL); - - // Put the gstreamer elements in the pipeline - gst_bin_add_many (GST_BIN (gst_element->bin), gst_element->input, - gst_element->capsfilter, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - - // Test if the fakesrc, typefind and audio* elements was correctly created - if (!gst_element->input - || !gst_element->capsfilter - || !gst_element->audioconvert - || !gst_element->audioresample) { - - log_error(_("Gstreamer element for audio handling could not be created")); - return; - } - - // Create a gstreamer decoder for the chosen sound. - - // Temp variables to make the code simpler and easier to read - audioCodecType soundFormat = sounddata->soundinfo->getFormat(); - bool soundStereo = sounddata->soundinfo->isStereo(); - boost::uint32_t soundSampleRate = sounddata->soundinfo->getSampleRate(); - - if (soundFormat == AUDIO_CODEC_MP3) { - - gst_element->decoder = gst_element_factory_make ("mad", NULL); - if (gst_element->decoder == NULL) { - gst_element->decoder = gst_element_factory_make ("flump3dec", NULL); - if (gst_element->decoder != NULL && !gst_default_registry_check_feature_version("flump3dec", 0, 10, 4)) - { - static bool warned=false; - if ( ! warned ) - { - // I keep getting these messages even if I hear sound... too much paranoia ? - log_debug(_("This version of fluendos mp3 plugin does not support flash streaming sounds, please upgrade to version 0.10.4 or higher")); - warned=true; - } - } - } - // Check if the element was correctly created - if (!gst_element->decoder) { - log_error(_("A gstreamer mp3-decoder element could not be created. You probably need to install a mp3-decoder plugin like gstreamer0.10-mad or gstreamer0.10-fluendo-mp3.")); - return; - } - gst_bin_add (GST_BIN (gst_element->bin), gst_element->decoder); - - // Set the info about the stream so that gstreamer knows what it is. - GstCaps *caps = gst_caps_new_simple ("audio/mpeg", - "mpegversion", G_TYPE_INT, 1, - "layer", G_TYPE_INT, 3, - "rate", G_TYPE_INT, soundSampleRate, - "channels", G_TYPE_INT, soundStereo ? 2 : 1, NULL); - g_object_set (G_OBJECT (gst_element->capsfilter), "caps", caps, NULL); - gst_caps_unref (caps); - - // setup fake source - g_object_set (G_OBJECT (gst_element->input), - "sizetype", 2, "can-activate-pull", FALSE, "signal-handoffs", TRUE, - "sizemax", BUFFER_SIZE, NULL); - // Setup the callback - gst_element->handoff_signal_id = g_signal_connect (gst_element->input, "handoff", G_CALLBACK (callback_handoff), gst_element); - - // link data, decoder, audio* and adder - gst_element_link_many (gst_element->input, - gst_element->capsfilter, - gst_element->decoder, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - - } else if (soundFormat == AUDIO_CODEC_ADPCM) { - gst_element->decoder = gst_element_factory_make ("ffdec_adpcm_swf", NULL); - - // Check if the element was correctly created - if (!gst_element->decoder) { - log_error(_("A gstreamer adpcm-decoder element could not be created. You probably need to install gst-ffmpeg.")); - return; - } - gst_bin_add (GST_BIN (gst_element->bin), gst_element->decoder); - - // Set the info about the stream so that gstreamer knows what it is. - GstCaps *caps = gst_caps_new_simple ("audio/x-adpcm", - "rate", G_TYPE_INT, soundSampleRate, - "channels", G_TYPE_INT, soundStereo ? 2 : 1, NULL); - g_object_set (G_OBJECT (gst_element->capsfilter), "caps", caps, NULL); - gst_caps_unref (caps); - - // setup fake source - g_object_set (G_OBJECT (gst_element->input), - "sizetype", 2, "can-activate-pull", FALSE, "signal-handoffs", TRUE, - "sizemax", BUFFER_SIZE, NULL); - // Setup the callback - gst_element->handoff_signal_id = g_signal_connect (gst_element->input, "handoff", G_CALLBACK (callback_handoff), gst_element); - - // link data, decoder, audio* and adder - gst_element_link_many (gst_element->input, - gst_element->capsfilter, - gst_element->decoder, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - - } else if (soundFormat == AUDIO_CODEC_NELLYMOSER_8HZ_MONO || soundFormat == AUDIO_CODEC_NELLYMOSER) { - return; - } else { - - // Set the info about the stream so that gstreamer knows what it is. - GstCaps *caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, soundSampleRate, - "channels", G_TYPE_INT, soundStereo ? 2 : 1, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "width", G_TYPE_INT, (sounddata->soundinfo->is16bit() ? 16 : 8), - "depth", G_TYPE_INT, 16, - //"signed", G_TYPE_INT, 1, - NULL); - g_object_set (G_OBJECT (gst_element->capsfilter), "caps", caps, NULL); - gst_caps_unref (caps); - - // setup fake source - g_object_set (G_OBJECT (gst_element->input), - "sizetype", 2, "can-activate-pull", FALSE, "signal-handoffs", TRUE, - "sizemax", BUFFER_SIZE, NULL); - // Setup the callback - gst_element->handoff_signal_id = g_signal_connect (gst_element->input, "handoff", G_CALLBACK (callback_handoff), gst_element); - - // Raw native sound-data, output directly - gst_element_link_many (gst_element->input, - gst_element->capsfilter, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - } - // Add ghostpad - GstPad *pad = gst_element_get_pad (gst_element->volume, "src"); - gst_element_add_pad (gst_element->bin, gst_ghost_pad_new ("src", pad)); - gst_object_unref (GST_OBJECT (pad)); - - // Add the bin to the main pipeline - gst_bin_add(GST_BIN (gst_element->pipeline), gst_element->bin); - // Link to the adder sink pad - GstPad *sinkpad = gst_element_get_pad (gst_element->audiosink, "sink"); - GstPad *srcpad = gst_element_get_pad (gst_element->bin, "src"); - gst_pad_link (srcpad, sinkpad); - gst_object_unref (GST_OBJECT (srcpad)); - gst_object_unref (GST_OBJECT (sinkpad)); - - // Set the volume - g_object_set (G_OBJECT (gst_element->volume), "volume", static_cast<double>(sounddata->volume) / 100.0, NULL); - - //gst_pad_add_event_probe(pad, G_CALLBACK(event_callback), sounddata); - - // Put the gst_element on the vector - sounddata->m_gst_elements.push_back(gst_element); - - // If not already playing, start doing it - gst_element_set_state (GST_ELEMENT (gst_element->pipeline), GST_STATE_PLAYING); - - ++_soundsStarted; - -} - - -void GST_sound_handler::stop_sound(int sound_handle) -{ - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) - { - // Invalid handle. - return; - } - - sound_data* sounddata = m_sound_data[sound_handle]; - - // Stop all the instances of this sound. - // TODO: fix the loop to use size_t instead of i - for (int i = sounddata->m_gst_elements.size()-1; i >= 0 ; i--) - { - gst_elements* elements = sounddata->m_gst_elements[i]; - - // Check if we can succesfully stop the elements - // playback - if not we skip cleaning this for now - // FIXME: what if it ain't possible to stop an element when this is called from ~GST_sound_handler - - // Disconnect signals - g_signal_handler_disconnect (elements->input, elements->handoff_signal_id); - - gst_element_set_state (GST_ELEMENT (elements->pipeline), GST_STATE_NULL); - gst_object_unref (GST_OBJECT (elements->pipeline)); - - // Delete the gst_element struct - // @@ we're deleting the elements from the start, so half-way of the loop we will be referring to undefined elements. Is this intended ? --strk; - delete elements; - sounddata->m_gst_elements.erase(sounddata->m_gst_elements.begin() + i); - } - - ++_soundsStopped; -} - - -void GST_sound_handler::delete_sound(int sound_handle) -// this gets called when it's done with a sample. -{ - try_mutex::scoped_lock lock(_mutex); - - if (sound_handle >= 0 && (unsigned int) sound_handle < m_sound_data.size()) - { - delete m_sound_data[sound_handle]; - m_sound_data.erase (m_sound_data.begin() + sound_handle); - } - -} - -// This will stop all sounds playing. Will cause problems if the soundhandler is made static -// and supplys sound_handling for many SWF's, since it will stop all sounds with no regard -// for what sounds is associated with what SWF. -void GST_sound_handler::stop_all_sounds() -{ - for (size_t i=0, e=m_sound_data.size(); i < e; ++i) - stop_sound(i); -} - -void -GST_sound_handler::reset() -{ - stop_all_sounds(); -} - - -// returns the sound volume level as an integer from 0 to 100, -// where 0 is off and 100 is full volume. The default setting is 100. -int GST_sound_handler::get_volume(int sound_handle) { - - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle >= 0 && (unsigned int) sound_handle < m_sound_data.size()) - { - return m_sound_data[sound_handle]->volume; - } else { - return 0; // Invalid handle - } -} - - -// A number from 0 to 100 representing a volume level. -// 100 is full volume and 0 is no volume. The default setting is 100. -void GST_sound_handler::set_volume(int sound_handle, int volume) { - - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) - { - // Invalid handle. - return; - } - - sound_data* sd = m_sound_data[sound_handle]; - - // Set volume for this sound. Should this only apply to the active sounds? - - sd->volume = volume; - - for (size_t i=0, n=sd->m_gst_elements.size(); i<n; ++i) - { - g_object_set ( - G_OBJECT (sd->m_gst_elements[i]->volume), - "volume", - static_cast<double>(volume/100.0), - NULL); - } - -} - -SoundInfo* GST_sound_handler::get_sound_info(int sound_handle) { - - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < m_sound_data.size()) - { - return m_sound_data[sound_handle]->soundinfo.get(); - } else { - return NULL; - } - -} - -// gnash calls this to mute audio -void GST_sound_handler::mute() { - stop_all_sounds(); - muted = true; -} - -// gnash calls this to unmute audio -void GST_sound_handler::unmute() { - muted = false; -} - -bool GST_sound_handler::is_muted() { - return muted; -} - - - -// The callback function which refills the buffer with data -void GST_sound_handler::callback_as_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data) -{ - gst_elements *gstelements = static_cast<gst_elements*>(user_data); - - try_mutex::scoped_try_lock lock(gstelements->handler->_mutex); - - // If we couldn't obtain a lock return to avoid a deadlock - if (!lock.locked()) { - - // We return nothing in this case to avoid noise being decoded and played - if (GST_BUFFER_SIZE(buffer) != 0 && GST_BUFFER_DATA(buffer)) { - GST_BUFFER_DATA(buffer) = 0; - GST_BUFFER_SIZE(buffer) = 0; - } - return; - } - - // First callback or after a couldn't-get-lock-return - if (GST_BUFFER_SIZE(buffer) == 0) { - if (gstelements->data_size > BUFFER_SIZE) { - GST_BUFFER_SIZE(buffer) = BUFFER_SIZE; - } else { - GST_BUFFER_SIZE(buffer) = gstelements->data_size; - } - - // Reallocate the required memory. - guint8* tmp_buf = new guint8[GST_BUFFER_SIZE(buffer)]; - memcpy(tmp_buf, GST_BUFFER_DATA(buffer), sizeof(buffer)); - - delete [] GST_BUFFER_DATA(buffer); - GST_BUFFER_DATA(buffer) = tmp_buf; - } - - aux_streamer_ptr aux_streamer = gstelements->handler->m_aux_streamer[gstelements->owner]; - - // If false is returned the sound doesn't want to be attached anymore - bool ret = (aux_streamer)(gstelements->owner, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); - -} - -void GST_sound_handler::attach_aux_streamer(aux_streamer_ptr ptr, void* owner) -{ - try_mutex::scoped_lock lock(_mutex); - assert(owner); - assert(ptr); - - if ( ! m_aux_streamer.insert(std::make_pair(owner, ptr)).second ) - { - // Already in the hash. - return; - } - - // Make a pipeline that can play the raw data - - // Make a "gst_elements" for this sound which is latter placed on the vector of instances of this sound being played - gst_elements* gst_element = new gst_elements; - if (gst_element == NULL) { - log_error (_("Could not allocate memory for gst_element")); - return; - } - - // Set the handler - gst_element->handler = this; - - // create main pipeline - gst_element->pipeline = gst_pipeline_new (NULL); - - // create an audio sink - use oss, alsa or...? make a commandline option? - // we first try atudetect, then alsa, then oss, then esd, then...? -#if !defined(__NetBSD__) - gst_element->audiosink = gst_element_factory_make ("autoaudiosink", NULL); - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("alsasink", NULL); - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("osssink", NULL); -#endif - if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("esdsink", NULL); - - // Check if the creation of the gstreamer pipeline, adder and audiosink was a succes - if (!gst_element->pipeline) { - log_error(_("The gstreamer pipeline element could not be created")); - } - if (!gst_element->audiosink) { - log_error(_("The gstreamer audiosink element could not be created")); - } - - // link adder and output to bin - gst_bin_add (GST_BIN (gst_element->pipeline), gst_element->audiosink); - - gst_element->bin = gst_bin_new(NULL); - gst_element->input = gst_element_factory_make ("fakesrc", NULL); - gst_element->capsfilter = gst_element_factory_make ("capsfilter", NULL); - gst_element->audioconvert = gst_element_factory_make ("audioconvert", NULL); - gst_element->audioresample = gst_element_factory_make ("audioresample", NULL); - gst_element->volume = gst_element_factory_make ("volume", NULL); - - // Put the gstreamer elements in the pipeline - gst_bin_add_many (GST_BIN (gst_element->bin), gst_element->input, - gst_element->capsfilter, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - - // Test if the fakesrc, typefind and audio* elements was correctly created - if (!gst_element->input - || !gst_element->capsfilter - || !gst_element->audioconvert - || !gst_element->audioresample) { - - log_error(_("Gstreamer element for audio handling could not be created")); - return; - } - - // Create a gstreamer decoder for the chosen sound. - - // Set the info about the stream so that gstreamer knows what it is. - // We know what the pre-decoded data format is. - GstCaps *caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, 44100, - "channels", G_TYPE_INT, 2, - "endianness", G_TYPE_INT, G_BIG_ENDIAN, - "width", G_TYPE_INT, 16, - "depth", G_TYPE_INT, 16, - //"signed", G_TYPE_INT, 1, - NULL); - g_object_set (G_OBJECT (gst_element->capsfilter), "caps", caps, NULL); - gst_caps_unref (caps); - - // setup fake source - g_object_set (G_OBJECT (gst_element->input), - "sizetype", 2, "can-activate-pull", FALSE, "signal-handoffs", TRUE, - "sizemax", BUFFER_SIZE, NULL); - // Setup the callback - gst_element->handoff_signal_id = g_signal_connect (gst_element->input, "handoff", G_CALLBACK (callback_as_handoff), gst_element); - - // we receive raw native sound-data, output directly - gst_element_link_many (gst_element->input, - gst_element->capsfilter, - gst_element->audioconvert, - gst_element->audioresample, - gst_element->volume, NULL); - - // Add ghostpad - GstPad *pad = gst_element_get_pad (gst_element->volume, "src"); - gst_element_add_pad (gst_element->bin, gst_ghost_pad_new ("src", pad)); - gst_object_unref (GST_OBJECT (pad)); - - // Add the bin to the main pipeline - gst_bin_add(GST_BIN (gst_element->pipeline), gst_element->bin); - // Link to the adder sink pad - GstPad *sinkpad = gst_element_get_pad (gst_element->audiosink, "sink"); - GstPad *srcpad = gst_element_get_pad (gst_element->bin, "src"); - gst_pad_link (srcpad, sinkpad); - gst_object_unref (GST_OBJECT (srcpad)); - gst_object_unref (GST_OBJECT (sinkpad)); - - gst_element->owner = owner; - - // Put the gst_element in the map - m_aux_streamer_gstelements[owner] = gst_element; - - // If not already playing, start doing it - gst_element_set_state (GST_ELEMENT (gst_element->pipeline), GST_STATE_PLAYING); -printf("pipeline stated playing\n"); -} - -void GST_sound_handler::detach_aux_streamer(void* owner) -{ - try_mutex::scoped_lock lock(_mutex); - - // TODO: stuff both gstelements and callbacks in the same container ! - - GstElementsMap::iterator it=m_aux_streamer_gstelements.find(owner); - if ( it != m_aux_streamer_gstelements.end() ) - { - delete it->second; - // WARNING: erasing would break any iteration in the map - m_aux_streamer_gstelements.erase(it); - } - - CallbacksMap::iterator it2=m_aux_streamer.find(owner); - if ( it2 != m_aux_streamer.end() ) - { - // WARNING: erasing would break any iteration in the map - m_aux_streamer.erase(it2); - } -} - -unsigned int GST_sound_handler::get_duration(int sound_handle) -{ - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) - { - // Invalid handle. - return 0; - } - - sound_data* sounddata = m_sound_data[sound_handle]; - - boost::uint32_t sampleCount = sounddata->soundinfo->getSampleCount(); - boost::uint32_t sampleRate = sounddata->soundinfo->getSampleRate(); - - // Return the sound duration in milliseconds - if (sampleCount > 0 && sampleRate > 0) { - unsigned int ret = sampleCount / sampleRate * 1000; - ret += ((sampleCount % sampleRate) * 1000) / sampleRate; - if (sounddata->soundinfo->isStereo()) ret = ret / 2; - return ret; - } else { - return 0; - } -} - -unsigned int GST_sound_handler::get_position(int sound_handle) -{ - try_mutex::scoped_lock lock(_mutex); - - // Check if the sound exists. - if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) - { - // Invalid handle. - return 0; - } - - sound_data* sounddata = m_sound_data[sound_handle]; - - // If there is no active sounds, return 0 - if (sounddata->m_gst_elements.size() == 0) { - return 0; - } - - // return the position of the last element added - GstElement *pipeline,*audioconvert; - GstStateChangeReturn ret; - GstState current, pending; - boost::int64_t pos; - GstFormat fmt = GST_FORMAT_TIME; - - pipeline = sounddata->m_gst_elements[sounddata->m_gst_elements.size()-1]->pipeline; - - ret = gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending, 0); - - if (current != GST_STATE_NULL) { - audioconvert = sounddata->m_gst_elements[sounddata->m_gst_elements.size()-1]->audioconvert; - if (gst_element_query_position (audioconvert, &fmt, &pos)) { - return static_cast<unsigned int>(pos / GST_MSECOND); - } else { - return 0; - } - } - return 0; -} - -// Pointer handling and checking functions -const boost::uint8_t* gst_elements::get_data_ptr(unsigned long int pos) -{ - assert(data_size > pos); - return data + pos; -} - -void gst_elements::set_data(const boost::uint8_t* idata) { - data = idata; -} - -sound_handler* create_sound_handler_gst() -// Factory. -{ - return new GST_sound_handler; -} - -} // gnash.media namespace -} // namespace gnash - -#endif // SOUND_GST - -// Local Variables: -// mode: C++ -// End: - Index: libmedia/gst/sound_handler_gst.h =================================================================== RCS file: libmedia/gst/sound_handler_gst.h diff -N libmedia/gst/sound_handler_gst.h --- libmedia/gst/sound_handler_gst.h 21 Jan 2008 23:10:15 -0000 1.9 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,229 +0,0 @@ -// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. - -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -// $Id: sound_handler_gst.h,v 1.9 2008/01/21 23:10:15 rsavoye Exp $ - -#ifndef SOUND_HANDLER_GST_H -#define SOUND_HANDLER_GST_H - -//#include "gnash.h" -#include "sound_handler.h" // for inheritance - -#include <vector> -#include <map> - -#include <gst/gst.h> -#include <boost/thread/thread.hpp> -#include <boost/bind.hpp> -#include <boost/thread/mutex.hpp> - -#define BUFFER_SIZE 5000 - -namespace gnash { -namespace media { - -// forward declaration -class GST_sound_handler; - -// Used to hold the gstreamer when doing on-demand-decoding -class gst_elements -{ -public: - // gstreamer pipeline objects - - // the main bin containing the adder and output (sink) - GstElement *pipeline; - GstElement *audiosink; - - // gstreamer objects - GstElement *input; - GstElement *decoder; - GstElement *capsfilter; - GstElement *audioconvert; - GstElement *audioresample; - GstElement *volume; - GstElement *bin; - GstPad *addersinkpad; - - // position in the stream - unsigned long position; - - // data size - unsigned long data_size; - - long loop_count; - - // signal id - guint handoff_signal_id; - - // The sound handler. Used to get access to the GST_sound_handler->_mutex - GST_sound_handler* handler; - - /// Returns the data pointer in the undecoded datastream - /// for the given position. Boundaries are checked. - const boost::uint8_t* get_data_ptr(unsigned long int pos); - - /// Set the undecoded data pointer - void set_data(const boost::uint8_t*); - - /// The owner of the audio data this element will get data from. - /// Only used when getting data from NetStream or Sound. - void* owner; - -private: - // The (un)compressed data - const guint8* data; - -}; - - -// Used to hold the sounddata when doing on-demand-decoding -class sound_data -{ - // The (un)compressed data - Buffer _data; - -public: - - sound_data() - {} - - /// Append size bytes to this sound - // - /// @param data - /// Data bytes, allocated with new[]. Ownership transferred. - /// - /// @param size - /// Size of the 'data' buffer. - /// - void append(unsigned char* data, unsigned int size) - { - _data.append(data, size); - } - - /// Return data size - size_t dataSize() const { return _data.size(); } - - /// Return data buffer - const boost::uint8_t* data() { return _data.data(); } - - // Object holding information about the sound - std::auto_ptr<SoundInfo> soundinfo; - - // Volume, SWF range: 0-100, GST range 0-10 (we only use 0-1, the rest is amplified) - // It's the SWF range that is represented here - int volume; - - // gstreamer objects - std::vector<gst_elements*> m_gst_elements; - -}; - -// Use gstreamer to handle sounds. -class GST_sound_handler : public sound_handler -{ -private: - /// AS classes (NetStream, Sound) audio callbacks - typedef std::map< void* /* owner */, aux_streamer_ptr /* callback */> CallbacksMap; - CallbacksMap m_aux_streamer; - - typedef std::map< void* /* owner */, gst_elements*> GstElementsMap; - GstElementsMap m_aux_streamer_gstelements; - - /// Vector containing all the sounds - std::vector<sound_data*> m_sound_data; - - /// Is the loop running? - bool looping; - - /// Is the audio muted? - bool muted; - - /// Mutex for making sure threads doesn't mess things up - boost::try_mutex _mutex; - - /// stop and delete all sounds - void delete_all_sounds(); - -public: - - /// Gstreamer callback function - static void callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data); - - /// Gstreamer callback function when using ActionScript audio source (NetStream, Sound) - static void callback_as_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data); - - GST_sound_handler(); - virtual ~GST_sound_handler(); - - /// Called to create a sound. - virtual int create_sound(void* data, unsigned int data_bytes, - std::auto_ptr<SoundInfo> sinfo); - - /// this gets called when a stream gets more data - virtual long fill_stream_data(unsigned char* data, unsigned int data_bytes, - unsigned int sample_count, int handle_id); - - /// Play the index'd sample. - virtual void play_sound(int sound_handle, int loop_count, int offset, - long start_position, const std::vector<sound_envelope>* envelopes); - - /// Stop the index'd sample. - virtual void stop_sound(int sound_handle); - - /// This gets called when it's done with a sample. - virtual void delete_sound(int sound_handle); - - /// This will stop all sounds playing. - virtual void stop_all_sounds(); - - // See dox in sound_handler.h - virtual void reset(); - - /// Returns the sound volume level as an integer from 0 to 100. AS-script only. - virtual int get_volume(int sound_handle); - - /// Sets the sound volume level as an integer from 0 to 100. AS-script only. - virtual void set_volume(int sound_handle, int volume); - - /// Gnash uses this to get info about a sound. Used when a stream needs more data. - virtual SoundInfo* get_sound_info(int sound_handle); - - /// Gnash calls this to mute audio. - virtual void mute(); - - /// Gnash calls this to unmute audio. - virtual void unmute(); - - /// Gnash calls this to get the mute state. - virtual bool is_muted(); - - /// Gets the duration in milliseconds of an event sound connected to an AS Sound obejct. - virtual unsigned int get_duration(int sound_handle); - - /// Gets the playhead position in milliseconds of an event sound connected to an AS Soound obejct. - virtual unsigned int get_position(int sound_handle); - - virtual void attach_aux_streamer(aux_streamer_ptr ptr, void* owner); - virtual void detach_aux_streamer(void* owner); - -}; - -} // gnash.media namespace -} // namespace gnash - -#endif // SOUND_HANDLER_GST_H - _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit