CVSROOT: /sources/gnash Module name: gnash Changes by: Tomas Groth <tgc> 07/06/21 09:02:06
Modified files: . : ChangeLog backend : sound_handler_gst.cpp sound_handler_gst.h sound_handler_sdl.cpp sound_handler_sdl.h Log message: * backend/sound_handler_gst.{cpp,h}: Made it threadsafe, fixes bug #20186. Made the internal variables private. * backend/sound_handler_sdl.{cpp,h}: Made the internal variables private. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3592&r2=1.3593 http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_gst.cpp?cvsroot=gnash&r1=1.48&r2=1.49 http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_gst.h?cvsroot=gnash&r1=1.9&r2=1.10 http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.69&r2=1.70 http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.h?cvsroot=gnash&r1=1.25&r2=1.26 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.3592 retrieving revision 1.3593 diff -u -b -r1.3592 -r1.3593 --- ChangeLog 21 Jun 2007 07:22:27 -0000 1.3592 +++ ChangeLog 21 Jun 2007 09:02:05 -0000 1.3593 @@ -1,3 +1,10 @@ +2007-06-21 Tomas Groth Christensen <[EMAIL PROTECTED]> + + * backend/sound_handler_gst.{cpp,h}: Made it threadsafe, fixes + bug #20186. Made the internal variables private. + * backend/sound_handler_sdl.{cpp,h}: Made the internal + variables private. + 2007-06-21 Zou Lunkai <[EMAIL PROTECTED]> * testsuite/actionscript.all/enumerate.as: more tests. Index: backend/sound_handler_gst.cpp =================================================================== RCS file: /sources/gnash/gnash/backend/sound_handler_gst.cpp,v retrieving revision 1.48 retrieving revision 1.49 diff -u -b -r1.48 -r1.49 --- backend/sound_handler_gst.cpp 7 Jun 2007 12:10:21 -0000 1.48 +++ backend/sound_handler_gst.cpp 21 Jun 2007 09:02:05 -0000 1.49 @@ -20,7 +20,7 @@ // 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.48 2007/06/07 12:10:21 tgc Exp $ */ +/* $Id: sound_handler_gst.cpp,v 1.49 2007/06/21 09:02:05 tgc Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -44,6 +44,8 @@ #define BUFFER_SIZE 5000 +using namespace boost; + GST_sound_handler::GST_sound_handler() : looping(false), muted(false) @@ -73,6 +75,8 @@ // can be use for playing it. { + mutex::scoped_lock lock(_mutex); + sound_data *sounddata = new sound_data; if (!sounddata) { gnash::log_error(_("Could not allocate memory for sound data")); @@ -135,6 +139,7 @@ // this gets called when a stream gets more data long GST_sound_handler::fill_stream_data(void* data, int data_bytes, int /*sample_count*/, int handle_id) { + mutex::scoped_lock lock(_mutex); // @@ does a negative handle_id have any meaning ? // should we change it to unsigned instead ? @@ -146,15 +151,16 @@ guint8* tmp_data = new guint8[data_bytes + sounddata->data_size]; memcpy(tmp_data, sounddata->data, sounddata->data_size); memcpy(tmp_data + sounddata->data_size, data, data_bytes); - delete [] sounddata->data; + if (sounddata->data_size > 0) delete [] sounddata->data; sounddata->data = tmp_data; sounddata->data_size += 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->data_size; - sound->data = sounddata->data; + sound->set_data(tmp_data); } return sounddata->data_size - data_bytes; @@ -171,10 +177,13 @@ } // The callback function which refills the buffer with data -static void callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_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); - guint8* data_pos = gstelements->data+gstelements->position; + + mutex::scoped_lock lock(gstelements->handler->_mutex); + + guint8* data_pos = gstelements->get_data_ptr(gstelements->position); // First callback if (GST_BUFFER_SIZE(buffer) == 0) { @@ -218,7 +227,7 @@ } 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->data, GST_BUFFER_SIZE(buffer)- 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--; @@ -238,6 +247,7 @@ 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. { + 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) @@ -269,9 +279,13 @@ gnash::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->data_size; - gst_element->data = sounddata->data; + 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. @@ -440,6 +454,7 @@ void GST_sound_handler::stop_sound(int sound_handle) { + mutex::scoped_lock lock(_mutex); // Check if the sound exists. if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) @@ -479,6 +494,7 @@ void GST_sound_handler::delete_sound(int sound_handle) // this gets called when it's done with a sample. { + mutex::scoped_lock lock(_mutex); if (sound_handle >= 0 && (unsigned int) sound_handle < m_sound_data.size()) { @@ -503,6 +519,8 @@ // where 0 is off and 100 is full volume. The default setting is 100. int GST_sound_handler::get_volume(int sound_handle) { + mutex::scoped_lock lock(_mutex); + // Check if the sound exists. if (sound_handle >= 0 && (unsigned int) sound_handle < m_sound_data.size()) { @@ -517,6 +535,8 @@ // 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) { + mutex::scoped_lock lock(_mutex); + // Check if the sound exists. if (sound_handle < 0 || (unsigned int) sound_handle >= m_sound_data.size()) { @@ -543,6 +563,8 @@ void GST_sound_handler::get_info(int sound_handle, int* format, bool* stereo) { + mutex::scoped_lock lock(_mutex); + // Check if the sound exists. if (sound_handle >= 0 && (unsigned int) sound_handle < m_sound_data.size()) { @@ -577,6 +599,16 @@ gnash::log_unimpl(__PRETTY_FUNCTION__); } +// Pointer handling and checking functions +uint8_t* gst_elements::get_data_ptr(unsigned long int pos) { + assert(data_size > pos); + return data + pos; +} + +void gst_elements::set_data(uint8_t* idata) { + data = idata; +} + gnash::sound_handler* gnash::create_sound_handler_gst() // Factory. { Index: backend/sound_handler_gst.h =================================================================== RCS file: /sources/gnash/gnash/backend/sound_handler_gst.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -b -r1.9 -r1.10 --- backend/sound_handler_gst.h 28 May 2007 15:40:57 -0000 1.9 +++ backend/sound_handler_gst.h 21 Jun 2007 09:02:06 -0000 1.10 @@ -23,9 +23,15 @@ #include <vector> #include <gst/gst.h> +#include <boost/thread/thread.hpp> +#include <boost/bind.hpp> +#include <boost/thread/mutex.hpp> #define BUFFER_SIZE 5000 +// forward declaration +class GST_sound_handler; + // Used to hold the gstreamer when doing on-demand-decoding class gst_elements { @@ -49,9 +55,6 @@ // position in the stream long position; - // The (un)compressed data - guint8* data; - // data size long data_size; @@ -60,6 +63,20 @@ // 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. + uint8_t* get_data_ptr(unsigned long int pos); + + /// Set the undecoded data pointer + void set_data(uint8_t*); + +private: + // The (un)compressed data + guint8* data; + }; @@ -97,7 +114,7 @@ // Use gstreamer to handle sounds. class GST_sound_handler : public gnash::sound_handler { -public: +private: /// Vector containing all the sounds std::vector<sound_data*> m_sound_data; @@ -107,6 +124,14 @@ /// Is the audio muted? bool muted; + /// Mutex for making sure threads doesn't mess things up + boost::mutex _mutex; + +public: + + /// Gstreamer callback function + static void callback_handoff (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data); + GST_sound_handler(); virtual ~GST_sound_handler(); Index: backend/sound_handler_sdl.cpp =================================================================== RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v retrieving revision 1.69 retrieving revision 1.70 diff -u -b -r1.69 -r1.70 --- backend/sound_handler_sdl.cpp 8 Jun 2007 11:38:17 -0000 1.69 +++ backend/sound_handler_sdl.cpp 21 Jun 2007 09:02:06 -0000 1.70 @@ -18,7 +18,7 @@ // Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003 // which has been donated to the Public Domain. -// $Id: sound_handler_sdl.cpp,v 1.69 2007/06/08 11:38:17 tgc Exp $ +// $Id: sound_handler_sdl.cpp,v 1.70 2007/06/21 09:02:06 tgc Exp $ #ifdef HAVE_CONFIG_H #include "config.h" @@ -33,8 +33,6 @@ using namespace boost; -static void sdl_audio_callback(void *udata, Uint8 *stream, int len); // SDL C audio handler - SDL_sound_handler::SDL_sound_handler() : soundOpened(false), soundsPlaying(0), @@ -44,7 +42,7 @@ audioSpec.freq = 44100; audioSpec.format = AUDIO_S16SYS; // AUDIO_S8 AUDIO_U8; audioSpec.channels = 2; - audioSpec.callback = sdl_audio_callback; + audioSpec.callback = SDL_sound_handler::sdl_audio_callback; audioSpec.userdata = this; audioSpec.samples = 2048; //512 - not enough for videostream } @@ -650,36 +648,8 @@ } -/// Callback invoked by the SDL audio thread. -// -/// Refills the output stream/buffer with data. -/// -/// We run trough all the attached auxiliary streamers fetching decoded -/// audio blocks and mixing them into the given output stream. -/// -/// <UnverifiedComment> -/// If sound is compresssed (mp3) a mp3-frame is decoded into a buffer, -/// and resampled if needed. When the buffer has been sampled, another -/// frame is decoded until all frames has been decoded. -/// If a sound is looping it will be decoded from the beginning again. -/// </UnverifiedComment> -/// -/// TODO: make a static method of the SDL_sound_handler class -/// -/// @param udata -/// User data pointer (SDL_sound_handler instance in our case). -/// We'll lock the SDL_sound_handler::_mutex during operations. -/// -/// @param stream -/// The output stream/buffer to fill -/// -/// @param buffer_length_in -/// Length of the buffer. -/// If zero or negative we log an error and return -/// (negative is probably an SDL bug, zero dunno yet). -/// -static void -sdl_audio_callback (void *udata, Uint8 *stream, int buffer_length_in) +// Callback invoked by the SDL audio thread. +void SDL_sound_handler::sdl_audio_callback (void *udata, Uint8 *stream, int buffer_length_in) { if ( buffer_length_in < 0 ) { Index: backend/sound_handler_sdl.h =================================================================== RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.h,v retrieving revision 1.25 retrieving revision 1.26 diff -u -b -r1.25 -r1.26 --- backend/sound_handler_sdl.h 28 May 2007 15:40:58 -0000 1.25 +++ backend/sound_handler_sdl.h 21 Jun 2007 09:02:06 -0000 1.26 @@ -14,7 +14,7 @@ // 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_sdl.h,v 1.25 2007/05/28 15:40:58 ann Exp $ +// $Id: sound_handler_sdl.h,v 1.26 2007/06/21 09:02:06 tgc Exp $ #ifndef SOUND_HANDLER_SDL_H #define SOUND_HANDLER_SDL_H @@ -145,7 +145,7 @@ // Use SDL and ffmpeg/mad/nothing to handle sounds. class SDL_sound_handler : public gnash::sound_handler { -public: +private: /// NetStream audio callbacks hash_wrapper< void* /* owner */, aux_streamer_ptr /* callback */> m_aux_streamer; //vv @@ -167,6 +167,7 @@ /// Mutex for making sure threads doesn't mess things up boost::mutex _mutex; +public: SDL_sound_handler(); virtual ~SDL_sound_handler(); @@ -212,6 +213,34 @@ virtual void attach_aux_streamer(aux_streamer_ptr ptr, void* owner); //vv virtual void detach_aux_streamer(void* owner); //vv + + /// Callback invoked by the SDL audio thread. + // + /// Refills the output stream/buffer with data. + /// + /// We run trough all the attached auxiliary streamers fetching decoded + /// audio blocks and mixing them into the given output stream. + /// + /// If sound is compresssed (mp3) a mp3-frame is decoded into a buffer, + /// and resampled if needed. When the buffer has been sampled, another + /// frame is decoded until all frames has been decoded. + /// If a sound is looping it will be decoded from the beginning again. + /// + /// TODO: make a static method of the SDL_sound_handler class + /// + /// @param udata + /// User data pointer (SDL_sound_handler instance in our case). + /// We'll lock the SDL_sound_handler::_mutex during operations. + /// + /// @param stream + /// The output stream/buffer to fill + /// + /// @param buffer_length_in + /// Length of the buffer. + /// If zero or negative we log an error and return + /// (negative is probably an SDL bug, zero dunno yet). + /// + static void sdl_audio_callback (void *udata, Uint8 *stream, int buffer_length_in); }; _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit