gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp l...


From: Tomas Groth
Subject: [Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp l...
Date: Wed, 14 Feb 2007 20:41:48 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Tomas Groth <tgc>       07/02/14 20:41:48

Modified files:
        .              : ChangeLog 
        backend        : sound_handler_sdl.cpp 
        libbase        : gstgnashsrc.h 
        server         : gnash.h 
        server/asobj   : Makefile.am NetConnection.cpp NetConnection.h 
                         NetStreamFfmpeg.cpp NetStreamFfmpeg.h 
                         NetStreamGst.cpp Sound.cpp Sound.h 
Added files:
        server/asobj   : SoundFfmpeg.cpp SoundFfmpeg.h SoundGst.cpp 
                         SoundGst.h SoundMad.cpp SoundMad.h 

Log message:
        * backend/sound_handler_sdl.cpp, server/asobj/NetStreamFfmpeg.{h,cpp},
          server/gnash.h: Changed the aux_streamer_ptr callback to return bool.
        * libbase/gstgnashsrc.h, server/asobj/NetStreamGst.cpp: Moved definition
          of gnash_plugin_desc to registering file to avoid multiple 
definitions.
        * server/asobj/SoundGst.{cpp,h}, server/asobj/SoundFfmpeg.{cpp,h},
          server/asobj/SoundMad.{cpp,h} Added FFMPEG, Gstreamer and libmad 
          backends for the Sound class.
        * server/asobj/Sound.{cpp,h}: Added support for the new backends.
        * server/asobj/Makefile.am: Added SoundGst.{h,cpp}, SoundFfmpeg.{h,cpp},
          and SoundMad.{h,cpp},
        * server/asobj/NetConnection.{cpp,h}: Made accept as_object as argument 
          instead of NetStream, to allow Sound to use NetConnection.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2360&r2=1.2361
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/gstgnashsrc.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/gnash.h?cvsroot=gnash&r1=1.83&r2=1.84
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Makefile.am?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.h?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.cpp?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.h?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundFfmpeg.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundFfmpeg.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundGst.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundGst.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundMad.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundMad.h?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2360
retrieving revision 1.2361
diff -u -b -r1.2360 -r1.2361
--- ChangeLog   14 Feb 2007 13:50:30 -0000      1.2360
+++ ChangeLog   14 Feb 2007 20:41:47 -0000      1.2361
@@ -1,3 +1,18 @@
+2007-02-14 Tomas Groth Christensen <address@hidden>
+
+       * backend/sound_handler_sdl.cpp, server/asobj/NetStreamFfmpeg.{h,cpp},
+         server/gnash.h: Changed the aux_streamer_ptr callback to return bool.
+       * libbase/gstgnashsrc.h, server/asobj/NetStreamGst.cpp: Moved definition
+         of gnash_plugin_desc to registering file to avoid multiple 
definitions.
+       * server/asobj/SoundGst.{cpp,h}, server/asobj/SoundFfmpeg.{cpp,h},
+         server/asobj/SoundMad.{cpp,h} Added FFMPEG, Gstreamer and libmad 
+         backends for the Sound class.
+       * server/asobj/Sound.{cpp,h}: Added support for the new backends.
+       * server/asobj/Makefile.am: Added SoundGst.{h,cpp}, SoundFfmpeg.{h,cpp},
+         and SoundMad.{h,cpp},
+       * server/asobj/NetConnection.{cpp,h}: Made accept as_object as argument 
+         instead of NetStream, to allow Sound to use NetConnection.
+
 2007-02-14 Sandro Santilli <address@hidden>
 
        * server/shape.h: add more public functions for

Index: backend/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- backend/sound_handler_sdl.cpp       2 Feb 2007 15:01:17 -0000       1.45
+++ backend/sound_handler_sdl.cpp       14 Feb 2007 20:41:48 -0000      1.46
@@ -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.45 2007/02/02 15:01:17 bjacques Exp $
+// $Id: sound_handler_sdl.cpp,v 1.46 2007/02/14 20:41:48 tgc Exp $
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -759,8 +759,8 @@
 
                        SDL_sound_handler::aux_streamer_ptr aux_streamer = 
it->second; //handler->m_aux_streamer[i]->ptr;
                        void* owner = it->first;
-                       (aux_streamer)(owner, buf, buffer_length);
-
+                       bool ret = (aux_streamer)(owner, buf, buffer_length);
+                       if (!ret) handler->m_aux_streamer.erase(it);
                        SDL_MixAudio(stream, buf, buffer_length, 
SDL_MIX_MAXVOLUME);
 
                }

Index: libbase/gstgnashsrc.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/gstgnashsrc.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libbase/gstgnashsrc.h       18 Jan 2007 11:53:37 -0000      1.4
+++ libbase/gstgnashsrc.h       14 Feb 2007 20:41:48 -0000      1.5
@@ -17,7 +17,7 @@
 // Based on the filesrc and fdsrc element in Gstreamer-core
 //
 
-/* $Id: gstgnashsrc.h,v 1.4 2007/01/18 11:53:37 tgc Exp $ */
+/* $Id: gstgnashsrc.h,v 1.5 2007/02/14 20:41:48 tgc Exp $ */
 
 #ifndef __GST_GNASH_SRC_H__
 #define __GST_GNASH_SRC_H__
@@ -77,24 +77,4 @@
 
 G_END_DECLS
 
-static gboolean
-register_elements (GstPlugin *plugin)
-{
-  return gst_element_register (plugin, "gnashsrc", GST_RANK_NONE, 
GST_TYPE_GNASH_SRC);
-}
-
-GstPluginDesc gnash_plugin_desc = {
-  0, // GST_VERSION_MAJOR
-  10, // GST_VERSION_MINOR
-  "gnashsrc",
-  "Use gnash as source via callbacks",
-  register_elements,
-  "0.0.1",
-  "LGPL",
-  "gnash",
-  "gnash",
-  "http://www.gnu.org/software/gnash/";,
-  GST_PADDING_INIT
-};
-
 #endif /* __GST_GNASH_SRC_H__ */

Index: server/gnash.h
===================================================================
RCS file: /sources/gnash/gnash/server/gnash.h,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -b -r1.83 -r1.84
--- server/gnash.h      18 Jan 2007 22:53:21 -0000      1.83
+++ server/gnash.h      14 Feb 2007 20:41:48 -0000      1.84
@@ -17,7 +17,7 @@
 // 
 //
 
-/* $Id: gnash.h,v 1.83 2007/01/18 22:53:21 strk Exp $ */
+/* $Id: gnash.h,v 1.84 2007/02/14 20:41:48 tgc Exp $ */
 
 /// \mainpage
 ///
@@ -411,7 +411,7 @@
 {
 public:
 
-       typedef void (*aux_streamer_ptr)(void *udata, uint8 *stream, int len);
+       typedef bool (*aux_streamer_ptr)(void *udata, uint8 *stream, int len);
 
        struct sound_envelope
        {

Index: server/asobj/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Makefile.am,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/asobj/Makefile.am    14 Feb 2007 09:41:38 -0000      1.31
+++ server/asobj/Makefile.am    14 Feb 2007 20:41:48 -0000      1.32
@@ -15,7 +15,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: Makefile.am,v 1.31 2007/02/14 09:41:38 tgc Exp $
+# $Id: Makefile.am,v 1.32 2007/02/14 20:41:48 tgc Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -42,7 +42,6 @@
 
 
 libgnashasobjs_la_SOURCES = \
-       Sound.cpp       \
        Boolean.cpp     \
        Camera.cpp      \
        Color.cpp       \
@@ -63,6 +62,7 @@
        Object.cpp      \
        Selection.cpp   \
        SharedObject.cpp\
+       Sound.cpp       \
        Stage.cpp       \
        System.cpp      \
        TextSnapshot.cpp\
@@ -76,7 +76,6 @@
        $(NULL)
 
 noinst_HEADERS = \
-       Sound.h         \
        Boolean.h       \
        Camera.h        \
        Color.h         \
@@ -100,6 +99,10 @@
        Object.h        \
        Selection.h     \
        SharedObject.h  \
+       Sound.h         \
+       SoundFfmpeg.h \
+       SoundGst.h \
+       SoundMad.h \
        Stage.h         \
        System.h        \
        TextSnapshot.h  \
@@ -116,17 +119,23 @@
        $(top_builddir)/libbase/libgnashbase.la
 
 if USE_FFMPEG_ENGINE
-libgnashasobjs_la_SOURCES += NetStreamFfmpeg.cpp
+libgnashasobjs_la_SOURCES += NetStreamFfmpeg.cpp SoundFfmpeg.cpp
 AM_CPPFLAGS += $(FFMPEG_CFLAGS)
 libgnashasobjs_la_LIBADD += $(FFMPEG_LIBS)
 endif
 
 if USE_SOUND_GST
-libgnashasobjs_la_SOURCES += NetStreamGst.cpp
+libgnashasobjs_la_SOURCES += NetStreamGst.cpp SoundGst.cpp
 AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
 libgnashasobjs_la_LIBADD += $(GSTREAMER_LIBS)
 endif
 
+if USE_MAD_ENGINE
+libgnashasobjs_la_SOURCES += SoundMad.cpp
+AM_CPPFLAGS += $(MAD_CFLAGS)
+libgnashasobjs_la_LIBADD += $(MAD_LIBS)
+endif
+
 libgnashasobjs_la_LDFLAGS = -avoid-version
 
 # Rebuild with GCC 4.x Mudflap support

Index: server/asobj/NetConnection.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/asobj/NetConnection.cpp      5 Feb 2007 22:22:32 -0000       1.21
+++ server/asobj/NetConnection.cpp      14 Feb 2007 20:41:48 -0000      1.22
@@ -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: NetConnection.cpp,v 1.21 2007/02/05 22:22:32 tgc Exp $ */
+/* $Id: NetConnection.cpp,v 1.22 2007/02/14 20:41:48 tgc Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -188,7 +188,7 @@
 /// RTMP. Newer Flash movies have a parameter to connect which is a
 /// URL string like rtmp://foobar.com/videos/bar.flv
 /*public*/
-bool NetConnection::openConnection(const char* char_url, NetStream* ns)
+bool NetConnection::openConnection(const char* char_url, as_object* ns)
 {
 
        // if already running there is no need to setup things again

Index: server/asobj/NetConnection.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/asobj/NetConnection.h        30 Jan 2007 12:49:03 -0000      1.15
+++ server/asobj/NetConnection.h        14 Feb 2007 20:41:48 -0000      1.16
@@ -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: NetConnection.h,v 1.15 2007/01/30 12:49:03 strk Exp $ */
+/* $Id: NetConnection.h,v 1.16 2007/02/14 20:41:48 tgc Exp $ */
 
 #ifndef __NETCONNECTION_H__
 #define __NETCONNECTION_H__
@@ -53,7 +53,7 @@
        ~NetConnection();
 
        /// Opens the connection to char_url
-       bool openConnection(const char* char_url, NetStream* ns);
+       bool openConnection(const char* char_url, as_object* ns);
 
        /// Put read pointer at given position
        bool seek(size_t pos);
@@ -113,7 +113,7 @@
 
        // The NetStream object which handles the video playback
        // Watch out for circular dependencies, see NetStream.h
-       NetStream* netStreamObj;
+       as_object* netStreamObj;
 
        // Total filesize
        double totalSize;

Index: server/asobj/NetStreamFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/asobj/NetStreamFfmpeg.cpp    8 Feb 2007 14:40:20 -0000       1.15
+++ server/asobj/NetStreamFfmpeg.cpp    14 Feb 2007 20:41:48 -0000      1.16
@@ -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: NetStreamFfmpeg.cpp,v 1.15 2007/02/08 14:40:20 tgc Exp $ */
+/* $Id: NetStreamFfmpeg.cpp,v 1.16 2007/02/14 20:41:48 tgc Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -478,7 +478,7 @@
 }
 
 // audio callback is running in sound handler thread
-void NetStreamFfmpeg::audio_streamer(void *owner, uint8 *stream, int len)
+bool NetStreamFfmpeg::audio_streamer(void *owner, uint8 *stream, int len)
 {
        NetStreamFfmpeg* ns = static_cast<NetStreamFfmpeg*>(owner);
 
@@ -501,6 +501,7 @@
                        delete samples;
                }
        }
+       return true;
 }
 
 bool NetStreamFfmpeg::read_frame()

Index: server/asobj/NetStreamFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/asobj/NetStreamFfmpeg.h      8 Feb 2007 13:25:41 -0000       1.11
+++ server/asobj/NetStreamFfmpeg.h      14 Feb 2007 20:41:48 -0000      1.12
@@ -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: NetStreamFfmpeg.h,v 1.11 2007/02/08 13:25:41 tgc Exp $ */
+/* $Id: NetStreamFfmpeg.h,v 1.12 2007/02/14 20:41:48 tgc Exp $ */
 
 #ifndef __NETSTREAMFFMPEG_H__
 #define __NETSTREAMFFMPEG_H__
@@ -163,7 +163,7 @@
 
        static void startPlayback(NetStreamFfmpeg* ns);
        static void av_streamer(NetStreamFfmpeg* ns);
-       static void audio_streamer(void *udata, uint8 *stream, int len);
+       static bool audio_streamer(void *udata, uint8 *stream, int len);
 
 private:
 

Index: server/asobj/NetStreamGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/asobj/NetStreamGst.cpp       8 Feb 2007 14:40:20 -0000       1.11
+++ server/asobj/NetStreamGst.cpp       14 Feb 2007 20:41:48 -0000      1.12
@@ -37,6 +37,25 @@
 
 namespace gnash {
 
+static gboolean
+register_elements (GstPlugin *plugin)
+{
+       return gst_element_register (plugin, "gnashsrc", GST_RANK_NONE, 
GST_TYPE_GNASH_SRC);
+}
+
+static GstPluginDesc gnash_plugin_desc = {
+       0, // GST_VERSION_MAJOR
+       10, // GST_VERSION_MINOR
+       "gnashsrc",
+       "Use gnash as source via callbacks",
+       register_elements,
+       "0.0.1",
+       "LGPL",
+       "gnash",
+       "gnash",
+       "http://www.gnu.org/software/gnash/";,
+       GST_PADDING_INIT
+};
 
 NetStreamGst::NetStreamGst():
 

Index: server/asobj/Sound.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/asobj/Sound.cpp      14 Feb 2007 09:41:38 -0000      1.1
+++ server/asobj/Sound.cpp      14 Feb 2007 20:41:48 -0000      1.2
@@ -1,5 +1,5 @@
 // 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//   Copyright (C) 2005, 2006, 2007 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
@@ -29,6 +29,14 @@
 #include "GnashException.h"
 #include "builtin_function.h"
 
+#ifdef SOUND_GST
+#include "SoundGst.h"
+#elif defined(USE_FFMPEG)
+#include "SoundFfmpeg.h"
+#elif defined(USE_MAD)
+#include "SoundMad.h"
+#endif
+
 #include <string>
 
 namespace gnash {
@@ -50,12 +58,15 @@
 
 Sound::Sound()         :
        as_object(getSoundInterface()),
-       soundName(""),
-       soundId(-1)
+       connection(NULL),
+       soundId(-1),
+       externalSound(false),
+       isStreaming(false)
 {
 }
 
 Sound::~Sound() {
+       if (connection) delete connection;
 }
 
 
@@ -103,11 +114,18 @@
 }
 
 void
-Sound::loadSound(std::string /*file*/, bool /*streaming*/)
+Sound::loadSound(std::string file, bool /*streaming*/)
 {
     log_msg("%s is still testing!! \n", __FUNCTION__);
 
+       if (connection) {
+               log_warning("This sound already has a connection?? (We try to 
handle this by deleting the old one...)\n");
+               delete connection;
+       }
+       externalURL = file;
 
+       connection = new NetConnection();
+       connection->openConnection(externalURL.c_str(), this);
 }
 
 void
@@ -159,11 +177,35 @@
        }
 }
 
+unsigned int
+Sound::getDuration()
+{
+       log_error("%s: only works when ffmpeg, gstreamer or libmad is 
enabled\n", __FUNCTION__);
+       return 0;
+}
+
+unsigned int
+Sound::getPosition()
+{
+       log_error("%s: only works when ffmpeg, gstreamer or libmad is 
enabled\n", __FUNCTION__);
+       return 0;
+}
+
+
 void
 sound_new(const fn_call& fn)
 {
-       Sound *sound_obj = new Sound;
+       Sound* sound_obj;
 
+#ifdef SOUND_GST
+       sound_obj = new SoundGst();
+#elif defined(USE_FFMPEG)
+       sound_obj = new SoundFfmpeg();
+#elif defined(USE_MAD)
+       sound_obj = new SoundMad();
+#else
+       sound_obj = new Sound();
+#endif
        fn.result->set_as_object(sound_obj);
 }
 
@@ -325,9 +367,16 @@
 }
 
 void
-sound_loadsound(const fn_call& /*fn*/)
+sound_loadsound(const fn_call& fn)
 {
-    log_msg("%s:unimplemented \n", __FUNCTION__);
+       if (fn.nargs != 2) {
+           log_error("loadSound needs 2 arguments!\n");
+           return;             
+       }
+
+       Sound* so = ensure_sound(fn.this_ptr);
+       so->loadSound(fn.arg(0).to_std_string(), fn.arg(1).to_bool());
+
 }
 
 void
@@ -358,9 +407,16 @@
 }
 
 void
-sound_duration(const fn_call& /*fn*/)
+sound_duration(const fn_call& fn)
 {
-       log_msg("%s:unimplemented \n", __FUNCTION__);
+       Sound* so = ensure_sound(fn.this_ptr);
+       if ( fn.nargs == 0 ) {
+               fn.result->set_int(so->getDuration());
+    } else {
+               IF_VERBOSE_ASCODING_ERRORS(
+                       log_aserror("Tried to set read-only property 
Sound.duration");
+               );
+    }
 }
 
 void
@@ -370,9 +426,16 @@
 }
 
 void
-sound_position(const fn_call& /*fn*/)
+sound_position(const fn_call& fn)
 {
-       log_msg("%s:unimplemented \n", __FUNCTION__);
+       Sound* so = ensure_sound(fn.this_ptr);
+       if ( fn.nargs == 0 ) {
+               fn.result->set_int(so->getPosition());
+    } else {
+               IF_VERBOSE_ASCODING_ERRORS(
+                       log_aserror("Tried to set read-only property 
Sound.position");
+               );
+    }
 }
 
 void

Index: server/asobj/Sound.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- server/asobj/Sound.h        14 Feb 2007 09:41:38 -0000      1.1
+++ server/asobj/Sound.h        14 Feb 2007 20:41:48 -0000      1.2
@@ -1,5 +1,5 @@
 // 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//   Copyright (C) 2005, 2006, 2007 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
@@ -16,8 +16,8 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-#ifndef __ASSOUND_H__
-#define __ASSOUND_H__
+#ifndef __SOUND_H__
+#define __SOUND_H__
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -36,21 +36,24 @@
 public:
        Sound();
        ~Sound();
-       void attachSound(int si, const char* name);
-       void getBytesLoaded();
-       void getBytesTotal();
-       void getPan();
-       void getTransform();
-       int getVolume();
-       void loadSound(std::string file, bool streaming);
-       void setPan();
-       void setTransform();
-       void setVolume(int volume);
-       void start(int offset, int loops);
-       void stop(int si);
+       virtual void attachSound(int si, const char* name);
+       virtual void getBytesLoaded();
+       virtual void getBytesTotal();
+       virtual void getPan();
+       virtual void getTransform();
+       virtual int getVolume();
+       virtual void loadSound(std::string file, bool streaming);
+       virtual void setPan();
+       virtual void setTransform();
+       virtual void setVolume(int volume);
+       virtual void start(int offset, int loops);
+       virtual void stop(int si);
+       virtual unsigned int getDuration();
+       virtual unsigned int getPosition();
 
        std::string soundName;
-private:
+
+protected:
        bool _duration;
        bool _id3;
        bool _onID3;
@@ -61,12 +64,14 @@
 
        int soundId;
        bool externalSound;
+       std::string externalURL;
+       bool isStreaming;
 };
 
 void sound_class_init(as_object& global);
 
 } // end of gnash namespace
 
-// __ASSOUND_H__
+// __SOUND_H__
 #endif
 

Index: server/asobj/SoundFfmpeg.cpp
===================================================================
RCS file: server/asobj/SoundFfmpeg.cpp
diff -N server/asobj/SoundFfmpeg.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundFfmpeg.cpp        14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,457 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+#include "SoundFfmpeg.h"
+#include "sound.h" // for sound_sample_impl
+#include "movie_definition.h"
+#include "sprite_instance.h"
+#include "fn_call.h"
+#include "GnashException.h"
+#include "builtin_function.h"
+
+#include <string>
+
+namespace gnash {
+
+// ffmpeg callback function
+int 
+SoundFfmpeg::readPacket(void* opaque, uint8_t* buf, int buf_size)
+{
+
+       SoundFfmpeg* so = static_cast<SoundFfmpeg*>(opaque);
+       NetConnection* nc = so->connection;
+
+       size_t ret = nc->read(static_cast<void*>(buf), buf_size);
+       so->inputPos += ret;
+       return ret;
+
+}
+
+// ffmpeg callback function
+offset_t 
+SoundFfmpeg::seekMedia(void *opaque, offset_t offset, int whence){
+
+       SoundFfmpeg* so = static_cast<SoundFfmpeg*>(opaque);
+       NetConnection* nc = so->connection;
+
+
+       // Offset is absolute new position in the file
+       if (whence == SEEK_SET) {
+               nc->seek(offset);
+               so->inputPos = offset;
+
+       // New position is offset + old position
+       } else if (whence == SEEK_CUR) {
+               nc->seek(so->inputPos + offset);
+               so->inputPos = so->inputPos + offset;
+
+       //      // New position is offset + end of file
+       } else if (whence == SEEK_END) {
+               // This is (most likely) a streamed file, so we can't seek to 
the end!
+               // Instead we seek to 50.000 bytes... seems to work fine...
+               nc->seek(50000);
+               so->inputPos = 50000;
+               
+       }
+
+       return so->inputPos;
+}
+
+
+void
+SoundFfmpeg::setupDecoder(SoundFfmpeg* so)
+{
+
+       NetConnection* nc = so->connection;
+       assert(nc);
+
+       // Pass stuff from/to the NetConnection object.
+       assert(so);
+       if ( !nc->openConnection(so->externalURL.c_str(), so) ) {
+               log_warning("Gnash could not open audio url: %s", 
so->externalURL.c_str());
+               delete so->lock;
+               return;
+       }
+
+       so->inputPos = 0;
+
+       // This registers all available file formats and codecs 
+       // with the library so they will be used automatically when
+       // a file with the corresponding format/codec is opened
+
+       av_register_all();
+
+       // Open video file
+
+       // Probe the file to detect the format
+       AVProbeData probe_data, *pd = &probe_data;
+       pd->filename = "";
+       pd->buf = new uint8_t[2048];
+       pd->buf_size = 2048;
+
+       if (readPacket(so, pd->buf, pd->buf_size) < 1){
+               log_warning("Gnash could not read from audio url: %s", 
so->externalURL.c_str());
+               delete[] pd->buf;
+               delete so->lock;
+               return;
+       }
+
+       AVInputFormat* inputFmt = av_probe_input_format(pd, 1);
+
+       // After the format probe, reset to the beginning of the file.
+       nc->seek(0);
+
+       // Setup the filereader/seeker mechanism. 7th argument (NULL) is the 
writer function,
+       // which isn't needed.
+       init_put_byte(&so->ByteIOCxt, new uint8_t[500000], 500000, 0, so, 
SoundFfmpeg::readPacket, NULL, SoundFfmpeg::seekMedia);
+       so->ByteIOCxt.is_streamed = 1;
+
+       so->formatCtx = av_alloc_format_context();
+
+       // Open the stream. the 4th argument is the filename, which we ignore.
+       if(av_open_input_stream(&so->formatCtx, &so->ByteIOCxt, "", inputFmt, 
NULL) < 0){
+               log_error("Couldn't open file '%s' for decoding", 
so->externalURL.c_str());
+               delete so->lock;
+               return;
+       }
+
+       // Next, we need to retrieve information about the streams contained in 
the file
+       // This fills the streams field of the AVFormatContext with valid 
information
+       int ret = av_find_stream_info(so->formatCtx);
+       if (ret < 0)
+       {
+               log_error("Couldn't find stream information from '%s', error 
code: %d", so->externalURL.c_str(), ret);
+               delete so->lock;
+               return;
+       }
+
+       // Find the first audio stream
+       so->audioIndex = -1;
+
+       for (unsigned int i = 0; i < so->formatCtx->nb_streams; i++)
+       {
+               AVCodecContext* enc = so->formatCtx->streams[i]->codec; 
+
+               switch (enc->codec_type)
+               {
+                       case CODEC_TYPE_AUDIO:
+                               if (so->audioIndex < 0)
+                               {
+                                       so->audioIndex = i;
+                                       so->audioStream = 
so->formatCtx->streams[i];
+                               }
+                               break;
+
+                       case CODEC_TYPE_VIDEO:
+                       case CODEC_TYPE_DATA:
+                       case CODEC_TYPE_SUBTITLE:
+                       case CODEC_TYPE_UNKNOWN:
+                               log_warning("Non-audio data found in file 
%s\n", so->externalURL.c_str());
+                               break;
+               }
+       }
+
+       if (so->audioIndex < 0)
+       {
+               log_error("Didn't find a audio stream from '%s'", 
so->externalURL.c_str());
+               return;
+       }
+
+       // Get a pointer to the audio codec context for the video stream
+       so->audioCodecCtx = so->formatCtx->streams[so->audioIndex]->codec;
+
+       // Find the decoder for the audio stream
+       AVCodec* pACodec = avcodec_find_decoder(so->audioCodecCtx->codec_id);
+    if(pACodec == NULL)
+       {
+               log_error("No available AUDIO decoder to process file: '%s'", 
so->externalURL.c_str());
+               delete so->lock;
+               return;
+       }
+    
+       // Open codec
+       if (avcodec_open(so->audioCodecCtx, pACodec) < 0)
+       {
+               log_error("Could not open AUDIO codec");
+               delete so->lock;
+               return;
+       }
+
+       // By deleting this lock we allow start() to start playback
+       delete so->lock;
+       return;
+}
+
+// audio callback is running in sound handler thread
+bool SoundFfmpeg::getAudio(void* owner, uint8_t* stream, int len)
+{
+       SoundFfmpeg* so = static_cast<SoundFfmpeg*>(owner);
+
+       int pos = 0;
+
+       // First use the data left over from last time
+       if (so->leftOverSize > 0) {
+
+               // If we have enough "leftover" data to fill the buffer,
+               // we don't bother to decode some new.
+               if (so->leftOverSize >= len) {
+                       memcpy(stream, so->leftOverData, len);
+                       int rest = so->leftOverSize - len;
+                       if (rest < 1) {
+                               delete[] so->leftOverData;
+                               so->leftOverSize = 0;
+                       } else {
+                               uint8_t* buf = new uint8_t[rest];
+                               memcpy(stream, so->leftOverData+len, rest);
+                               delete[] so->leftOverData;
+                               so->leftOverData = buf;
+                               so->leftOverSize -= len;
+                       }       
+                       return true;
+               } else {
+                       memcpy(stream, so->leftOverData, so->leftOverSize);
+                       pos += so->leftOverSize;
+                       so->leftOverSize = 0;
+                       delete[] so->leftOverData;
+               }
+       }
+
+       AVPacket packet;
+       int rc;
+       bool loop = true;
+       int outputsamples = 0;
+       uint8_t* ptr = new uint8_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
+       bool ret = true;
+       while (loop) {
+               // Parse file
+               rc = av_read_frame(so->formatCtx, &packet);
+               if (rc >= 0)
+               {
+                       if (packet.stream_index == so->audioIndex)
+                       {
+                               sound_handler* s = get_sound_handler();
+                               if (s)
+                               {
+                                       // Decode audio
+                                       int frame_size;
+                                       if 
(avcodec_decode_audio(so->audioCodecCtx, (int16_t*) ptr, &frame_size, 
packet.data, packet.size) >= 0)
+                                       {
+
+                                               bool stereo = 
so->audioCodecCtx->channels > 1 ? true : false;
+                                               int samples = stereo ? 
frame_size >> 2 : frame_size >> 1;
+                                               int newDataSize = 0;
+                                               int16_t* output_data = NULL;
+
+                                               // Resample if needed
+                                               if (so->audioCodecCtx->channels 
!= 2 || so->audioCodecCtx->sample_rate != 44100) {
+                                                       // Resampeling using 
ffmpegs (libavcodecs) resampler
+                                                       if (!so->resampleCtx) {
+                                                               // arguments: 
(output channels, input channels, output rate, input rate)
+                                                               so->resampleCtx 
= audio_resample_init (2, so->audioCodecCtx->channels, 44100, 
so->audioCodecCtx->sample_rate);
+                                                       }
+                                                       // The size of this is 
a guess, we don't know yet... Lets hope it's big enough
+                                                       output_data = new 
int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
+                                                       samples = 
audio_resample (so->resampleCtx, output_data, (int16_t*)ptr, samples);
+                                                       newDataSize =  samples 
* 2 * 2; // 2 for stereo and 2 for samplesize = 2 bytes
+                                               } else {
+                                                       output_data = 
(int16_t*)ptr;
+                                                       newDataSize = samples * 
2 * 2;
+                                               }
+
+                                               // Copy the data to buffer
+                                               // If the decoded data isn't 
enough to fill the buffer, we put the decoded
+                                               // data into the buffer, and 
continues decoding.
+                                               if (newDataSize <= len-pos) {
+                                                       memcpy(stream+pos, 
(uint8_t*)output_data, newDataSize);
+                                                       pos += newDataSize;
+                                               } else {
+                                               // If we can fill the buffer, 
and still have "leftovers", we save them
+                                               // and use them later.
+                                                       int rest = len-pos;
+                                                       so->leftOverSize = 
newDataSize - rest;
+                                                       memcpy(stream+pos, 
(uint8_t*)output_data, rest);
+                                                       so->leftOverData = new 
uint8_t[so->leftOverSize];
+                                                       
memcpy(so->leftOverData, ((uint8_t*)output_data)+rest, so->leftOverSize);
+                                                       loop = false;
+                                                       pos += rest;
+                                               }
+                                               delete[] output_data;
+                                       }
+                               }
+                       }
+               } else {
+                       // If we should loop we make sure we do.
+                       if (so->remainingLoops != 0) {
+                               so->remainingLoops--;
+
+                               // Seek to begining of file
+                               if (av_seek_frame(so->formatCtx, 
so->audioIndex, 0, 0) < 0) {
+                                       log_warning("seeking to start of file 
(for looping) failed\n");
+                                       so->remainingLoops = 0;
+                               }
+                       } else {
+                        // Stops playback by returning false which makes the 
soundhandler
+                        // detach this sound.
+                        ret = false;
+                        so->isAttached = false;
+                        break;
+                       }
+               } 
+       } // while
+       delete[] ptr;
+       return ret;
+}
+
+SoundFfmpeg::~SoundFfmpeg() {
+       if (leftOverData && leftOverSize) delete[] leftOverData;
+
+       if (audioCodecCtx) avcodec_close(audioCodecCtx);
+       audioCodecCtx = NULL;
+
+       if (formatCtx) {
+               formatCtx->iformat->flags = AVFMT_NOFILE;
+               av_close_input_file(formatCtx);
+               formatCtx = NULL;
+       }
+
+       if (resampleCtx) {
+               audio_resample_close (resampleCtx);
+       }
+
+/*     if (isAttached) {
+               sound_handler* s = get_sound_handler();
+               if (s) {
+                       s->detach_aux_streamer(this);
+               }
+       }*/
+
+}
+
+void
+SoundFfmpeg::loadSound(std::string file, bool streaming)
+{
+       leftOverData = NULL;
+       leftOverSize = 0;
+       audioIndex = -1;
+       resampleCtx = NULL;
+       remainingLoops = 0;
+
+       if (connection) {
+               log_warning("This sound already has a connection?? (We try to 
handle this by deleting the old one...)\n");
+               delete connection;
+       }
+       externalURL = file;
+
+       connection = new NetConnection();
+
+       externalSound = true;
+       isStreaming = streaming;
+
+       lock = new boost::mutex::scoped_lock(setupMutex);
+
+       // To avoid blocking while connecting, we use a thread.
+       setupThread = new boost::thread(boost::bind(SoundFfmpeg::setupDecoder, 
this));
+
+}
+
+void
+SoundFfmpeg::start(int offset, int loops)
+{
+       boost::mutex::scoped_lock lock(setupMutex);
+
+       if (externalSound) {
+               if (offset > 0) {
+                       // Seek to offset position
+                       double timebase = 
(double)formatCtx->streams[audioIndex]->time_base.num / 
(double)formatCtx->streams[audioIndex]->time_base.den;
+
+                       long newpos = (long)(offset / timebase);
+
+                       if (av_seek_frame(formatCtx, audioIndex, newpos, 0) < 
0) {
+                               log_warning("seeking to offset failed\n");
+                       }
+               }
+               // Save how many loops to do
+               if (loops > 0) {
+                       remainingLoops = loops;
+               }
+       }
+
+       // Start sound
+       sound_handler* s = get_sound_handler();
+       if (s) {
+               if (externalSound) {
+                       if (audioIndex >= 0)
+                       {
+                               s->attach_aux_streamer(getAudio, (void*) this);
+                               isAttached = true;
+                       } 
+               } else {
+               s->play_sound(soundId, loops, offset, 0, NULL);
+           }
+       }
+}
+
+void
+SoundFfmpeg::stop(int si)
+{
+       // stop the sound
+       sound_handler* s = get_sound_handler();
+       if (s != NULL)
+       {
+           if (si > -1) {
+               if (externalSound) {
+                       s->detach_aux_streamer(this);
+               } else {
+                               s->stop_sound(soundId);
+                       }
+               } else {
+                       s->stop_sound(si);
+               }
+       }
+}
+
+unsigned int
+SoundFfmpeg::getDuration()
+{
+       // Return the duration of the file in milliseconds
+       if (formatCtx && audioIndex) {
+               return static_cast<unsigned int>(formatCtx->duration * 1000);
+       } else {
+               return 0;
+       }
+}
+
+unsigned int
+SoundFfmpeg::getPosition()
+{
+       // Return the position in the file in milliseconds
+       if (formatCtx && audioIndex) {
+               double time = 
(double)formatCtx->streams[audioIndex]->time_base.num / 
formatCtx->streams[audioIndex]->time_base.den * 
(double)formatCtx->streams[audioIndex]->cur_dts;
+               return static_cast<unsigned int>(time * 1000);
+       } else {
+               return 0;
+       }
+}
+
+} // end of gnash namespace
+

Index: server/asobj/SoundFfmpeg.h
===================================================================
RCS file: server/asobj/SoundFfmpeg.h
diff -N server/asobj/SoundFfmpeg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundFfmpeg.h  14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,96 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifndef __SOUNDFFMPEG_H__
+#define __SOUNDFFMPEG_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "impl.h"
+#include "as_object.h"
+#include "NetConnection.h"
+#include "Sound.h" // for inheritance
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp> 
+#include <boost/thread/mutex.hpp>
+
+#include <ffmpeg/avformat.h>
+
+namespace gnash {
+
+// Forward declarations
+class fn_call;
+  
+class SoundFfmpeg : public Sound {
+public:
+
+       ~SoundFfmpeg();
+
+       void loadSound(std::string file, bool streaming);
+       void start(int offset, int loops);
+       void stop(int si);
+       unsigned int getDuration();
+       unsigned int getPosition();
+
+       // Used for ffmpeg data read and seek callbacks
+       static int readPacket(void* opaque, uint8_t* buf, int buf_size);
+       static offset_t seekMedia(void *opaque, offset_t offset, int whence);
+
+       static void setupDecoder(SoundFfmpeg* so);
+       static bool getAudio(void *owner, uint8 *stream, int len);
+private:
+
+       // audio
+       AVCodecContext *audioCodecCtx;
+       AVStream* audioStream;
+
+       AVFormatContext *formatCtx;
+
+       AVFrame* audioFrame;
+
+       ReSampleContext *resampleCtx;
+
+       boost::thread *setupThread;
+       boost::mutex setupMutex;
+       boost::mutex::scoped_lock *lock;
+
+       long inputPos;
+
+       ByteIOContext ByteIOCxt;
+
+       // The stream in the file that we use
+       int audioIndex;
+
+       // If the decoded data doesn't fit the buffer we put the leftovers here
+       uint8_t* leftOverData;
+       int leftOverSize;
+
+       // Are this sound attached to the soundhandler?
+       bool isAttached;
+
+       int remainingLoops;
+};
+
+
+} // end of gnash namespace
+
+// __ASSOUND_H__
+#endif
+

Index: server/asobj/SoundGst.cpp
===================================================================
RCS file: server/asobj/SoundGst.cpp
diff -N server/asobj/SoundGst.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundGst.cpp   14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,331 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+#include "SoundGst.h"
+#include "sound.h" // for sound_sample_impl
+#include "movie_definition.h"
+#include "sprite_instance.h"
+#include "fn_call.h"
+#include "GnashException.h"
+#include "builtin_function.h"
+
+#include "gstgnashsrc.h"
+
+#include <string>
+
+namespace gnash {
+
+static gboolean
+register_elements (GstPlugin *plugin)
+{
+       return gst_element_register (plugin, "gnashsrc", GST_RANK_NONE, 
GST_TYPE_GNASH_SRC);
+}
+
+static GstPluginDesc gnash_plugin_desc = {
+       0, // GST_VERSION_MAJOR
+       10, // GST_VERSION_MINOR
+       "gnashsrc",
+       "Use gnash as source via callbacks",
+       register_elements,
+       "0.0.1",
+       "LGPL",
+       "gnash",
+       "gnash",
+       "http://www.gnu.org/software/gnash/";,
+       GST_PADDING_INIT
+};
+
+// Gstreamer callback function
+int 
+SoundGst::readPacket(void* opaque, char* buf, int buf_size)
+{
+
+       SoundGst* so = static_cast<SoundGst*>(opaque);
+       NetConnection* nc = so->connection;
+
+       size_t ret = nc->read(static_cast<void*>(buf), buf_size);
+       so->inputPos += ret;
+       return ret;
+
+}
+
+// Gstreamer callback function
+int 
+SoundGst::seekMedia(void *opaque, int offset, int whence){
+
+       SoundGst* so = static_cast<SoundGst*>(opaque);
+       NetConnection* nc = so->connection;
+
+
+       // Offset is absolute new position in the file
+       if (whence == SEEK_SET) {
+               nc->seek(offset);
+               so->inputPos = offset;
+
+       // New position is offset + old position
+       } else if (whence == SEEK_CUR) {
+               nc->seek(so->inputPos + offset);
+               so->inputPos = so->inputPos + offset;
+
+       //      // New position is offset + end of file
+       } else if (whence == SEEK_END) {
+               // This is (most likely) a streamed file, so we can't seek to 
the end!
+               // Instead we seek to 50.000 bytes... seems to work fine...
+               nc->seek(50000);
+               so->inputPos = 50000;
+               
+       }
+
+       return so->inputPos;
+}
+
+// Callback function used by Gstreamer to to attached audio and video streams
+// detected by decoderbin to either the video out or audio out elements.
+void
+SoundGst::callback_newpad (GstElement* /*decodebin*/, GstPad *pad, gboolean 
/*last*/, gpointer data)
+{
+printf("new pad found\n");
+       SoundGst* so = static_cast<SoundGst*>(data);
+       GstCaps *caps;
+       GstStructure *str;
+       GstPad *audiopad;
+
+       audiopad = gst_element_get_pad (so->audioconv, "sink");
+
+       // check media type
+       caps = gst_pad_get_caps (pad);
+       str = gst_caps_get_structure (caps, 0);
+       if (g_strrstr (gst_structure_get_name (str), "audio")) {
+               // link'n'play
+               gst_pad_link (pad, audiopad);
+printf("new pad connected\n");
+       } else {
+               gst_object_unref (audiopad);
+               log_warning("Non-audio data found in file %s\n", 
so->externalURL.c_str());
+       }
+       gst_caps_unref (caps);
+       return;
+
+}
+
+void
+SoundGst::setupDecoder(SoundGst* so)
+{
+
+       NetConnection* nc = so->connection;
+       assert(nc);
+
+       // Pass stuff from/to the NetConnection object.
+       assert(so);
+       if ( !nc->openConnection(so->externalURL.c_str(), so) ) {
+               log_warning("Gnash could not open audio url: %s", 
so->externalURL.c_str());
+               delete so->lock;
+               return;
+       }
+
+       so->inputPos = 0;
+
+       // init GStreamer
+       gst_init (NULL, NULL);
+
+       // setup the GnashNC plugin
+       _gst_plugin_register_static (&gnash_plugin_desc);
+
+       // setup the pipeline
+       so->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 the gstreamer adder ever gets fixed this should be connected to 
the
+       // adder in the soundhandler.
+#if !defined(__NetBSD__)
+       so->audiosink = gst_element_factory_make ("autoaudiosink", NULL);
+       if (!so->audiosink) so->audiosink = gst_element_factory_make 
("alsasink", NULL);
+       if (!so->audiosink) so->audiosink = gst_element_factory_make 
("osssink", NULL);
+#endif
+       if (!so->audiosink) so->audiosink = gst_element_factory_make 
("esdsink", NULL);
+
+       // Check if the creation of the gstreamer pipeline and audiosink was a 
succes
+       if (!so->pipeline) {
+               gnash::log_error("The gstreamer pipeline element could not be 
created\n");
+               return;
+       }
+       if (!so->audiosink) {
+               gnash::log_error("The gstreamer audiosink element could not be 
created\n");
+               return;
+       }
+
+       // setup gnashnc source (our homegrown source element)
+       so->source = gst_element_factory_make ("gnashsrc", NULL);
+       gnashsrc_callback* gc = new gnashsrc_callback;
+       gc->read = SoundGst::readPacket;
+       gc->seek = SoundGst::seekMedia;
+       g_object_set (G_OBJECT (so->source), "data", so, "callbacks", gc, NULL);
+
+       // setup the audio converter
+       so->audioconv = gst_element_factory_make ("audioconvert", NULL);
+
+       // setup the volume controller
+       so->volume = gst_element_factory_make ("volume", NULL);
+
+       // setup the decoder with callback
+       so->decoder = gst_element_factory_make ("decodebin", NULL);
+       g_signal_connect (so->decoder, "new-decoded-pad", G_CALLBACK 
(SoundGst::callback_newpad), so);
+
+
+       if (!so->source || !so->audioconv || !so->volume || !so->decoder) {
+               gnash::log_error("Gstreamer element(s) for movie handling could 
not be created\n");
+               return;
+       }
+
+       // put it all in the pipeline
+       gst_bin_add_many (GST_BIN (so->pipeline), so->source, so->decoder, 
so->audiosink, so->audioconv, so->volume, NULL);
+
+       // link the elements
+       gst_element_link(so->source, so->decoder);
+       gst_element_link_many(so->audioconv, so->volume, so->audiosink, NULL);
+       
+       // By deleting this lock we allow start() to start playback
+       delete so->lock;
+       return;
+}
+
+SoundGst::~SoundGst() {
+
+       gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+       gst_object_unref (GST_OBJECT (pipeline));
+}
+
+void
+SoundGst::loadSound(std::string file, bool streaming)
+{
+       remainingLoops = 0;
+
+       if (connection) {
+               log_warning("This sound already has a connection?? (We try to 
handle this by deleting the old one...)\n");
+               delete connection;
+       }
+       externalURL = file;
+
+       connection = new NetConnection();
+
+       externalSound = true;
+       isStreaming = streaming;
+
+       lock = new boost::mutex::scoped_lock(setupMutex);
+
+       // To avoid blocking while connecting, we use a thread.
+       setupThread = new boost::thread(boost::bind(SoundGst::setupDecoder, 
this));
+
+}
+
+void
+SoundGst::start(int offset, int loops)
+{
+       boost::mutex::scoped_lock lock(setupMutex);
+
+       if (externalSound) {
+               if (offset > 0) {
+                       // Seek to offset position
+                       if (!gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME, 
GST_SEEK_FLAG_FLUSH,
+                               GST_SEEK_TYPE_SET, GST_SECOND * 
static_cast<long>(offset),
+                               GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
+                               log_warning("seeking to offset failed\n");
+                       }
+
+               }
+               // Save how many loops to do
+               if (loops > 0) {
+                       remainingLoops = loops;
+               }
+               // start playing        
+               gst_element_set_state (pipeline, GST_STATE_PLAYING);
+printf("playback started\n");
+
+       }
+
+
+       // Start sound
+       sound_handler* s = get_sound_handler();
+       if (s) {
+               if (!externalSound) {
+               s->play_sound(soundId, loops, offset, 0, NULL);
+           }
+       }
+}
+
+void
+SoundGst::stop(int si)
+{
+       // stop the sound
+       sound_handler* s = get_sound_handler();
+       if (s != NULL)
+       {
+           if (si > -1) {
+               if (externalSound) {
+                               gst_element_set_state (GST_ELEMENT (pipeline), 
GST_STATE_NULL);
+               } else {
+                               s->stop_sound(soundId);
+                       }
+               } else {
+                       s->stop_sound(si);
+               }
+       }
+}
+
+unsigned int
+SoundGst::getDuration()
+{
+       // Return the duration of the file in milliseconds
+       GstFormat fmt = GST_FORMAT_TIME;
+       int64_t len;
+
+       if (pipeline && gst_element_query_duration (pipeline, &fmt, &len)) {
+               return static_cast<unsigned int>(len*1000);
+       } else {
+               return 0;
+       }
+}
+
+unsigned int
+SoundGst::getPosition()
+{
+       // Return the position in the file in milliseconds
+       if (!pipeline) return 0;
+
+       GstFormat fmt = GST_FORMAT_TIME;
+       int64_t pos;
+       GstStateChangeReturn ret;
+       GstState current, pending;
+
+       ret = gst_element_get_state (GST_ELEMENT (pipeline), &current, 
&pending, 0);
+
+       if (current != GST_STATE_NULL && gst_element_query_position (pipeline, 
&fmt, &pos)) {
+               return static_cast<unsigned int>(pos * 1000);
+       } else {
+               return 0;
+       }
+}
+
+} // end of gnash namespace
+

Index: server/asobj/SoundGst.h
===================================================================
RCS file: server/asobj/SoundGst.h
diff -N server/asobj/SoundGst.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundGst.h     14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,87 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifndef __SOUNDGST_H__
+#define __SOUNDGST_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "impl.h"
+#include "as_object.h"
+#include "NetConnection.h"
+#include "Sound.h" // for inheritance
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp> 
+#include <boost/thread/mutex.hpp>
+
+#include <gst/gst.h>
+
+namespace gnash {
+
+// Forward declarations
+class fn_call;
+  
+class SoundGst : public Sound {
+public:
+
+       ~SoundGst();
+
+       void loadSound(std::string file, bool streaming);
+       void start(int offset, int loops);
+       void stop(int si);
+       unsigned int getDuration();
+       unsigned int getPosition();
+
+       // Used for ffmpeg data read and seek callbacks
+       static int readPacket(void* opaque, char* buf, int buf_size);
+       static int seekMedia(void *opaque, int offset, int whence);
+
+       static void setupDecoder(SoundGst* so);
+       static bool getAudio(void *owner, uint8 *stream, int len);
+
+       static void callback_newpad (GstElement *decodebin, GstPad *pad, 
gboolean last, gpointer data);
+private:
+
+       // gstreamer pipeline objects
+       GstElement *pipeline;
+       GstElement *audiosink;
+       GstElement *source;
+       GstElement *decoder;
+       GstElement *volume;
+       GstElement *audioconv;
+
+       boost::thread *setupThread;
+       boost::mutex setupMutex;
+       boost::mutex::scoped_lock *lock;
+
+       long inputPos;
+
+       // Are this sound attached to the soundhandler?
+       bool isAttached;
+
+       int remainingLoops;
+};
+
+
+} // end of gnash namespace
+
+// __SOUNDGST_H__
+#endif
+

Index: server/asobj/SoundMad.cpp
===================================================================
RCS file: server/asobj/SoundMad.cpp
diff -N server/asobj/SoundMad.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundMad.cpp   14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,439 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+#include "SoundMad.h"
+#include "sound.h" // for sound_sample_impl
+#include "movie_definition.h"
+#include "sprite_instance.h"
+#include "fn_call.h"
+#include "GnashException.h"
+#include "builtin_function.h"
+
+#include <string>
+
+namespace gnash {
+
+int 
+SoundMad::readPacket(uint8_t* buf, int buf_size)
+{
+
+       size_t ret = connection->read(static_cast<void*>(buf), buf_size);
+       inputPos += ret;
+       return ret;
+
+}
+
+int 
+SoundMad::seekMedia(int offset, int whence){
+
+       // Offset is absolute new position in the file
+       if (whence == SEEK_SET) {
+               connection->seek(offset);
+               inputPos = offset;
+
+       // New position is offset + old position
+       } else if (whence == SEEK_CUR) {
+               connection->seek(inputPos + offset);
+               inputPos = inputPos + offset;
+
+       //      // New position is offset + end of file
+       } else if (whence == SEEK_END) {
+               // This is (most likely) a streamed file, so we can't seek to 
the end!
+               // Instead we seek to 50.000 bytes... seems to work fine...
+               connection->seek(50000);
+               inputPos = 50000;
+               
+       }
+
+       return inputPos;
+}
+
+
+void
+SoundMad::setupDecoder(SoundMad* so)
+{
+
+       NetConnection* nc = so->connection;
+       assert(nc);
+
+       // Pass stuff from/to the NetConnection object.
+       assert(so);
+       if ( !nc->openConnection(so->externalURL.c_str(), so) ) {
+               log_warning("Gnash could not open audio url: %s", 
so->externalURL.c_str());
+               delete so->lock;
+               return;
+       }
+
+       so->inputPos = 0;
+
+       // Init the mad decoder
+       mad_stream_init(&so->stream);
+       mad_frame_init(&so->frame);
+       mad_synth_init(&so->synth);
+
+       // Decode a single frame to decode the header
+
+       // Fetch data from the file
+       so->seekMedia(0, SEEK_SET);
+       uint8_t* buf = new uint8_t[1024];
+       int bufSize = so->readPacket(buf, 1024);
+
+       // Setup the mad decoder
+       mad_stream_buffer(&so->stream, buf, bufSize);
+
+       int ret;
+
+       int loops = 0;
+       while(true) {
+
+               ret = mad_frame_decode(&so->frame, &so->stream);
+               loops++;
+               
+               // There is always some junk in front of the data, 
+               // so we continue until we get past it.
+               if (ret && so->stream.error == MAD_ERROR_LOSTSYNC) continue;
+               
+               // Error handling is done by relooping (max. 8 times) and just 
hooping that it will work...
+               if (loops > 8) break;
+               if (ret == -1 && so->stream.error != MAD_ERROR_BUFLEN && 
MAD_RECOVERABLE(so->stream.error)) {
+                       log_warning("Recoverable error while decoding MP3, MAD 
error: %s", mad_stream_errorstr (&so->stream));
+                       continue;
+               }
+               break;
+       }
+       so->bitrate = so->frame.header.bitrate;
+
+       so->seekMedia(0, SEEK_SET);
+       delete [] buf;
+
+       // By deleting this lock we allow start() to start playback
+       delete so->lock;
+       return;
+}
+
+// audio callback is running in sound handler thread
+bool SoundMad::getAudio(void* owner, uint8_t* stream, int len)
+{
+       SoundMad* so = static_cast<SoundMad*>(owner);
+
+       int pos = 0;
+
+       // First use the data left over from last time
+       if (so->leftOverSize > 0) {
+
+               // If we have enough "leftover" data to fill the buffer,
+               // we don't bother to decode some new.
+               if (so->leftOverSize >= len) {
+                       memcpy(stream, so->leftOverData, len);
+                       int rest = so->leftOverSize - len;
+                       if (rest < 1) {
+                               delete[] so->leftOverData;
+                               so->leftOverSize = 0;
+                       } else {
+                               uint8_t* buf = new uint8_t[rest];
+                               memcpy(stream, so->leftOverData+len, rest);
+                               delete[] so->leftOverData;
+                               so->leftOverData = buf;
+                               so->leftOverSize -= len;
+                       }       
+                       return true;
+               } else {
+                       memcpy(stream, so->leftOverData, so->leftOverSize);
+                       pos += so->leftOverSize;
+                       so->leftOverSize = 0;
+                       delete[] so->leftOverData;
+               }
+       }
+
+       uint8_t* buf = new uint8_t[8192];
+       int bufSize = so->readPacket(buf, 8192);
+       int orgBufSize = bufSize;
+
+       bool loop = true;
+       int outputsamples = 0;
+
+       uint8_t* ptr = new uint8_t[8192];
+
+       bool ret = true;
+       sound_handler* s = get_sound_handler();
+       if (bufSize > 0) {
+               if (s) {
+                       // temp raw buffer
+                       uint8_t* tmp_raw_buffer;
+                       unsigned int tmp_raw_buffer_size;
+                       int outsize = 0;
+                       while (loop) {
+                       // Decode audio
+
+                               // Setup the mad decoder
+                               mad_stream_buffer(&so->stream, 
buf+(orgBufSize-bufSize), bufSize);
+
+                               int ret;
+                               const unsigned char* old_next_frame = 
so->stream.next_frame;
+                               int loops = 0;
+                               while(true) {
+
+                                       ret = mad_frame_decode(&so->frame, 
&so->stream);
+                                       loops++;
+                                       
+                                       // There is always some junk in front 
of the data, 
+                                       // so we continue until we get past it.
+                                       if (ret && so->stream.error == 
MAD_ERROR_LOSTSYNC) continue;
+                                       
+                                       // Error handling is done by relooping 
(max. 8 times) and just hooping that it will work...
+                                       if (loops > 8) break;
+                                       if (ret == -1 && so->stream.error != 
MAD_ERROR_BUFLEN && MAD_RECOVERABLE(so->stream.error)) {
+                                               log_warning("Recoverable error 
while decoding MP3, MAD error: %s", mad_stream_errorstr (&so->stream));
+                                               continue;
+                                       }
+                                       
+                                       break;
+                               }
+
+                               if (ret == -1 && so->stream.error != 
MAD_ERROR_BUFLEN) {
+                                       log_error("Unrecoverable error while 
decoding MP3, MAD error: %s", mad_stream_errorstr (&so->stream));
+                                       bufSize = 0;
+                                       loop = false;
+                               } else if (ret == -1 && so->stream.error == 
MAD_ERROR_BUFLEN) {
+                                       // the buffer is empty, no more to 
decode!
+                                       bufSize = 0;
+                                       loop = false;
+                               } else {
+                                       bufSize -= so->stream.next_frame - 
old_next_frame;
+                               }
+
+                               mad_synth_frame (&so->synth, &so->frame);
+                               
+                               outsize = so->synth.pcm.length * 
((so->frame.header.mode) ? 4 : 2);
+
+                               tmp_raw_buffer = new uint8_t[outsize];
+                               int sample;
+                               
+                               int16_t* dst = 
reinterpret_cast<int16_t*>(tmp_raw_buffer);
+
+                               // transfer the decoded samples into the 
sound-struct, and do some
+                               // scaling while we're at it.
+                               for(int f = 0; f < so->synth.pcm.length; f++)
+                               {
+                                       for (int e = 0; e < 
((so->frame.header.mode) ? 2 : 1); e++){ // channels (stereo/mono)
+
+                                               mad_fixed_t mad_sample = 
so->synth.pcm.samples[e][f];
+
+                                               // round
+                                               mad_sample += (1L << 
(MAD_F_FRACBITS - 16));
+
+                                               // clip
+                                               if (mad_sample >= MAD_F_ONE) 
mad_sample = MAD_F_ONE - 1;
+                                               else if (mad_sample < 
-MAD_F_ONE) mad_sample = -MAD_F_ONE;
+
+                                               // quantize
+                                               sample = mad_sample >> 
(MAD_F_FRACBITS + 1 - 16);
+
+                                               if ( sample != 
static_cast<int16_t>(sample) ) sample = sample < 0 ? -32768 : 32767;
+
+                                               *dst++ = sample;
+                                       }
+                               }
+
+                               // If we need to convert samplerate or/and from 
mono to stereo...
+                               if (outsize > 0 && (so->frame.header.samplerate 
!= 44100 || !so->frame.header.mode)) {
+
+                                       int16_t* adjusted_data = 0;
+                                       int     adjusted_size = 0;
+                                       int sample_count = outsize / 
((so->frame.header.mode) ? 4 : 2);
+
+                                       // Convert to needed samplerate
+                                       s->convert_raw_data(&adjusted_data, 
&adjusted_size, tmp_raw_buffer, sample_count, 0, 
+                                                       
so->frame.header.samplerate, so->frame.header.mode);
+
+                                       // Hopefully this wont happen
+                                       if (!adjusted_data) {
+                                               log_warning("Error in sound 
sample convertion");
+                                               continue;
+                                       }
+
+                                       // Move the new data to the sound-struct
+                                       delete[] tmp_raw_buffer;
+                                       tmp_raw_buffer = 
reinterpret_cast<uint8_t*>(adjusted_data);
+                                       tmp_raw_buffer_size = adjusted_size;
+
+                               } else {
+                                       tmp_raw_buffer_size = outsize;
+                               }
+
+
+
+
+                               // Copy the data to buffer
+                               // If the decoded data isn't enough to fill the 
buffer, we put the decoded
+                               // data into the buffer, and continues decoding.
+                               if (tmp_raw_buffer_size <= len-pos) {
+                                       memcpy(stream+pos, tmp_raw_buffer, 
tmp_raw_buffer_size);
+                                       pos += tmp_raw_buffer_size;
+                               } else {
+                               // If we can fill the buffer, and still have 
"leftovers", we save them
+                               // and use them later.
+                                       int rest = len-pos;
+                                       so->leftOverSize = tmp_raw_buffer_size 
- rest;
+                                       memcpy(stream+pos, tmp_raw_buffer, 
rest);
+                                       so->leftOverData = new 
uint8_t[so->leftOverSize];
+                                       memcpy(so->leftOverData, 
(tmp_raw_buffer)+rest, so->leftOverSize);
+                                       loop = false;
+                                       pos += rest;
+                               }
+                               delete[] tmp_raw_buffer;
+                       } // while               
+               } // (s) 
+       } else { // bufSize > 0
+               // If we should loop we make sure we do.
+               if (so->remainingLoops != 0) {
+                       so->remainingLoops--;
+
+                       // Seek to begining of file
+                       so->seekMedia(0, SEEK_SET);
+               } else {
+                        // Stops playback by returning false which makes the 
soundhandler
+                        // detach this sound.
+                        ret = false;
+                        so->isAttached = false;
+               }
+       }
+       so->seekMedia(-bufSize, SEEK_CUR);
+       delete[] ptr;
+       return ret;
+}
+
+SoundMad::~SoundMad() {
+       if (leftOverData && leftOverSize) delete[] leftOverData;
+
+       mad_synth_finish(&synth);
+       mad_frame_finish(&frame);
+       mad_stream_finish(&stream);
+
+/*     if (isAttached) {
+               sound_handler* s = get_sound_handler();
+               if (s) {
+                       s->detach_aux_streamer(this);
+               }
+       }*/
+
+}
+
+void
+SoundMad::loadSound(std::string file, bool streaming)
+{
+       leftOverData = NULL;
+       leftOverSize = 0;
+       remainingLoops = 0;
+
+       if (connection) {
+               log_warning("This sound already has a connection?? (We try to 
handle this by deleting the old one...)\n");
+               delete connection;
+       }
+       externalURL = file;
+
+       connection = new NetConnection();
+
+       externalSound = true;
+       isStreaming = streaming;
+
+       lock = new boost::mutex::scoped_lock(setupMutex);
+
+       // To avoid blocking while connecting, we use a thread.
+       setupThread = new boost::thread(boost::bind(SoundMad::setupDecoder, 
this));
+
+}
+
+void
+SoundMad::start(int offset, int loops)
+{
+       boost::mutex::scoped_lock lock(setupMutex);
+
+       if (externalSound) {
+               seekMedia((bitrate*offset)/8, SEEK_SET);
+
+               // Save how many loops to do
+               if (loops > 0) {
+                       remainingLoops = loops;
+               }
+       }
+
+       // Start sound
+       sound_handler* s = get_sound_handler();
+       if (s) {
+               if (externalSound) {
+                       if (1)
+                       {
+                               s->attach_aux_streamer(getAudio, (void*) this);
+                               isAttached = true;
+                       } 
+               } else {
+               s->play_sound(soundId, loops, offset, 0, NULL);
+           }
+       }
+}
+
+void
+SoundMad::stop(int si)
+{
+       // stop the sound
+       sound_handler* s = get_sound_handler();
+       if (s != NULL)
+       {
+           if (si > -1) {
+               if (externalSound) {
+                       s->detach_aux_streamer(this);
+               } else {
+                               s->stop_sound(soundId);
+                       }
+               } else {
+                       s->stop_sound(si);
+               }
+       }
+}
+
+unsigned int
+SoundMad::getDuration()
+{
+       // Return the duration of the file in milliseconds
+/*     if (formatCtx && audioIndex) {
+               return static_cast<unsigned int>(formatCtx->duration * 1000);
+       } else {
+               return 0;
+       }*/
+       return 0;
+}
+
+unsigned int
+SoundMad::getPosition()
+{
+       // Return the position in the file in milliseconds
+       if (1) {
+               return inputPos/bitrate/8*1000;
+       } else {
+               return 0;
+       }
+}
+
+} // end of gnash namespace
+

Index: server/asobj/SoundMad.h
===================================================================
RCS file: server/asobj/SoundMad.h
diff -N server/asobj/SoundMad.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/SoundMad.h     14 Feb 2007 20:41:48 -0000      1.1
@@ -0,0 +1,88 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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 2 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
+//
+
+#ifndef __SOUNDMAD_H__
+#define __SOUNDMAD_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "impl.h"
+#include "as_object.h"
+#include "NetConnection.h"
+#include "Sound.h" // for inheritance
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp> 
+#include <boost/thread/mutex.hpp>
+
+#include <mad.h>
+
+namespace gnash {
+
+// Forward declarations
+class fn_call;
+  
+class SoundMad : public Sound {
+public:
+
+       ~SoundMad();
+
+       void loadSound(std::string file, bool streaming);
+       void start(int offset, int loops);
+       void stop(int si);
+       unsigned int getDuration();
+       unsigned int getPosition();
+
+       static void setupDecoder(SoundMad* so);
+       static bool getAudio(void *owner, uint8 *stream, int len);
+private:
+
+       long inputPos;
+
+       boost::thread *setupThread;
+       boost::mutex setupMutex;
+       boost::mutex::scoped_lock *lock;
+
+       // bitrate in bps
+       unsigned long bitrate;
+
+       int readPacket(uint8_t* buf, int buf_size);
+       int seekMedia(int offset, int whence);
+
+       /// mad stuff
+       mad_stream      stream;
+       mad_frame       frame;
+       mad_synth       synth;
+
+       // If the decoded data doesn't fit the buffer we put the leftovers here
+       uint8_t* leftOverData;
+       int leftOverSize;
+
+       // Are this sound attached to the soundhandler?
+       bool isAttached;
+
+       int remainingLoops;
+};
+
+
+} // end of gnash namespace
+
+// __ASSOUND_H__
+#endif
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]