gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog configure.ac gui/Makefile.am li... [relea


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog configure.ac gui/Makefile.am li... [release_0_8_2_rc1]
Date: Fri, 22 Feb 2008 14:16:43 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Branch:         release_0_8_2_rc1
Changes by:     Sandro Santilli <strk>  08/02/22 14:16:42

Modified files:
        .              : ChangeLog configure.ac 
        gui            : Makefile.am 
        libmedia       : Makefile.am sound_handler.h 
        po             : Makefile.am 
        pythonmodule   : Makefile.am 
        server         : Makefile.am 
        server/asobj   : Makefile.am NetConnection.cpp NetConnection.h 
                         NetStreamFfmpeg.cpp NetStreamFfmpeg.h 
        server/parser  : Makefile.am video_stream_def.cpp 
                         video_stream_def.h 
        server/vm      : Makefile.am 
        utilities      : Makefile.am 
Added files:
        libmedia/ffmpeg: AudioDecoderFfmpeg.cpp AudioDecoderFfmpeg.h 
                         VideoDecoderFfmpeg.cpp VideoDecoderFfmpeg.h 
                         ffmpegNetStreamUtil.cpp ffmpegNetStreamUtil.h 
                         sound_handler_sdl.cpp sound_handler_sdl.h 

Log message:
        Re-enable ffmpeg backend option. Work of Hong Yu (many thanks)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.5711.2.10&r2=1.5711.2.11
http://cvs.savannah.gnu.org/viewcvs/gnash/configure.ac?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.479.2.2&r2=1.479.2.3
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.118&r2=1.118.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.13&r2=1.13.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sound_handler.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.10&r2=1.10.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/AudioDecoderFfmpeg.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/AudioDecoderFfmpeg.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/ffmpegNetStreamUtil.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/ffmpegNetStreamUtil.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/sound_handler_sdl.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/sound_handler_sdl.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&rev=1.1.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/po/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.15&r2=1.15.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/pythonmodule/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.3&r2=1.3.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.138&r2=1.138.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.48&r2=1.48.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.57&r2=1.57.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.38&r2=1.38.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.105&r2=1.105.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.56&r2=1.56.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.42&r2=1.42.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.39&r2=1.39.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.22&r2=1.22.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.17&r2=1.17.2.1
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/Makefile.am?cvsroot=gnash&only_with_tag=release_0_8_2_rc1&r1=1.64&r2=1.64.2.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5711.2.10
retrieving revision 1.5711.2.11
diff -u -b -r1.5711.2.10 -r1.5711.2.11
--- ChangeLog   22 Feb 2008 11:25:05 -0000      1.5711.2.10
+++ ChangeLog   22 Feb 2008 14:16:31 -0000      1.5711.2.11
@@ -1,3 +1,23 @@
+2008-02-22 Hong Yu <address@hidden>
+
+       * configure.ac, gui/Makefile.am, libmedia/Makefile.am,
+         libmedia/sound_handler.h, libmedia/ffmpeg/AudioDecoderFfmpeg.cpp,
+         libmedia/ffmpeg/AudioDecoderFfmpeg.h,
+         libmedia/ffmpeg/VideoDecoderFfmpeg.cpp,
+         libmedia/ffmpeg/VideoDecoderFfmpeg.h,
+         libmedia/ffmpeg/ffmpegNetStreamUtil.cpp,
+         libmedia/ffmpeg/ffmpegNetStreamUtil.h,
+         libmedia/ffmpeg/sound_handler_sdl.cpp,
+         libmedia/ffmpeg/sound_handler_sdl.h,
+         po/Makefile.am, pythonmodule/Makefile.am,
+         server/Makefile.am, server/asobj/Makefile.am,
+         server/asobj/NetConnection.cpp, server/asobj/NetConnection.h,
+         server/asobj/NetStreamFfmpeg.cpp, server/asobj/NetStreamFfmpeg.h,
+         server/parser/Makefile.am, server/parser/video_stream_def.cpp,
+         server/parser/video_stream_def.h, server/vm/Makefile.am,
+         utilities/Makefile.am:
+         Re-enable ffmpeg backend option.
+
 2008-02-22 Sandro Santilli <address@hidden>
 
        * cygnal/cygnal.cpp: don't call LogFile::openLog explicitly,

Index: configure.ac
===================================================================
RCS file: /sources/gnash/gnash/configure.ac,v
retrieving revision 1.479.2.2
retrieving revision 1.479.2.3
diff -u -b -r1.479.2.2 -r1.479.2.3
--- configure.ac        21 Feb 2008 22:32:15 -0000      1.479.2.2
+++ configure.ac        22 Feb 2008 14:16:32 -0000      1.479.2.3
@@ -580,12 +580,16 @@
 
 media_handler_specified=false
 AC_ARG_ENABLE(media,
- AC_HELP_STRING([--enable-media=handler], [Enable media handling support using 
the specified handler: gst or none (no sound) [[none]] ]),
+ AC_HELP_STRING([--enable-media=handler], [Enable media handling support using 
the specified handler: gst, ffmpeg or none (no sound) [[gst]] ]),
  [case "${enableval}" in
    GST|gst)
      media_handler=gst
      media_handler_specified=true
      ;;
+   ffmpeg|FFMPEG)
+     media_handler=ffmpeg
+     media_handler_specified=true
+     ;;
    no|NO|none)
      media_handler=none
      media_handler_specified=true
@@ -1596,9 +1600,14 @@
 
 case "${media_handler}" in
   gst) AC_DEFINE([SOUND_GST],  [1], [Use GSTREAMER for media handling]) ;;
+  ffmpeg) AC_DEFINE([SOUND_SDL],  [1], [Use SDL for sound handling]) ;;
   *)
 esac
 
+case "${media_handler}" in
+  ffmpeg)  AC_DEFINE([USE_FFMPEG],  [1], [Use FFMPEG for media decoding]) ;;
+  *)
+esac
 dnl I'm kinda lazy, get rid of this later... //Markus
 AM_CONDITIONAL(HAVE_GST, test x$media_handler = xgst)
 

Index: gui/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/gui/Makefile.am,v
retrieving revision 1.118
retrieving revision 1.118.2.1
diff -u -b -r1.118 -r1.118.2.1
--- gui/Makefile.am     17 Feb 2008 02:04:26 -0000      1.118
+++ gui/Makefile.am     22 Feb 2008 14:16:32 -0000      1.118.2.1
@@ -42,11 +42,10 @@
         -I$(top_srcdir)/backend \
         -I$(top_srcdir)/libgeometry \
                -I$(top_srcdir)/libmedia \
-               -I$(top_srcdir)/libmedia/sdl \
+               -I$(top_srcdir)/libmedia/ffmpeg \
                -I$(top_srcdir)/libmedia/gst \
        -DLOCALEDIR=\"$(localedir)\" \
        -DPLUGINSDIR=\"$(pluginsdir)\" \
-       $(GLIB_CFLAGS) \
         $(LIBXML_CFLAGS) \
         $(DMALLOC_CFLAGS) \
        $(LIRC_CFLAGS) \
@@ -79,7 +78,6 @@
 AM_LDFLAGS =  \
        $(GLIB_LIBS) \
        $(LIBLTDL) \
-       $(FFMPEG_LIBS) \
        $(CURL_LIBS) \
        $(LIBXML_LIBS) \
        $(INCLTDL) \
@@ -127,19 +125,19 @@
 endif # HAVE_OPENGL
 endif # BUILD_AQUA_GUI
 
-if USE_SOUND_SDL
 if USE_FFMPEG_ENGINE
 AM_LDFLAGS += $(FFMPEG_LIBS)
 AM_CPPFLAGS += $(FFMPEG_CFLAGS)
 endif
+
 if USE_MAD_ENGINE
 AM_LDFLAGS += $(MAD_LIBS)
 AM_CPPFLAGS += $(MAD_CFLAGS)
 endif
-endif
 
 if USE_SOUND_GST
 AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
+AM_LDFLAGS += $(GSTREAMER_LIBS) 
 endif
 
 # if USE_GUI_FLTK
@@ -165,8 +163,8 @@
 bin_PROGRAMS = 
 
 gnash: gnash.in
-       $(INSTALL_DATA) $? gnash
-       chmod a+x gnash
+       cp $< $@
+       chmod +x $@
 
 GUI_SRCS = gnash.cpp \
        gui.cpp gui.h \

Index: libmedia/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libmedia/Makefile.am,v
retrieving revision 1.13
retrieving revision 1.13.2.1
diff -u -b -r1.13 -r1.13.2.1
--- libmedia/Makefile.am        20 Feb 2008 19:03:58 -0000      1.13
+++ libmedia/Makefile.am        22 Feb 2008 14:16:32 -0000      1.13.2.1
@@ -42,12 +42,11 @@
        -I$(top_srcdir)/server/parser \
        -I$(top_srcdir)/libgeometry \
        $(PTHREAD_CFLAGS) \
+       $(DMALLOC_CFLAGS) \
        $(OPENGL_CFLAGS) \
        $(LIBXML_CFLAGS) \
        $(PNG_CFLAGS) \
-       $(SDL_CFLAGS) \
        $(GLIB_CFLAGS) \
-       $(GSTREAMER_CFLAGS) \
        $(CURL_CFLAGS) \
        $(Z_CFLAGS) \
        $(JPEG_CFLAGS) \
@@ -72,7 +71,6 @@
        $(LIBLTDLHEAD) \
        $(BOOST_LIBS) \
        $(PTHREAD_LIBS) \
-       $(SDL_LIBS) \
        $(NULL)
 
 libgnashmedia_la_SOURCES = \
@@ -134,36 +132,36 @@
 
 if USE_FFMPEG_ENGINE
    libgnashmedia_la_SOURCES += \
-               sdl/MediaDecoderSdl.cpp \
-               sdl/AudioDecoderFfmpeg.cpp \
-               sdl/VideoDecoderFfmpeg.cpp \
-               sdl/MediaParserFfmpeg.cpp \
-               sdl/sound_handler_sdl.cpp
+               ffmpeg/AudioDecoderFfmpeg.cpp \
+               ffmpeg/VideoDecoderFfmpeg.cpp \
+               ffmpeg/sound_handler_sdl.cpp \
+               ffmpeg/ffmpegNetStreamUtil.cpp 
 
    noinst_HEADERS += \
-               sdl/AudioDecoderFfmpeg.h \
-               sdl/VideoDecoderFfmpeg.h \
-               sdl/sound_handler_sdl.h \
-               sdl/MediaDecoderSdl.h \
-               sdl/MediaParserFfmpeg.h
+               ffmpeg/AudioDecoderFfmpeg.h \
+               ffmpeg/VideoDecoderFfmpeg.h \
+               ffmpeg/sound_handler_sdl.h \
+               ffmpeg/ffmpegNetStreamUtil.h 
 
    libgnashmedia_la_LIBADD += \
-               $(FFMPEG_LIBS)
+               $(FFMPEG_LIBS) \
+               $(SDL_LIBS)
 
    libgnashmedia_la_CPPFLAGS += \
-               $(FFMPEG_CFLAGS)
+               $(FFMPEG_CFLAGS) \
+               $(SDL_CFLAGS)
 endif
 
 if USE_MAD_ENGINE
    libgnashmedia_la_SOURCES += \
-               sdl/MediaDecoderSdl.cpp \
-               sdl/AudioDecoderMad.cpp \
-               sdl/sound_handler_sdl.cpp
+               ffmpeg/MediaDecoderSdl.cpp \
+               ffmpeg/AudioDecoderMad.cpp \
+               ffmpeg/sound_handler_sdl.cpp
 
    noinst_HEADERS += \
-               sdl/MediaDecoderSdl.h \
-               sdl/AudioDecoderMad.h \
-               sdl/sound_handler_sdl.h
+               ffmpeg/MediaDecoderSdl.h \
+               ffmpeg/AudioDecoderMad.h \
+               ffmpeg/sound_handler_sdl.h
 
    libgnashmedia_la_LIBADD += \
                $(MAD_LIBS)

Index: libmedia/sound_handler.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sound_handler.h,v
retrieving revision 1.10
retrieving revision 1.10.2.1
diff -u -b -r1.10 -r1.10.2.1
--- libmedia/sound_handler.h    9 Feb 2008 15:06:01 -0000       1.10
+++ libmedia/sound_handler.h    22 Feb 2008 14:16:33 -0000      1.10.2.1
@@ -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: sound_handler.h,v 1.10 2008/02/09 15:06:01 bjacques Exp $ */
+/* $Id: sound_handler.h,v 1.10.2.1 2008/02/22 14:16:33 strk Exp $ */
 
 /// \page sound_handler_intro Sound handler introduction
 ///
@@ -355,7 +355,41 @@
        ///
        virtual bool    is_muted() = 0;
 
-
+#ifdef USE_FFMPEG
+       /// This is called by AS classes NetStream or Sound to attach callback, 
so
+       /// that audio from the classes will be played through the soundhandler.
+       //
+       /// This is actually only used by the SDL sound_handler. It uses these 
"auxiliary"
+       /// streamers to fetch decoded audio data to mix and send to the output 
channel.
+       ///
+       /// The "aux streamer" will be called with the 'udata' pointer as first 
argument,
+       /// then will be passed a buffer pointer as second argument and it's 
length
+       /// as third. The callbacks should fill the given buffer if possible.
+       /// The callback should return true if wants to remain attached, false 
if wants
+       /// to be detached. 
+       ///
+       /// @param ptr
+       ///     The pointer to the callback function
+       ///
+       /// @param udata
+       ///     User data pointer, passed as first argument to the registered 
callback.
+       ///     WARNING: this is currently also used to *identify* the callback 
for later
+       ///     removal, see detach_aux_streamer. TODO: stop using the data 
pointer for 
+       ///     identification purposes and use the callback pointer directly 
instead.
+       ///
+       virtual void    attach_aux_streamer(aux_streamer_ptr ptr, void* owner) 
= 0;
+
+       /// This is called by AS classes NetStream or Sound to dettach 
callback, so
+       /// that audio from the classes no longer will be played through the 
+       /// soundhandler.
+       //
+       /// @param udata
+       ///     The key identifying the auxiliary streamer.
+       ///     WARNING: this need currently be the 'udata' pointer passed to 
attach_aux_streamer.
+       ///     TODO: get the aux_streamer_ptr as key !!
+       ///
+       virtual void    detach_aux_streamer(void* udata) = 0;
+#endif
 
        virtual ~sound_handler() {};
        

Index: po/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/po/Makefile.am,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -b -r1.15 -r1.15.2.1
--- po/Makefile.am      13 Jan 2008 10:31:52 -0000      1.15
+++ po/Makefile.am      22 Feb 2008 14:16:37 -0000      1.15.2.1
@@ -35,7 +35,7 @@
        $(top_srcdir)/backend \
        $(top_srcdir)/libamf \
        $(top_srcdir)/libmedia \
-       $(top_srcdir)/libmedia/sdl \
+       $(top_srcdir)/libmedia/ffmpeg \
        $(top_srcdir)/libmedia/gst \
        $(top_srcdir)/server \
        $(top_srcdir)/server/vm \

Index: pythonmodule/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/pythonmodule/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -b -r1.3 -r1.3.2.1
--- pythonmodule/Makefile.am    10 Jan 2008 08:25:28 -0000      1.3
+++ pythonmodule/Makefile.am    22 Feb 2008 14:16:37 -0000      1.3.2.1
@@ -34,6 +34,7 @@
        $(GLIB_LIBS) \
        $(LIBLTDL) \
        $(FFMPEG_LIBS) \
+       $(GSTREAMER_LIBS) \
        $(CURL_LIBS) \
        $(LIBXML_LIBS) \
        $(INCLTDL) \
@@ -51,7 +52,7 @@
         -I$(top_srcdir)/backend \
         -I$(top_srcdir)/libgeometry \
                -I$(top_srcdir)/libmedia \
-               -I$(top_srcdir)/libmedia/sdl \
+               -I$(top_srcdir)/libmedia/ffmpeg \
                -I$(top_srcdir)/libmedia/gst \
        -DLOCALEDIR=\"$(localedir)\" \
        $(BOOSTPYTHON_CFLAGS) \
@@ -84,7 +85,7 @@
         -I$(top_srcdir)/backend \
         -I$(top_srcdir)/libgeometry \
                -I$(top_srcdir)/libmedia \
-               -I$(top_srcdir)/libmedia/sdl \
+               -I$(top_srcdir)/libmedia/ffmpeg \
                -I$(top_srcdir)/libmedia/gst \
        -DLOCALEDIR=\"$(localedir)\" \
        -DBOOST_PYTHON_DYNAMIC_LIB \

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.138
retrieving revision 1.138.2.1
diff -u -b -r1.138 -r1.138.2.1
--- server/Makefile.am  8 Feb 2008 15:27:32 -0000       1.138
+++ server/Makefile.am  22 Feb 2008 14:16:38 -0000      1.138.2.1
@@ -37,13 +37,10 @@
        -I$(top_srcdir)/libbase \
        -I$(top_srcdir)/libgeometry \
        -I$(top_srcdir)/libmedia \
-       -I$(top_srcdir)/libmedia/sdl \
-       -I$(top_srcdir)/libmedia/gst \
        -I$(top_srcdir) \
        $(PTHREAD_CFLAGS) \
        $(DMALLOC_CFLAGS) \
        $(GLIB_CFLAGS) \
-       $(GSTREAMER_CFLAGS) \
        $(BOOST_CFLAGS) \
        $(LIBXML_CFLAGS) \
        $(FREETYPE2_CFLAGS) \
@@ -202,10 +199,15 @@
        $(NULL)
 
 if USE_SOUND_GST
-AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
+AM_CPPFLAGS += $(GSTREAMER_CFLAGS) \
+               -I$(top_srcdir)/libmedia/gst
 libgnashserver_la_LIBADD += $(GSTREAMER_LIBS)
 endif
 
+if USE_FFMPEG_ENGINE
+AM_CPPFLAGS += $(FFMPEG_CFLAGS) \
+               -I$(top_srcdir)/libmedia/ffmpeg
+endif
 
 # Enable building the Flash debugger
 if DEBUGGER

Index: server/asobj/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Makefile.am,v
retrieving revision 1.48
retrieving revision 1.48.2.1
diff -u -b -r1.48 -r1.48.2.1
--- server/asobj/Makefile.am    21 Jan 2008 20:55:56 -0000      1.48
+++ server/asobj/Makefile.am    22 Feb 2008 14:16:38 -0000      1.48.2.1
@@ -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.48 2008/01/21 20:55:56 rsavoye Exp $
+# $Id: Makefile.am,v 1.48.2.1 2008/02/22 14:16:38 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -32,14 +32,10 @@
        -I$(top_srcdir)/libamf \
        -I$(top_srcdir)/libltdl \
        -I$(top_srcdir)/libmedia \
-       -I$(top_srcdir)/libmedia/gst \
-       -I$(top_srcdir)/libmedia/sdl \
        -I$(top_srcdir) \
        $(PTHREAD_CFLAGS) \
        $(DMALLOC_CFLAGS) \
        $(GLIB_CFLAGS) \
-       $(FFMPEG_CFLAGS) \
-       $(GSTREAMER_CFLAGS) \
        $(BOOST_CFLAGS) \
        $(LIBXML_CFLAGS) \
        $(NULL)
@@ -71,7 +67,7 @@
        Math.cpp        \
        Microphone.cpp  \
        Mouse.cpp       \
-       NetConnection.cpp\
+       NetConnection.cpp \
        NetStream.cpp   \
        Number.cpp      \
        Object.cpp      \
@@ -145,14 +141,19 @@
        $(LIBXML_LIBS)
 
 if USE_FFMPEG_ENGINE
-libgnashasobjs_la_SOURCES += NetStreamFfmpeg.cpp SoundFfmpeg.cpp
-AM_CPPFLAGS += $(FFMPEG_CFLAGS)
-# libgnashasobjs_la_LIBADD += $(FFMPEG_LIBS)
+libgnashasobjs_la_SOURCES += NetStreamFfmpeg.cpp \
+                               SoundFfmpeg.cpp
+AM_CPPFLAGS += $(FFMPEG_CFLAGS) \
+               $(SDL_CFLAGS) \
+               -I$(top_srcdir)/libmedia/ffmpeg
+libgnashasobjs_la_LIBADD += $(FFMPEG_LIBS) \
+                               $(SDL_LIBS)
 endif
 
 if USE_SOUND_GST
 libgnashasobjs_la_SOURCES += NetStreamGst.cpp SoundGst.cpp
-AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
+AM_CPPFLAGS += $(GSTREAMER_CFLAGS) \
+               -I$(top_srcdir)/libmedia/gst
 libgnashasobjs_la_LIBADD += $(GSTREAMER_LIBS)
 endif
 

Index: server/asobj/NetConnection.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.cpp,v
retrieving revision 1.57
retrieving revision 1.57.2.1
diff -u -b -r1.57 -r1.57.2.1
--- server/asobj/NetConnection.cpp      19 Feb 2008 19:20:54 -0000      1.57
+++ server/asobj/NetConnection.cpp      22 Feb 2008 14:16:39 -0000      1.57.2.1
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: NetConnection.cpp,v 1.57 2008/02/19 19:20:54 bwy Exp $ */
+/* $Id: NetConnection.cpp,v 1.57.2.1 2008/02/22 14:16:39 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h"
@@ -50,15 +50,80 @@
 
 NetConnection::NetConnection()
        :
-       as_object(getNetConnectionInterface())
+       as_object(getNetConnectionInterface()),
+       _loader()
 {
        attachProperties();
 }
 
+
 NetConnection::~NetConnection()
 {
 }
 
+
+/*public*/
+bool NetConnection::openConnection(const std::string& url)
+{
+  // if already running there is no need to setup things again
+  if ( _loader.get() ) {
+    log_debug("NetConnection::openConnection() called when already connected 
to a stream. Checking if the existing connection can be used.");
+    std::string newurl;
+    if (_prefixUrl.size() > 0) {
+      newurl += _prefixUrl + "/" + url;
+    } else {
+      newurl += url;
+    }
+    if (newurl.compare(_completeUrl) == 0) {
+      return true;
+    } else { 
+      return false;
+    }
+  }
+
+  if ( _prefixUrl.size() > 0 ) {
+    _completeUrl += _prefixUrl + "/" + url;
+  } else {
+    _completeUrl += url;
+  }
+
+  URL uri( _completeUrl, get_base_url() );
+
+  std::string uriStr( uri.str() );
+  assert( uriStr.find( "://" ) != std::string::npos );
+
+  // Check if we're allowed to open url
+  if ( ! URLAccessManager::allow( uri ) ) {
+    log_security( _("Gnash is not allowed to open this url: %s"), 
uriStr.c_str() );
+    return false;
+  }
+
+  log_security( _("Connecting to movie: %s"), uriStr.c_str() );
+
+  _loader.reset( new LoadThread() );
+
+  if ( ! _loader->setStream( 
std::auto_ptr<tu_file>(StreamProvider::getDefaultInstance().getStream( uri ) ) 
) ) {
+    log_error( _("Gnash could not open this url: %s"), uriStr.c_str() );
+    _loader.reset();
+
+    return false;
+  }
+
+  log_debug( _("Connection established to movie: %s"), uriStr.c_str() );
+
+  return true;
+}
+
+
+/*public*/
+bool
+NetConnection::eof()
+{
+       if (!_loader.get()) return true; // @@ correct ?
+       return _loader->eof();
+}
+
+
 /*public*/
 std::string NetConnection::validateURL(const std::string& url)
 {
@@ -85,7 +150,7 @@
        return uriStr;
 }
 
-/*public*/
+/*private*/
 void
 NetConnection::addToURL(const std::string& url)
 {
@@ -100,6 +165,82 @@
 }
 
 
+/*public*/
+size_t
+NetConnection::read( void *dst, size_t bytes )
+{
+  if ( ! _loader.get() ) {
+    return 0;
+  }
+
+  return _loader->read( dst, bytes );
+}
+
+
+/*public*/
+bool
+NetConnection::seek( size_t pos )
+{
+  if ( ! _loader.get() ) {
+    return false;
+  }
+
+  return _loader->seek( pos );
+}
+
+
+/*public*/
+size_t
+NetConnection::tell()
+{
+       if (!_loader.get()) return 0; // @@ correct ?
+       return _loader->tell();
+}
+
+
+/*public*/
+long
+NetConnection::getBytesLoaded()
+{
+       if (!_loader.get()) return 0; // @@ correct ?
+       return _loader->getBytesLoaded();
+}
+
+
+/*public*/
+long
+NetConnection::getBytesTotal()
+{
+       if (!_loader.get()) return 0; // @@ correct ?
+       return _loader->getBytesTotal();
+}
+
+
+/*public*/
+bool
+NetConnection::loadCompleted()
+{
+  if ( ! _loader.get() ) {
+    return false;
+  }
+
+  return _loader->completed();
+}
+
+
+std::auto_ptr<FLVParser>
+NetConnection::getConnectedParser() const
+{
+  std::auto_ptr<FLVParser> ret;
+
+  if ( _loader.get() ) {
+    ret.reset( new FLVParser(*_loader) );
+  }
+
+  return ret;
+}
+
+
 /// \brief callback to instantiate a new NetConnection object.
 /// \param fn the parameters from the Flash movie
 /// \return nothing from the function call.

Index: server/asobj/NetConnection.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.h,v
retrieving revision 1.38
retrieving revision 1.38.2.1
diff -u -b -r1.38 -r1.38.2.1
--- server/asobj/NetConnection.h        21 Jan 2008 20:55:56 -0000      1.38
+++ server/asobj/NetConnection.h        22 Feb 2008 14:16:39 -0000      1.38.2.1
@@ -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: NetConnection.h,v 1.38 2008/01/21 20:55:56 rsavoye Exp $ */
+/* $Id: NetConnection.h,v 1.38.2.1 2008/02/22 14:16:39 strk Exp $ */
 
 #ifndef __NETCONNECTION_H__
 #define __NETCONNECTION_H__
@@ -80,6 +80,83 @@
        /// Register the "NetConnection" constructor to the given global object
        static void registerConstructor(as_object& global);
 
+       /// Open a connection to stream FLV files.
+       //
+       /// If already connected an error is raised and false
+       /// is returned. Otherwise, a connection is attempted
+       /// using a separate thread that starts loading data
+       /// caching it.
+       ///
+       /// @param url
+       ///     An url portion to append to the base url (???)
+       ///
+       /// @return true on success, false on error.
+       ///
+       /// @note Older Flash movies can only take a NULL value as
+       /// the parameter, which therefor only connects to the localhost using
+       /// RTMP. Newer Flash movies have a parameter to connect which is a
+       /// URL string like rtmp://foobar.com/videos/bar.flv
+       ///
+       bool openConnection(const std::string& url);
+
+       /// Put read pointer at given position
+       //
+       /// If the position has not been loaded yet
+       /// this call blocks. If not connected false
+       /// is returned w/out blocking.
+       ///
+       bool seek(size_t pos);
+
+       /// Read 'bytes' bytes into the given buffer.
+       //
+       /// If not enough bytes have been loaded yet
+       /// this call blocks. If not connected false
+       /// is returned w/out blocking.
+       ///
+       /// Return number of actually read bytes
+       ///
+       size_t read(void *dst, size_t bytes);
+
+       /// Return true if EOF has been reached
+       //
+       /// This call never blocks.
+       /// If not connected, true is returned (is this correct behaviour?)
+       ///
+       bool eof();
+
+       /// Report global position within the file
+       //
+       /// This call never blocks.
+       /// If not connected, 0 is returned (is this correct behaviour?)
+       ///
+       size_t tell();
+
+       /// Returns the number of bytes cached
+       //
+       /// This call never blocks.
+       /// If not connected, 0 is returned (is this correct behaviour?)
+       ///
+       long getBytesLoaded();
+
+       /// Returns the total size of the file
+       //
+       /// This call never blocks.
+       /// If not connected, 0 is returned (is this correct behaviour?)
+       ///
+       long getBytesTotal();
+
+       /// Return an FLVParser using our LoadThread for input
+       //
+       /// If not connected, a NULL auto_ptr is returned.
+       ///
+       std::auto_ptr<FLVParser> getConnectedParser() const;
+
+       /// Returns whether the load is complete
+       //
+       /// This call never blocks.
+       ///
+       bool loadCompleted();
+
 private:
 
        /// Extend the URL to be used for playing
@@ -88,6 +165,12 @@
        /// the url prefix optionally passed to connect()
        std::string _prefixUrl;
 
+       /// the complete url of the file
+       std::string _completeUrl;
+
+       /// The file/stream loader thread and interface
+       std::auto_ptr<LoadThread> _loader;
+
        /// Attach ActionScript instance properties
        void attachProperties();
 

Index: server/asobj/NetStreamFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.cpp,v
retrieving revision 1.105
retrieving revision 1.105.2.1
diff -u -b -r1.105 -r1.105.2.1
--- server/asobj/NetStreamFfmpeg.cpp    19 Feb 2008 19:20:55 -0000      1.105
+++ server/asobj/NetStreamFfmpeg.cpp    22 Feb 2008 14:16:40 -0000      
1.105.2.1
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: NetStreamFfmpeg.cpp,v 1.105 2008/02/19 19:20:55 bwy Exp $ */
+/* $Id: NetStreamFfmpeg.cpp,v 1.105.2.1 2008/02/22 14:16:40 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h"
@@ -31,7 +31,6 @@
 #include "NetStream.h"
 #include "render.h"    
 #include "movie_root.h"
-#include "NetConnection.h"
 #include "sound_handler.h"
 #include "VideoDecoderFfmpeg.h"
 #include "tu_timer.h" // TODO: use the VirtualClock instead ?
@@ -88,26 +87,33 @@
        close();
 }
 
-void NetStreamFfmpeg::pause(int mode)
-{
 
-       if (mode == -1)
-       {
-               if (m_pause) unpausePlayback();
-               else pausePlayback();
+void NetStreamFfmpeg::pause( PauseMode mode )
+{
+  switch ( mode ) {
+    case pauseModeToggle:
+                       if ( m_pause ) {
+                         unpausePlayback();
+                       } else {
+                         pausePlayback();
        }
-       else
-       {
-               if (mode == 0) pausePlayback();
-               else unpausePlayback();
+                       break;
+    case pauseModePause:
+                       pausePlayback();
+                       break;
+    case pauseModeUnPause:
+                       unpausePlayback();
+                       break;
+    default:
+                       break;
        }
-       if (!m_pause && !m_go)
-       { 
-               setStatus(playStart);
+
+  if ( !m_pause && !m_go ) {
+    setStatus( playStart );
                m_go = true;
-               _decodeThread = new 
boost::thread(boost::bind(NetStreamFfmpeg::av_streamer, this)); 
-       }
 
+    _decodeThread = new boost::thread( 
boost::bind(NetStreamFfmpeg::av_streamer, this) );
+  }
 }
 
 void NetStreamFfmpeg::close()
@@ -136,23 +142,13 @@
        if (m_Frame) av_free(m_Frame);
        m_Frame = NULL;
 
-       if (m_VCodecCtx)
-       {
-               avcodec_close(m_VCodecCtx);
-               if (m_isFLV)
-               {
-                       av_free(m_VCodecCtx);
-               }
+  if ( m_VCodecCtx ) {
+    avcodec_close( m_VCodecCtx );
        }
        m_VCodecCtx = NULL;
 
-       if (m_ACodecCtx)
-       {
-               avcodec_close(m_ACodecCtx);
-               if (m_isFLV)
-               {
-                       av_free(m_ACodecCtx);
-               }
+  if ( m_ACodecCtx ) {
+    avcodec_close( m_ACodecCtx );
        }
        m_ACodecCtx = NULL;
 
@@ -451,16 +447,13 @@
                if (!m_VCodecCtx)
                {
                        log_error(_("Failed to initialize FLV video codec"));
+                       return false;
                }
 
                m_ACodecCtx = initFlvAudio(m_parser.get());
                if (!m_ACodecCtx)
                {
                        log_error(_("Failed to initialize FLV audio codec"));
-               }
-
-               if (!m_ACodecCtx && !m_VCodecCtx)
-               {
                        return false;
                }
 
@@ -625,24 +618,20 @@
 ///            of this structure must be initialized.
 /// @param width the width, in bytes, of a row of video data.
 static void
-rgbcopy(image::rgb* dst, raw_mediadata_t* src, int width)
+rgbcopy(image::rgb* dst, media::raw_mediadata_t* src, int width)
 {
-       assert( dst->size() >= src->m_size ); 
-       assert( dst->pitch() >= width );
-       dst->update(src->m_data);
+  assert( src->m_size <= static_cast<boost::uint32_t>(dst->width() * 
dst->height() * 3) ); 
 
-#if 0
-       boost::uint8_t* dstptr = dst->m_data;
+  boost::uint8_t* dstptr = dst->data();
 
        boost::uint8_t* srcptr = src->m_data;
        boost::uint8_t* srcend = src->m_data + src->m_size;
 
        while (srcptr < srcend) {
                memcpy(dstptr, srcptr, width);
-               dstptr += dst->m_pitch;
+    dstptr += dst->pitch();
                srcptr += width;
        }
-#endif
 }
 
 // decoder thread
@@ -695,7 +684,7 @@
                if (ns->m_isFLV)
                {
                        // If queues are full then don't bother filling it
-                       if ((ns->m_VCodecCtx && ns->m_qvideo.size() < 20) || 
(ns->m_ACodecCtx && ns->m_qaudio.size() < 20))
+                       if ( ns->m_qvideo.size() < 20 || ns->m_qaudio.size() < 
20 ) 
                        {
 
                                // If we have problems with decoding - break
@@ -747,7 +736,7 @@
 
        while (len > 0 && ns->m_qaudio.size() > 0)
        {
-               raw_mediadata_t* samples = ns->m_qaudio.front();
+               media::raw_mediadata_t* samples = ns->m_qaudio.front();
 
                int n = imin(samples->m_size, len);
                memcpy(stream, samples->m_ptr, n);
@@ -771,12 +760,10 @@
 bool NetStreamFfmpeg::decodeFLVFrame()
 {
        FLVFrame* frame = NULL;
-       if (m_qvideo.size() < m_qaudio.size() && m_VCodecCtx)
+       if ( m_qvideo.size() < m_qaudio.size() ) 
        {
                frame = m_parser->nextVideoFrame();
-       }
-       else if (m_ACodecCtx)
-       {
+       } else {
                frame = m_parser->nextAudioFrame();
        }
 
@@ -788,7 +775,7 @@
                        log_debug("decodeFLVFrame: load completed, stopping");
 #endif
                        // Stop!
-                       //m_go = false;
+                       this->m_go = false;
                }
                else
                {
@@ -799,28 +786,29 @@
                return false;
        }
 
-       AvPkt packet;
-       // TODO: move this logic in AvPkt itself  ?
-       packet->destruct = avpacket_destruct;
-       packet->size = frame->dataSize;
-       packet->data = frame->data;
+       AVPacket packet;
+
+       packet.destruct = avpacket_destruct;
+       packet.size = frame->dataSize;
+       packet.data = frame->data;
        // FIXME: is this the right value for packet.dts?
-       packet->pts = packet->dts = 
static_cast<boost::int64_t>(frame->timestamp);
+       packet.pts = packet.dts = static_cast<boost::int64_t>(frame->timestamp);
 
        if (frame->tag == 9)
        {
-               packet->stream_index = 0;
-               return decodeVideo(packet);
+               packet.stream_index = 0;
+               return decodeVideo(&packet);
        }
        else
        {
-               packet->stream_index = 1;
-               return decodeAudio(packet);
+               packet.stream_index = 1;
+               return decodeAudio(&packet);
        }
 
 }
 
-bool NetStreamFfmpeg::decodeAudio(AvPkt& packet)
+
+bool NetStreamFfmpeg::decodeAudio( AVPacket* packet )
 {
        if (!m_ACodecCtx) return false;
 
@@ -852,7 +840,7 @@
                        ptr = reinterpret_cast<boost::uint8_t*>(output);
                }
                
-               raw_mediadata_t* raw = new raw_mediadata_t();
+               media::raw_mediadata_t* raw = new media::raw_mediadata_t();
                
                raw->m_data = ptr;
                raw->m_ptr = raw->m_data;
@@ -895,7 +883,8 @@
        return true;
 }
 
-bool NetStreamFfmpeg::decodeVideo(AvPkt& packet)
+
+bool NetStreamFfmpeg::decodeVideo(AVPacket* packet)
 {
        if (!m_VCodecCtx) return false;
 
@@ -925,7 +914,7 @@
                }
                else if (m_videoFrameFormat == render::YUV && 
m_VCodecCtx->pix_fmt != PIX_FMT_YUV420P)
                {
-                       abort();        // TODO
+                       assert( 0 );    // TODO
                        //img_convert((AVPicture*) pFrameYUV, PIX_FMT_YUV420P, 
(AVPicture*) pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
                        // Don't use depreceted img_convert, use sws_scale
 
@@ -935,7 +924,7 @@
                        
buffer.reset(media::VideoDecoderFfmpeg::convertRGB24(m_VCodecCtx, m_Frame));
                }
 
-               raw_mediadata_t* video = new raw_mediadata_t;
+               media::raw_mediadata_t* video = new media::raw_mediadata_t();
 
                if (m_videoFrameFormat == render::YUV)
                {
@@ -944,7 +933,7 @@
                else if (m_videoFrameFormat == render::RGB)
                {
                        image::rgb* tmp = 
static_cast<image::rgb*>(m_imageframe);
-                       video->m_data = new 
boost::uint8_t[m_imageframe->size()]; // tmp->m_pitch * tmp->m_height];
+                       video->m_data = new boost::uint8_t[tmp->pitch() * 
tmp->height()];
                }
 
                video->m_ptr = video->m_data;
@@ -1052,29 +1041,30 @@
                return true;
        }
 
-       AvPkt packet;
+       AVPacket packet;
        
-       int rc = av_read_frame(m_FormatCtx, packet.get());
+       int rc = av_read_frame(m_FormatCtx, &packet);
 
        if (rc >= 0)
        {
-               if (packet->stream_index == m_audio_index && 
get_sound_handler())
+               if (packet.stream_index == m_audio_index && get_sound_handler())
                {
-                       if (!decodeAudio(packet))
+                       if (!decodeAudio(&packet)) 
                        {
                                log_error(_("Problems decoding audio frame"));
                                return false;
                        }
                }
                else
-               if (packet->stream_index == m_video_index)
+               if (packet.stream_index == m_video_index)
                {
-                       if (!decodeVideo(packet))
+                       if (!decodeVideo(&packet)) 
                        {
                                log_error(_("Problems decoding video frame"));
                                return false;
                        }
                }
+               av_free_packet(&packet);
        }
        else
        {
@@ -1107,7 +1097,7 @@
        {
 
                AVStream* videostream = m_FormatCtx->streams[m_video_index];
-               timebase = as_double(videostream->time_base);
+               timebase = static_cast<double>(videostream->time_base.num / 
videostream->time_base.den);
                newpos = static_cast<long>(pos / timebase);
                
                if (av_seek_frame(m_FormatCtx, m_video_index, newpos, 0) < 0)
@@ -1144,19 +1134,23 @@
        }
        else
        {
-               AvPkt packet;
+               AVPacket Packet;
+               av_init_packet(&Packet);
                double newtime = 0;
                while (newtime == 0)
                {
-                       if ( av_read_frame(m_FormatCtx, packet.get()) < 0)
+                       if (av_read_frame(m_FormatCtx, &Packet) < 0) 
                        {
                                av_seek_frame(m_FormatCtx, -1, 0, 
AVSEEK_FLAG_BACKWARD);
+                               av_free_packet( &Packet );
                                return;
                        }
 
                        newtime = timebase * 
(double)m_FormatCtx->streams[m_video_index]->cur_dts;
                }
 
+               av_free_packet( &Packet );
+
                av_seek_frame(m_FormatCtx, m_video_index, newpos, 0);
                boost::uint32_t newtime_ms = 
static_cast<boost::int32_t>(newtime / 1000.0);
                m_start_clock += m_last_audio_timestamp - newtime_ms;
@@ -1167,8 +1161,16 @@
        }
        
        // Flush the queues
-       m_qvideo.clear();
-       m_qaudio.clear();
+       while ( m_qvideo.size() > 0 ) 
+       {
+               delete m_qvideo.front();
+               m_qvideo.pop();
+       }
+       while ( m_qaudio.size() > 0 ) 
+       {
+               delete m_qaudio.front();
+               m_qaudio.pop();
+       }
 
 }
 
@@ -1183,7 +1185,7 @@
        {
                // Get video frame from queue, will have the lowest timestamp
                // will return NULL if empty(). See multithread_queue::front
-               raw_mediadata_t* video = m_qvideo.front();
+               media::raw_mediadata_t* video = m_qvideo.front();
 
                // If the queue is empty we have nothing to do
                if (!video)
@@ -1279,7 +1281,7 @@
 
        if (m_FormatCtx && m_FormatCtx->nb_streams > 0)
        {
-               double time = as_double(m_FormatCtx->streams[0]->time_base) * 
(double)m_FormatCtx->streams[0]->cur_dts;
+               double time = (double)m_FormatCtx->streams[0]->time_base.num / 
(double)m_FormatCtx->streams[0]->time_base.den * 
(double)m_FormatCtx->streams[0]->cur_dts;
                return static_cast<boost::int32_t>(time);
        }
        else if
@@ -1328,10 +1330,39 @@
        // Re-connect to the soundhandler.
        // It was disconnected to avoid to keep playing sound while paused
        media::sound_handler* s = get_sound_handler();
-       if (s && m_ACodecCtx) s->attach_aux_streamer(audio_streamer, (void*) 
this);
+       if ( s )     s->attach_aux_streamer(audio_streamer, (void*) this);
+}
+
+
+long
+NetStreamFfmpeg::bytesLoaded ()
+{
+       long ret_val = 0;
+
+       if ( _netCon ) 
+       {
+               ret_val = _netCon->getBytesLoaded();
+       }
+
+       return ret_val;
+}
+
+
+long
+NetStreamFfmpeg::bytesTotal ()
+{
+       long ret_val = 0;
+
+       if ( _netCon ) 
+       {
+               ret_val = _netCon->getBytesTotal();
+       }
+
+       return ret_val;
 }
 
 
 } // gnash namespcae
 
 #endif // USE_FFMPEG
+

Index: server/asobj/NetStreamFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.h,v
retrieving revision 1.56
retrieving revision 1.56.2.1
diff -u -b -r1.56 -r1.56.2.1
--- server/asobj/NetStreamFfmpeg.h      21 Jan 2008 20:55:57 -0000      1.56
+++ server/asobj/NetStreamFfmpeg.h      22 Feb 2008 14:16:40 -0000      1.56.2.1
@@ -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: NetStreamFfmpeg.h,v 1.56 2008/01/21 20:55:57 rsavoye Exp $ */
+/* $Id: NetStreamFfmpeg.h,v 1.56.2.1 2008/02/22 14:16:40 strk Exp $ */
 
 #ifndef __NETSTREAMFFMPEG_H__
 #define __NETSTREAMFFMPEG_H__
@@ -37,7 +37,6 @@
 #include <boost/thread/condition.hpp>
 
 #include "impl.h"
-#include "video_stream_instance.h"
 
 extern "C" {
 #include <ffmpeg/avformat.h>
@@ -49,194 +48,11 @@
 
 #include "FLVParser.h"
 
-namespace gnash {
-  
-class raw_mediadata_t
-{
-public:
-       raw_mediadata_t():
-       m_stream_index(-1),
-       m_size(0),
-       m_data(NULL),
-       m_ptr(NULL),
-       m_pts(0)
-       {
-       }
-
-       ~raw_mediadata_t()
-       {
-               if (m_data) delete [] m_data;
-       }
-
-       int m_stream_index;
-       boost::uint32_t m_size;
-       boost::uint8_t* m_data;
-       boost::uint8_t* m_ptr;
-       boost::uint32_t m_pts;  // presentation timestamp in millisec
-};
-
-/// Threadsafe elements-owning queue
-//
-/// This class is a threadsafe queue, using std:queue and locking.
-/// It is used to store decoded audio and video data which are waiting to be 
"played"
-/// Elements of the queue are owned by instances of this class.
-///
-template<class T>
-class multithread_queue
-{
-       public:
-
-       multithread_queue()
-               {
-               }
-
-       // Destroy all elements of the queue. Locks.
-       ~multithread_queue()
-       {
-               clear();
-       }
-
-       // Destroy all elements of the queue. Locks.
-       void clear()
-       {
-               boost::mutex::scoped_lock lock(_mutex);
-               while (!m_queue.empty())
-               {
-                       T x = m_queue.front();
-                       m_queue.pop();
-                       delete x;
-               }
-       }
-
-       /// Returns the size if the queue. Locks.
-       //
-       /// @return the size of the queue
-       ///
-       size_t size()
-       {
-               boost::mutex::scoped_lock lock(_mutex);
-               size_t n = m_queue.size();
-               return n;
-       }
-
-       /// Pushes an element to the queue. Locks.
-       //
-       /// @param member
-       /// The element to be pushed unto the queue.
-       ///
-       /// @return true if queue isn't full and the element was pushed to the 
queue,
-       /// or false if the queue was full, and the element wasn't push unto it.
-       ///
-       bool push(T member)
-       {
-               bool rc = false;
-               boost::mutex::scoped_lock lock(_mutex);
+#include "ffmpegNetStreamUtil.h"
 
-               // We only keep max 20 items in the queue.
-               // If it's "full" the item must wait, see calls
-               // to this function in read_frame() to see how it is done.
-               if (m_queue.size() < 20)
-               {
-                       m_queue.push(member);
-                       rc = true;
-               }
-               return rc;
-       }
-
-       /// Returns a pointer to the first element on the queue. Locks.
-       //
-       /// If no elements are available this function returns NULL.
-       ///
-       /// @return a pointer to the first element on the queue, NULL if queue 
is empty.
-       ///
-       T front()
-       {
-               boost::mutex::scoped_lock lock(_mutex);
-               T member = NULL;
-               if (!m_queue.empty())
-               {
-                       member = m_queue.front();
-               }
-               return member;
-       }
-
-       /// Pops the first element from the queue. Locks.
-       //
-       /// If no elements are available this function is
-       /// a noop. 
-       ///
-       void pop()
-       {
-               boost::mutex::scoped_lock lock(_mutex);
-               if (!m_queue.empty())
-               {
-                       m_queue.pop();
-               }
-       }
 
-private:
-
-       // Mutex used for locking
-       boost::mutex _mutex;
-
-       // The actual queue.
-       std::queue < T > m_queue;
-};
-
-/// This class is used to provide an easy interface to libavcodecs audio 
resampler.
-///
-class AudioResampler
-{
-public:
-       AudioResampler() : _context(NULL) {}
-       ~AudioResampler()
-       { 
-               if(_context) {
-                       audio_resample_close (_context);
-               }
-       }
-       
-       /// Initializes the resampler
-       //
-       /// @param ctx
-       /// The audio format container.
-       ///
-       /// @return true if resampling is needed, if not false
-       ///
-       bool init(AVCodecContext* ctx)
-       {
-               if (ctx->sample_rate != 44100 || ctx->channels != 2) {
-                       if (!_context) {
-                               _context = audio_resample_init(2,  
ctx->channels, 
-                                       44100, ctx->sample_rate);
-                       }
-                       return true;
-               }
-               return false;
-       }
-       
-       /// Resamples audio
-       //
-       /// @param input
-       /// A pointer to the audio data that needs resampling
-       ///
-       /// @param output
-       /// A pointer to where the resampled output should be placed
-       ///
-       /// @param samples
-       /// Number of samples in the audio
-       ///
-       /// @return the number of samples in the output data.
-       ///
-       int resample(boost::int16_t* input, boost::int16_t* output, int samples)
-       {
-               return audio_resample (_context, output, input, samples);
-       }
+namespace gnash {
 
-private:
-       // The container of the resample format information.
-       ReSampleContext* _context;
-};
 
 class NetStreamFfmpeg: public NetStream {
 public:
@@ -247,7 +63,7 @@
        void close();
 
        // See dox in NetStream.h
-       void pause(int mode);
+       void pause( PauseMode mode );
 
        // See dox in NetStream.h
        void play(const std::string& source);
@@ -284,48 +100,11 @@
        ///
        static bool audio_streamer(void *udata, boost::uint8_t *stream, int 
len);
 
-private:
-
-       /// A C++ wrapper around ffmpeg's AVPacket structure
-       //
-       /// Used in decodeVideo() and decodeAudio(). 
-       //
-       /// Use Pkt.get() to access.
-       ///
-       class AvPkt
-       {
-       public:
-       
-               /// Constructs and initialize an AVPacket 
-               AvPkt ()
-               {
-                       av_init_packet(&_pkt);
-               }
-               
-               /// Properly deinitialize the owned AVPacket 
-               ~AvPkt ()
-               {
-                       av_free_packet(&_pkt);
-               }
-
-               /// @ return AVPacket* owned by this instance
-               AVPacket* get ()
-               {
-                       return &_pkt;
-       
-               }
+       long bytesLoaded();
                
-               /// @ return AVPacket* owned by this instance
-               AVPacket* operator-> ()
-               {
-                       return &_pkt;
-               }
+       long bytesTotal();
 
-       private:
-               AVPacket _pkt;
-               AvPkt(const AvPkt&);
-               AvPkt& operator= (const AvPkt&);
-       };
+private:
 
        // Setups the playback
        bool startPlayback();
@@ -378,10 +157,10 @@
        bool decodeFLVFrame();
 
        // Used to decode a video frame and push it on the videoqueue
-       bool decodeVideo(AvPkt& packet);
+       bool decodeVideo( AVPacket* packet );
 
        // Used to decode a audio frame and push it on the audioqueue
-       bool decodeAudio(AvPkt& packet);
+       bool decodeAudio( AVPacket* packet );
 
        // Used to calculate a decimal value from a ffmpeg fraction
        inline double as_double(AVRational time)
@@ -406,7 +185,7 @@
        AVFrame* m_Frame;
 
        // Use for resampling audio
-       AudioResampler _resampler;
+       media::AudioResampler _resampler;
 
        // The decoding thread
        boost::thread* _decodeThread;
@@ -422,15 +201,15 @@
        boost::uint32_t m_current_timestamp;
 
        // The queues of audio and video data.
-       multithread_queue <raw_mediadata_t*> m_qaudio;
-       multithread_queue <raw_mediadata_t*> m_qvideo;
+       media::multithread_queue <media::raw_mediadata_t*> m_qaudio;
+       media::multithread_queue <media::raw_mediadata_t*> m_qvideo;
 
        // The time we started playing in seconds (since VM start ?)
        volatile boost::uint64_t m_start_clock;
 
        // When the queues are full, this is where we keep the audio/video frame
        // there wasn't room for on its queue
-       raw_mediadata_t* m_unqueued_data;
+       media::raw_mediadata_t* m_unqueued_data;
 
        ByteIOContext ByteIOCxt;
 
@@ -438,8 +217,10 @@
        volatile boost::uint64_t m_time_of_pause;
 };
 
+
 } // gnash namespace
 
+
 #endif // USE_FFMPEG
 
 #endif //  __NETSTREAMFFMPEG_H__

Index: server/parser/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/parser/Makefile.am,v
retrieving revision 1.42
retrieving revision 1.42.2.1
diff -u -b -r1.42 -r1.42.2.1
--- server/parser/Makefile.am   21 Jan 2008 20:55:59 -0000      1.42
+++ server/parser/Makefile.am   22 Feb 2008 14:16:41 -0000      1.42.2.1
@@ -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.42 2008/01/21 20:55:59 rsavoye Exp $
+# $Id: Makefile.am,v 1.42.2.1 2008/02/22 14:16:41 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -36,8 +36,6 @@
         -I$(top_srcdir)/libbase \
         -I$(top_srcdir)/libgeometry \
         -I$(top_srcdir)/libmedia \
-        -I$(top_srcdir)/libmedia/sdl \
-        -I$(top_srcdir)/libmedia/gst \
         -I$(top_srcdir)/libamf \
         -I$(top_srcdir)        \
        $(LIBXML_CFLAGS) \
@@ -91,11 +89,13 @@
 libgnashparser_la_LDFLAGS = $(BOOST_LIBS) -export-dynamic # -release 
$(VERSION) -no-undefined 
 
 if USE_SOUND_GST
-AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
+AM_CPPFLAGS += $(GSTREAMER_CFLAGS) \
+               -I$(top_srcdir)/libmedia/gst
 endif
 
 if USE_FFMPEG_ENGINE
-AM_CPPFLAGS += $(FFMPEG_CFLAGS)
+AM_CPPFLAGS += $(FFMPEG_CFLAGS) \
+               -I$(top_srcdir)/libmedia/ffmpeg
 endif
 
 # Rebuild with GCC 4.x Mudflap support

Index: server/parser/video_stream_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v
retrieving revision 1.39
retrieving revision 1.39.2.1
diff -u -b -r1.39 -r1.39.2.1
--- server/parser/video_stream_def.cpp  20 Feb 2008 15:54:59 -0000      1.39
+++ server/parser/video_stream_def.cpp  22 Feb 2008 14:16:41 -0000      1.39.2.1
@@ -16,14 +16,19 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 // 
-// $Id: video_stream_def.cpp,v 1.39 2008/02/20 15:54:59 bjacques Exp $
+// $Id: video_stream_def.cpp,v 1.39.2.1 2008/02/22 14:16:41 strk Exp $
 
 #include "video_stream_def.h"
 #include "video_stream_instance.h"
 #include "render.h"
 #include "BitsReader.h"
 
-#include "VideoDecoderGst.h"
+#ifdef SOUND_GST
+# include "VideoDecoderGst.h"
+#elif defined(USE_FFMPEG)
+# include "VideoDecoderFfmpeg.h"
+#endif
+
 #include <boost/bind.hpp>
 
 
@@ -39,22 +44,31 @@
 {
 }
 
+
+#ifdef SOUND_GST
 void myunref(GstBuffer* buf)
 {
        gst_buffer_unref(buf);
 }
+#endif
 
 
 video_stream_definition::~video_stream_definition()
 {
+#ifdef SOUND_GST
        std::for_each(_video_frames.begin(), _video_frames.end(), myunref);
+#elif defined(USE_FFMPEG)
+       for ( int32_t size = _video_frames.size()-1; size >= 0; size-- ) {
+               delete _video_frames[size];
+       }
+       _video_frames.clear();
+#endif
 }
 
 
 void
 video_stream_definition::readDefineVideoStream(stream* in, SWF::tag_type tag, 
movie_definition* m)
 {
-
        // Character ID has been read already, and was loaded in the constructor
 
        assert(tag == SWF::DEFINEVIDEOSTREAM);
@@ -62,7 +76,7 @@
 
        m_start_frame = m->get_loading_frame();
 
-       // numFrames:2 width:2 height:2 flags:1 codec:1
+       // numFrames:2 width:2 height:2 flags:1
        in->ensureBytes(8);
 
        m_num_frames = in->read_u16();
@@ -89,13 +103,18 @@
                return;
        }
 
+#ifdef SOUND_GST
        _decoder.reset( new media::VideoDecoderGst(m_codec_id, _width, _height) 
);
-
+#elif defined(USE_FFMPEG)
+       _decoder.reset( new media::VideoDecoderFfmpeg() );
+#endif
 }
 
 void
 video_stream_definition::readDefineVideoFrame(stream* in, SWF::tag_type tag, 
movie_definition* m)
 {
+#ifdef SOUND_GST
+
        // Character ID has been read already, and was loaded in the constructor
 
        assert(tag == SWF::VIDEOFRAME);
@@ -129,6 +148,8 @@
        in->read((char*)GST_BUFFER_DATA(buffer), dataSize);
 
        _video_frames.push_back(buffer);
+
+#endif
 }
 
 
@@ -139,15 +160,21 @@
        return ch;
 }
 
+#ifdef SOUND_GST
+
 bool
 has_frame_number(GstBuffer* buf, boost::uint32_t frameNumber)
 {
        return GST_BUFFER_OFFSET(buf) == frameNumber;
 }
 
+#endif
+
 std::auto_ptr<image::image_base>
 video_stream_definition::get_frame_data(boost::uint32_t frameNum)
 {
+#ifdef SOUND_GST
+
        if (_video_frames.empty()) {
                return std::auto_ptr<image::image_base>();
        }
@@ -196,6 +223,12 @@
        }
 
        return std::auto_ptr<image::image_base>(buffer.release());
+
+#elif defined(USE_FFMPEG)
+
+       return std::auto_ptr<image::image_base>( NULL );
+
+#endif
 }
 
 

Index: server/parser/video_stream_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v
retrieving revision 1.22
retrieving revision 1.22.2.1
diff -u -b -r1.22 -r1.22.2.1
--- server/parser/video_stream_def.h    27 Jan 2008 07:18:20 -0000      1.22
+++ server/parser/video_stream_def.h    22 Feb 2008 14:16:41 -0000      1.22.2.1
@@ -16,7 +16,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 // 
-// $Id: video_stream_def.h,v 1.22 2008/01/27 07:18:20 bjacques Exp $
+// $Id: video_stream_def.h,v 1.22.2.1 2008/02/22 14:16:41 strk Exp $
 
 #ifndef GNASH_VIDEO_STREAM_DEF_H
 #define GNASH_VIDEO_STREAM_DEF_H
@@ -31,7 +31,13 @@
 #include "swf.h"
 #include "rect.h" // for composition
 #include "ControlTag.h"
-#include "VideoDecoderGst.h"
+
+#ifdef SOUND_GST
+# include "VideoDecoderGst.h"
+#elif defined(USE_FFMPEG)
+# include "VideoDecoderFfmpeg.h"
+#endif
+
 #include "image.h"
 
 #include <map>
@@ -157,7 +163,12 @@
        /// Elements of this vector are owned by this instance, and will be 
deleted 
        /// at instance destruction time.
        ///
+#ifdef SOUND_GST
        typedef std::vector<GstBuffer*> EmbedFrameVec;
+#elif defined(USE_FFMPEG)
+       typedef std::vector<uint8_t*> EmbedFrameVec;
+#endif
+
        EmbedFrameVec _video_frames;
 
        /// Last decoded frame number
@@ -170,7 +181,11 @@
        boost::uint32_t _height;
 
        /// The decoder used to decode the video frames
+#ifdef SOUND_GST
        boost::scoped_ptr<media::VideoDecoderGst> _decoder;
+#elif defined(USE_FFMPEG)
+       boost::scoped_ptr<media::VideoDecoderFfmpeg> _decoder;
+#endif
 };
 
 }      // end namespace gnash

Index: server/vm/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/vm/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.17.2.1
diff -u -b -r1.17 -r1.17.2.1
--- server/vm/Makefile.am       21 Jan 2008 20:56:04 -0000      1.17
+++ server/vm/Makefile.am       22 Feb 2008 14:16:41 -0000      1.17.2.1
@@ -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.17 2008/01/21 20:56:04 rsavoye Exp $
+# $Id: Makefile.am,v 1.17.2.1 2008/02/22 14:16:41 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -31,12 +31,8 @@
         -I$(top_srcdir)/libgeometry \
         -I$(top_srcdir)/libamf \
         -I$(top_srcdir)/libmedia \
-        -I$(top_srcdir)/libmedia/sdl \
-        -I$(top_srcdir)/libmedia/gst \
         -I$(top_srcdir)        \
        $(GLIB_CFLAGS) \
-       $(FFMPEG_CFLAGS) \
-       $(GSTREAMER_CFLAGS) \
        $(PTHREAD_CFLAGS) \
        $(DMALLOC_CFLAGS) \
        $(BOOST_CFLAGS) \

Index: utilities/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/utilities/Makefile.am,v
retrieving revision 1.64
retrieving revision 1.64.2.1
diff -u -b -r1.64 -r1.64.2.1
--- utilities/Makefile.am       13 Feb 2008 02:36:34 -0000      1.64
+++ utilities/Makefile.am       22 Feb 2008 14:16:42 -0000      1.64.2.1
@@ -36,9 +36,7 @@
        $(LIBLTDL) \
         $(MYSQL_LIBS) \
        $(LIBXML_LIBS) \
-       $(FFMPEG_LIBS) \
        $(CURL_LIBS) \
-       $(INTLLIBS) \
        $(BOOST_LIBS) \
        $(PTHREAD_LIBS) \
        $(NULL)
@@ -56,8 +54,6 @@
         -I$(top_srcdir)/server/parser \
         -I$(top_srcdir)/server/vm \
         -I$(top_srcdir)/libmedia \
-        -I$(top_srcdir)/libmedia/sdl \
-        -I$(top_srcdir)/libmedia/gst \
         -DLOCALEDIR=\"$(localedir)\" \
        $(PTHREAD_CFLAGS) \
        $(BOOST_CFLAGS) \
@@ -66,7 +62,8 @@
        $(NULL)
 
 if USE_FFMPEG_ENGINE
- AM_CPPFLAGS += $(FFMPEG_INCLS) 
+ AM_CPPFLAGS += $(FFMPEG_CFLAGS) \
+               -I$(top_srcdir)/libmedia/ffmpeg 
  GNASH_LIBS += $(FFMPEG_LIBS)
 endif
 
@@ -76,6 +73,8 @@
 endif
 
 #if USE_SOUND_GST
+ AM_CPPFLAGS += $(GSTREAMER_CFLAGS) \
+               -I$(top_srcdir)/libmedia/gst
  GNASH_LIBS += $(GLIB_LIBS) $(GSTREAMER_LIBS)
 #endif
 
@@ -86,14 +85,14 @@
 gprocessor_CPPFLAGS = $(AM_CPPFLAGS)
 # export our symbols so they can be used by Gnash plugins
 gprocessor_LDFLAGS = -export-dynamic $(LIBLTDL)
-gprocessor_LDADD = $(GNASH_LIBS) $(AM_LDFLAGS)
+gprocessor_LDADD = $(GNASH_LIBS) 
 #gprocessor_DEPENDENCIES = 
 
 dumpshm_SOURCES = dumpshm.cpp
-dumpshm_LDADD = $(GNASH_LIBS) $(AM_LDFLAGS)
+dumpshm_LDADD = $(GNASH_LIBS)
 
 soldumper_SOURCES = soldumper.cpp
-soldumper_LDADD = $(GNASH_LIBS) $(AM_LDFLAGS)
+soldumper_LDADD = $(GNASH_LIBS)
 
 # Rebuild with GCC 4.x Mudflap support
 mudflap:

Index: libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
===================================================================
RCS file: libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
diff -N libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/AudioDecoderFfmpeg.cpp      22 Feb 2008 14:16:33 -0000      
1.1.2.1
@@ -0,0 +1,284 @@
+// AudioDecoderFfmpeg.cpp: Audio decoding using the FFMPEG library.
+// 
+//   Copyright (C) 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: AudioDecoderFfmpeg.cpp,v 1.1.2.1 2008/02/22 14:16:33 strk Exp $
+
+#include "AudioDecoderFfmpeg.h"
+
+namespace gnash {
+namespace media {
+       
+AudioDecoderFfmpeg::AudioDecoderFfmpeg ()
+       :
+       _audioCodec(NULL),
+       _audioCodecCtx(NULL),
+       _parser(NULL)
+{}
+
+AudioDecoderFfmpeg::~AudioDecoderFfmpeg()
+{
+       if (_audioCodecCtx)
+       {
+               avcodec_close(_audioCodecCtx);
+               av_free(_audioCodecCtx);
+       }
+       if (_parser) av_parser_close(_parser);
+}
+
+bool AudioDecoderFfmpeg::setup(SoundInfo* info)
+{
+       // Init the avdecoder-decoder
+       avcodec_init();
+       avcodec_register_all();// change this to only register need codec?
+
+       enum CodecID codec_id;
+
+       switch(info->getFormat()) {
+               case AUDIO_CODEC_RAW:
+                       codec_id = CODEC_ID_PCM_U16LE;
+                       break;
+               case AUDIO_CODEC_ADPCM:
+                       codec_id = CODEC_ID_ADPCM_SWF;
+                       break;
+               case AUDIO_CODEC_MP3:
+                       codec_id = CODEC_ID_MP3;
+                       // Init the parser
+                       _parser = av_parser_init(codec_id);
+
+                       if (!_parser) { 
+                               log_error(_("libavcodec can't parse the current 
audio format"));
+                               return false;
+                       }
+                       break;
+               default:
+                       log_error(_("Unsupported audio codec %d"), 
static_cast<int>(info->getFormat()));
+                       return false;
+       }
+       _audioCodec = avcodec_find_decoder(codec_id);
+
+       if (!_audioCodec) {
+               log_error(_("libavcodec can't decode the current audio 
format"));
+               return false;
+       }
+
+       _audioCodecCtx = avcodec_alloc_context();
+       if (!_audioCodecCtx) {
+               log_error(_("libavcodec couldn't allocate context"));
+               return false;
+       }
+
+       int ret = avcodec_open(_audioCodecCtx, _audioCodec);
+       if (ret < 0) {
+               avcodec_close(_audioCodecCtx);
+               log_error(_("libavcodec failed to initialize codec"));
+               return false;
+       }
+
+       if (_audioCodecCtx->codec->id != CODEC_ID_MP3) {
+               _audioCodecCtx->channels = (info->isStereo() ? 2 : 1);
+               _audioCodecCtx->sample_rate = info->getSampleRate();
+               _audioCodecCtx->sample_fmt = SAMPLE_FMT_S16;
+       }
+
+       return true;
+}
+
+bool AudioDecoderFfmpeg::setup(AudioInfo* info)
+{
+       // Init the avdecoder-decoder
+       avcodec_init();
+       avcodec_register_all();// change this to only register need codec?
+
+       if (info->type == FLASH) {
+               enum CodecID codec_id;
+
+               switch(info->codec)
+               {
+                       case AUDIO_CODEC_RAW:
+                               codec_id = CODEC_ID_PCM_U16LE;
+                               break;
+                       case AUDIO_CODEC_ADPCM:
+                               codec_id = CODEC_ID_ADPCM_SWF;
+                               break;
+                       case AUDIO_CODEC_MP3:
+                               codec_id = CODEC_ID_MP3;
+                               break;
+                       default:
+                               log_error(_("Unsupported audio codec %d"), 
static_cast<int>(info->codec));
+                               return false;
+               }
+               _audioCodec = avcodec_find_decoder(codec_id);
+               // Init the parser
+               _parser = av_parser_init(codec_id);
+       }
+       else if (info->type == FFMPEG)
+       {
+               _audioCodec = 
avcodec_find_decoder(static_cast<CodecID>(info->codec));
+               // Init the parser
+               _parser = av_parser_init(static_cast<CodecID>(info->codec));
+       }
+       else
+       {
+               return false;
+       }
+
+       if (!_audioCodec)
+       {
+               log_error(_("libavcodec can't decode the current audio 
format"));
+               return false;
+       }
+
+       // Reuse the audioCodecCtx from the ffmpeg parser if exists/possible
+       if (info->audioCodecCtx)
+       {
+               log_debug("re-using the parser's audioCodecCtx");
+               _audioCodecCtx = info->audioCodecCtx;
+       } 
+       else
+       {
+               _audioCodecCtx = avcodec_alloc_context();
+       }
+
+       if (!_audioCodecCtx) {
+               log_error(_("libavcodec couldn't allocate context"));
+               return false;
+       }
+
+       int ret = avcodec_open(_audioCodecCtx, _audioCodec);
+       if (ret < 0) {
+               avcodec_close(_audioCodecCtx);
+               log_error(_("libavcodec failed to initialize codec"));
+               return false;
+       }
+
+       if (_audioCodecCtx->codec->id != CODEC_ID_MP3) {
+               _audioCodecCtx->channels = (info->stereo ? 2 : 1);
+               _audioCodecCtx->sample_rate = info->sampleRate;
+               //_audioCodecCtx->sample_fmt = SAMPLE_FMT_S16;
+       }
+
+       return true;
+}
+
+boost::uint8_t* AudioDecoderFfmpeg::decode(boost::uint8_t* input, 
boost::uint32_t inputSize, boost::uint32_t& outputSize, boost::uint32_t& 
decodedBytes, bool parse)
+{
+
+       long bytes_decoded = 0;
+       int bufsize = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
+       boost::uint8_t* output = new boost::uint8_t[bufsize];
+       boost::uint32_t orgbufsize = bufsize;
+       decodedBytes = 0;
+
+       if (parse) {
+       
+               if (!_parser)
+               {       
+                       log_error(_("libavcodec can't parse the current audio 
format"));
+                       return NULL;
+               }
+       
+       
+               bufsize = 0;
+               while (bufsize == 0 && decodedBytes < inputSize) {
+                       boost::uint8_t* frame;
+                       int framesize;
+
+                       bytes_decoded = av_parser_parse(_parser, 
_audioCodecCtx, &frame, &framesize, input+decodedBytes, inputSize-decodedBytes, 
0, 0); //the last 2 is pts & dts
+
+                       int tmp = 0;
+#ifdef FFMPEG_AUDIO2
+                       bufsize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+                       tmp = avcodec_decode_audio2(_audioCodecCtx, 
reinterpret_cast<boost::int16_t*>(output), &bufsize, frame, framesize);
+#else
+                       tmp = avcodec_decode_audio(_audioCodecCtx, 
reinterpret_cast<boost::int16_t*>(output), &bufsize, frame, framesize);
+#endif
+
+                       if (bytes_decoded < 0 || tmp < 0 || bufsize < 0) {
+                               log_error(_("Error while decoding audio data. 
Upgrading ffmpeg/libavcodec might fix this issue."));
+                               // Setting data position to data size will get 
the sound removed
+                               // from the active sound list later on.
+                               decodedBytes = inputSize;
+                               break;
+                       }
+
+                       decodedBytes += bytes_decoded;
+               }
+
+       } else {
+
+               int tmp = 0;
+
+#ifdef FFMPEG_AUDIO2
+               tmp = avcodec_decode_audio2(_audioCodecCtx, 
reinterpret_cast<boost::int16_t*>(output), &bufsize, input, inputSize);
+#else
+               tmp = avcodec_decode_audio(_audioCodecCtx, 
reinterpret_cast<boost::int16_t*>(output), &bufsize, input, inputSize);
+#endif
+
+
+
+               if (bytes_decoded < 0 || tmp < 0 || bufsize < 0) {
+                       log_error(_("Error while decoding audio data. Upgrading 
ffmpeg/libavcodec might fix this issue."));
+                       // Setting data position to data size will get the 
sound removed
+                       // from the active sound list later on.
+                       decodedBytes = 0;
+                       outputSize = 0;
+                       delete [] output;
+                       return NULL;
+               }
+
+               decodedBytes = inputSize;
+       }
+
+       // Error handling
+       if (bufsize < 1) {
+               log_error(_("Error while decoding audio data."));
+               delete [] output;
+               decodedBytes = 0;
+               outputSize = 0;
+               return NULL;
+       }
+
+       // Resampling is needed.
+       if (_resampler.init(_audioCodecCtx)) {
+               bool stereo = _audioCodecCtx->channels > 1 ? true : false;
+               int samples = stereo ? bufsize >> 2 : bufsize >> 1;
+
+               boost::uint8_t* tmp = new boost::uint8_t[orgbufsize];
+                       
+               samples = 
_resampler.resample(reinterpret_cast<boost::int16_t*>(output),
+                                                
reinterpret_cast<boost::int16_t*>(tmp),
+                                                samples);
+               outputSize = samples *2 *2; // the resampled audio has 
samplesize 2, and is stereo
+               boost::uint8_t* ret = new boost::uint8_t[outputSize];
+               memcpy(ret, tmp, outputSize);
+               delete [] tmp;
+               delete [] output;
+               return ret;
+       } else {
+               outputSize = bufsize;
+               boost::uint8_t* ret = new boost::uint8_t[outputSize];
+               memcpy(ret, output, outputSize);
+               delete [] output;
+               return ret;             
+       }
+}
+
+
+} // gnash.media namespace 
+} // gnash namespace

Index: libmedia/ffmpeg/AudioDecoderFfmpeg.h
===================================================================
RCS file: libmedia/ffmpeg/AudioDecoderFfmpeg.h
diff -N libmedia/ffmpeg/AudioDecoderFfmpeg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/AudioDecoderFfmpeg.h        22 Feb 2008 14:16:34 -0000      
1.1.2.1
@@ -0,0 +1,63 @@
+// AudioDecoderFfmpeg.h: Audio decoding using the FFMPEG library.
+// 
+//   Copyright (C) 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: AudioDecoderFfmpeg.h,v 1.1.2.1 2008/02/22 14:16:34 strk Exp $
+
+#ifndef __AUDIODECODERFFMPEG_H__
+#define __AUDIODECODERFFMPEG_H__
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+extern "C" {
+#include <ffmpeg/avcodec.h>
+}
+
+#include "log.h"
+#include "AudioDecoder.h"
+#include "ffmpegNetStreamUtil.h"
+
+namespace gnash {
+namespace media {
+
+class AudioDecoderFfmpeg : public AudioDecoder {
+       
+public:
+       AudioDecoderFfmpeg();
+       ~AudioDecoderFfmpeg();
+
+       bool setup(AudioInfo* info);
+       bool setup(SoundInfo* info);
+
+       boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t 
inputSize, boost::uint32_t& outputSize, boost::uint32_t& decodedBytes, bool 
parse);
+
+private:
+
+       AVCodec* _audioCodec;
+       AVCodecContext* _audioCodecCtx;
+       AVCodecParserContext* _parser;
+
+       // Use for resampling audio
+       AudioResampler _resampler;
+};
+       
+} // gnash.media namespace 
+} // gnash namespace
+
+#endif // __AUDIODECODERFFMPEG_H__

Index: libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
===================================================================
RCS file: libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
diff -N libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.cpp      22 Feb 2008 14:16:34 -0000      
1.1.2.1
@@ -0,0 +1,374 @@
+// VideoDecoderFfmpeg.cpp: Video decoding using the FFMPEG library.
+// 
+//   Copyright (C) 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: VideoDecoderFfmpeg.cpp,v 1.1.2.1 2008/02/22 14:16:34 strk Exp $
+
+#include "VideoDecoderFfmpeg.h"
+
+#ifdef HAVE_SWSCALE_H
+extern "C" {
+#include <ffmpeg/swscale.h>
+}
+#endif
+#include <boost/scoped_array.hpp>
+
+namespace gnash {
+namespace media {
+       
+VideoDecoderFfmpeg::VideoDecoderFfmpeg ()
+       :
+       _videoCodec(NULL),
+       _videoCodecCtx(NULL)
+{}
+
+VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
+{
+       if (_videoCodecCtx)
+       {
+               avcodec_close(_videoCodecCtx);
+               av_free(_videoCodecCtx);
+       }
+}
+
+bool VideoDecoderFfmpeg::setup(
+               int width,
+               int height,
+               int /*deblocking*/,
+               bool /*smoothing*/,
+               videoCodecType format, // should this argument be of codecType 
type ?
+               int /*outputFormat*/)
+{
+       // Init the avdecoder-decoder
+       avcodec_init();
+       avcodec_register_all();// change this to only register need codec?
+
+       enum CodecID codec_id;
+
+       // Find the decoder and init the parser
+       switch(format) {
+               case VIDEO_CODEC_H263:
+                       codec_id = CODEC_ID_FLV1;
+                       break;
+#ifdef FFMPEG_VP6
+               case VIDEO_CODEC_VP6:
+                       codec_id = CODEC_ID_VP6F;
+                       break;
+#endif
+               case VIDEO_CODEC_SCREENVIDEO:
+                       codec_id = CODEC_ID_FLASHSV;
+                       break;
+               default:
+                       log_error(_("Unsupported video codec %d"),
+                                               static_cast<int>(format));
+                       return false;
+       }
+
+       _videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id));
+
+       if (!_videoCodec) {
+               log_error(_("libavcodec can't decode the current video 
format"));
+               return false;
+       }
+
+       _videoCodecCtx = avcodec_alloc_context();
+       if (!_videoCodecCtx) {
+               log_error(_("libavcodec couldn't allocate context"));
+               return false;
+       }
+
+       int ret = avcodec_open(_videoCodecCtx, _videoCodec);
+       if (ret < 0) {
+               log_error(_("libavcodec failed to initialize codec"));
+               return false;
+       }
+       _videoCodecCtx->width = width;
+       _videoCodecCtx->height = height;
+
+       assert(_videoCodecCtx->width > 0);
+       assert(_videoCodecCtx->height > 0);
+       return true;
+}
+
+bool VideoDecoderFfmpeg::setup(VideoInfo* info)
+{
+       // Init the avdecoder-decoder
+       avcodec_init();
+       avcodec_register_all();// change this to only register need codec?
+
+       if (info->type == FLASH) {
+               enum CodecID codec_id;
+
+               // Find the decoder and init the parser
+               switch(info->codec) {
+                       case VIDEO_CODEC_H263:
+                               codec_id = CODEC_ID_FLV1;
+                               break;
+#ifdef FFMPEG_VP6
+                       case VIDEO_CODEC_VP6:
+                               codec_id = CODEC_ID_VP6F;
+                               break;
+#endif
+                       case VIDEO_CODEC_SCREENVIDEO:
+                               codec_id = CODEC_ID_FLASHSV;
+                               break;
+                       default:
+                               log_error(_("Unsupported video codec %d"),
+                                               static_cast<int>(info->codec));
+                               return false;
+               }
+               _videoCodec = 
avcodec_find_decoder(static_cast<CodecID>(codec_id));
+       } else if (info->type == FFMPEG) {
+               _videoCodec = 
avcodec_find_decoder(static_cast<CodecID>(info->codec));
+       } else {
+               //log_error("Video codecType unknown: %d, %d, %d",
+               //                              info->type, FLASH, FFMPEG);
+               return false;
+       }
+
+       if (!_videoCodec) {
+               log_error(_("libavcodec can't decode the current video 
format"));
+               return false;
+       }
+
+       // Reuse the videoCodecCtx from the ffmpeg parser if exists/possible
+       if (info->videoCodecCtx) {
+               log_debug("re-using the parsers videoCodecCtx");
+               _videoCodecCtx = info->videoCodecCtx;
+       } else {
+               _videoCodecCtx = avcodec_alloc_context();
+       }
+
+       if (!_videoCodecCtx) {
+               log_error(_("libavcodec couldn't allocate context"));
+               return false;
+       }
+
+       int ret = avcodec_open(_videoCodecCtx, _videoCodec);
+       if (ret < 0) {
+               log_error(_("libavcodec failed to initialize codec"));
+               return false;
+       }
+
+       return true;
+}
+
+boost::uint8_t*
+VideoDecoderFfmpeg::convertRGB24(AVCodecContext* srcCtx, AVFrame* srcFrame)
+{
+       int width = srcCtx->width, height = srcCtx->height;
+
+       int bufsize = avpicture_get_size(PIX_FMT_RGB24, width, height);
+       if (bufsize == -1) {
+               return NULL;
+       }
+
+       boost::uint8_t* buffer = new boost::uint8_t[bufsize];
+       if (!buffer) {
+               return NULL;
+       }
+
+       AVPicture picture;
+
+       avpicture_fill(&picture, buffer, PIX_FMT_RGB24, width, height);
+
+#ifndef HAVE_SWSCALE_H
+       img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) srcFrame,
+                       srcCtx->pix_fmt, width, height);
+#else
+       static struct SwsContext* context = NULL;
+
+       if (!context)
+       {
+               context = sws_getContext(width, height, srcCtx->pix_fmt,
+                                        width, height, PIX_FMT_RGB24,
+                                        SWS_FAST_BILINEAR, NULL, NULL, NULL);
+               
+               if (!context)
+               {
+                       delete [] buffer;
+                       return NULL;
+               }
+       }
+
+       int rv = sws_scale( 
+               context, srcFrame->data, srcFrame->linesize, 0, height, 
+               picture.data, picture.linesize 
+       );
+
+       if (rv == -1)
+       {
+               delete [] buffer;
+               return NULL;
+       }
+
+#endif // HAVE_SWSCALE_H
+
+       srcFrame->linesize[0] = picture.linesize[0];
+       srcFrame->data[0] = picture.data[0];
+
+       return buffer;
+}
+
+boost::uint8_t* VideoDecoderFfmpeg::decode(boost::uint8_t* input,
+                               boost::uint32_t inputSize,
+                               boost::uint32_t& outputSize)
+{
+       // Allocate a frame to store the decoded frame in
+       AVFrame* frame = avcodec_alloc_frame();
+       if ( ! frame )
+       {
+               log_error(_("Out of memory while allocating avcodec frame"));
+               throw std::bad_alloc();
+       }
+
+       int got = 0;
+       
+       avcodec_decode_video(_videoCodecCtx, frame, &got, input, inputSize);
+       
+       if (got)
+       {
+               boost::scoped_array<boost::uint8_t> buffer;
+               
+               // Set to the next multiple of four. Some videos have
+               // padding bytes, so that the source width is more than three 
times
+               // the video width. A likely explanation (supported by
+               // tests) is that it is always padded out to a multiple of 4.
+               // Have found no documenation on this.
+               unsigned int srcwidth = (_videoCodecCtx->width * 3 + 3) &~ 3; 
+
+               boost::uint8_t* decodedData = new boost::uint8_t[srcwidth * 
_videoCodecCtx->height];
+
+               buffer.reset(convertRGB24(_videoCodecCtx, frame));
+
+               // Copy the data to the buffer in the correct RGB format
+               boost::uint8_t* srcptr = frame->data[0];
+               boost::uint8_t* srcend = frame->data[0]
+                                       + frame->linesize[0]
+                                       * _videoCodecCtx->height;
+               boost::uint8_t* dstptr = decodedData;
+
+               outputSize = 0;
+
+               while (srcptr < srcend)
+               {
+                       memcpy(dstptr, srcptr, srcwidth);
+                       srcptr += frame->linesize[0];
+                       dstptr += srcwidth;
+                       outputSize += srcwidth;
+               }
+
+               av_free(frame);
+               return decodedData;
+
+/*             if (_videoFrameFormat == NONE) { // NullGui?
+                       return;
+
+               } else if (_videoFrameFormat == YUV && _videoCodecCtx->pix_fmt 
!= PIX_FMT_YUV420P) {
+                       abort();        // TODO
+                       //img_convert((AVPicture*) pFrameYUV, PIX_FMT_YUV420P, 
(AVPicture*) pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
+                       // Don't use depreceted img_convert, use sws_scale
+
+               } else if (_videoFrameFormat == RGB && _videoCodecCtx->pix_fmt 
!= PIX_FMT_RGB24) {
+                       buffer.reset(convertRGB24(_videoCodecCtx, frame));
+               }
+
+               raw_mediadata_t* video = new raw_mediadata_t;
+               if (_videoFrameFormat == YUV) {
+                       abort(); // See image.cpp to see what yuv size is
+                       //video->m_data = new 
boost::uint8_t[static_cast<image::yuv*>(m_imageframe)->size()];
+               } else if (_videoFrameFormat == RGB) {
+                       video->m_data = new 
boost::uint8_t[_videoCodecCtx->width * _videoCodecCtx->height * 3];
+               //}
+
+               video->m_ptr = video->m_data;
+               video->m_stream_index = _videoIndex;
+               video->m_pts = 0;
+
+               video->m_pts = 
static_cast<boost::uint32_t>((as_double(_videoStream->time_base) * packet->dts) 
* 1000.0);
+
+
+               if (_videoFrameFormat == YUV) {
+                       //image::yuv* yuvframe = 
static_cast<image::yuv*>(_imageframe);
+                       int copied = 0;
+                       boost::uint8_t* ptr = video->m_data;
+                       for (int i = 0; i < 3 ; i++)
+                       {
+                               int shift = (i == 0 ? 0 : 1);
+                               boost::uint8_t* yuv_factor = _frame->data[i];
+                               int h = _videoCodecCtx->height >> shift;
+                               int w = _videoCodecCtx->width >> shift;
+                               for (int j = 0; j < h; j++)
+                               {
+                                       copied += w;
+                                       //assert(copied <= yuvframe->size());
+                                       memcpy(ptr, yuv_factor, w);
+                                       yuv_factor += _frame->linesize[i];
+                                       ptr += w;
+                               }
+                       }
+                       video->m_size = copied;
+               } else if (_videoFrameFormat == RGB) {
+
+                       boost::uint8_t* srcptr = _frame->data[0];
+                       boost::uint8_t* srcend = _frame->data[0] + 
_frame->linesize[0] * _videoCodecCtx->height;
+                       boost::uint8_t* dstptr = video->m_data;
+                       unsigned int srcwidth = _videoCodecCtx->width * 3;
+
+                       video->m_size = 0;
+
+                       while (srcptr < srcend) {
+                               memcpy(dstptr, srcptr, srcwidth);
+                               srcptr += _frame->linesize[0];
+                               dstptr += srcwidth;
+                               video->m_size += srcwidth;
+                       }
+
+               }*/
+       }
+       else
+       {
+               log_error("Decoding of a video frame failed");
+               av_free(frame);
+               return NULL;
+       }
+}
+
+std::auto_ptr<image::image_base>
+VideoDecoderFfmpeg::decodeToImage(boost::uint8_t* input, boost::uint32_t 
inputSize)
+{
+       boost::uint32_t outputSize = 0;
+       boost::uint8_t* decodedData = decode(input, inputSize, outputSize);
+
+       if (!decodedData || outputSize == 0)
+       {
+               return std::auto_ptr<image::image_base>(NULL);
+       }
+
+       std::auto_ptr<image::image_base> ret(new image::rgb(
+                                               _videoCodecCtx->width,
+                                               _videoCodecCtx->height
+                                               ));
+       ret->update(decodedData);
+       delete [] decodedData;
+       return ret;
+       
+}
+
+} // gnash.media namespace 
+} // gnash namespace

Index: libmedia/ffmpeg/VideoDecoderFfmpeg.h
===================================================================
RCS file: libmedia/ffmpeg/VideoDecoderFfmpeg.h
diff -N libmedia/ffmpeg/VideoDecoderFfmpeg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.h        22 Feb 2008 14:16:35 -0000      
1.1.2.1
@@ -0,0 +1,74 @@
+// VideoDecoderFfmpeg.h: Video decoding using the FFMPEG library.
+// 
+//   Copyright (C) 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: VideoDecoderFfmpeg.h,v 1.1.2.1 2008/02/22 14:16:35 strk Exp $
+
+#ifndef __VIDEODECODERFFMPEG_H__
+#define __VIDEODECODERFFMPEG_H__
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "log.h"
+#include "VideoDecoder.h"
+
+extern "C" {
+#include <ffmpeg/avcodec.h>
+}
+
+
+namespace gnash {
+namespace media {
+
+
+class VideoDecoderFfmpeg : public VideoDecoder {
+       
+public:
+       VideoDecoderFfmpeg();
+       ~VideoDecoderFfmpeg();
+
+       virtual unsigned getPaddingBytes() const { return 
FF_INPUT_BUFFER_PADDING_SIZE; }
+
+       bool setup(VideoInfo* info);
+
+       bool setup(
+               int /*width*/,
+               int /*height*/,
+               int /*deblocking*/,
+               bool /*smoothing*/,
+               videoCodecType /*format*/,
+               int /*outputFormat*/);
+
+       boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t 
inputSize, boost::uint32_t& outputSize);
+
+       std::auto_ptr<image::image_base> decodeToImage(boost::uint8_t* 
/*input*/, boost::uint32_t /*inputSize*/);
+
+       static boost::uint8_t* convertRGB24(AVCodecContext* srcCtx, AVFrame* 
srcFrame);
+
+private:
+
+       AVCodec* _videoCodec;
+       AVCodecContext* _videoCodecCtx;
+
+};
+       
+} // gnash.media namespace 
+} // gnash namespace
+
+#endif // __VIDEODECODERFFMPEG_H__

Index: libmedia/ffmpeg/ffmpegNetStreamUtil.cpp
===================================================================
RCS file: libmedia/ffmpeg/ffmpegNetStreamUtil.cpp
diff -N libmedia/ffmpeg/ffmpegNetStreamUtil.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/ffmpegNetStreamUtil.cpp     22 Feb 2008 14:16:35 -0000      
1.1.2.1
@@ -0,0 +1,127 @@
+// ffmpegNetStreamUtil.cpp: Utility classes for use in 
+// server/asobj/NetStreamFfmpeg.*
+//
+//   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
+//
+
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// #include "utility.h" // for convert_raw_data
+// #include "AudioDecoderSimple.h"
+// #include "AudioDecoderNellymoser.h"
+
+#ifdef USE_FFMPEG
+# include "ffmpegNetStreamUtil.h"
+#endif
+
+
+#include "log.h"
+#include <cmath>
+#include <vector>
+#include <boost/scoped_array.hpp>
+#include <SDL.h>
+
+namespace gnash {
+namespace media {
+
+raw_mediadata_t::raw_mediadata_t()
+       :
+       m_stream_index(-1),
+       m_size(0),
+       m_data(NULL),
+       m_ptr(NULL),
+       m_pts(0)
+{
+}
+
+raw_mediadata_t::~raw_mediadata_t()
+{
+  if ( m_data ) {
+    delete [] m_data;
+  }
+}
+
+
+AudioResampler::AudioResampler()
+       :_context(NULL)
+{
+}
+
+AudioResampler::~AudioResampler()
+{
+  if ( _context ) {
+    audio_resample_close( _context );
+  }
+}
+
+/// Initialize the resampler
+//     
+/// @param ctx
+/// The audio format container.
+///
+/// @return true if resampling is needed, false if not
+///
+bool
+AudioResampler::init( AVCodecContext* ctx ) 
+{
+  if ( (ctx->sample_rate != 44100) || (ctx->channels != 2) ) {
+    if ( ! _context ) {
+      _context = audio_resample_init( 
+               2, ctx->channels, 44100, ctx->sample_rate 
+       );
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+/// Resample audio
+// 
+/// @param input
+/// A pointer to the audio data that needs resampling
+///
+/// @param output
+/// A pointer to where the resampled output should be placed
+///
+/// @param samples
+/// Number of samples in the audio
+///
+/// @return the number of samples in the output data.
+///
+int
+AudioResampler::resample( 
+                               boost::int16_t* input, 
+                               boost::int16_t* output, 
+                               int samples 
+                       ) 
+{
+  return audio_resample( _context, output, input, samples );
+}
+
+
+} // gnash.media namespace 
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// End:
+

Index: libmedia/ffmpeg/ffmpegNetStreamUtil.h
===================================================================
RCS file: libmedia/ffmpeg/ffmpegNetStreamUtil.h
diff -N libmedia/ffmpeg/ffmpegNetStreamUtil.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/ffmpegNetStreamUtil.h       22 Feb 2008 14:16:36 -0000      
1.1.2.1
@@ -0,0 +1,221 @@
+// ffmpegNetStreamUtil.h: Utility classes for use in 
+// server/asobj/NetStreamFfmpeg.*
+//
+//   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
+
+
+#ifndef FFMPEGNETSTREAMUTIL_H
+#define FFMPEGNETSTREAMUTIL_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "log.h"
+
+#ifdef USE_FFMPEG
+extern "C" {
+#include <ffmpeg/avcodec.h>
+}
+#endif
+
+#include <queue>
+
+#include <SDL_audio.h>
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+namespace gnash {
+namespace media {
+
+class raw_mediadata_t
+{
+public:
+       raw_mediadata_t();
+
+       ~raw_mediadata_t();
+
+       int m_stream_index;
+       boost::uint32_t m_size;
+       boost::uint8_t* m_data;
+       boost::uint8_t* m_ptr;
+       boost::uint32_t m_pts;  // presentation timestamp in millisec
+};
+
+
+/// Threadsafe elements-owning queue
+//
+/// This class is a threadsafe queue, using std:queue and locking.
+/// It is used to store decoded audio and video data which are waiting to be 
"played"
+/// Elements of the queue are owned by instances of this class.
+///
+template<class T>
+class multithread_queue
+{
+public:
+
+       multithread_queue() 
+       {
+       }
+
+       // Destroy all elements of the queue. Locks.
+       ~multithread_queue()
+       {
+         clear();
+       }
+
+       // Destroy all elements of the queue. Locks.
+       void clear()
+       {
+         boost::mutex::scoped_lock lock( _mutex );
+
+         while ( ! m_queue.empty() ) {
+           T x = m_queue.front();
+           m_queue.pop();
+           delete x;
+         }
+       }
+
+       /// Returns the size if the queue. Locks.
+       //
+       /// @return the size of the queue
+       ///
+       size_t size()
+       {
+         boost::mutex::scoped_lock lock( _mutex );
+
+         size_t n = m_queue.size();
+
+         return n;
+       }
+
+       /// Pushes an element to the queue. Locks.
+       //
+       /// @param member
+       /// The element to be pushed unto the queue.
+       ///
+       /// @return true if queue isn't full and the element was pushed to the 
queue,
+       /// or false if the queue was full, and the element wasn't push unto it.
+       ///
+       bool push(T member)
+       {
+         bool rc = false;
+         boost::mutex::scoped_lock lock( _mutex );
+
+         // We only keep max 20 items in the queue.
+         // If it's "full" the item must wait, see calls to 
+         // this function in read_frame() to see how it is 
+         // done.
+         if ( m_queue.size() < 20 ) {
+           m_queue.push( member );
+           rc = true;
+         }
+
+         return rc;
+       }
+
+       /// Returns a pointer to the first element on the queue. Locks.
+       //
+       /// If no elements are available this function returns NULL.
+       ///
+       /// @return a pointer to the first element on the queue, NULL if queue 
is empty.
+       ///
+       T front()
+       {
+         boost::mutex::scoped_lock lock( _mutex );
+       
+         T member = NULL;
+
+         if ( ! m_queue.empty() ) {
+           member = m_queue.front();
+         }
+  
+         return member;
+       }
+
+       /// Pops the first element from the queue. Locks.
+       //
+       /// If no elements are available this function is
+       /// a noop. 
+       ///
+       void pop()
+       {
+         boost::mutex::scoped_lock lock( _mutex );
+
+         if ( ! m_queue.empty() ) {
+           m_queue.pop();
+         }
+       }
+
+private:
+
+       // Mutex used for locking
+       boost::mutex _mutex;
+
+       // The actual queue.
+       std::queue<T> m_queue;
+};
+
+
+/// This class is used to provide an easy interface to libavcodecs audio 
resampler.
+///
+class AudioResampler
+{
+public:
+       AudioResampler();
+
+       ~AudioResampler();
+       
+       /// Initializes the resampler
+       //
+       /// @param ctx
+       /// The audio format container.
+       ///
+       /// @return true if resampling is needed, if not false
+       ///
+       bool init(AVCodecContext* ctx);
+       
+       /// Resamples audio
+       //
+       /// @param input
+       /// A pointer to the audio data that needs resampling
+       ///
+       /// @param output
+       /// A pointer to where the resampled output should be placed
+       ///
+       /// @param samples
+       /// Number of samples in the audio
+       ///
+       /// @return the number of samples in the output data.
+       ///
+       int resample(
+               boost::int16_t* input, boost::int16_t* output, int samples
+       );
+
+private:
+       // The container of the resample format information.
+       ReSampleContext* _context;
+};
+
+} // gnash.media namespace 
+} // namespace gnash
+
+
+#endif // FFMPEGNETSTREAMUTIL_H

Index: libmedia/ffmpeg/sound_handler_sdl.cpp
===================================================================
RCS file: libmedia/ffmpeg/sound_handler_sdl.cpp
diff -N libmedia/ffmpeg/sound_handler_sdl.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/sound_handler_sdl.cpp       22 Feb 2008 14:16:36 -0000      
1.1.2.1
@@ -0,0 +1,826 @@
+// sound_handler_sdl.cpp: Sound handling using standard SDL
+//
+//   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_sdl.cpp,v 1.1.2.1 2008/02/22 14:16:36 strk Exp $
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "sound_handler_sdl.h"
+#include "utility.h" // for convert_raw_data
+#include "AudioDecoderSimple.h"
+#include "AudioDecoderNellymoser.h"
+
+#ifdef USE_FFMPEG
+#include "AudioDecoderFfmpeg.h"
+#endif
+
+#ifdef USE_MAD
+#include "AudioDecoderMad.h"
+#endif
+
+#include "log.h"
+#include <cmath>
+#include <vector>
+#include <boost/scoped_array.hpp>
+#include <SDL.h>
+
+namespace gnash {
+namespace media {
+
+SDL_sound_handler::SDL_sound_handler()
+       : soundOpened(false),
+               soundsPlaying(0),
+               muted(false)
+{
+       // This is our sound settings
+       audioSpec.freq = 44100;
+       audioSpec.format = AUDIO_S16SYS; // AUDIO_S8 AUDIO_U8;
+       audioSpec.channels = 2;
+       audioSpec.callback = SDL_sound_handler::sdl_audio_callback;
+       audioSpec.userdata = this;
+       audioSpec.samples = 2048;               //512 - not enough for  
videostream
+}
+
+void
+SDL_sound_handler::reset()
+{
+       //delete_all_sounds();
+       stop_all_sounds();
+}
+
+void
+SDL_sound_handler::delete_all_sounds()
+{
+       stop_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();
+}
+
+SDL_sound_handler::~SDL_sound_handler()
+{
+       delete_all_sounds();
+       if (soundOpened) SDL_CloseAudio();
+}
+
+
+int    SDL_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.
+{
+
+       assert(sinfo.get());
+       std::auto_ptr<sound_data> sounddata ( new sound_data );
+
+       //sounddata->data_size = data_bytes;
+       sounddata->volume = 100;
+       sounddata->soundinfo = sinfo;
+
+       boost::mutex::scoped_lock lock(_mutex);
+
+       switch (sounddata->soundinfo->getFormat())
+       {
+       case AUDIO_CODEC_MP3:
+#ifndef USE_FFMPEG
+#ifndef USE_MAD
+               log_error(_("gnash has not been compiled to handle mp3 audio"));
+               return -1;
+#endif
+#endif
+               sounddata->append(reinterpret_cast<boost::uint8_t*>(data), 
data_bytes);
+               break;
+
+       case AUDIO_CODEC_RAW:
+       case AUDIO_CODEC_ADPCM:
+       case AUDIO_CODEC_UNCOMPRESSED:
+       case AUDIO_CODEC_NELLYMOSER:
+               sounddata->append(reinterpret_cast<boost::uint8_t*>(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.release()); // the vector takes 
ownership
+       int sound_id = m_sound_data.size()-1;
+
+       return sound_id;
+
+}
+
+// this gets called when a stream gets more data
+long   SDL_sound_handler::fill_stream_data(unsigned char* data, unsigned int 
data_bytes, unsigned int /*sample_count*/, int handle_id)
+
+{
+
+       boost::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+1 > m_sound_data.size())
+       {
+               delete [] data;
+               return -1;
+       }
+       sound_data* sounddata = m_sound_data[handle_id];
+
+       // If doing ADPCM, knowing the framesize is needed to decode!
+       if (sounddata->soundinfo->getFormat() == AUDIO_CODEC_ADPCM) {
+               sounddata->m_frames_size[sounddata->size()] = data_bytes;
+       }
+
+       // Handling of the sound data
+       size_t start_size = sounddata->size();
+       sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
+
+       return start_size;
+}
+
+
+void   SDL_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.
+{
+       boost::mutex::scoped_lock lock(_mutex);
+
+       // Check if the sound exists, or if audio is muted
+       if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >= 
m_sound_data.size() || muted)
+       {
+               // Invalid handle or 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_active_sounds.size() > 0) {
+               return;
+       }
+
+       // Make sure sound actually got some data
+       if (sounddata->size() < 1) {
+               IF_VERBOSE_MALFORMED_SWF(
+                       log_swferror(_("Trying to play sound with size 0"));
+               );
+               return;
+       }
+
+       // Make a "active_sound" for this sound which is later placed on the 
vector of instances of this sound being played
+       std::auto_ptr<active_sound> sound ( new active_sound() );
+
+       // Set source data to the active_sound
+       sound->set_data(sounddata);
+
+       // Set the given options of the sound
+       if (start_position < 0) sound->position = 0;
+       else sound->position = start_position;
+
+       if (offset < 0) sound->offset = 0;
+       else sound->offset = (sounddata->soundinfo->isStereo() ? offset : 
offset*2); // offset is stored as stereo
+
+       sound->envelopes = envelopes;
+
+       // Set number of loop we should do. -1 is infinte loop, 0 plays it 
once, 1 twice etc.
+       sound->loop_count = loop_count;
+
+       sound->decoder = NULL;
+
+       switch (sounddata->soundinfo->getFormat()) {
+       case AUDIO_CODEC_NELLYMOSER:
+       case AUDIO_CODEC_NELLYMOSER_8HZ_MONO:
+               sound->decoder = new AudioDecoderNellymoser();
+
+               if (!sound->decoder->setup(sounddata->soundinfo.get())) {
+                       log_error("The audio decoder can't decode the audio");
+                       delete sound->decoder;
+                       sound->decoder = NULL;
+               }
+
+               break;
+       case AUDIO_CODEC_MP3:
+#ifdef USE_MAD
+               sound->decoder = new AudioDecoderMad();
+
+               if (!sound->decoder->setup(sounddata->soundinfo.get())) {
+                       log_error("The audio decoder can't decode the audio");
+                       delete sound->decoder;
+                       sound->decoder = NULL;
+               }
+
+               break;
+#endif
+#ifdef USE_FFMPEG
+               sound->decoder = new AudioDecoderFfmpeg();
+
+               if (!sound->decoder->setup(sounddata->soundinfo.get())) {
+                       log_error("The audio decoder can't decode the audio");
+                       delete sound->decoder;
+                       sound->decoder = NULL;
+               }
+
+               break;
+#endif
+       case AUDIO_CODEC_ADPCM:
+       default:
+
+               sound->decoder = new AudioDecoderSimple();
+
+               if (!sound->decoder->setup(sounddata->soundinfo.get())) {
+                       log_error("The audio decoder can't decode the audio");
+                       delete sound->decoder;
+                       sound->decoder = NULL;
+               }
+
+       }
+               
+       if (!soundOpened) {
+               if (SDL_OpenAudio(&audioSpec, NULL) < 0 ) {
+                       log_error(_("Unable to start SDL sound: %s"), 
SDL_GetError());
+                       return;
+               }
+               soundOpened = true;
+
+       }
+
+       ++soundsPlaying;
+       ++_soundsStarted;
+       sounddata->m_active_sounds.push_back(sound.release());
+
+       if (soundsPlaying == 1) {
+               SDL_PauseAudio(0);
+       }
+
+}
+
+
+void   SDL_sound_handler::stop_sound(int sound_handle)
+{
+       boost::mutex::scoped_lock lock(_mutex);
+
+       // Check if the sound exists.
+       if (sound_handle < 0 || (unsigned int) sound_handle >= 
m_sound_data.size())
+       {
+               // Invalid handle.
+       } else {
+       
+               sound_data* sounddata = m_sound_data[sound_handle];
+       
+               for (boost::int32_t i = (boost::int32_t) 
sounddata->m_active_sounds.size()-1; i >-1; i--) {
+
+                       //active_sound* sound = sounddata->m_active_sounds[i];
+
+                       // Stop sound, remove it from the active list
+                       //sound->delete_raw_data();
+                       //delete sound->decoder;
+                       
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + i);
+                       
+                       --soundsPlaying;
+                       ++_soundsStopped;
+               }
+       }
+
+}
+
+
+// this gets called when it's done with a sample.
+void   SDL_sound_handler::delete_sound(int sound_handle)
+{
+       boost::mutex::scoped_lock lock(_mutex);
+
+       if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
m_sound_data.size())
+       {
+               delete m_sound_data[sound_handle];
+               m_sound_data[sound_handle] = NULL;
+       }
+
+}
+
+// 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   SDL_sound_handler::stop_all_sounds()
+{
+       boost::mutex::scoped_lock lock(_mutex);
+
+       boost::int32_t num_sounds = (boost::int32_t) m_sound_data.size()-1;
+       for (boost::int32_t j = num_sounds; j > -1; j--) {//Optimized
+               sound_data* sounddata = m_sound_data[j];
+               boost::int32_t num_active_sounds = (boost::int32_t) 
sounddata->m_active_sounds.size()-1;
+               for (boost::int32_t i = num_active_sounds; i > -1; i--) {
+
+                       //active_sound* sound = sounddata->m_active_sounds[i];
+
+                       // Stop sound, remove it from the active list
+                       //delete sound->decoder;
+                       
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + i);
+                       
+                       --soundsPlaying;
+                       ++_soundsStopped;
+               }
+       }
+}
+
+
+//     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    SDL_sound_handler::get_volume(int sound_handle) {
+
+       boost::mutex::scoped_lock lock(_mutex);
+
+       int ret;
+       // Check if the sound exists.
+       if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
m_sound_data.size())
+       {
+               ret = m_sound_data[sound_handle]->volume;
+       } else {
+               ret = 0; // Invalid handle
+       }
+       return ret;
+}
+
+
+//     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   SDL_sound_handler::set_volume(int sound_handle, int volume) {
+
+       boost::mutex::scoped_lock lock(_mutex);
+
+       // Check if the sound exists.
+       if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >= 
m_sound_data.size())
+       {
+               // Invalid handle.
+       } else {
+
+               // Set volume for this sound. Should this only apply to the 
active sounds?
+               m_sound_data[sound_handle]->volume = volume;
+       }
+
+
+}
+       
+SoundInfo* SDL_sound_handler::get_sound_info(int sound_handle) {
+
+       boost::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 SDL_sound_handler::mute() {
+       stop_all_sounds();
+       muted = true;
+}
+
+// gnash calls this to unmute audio
+void SDL_sound_handler::unmute() {
+       muted = false;
+}
+
+bool SDL_sound_handler::is_muted()
+{
+       return muted;
+}
+
+void   SDL_sound_handler::attach_aux_streamer(aux_streamer_ptr ptr, void* 
owner)
+{
+       boost::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;
+       }
+
+       ++soundsPlaying;
+
+       if (!soundOpened) {
+               if (SDL_OpenAudio(&audioSpec, NULL) < 0 ) {
+                       log_error(_("Unable to start aux SDL sound: %s"), 
SDL_GetError());
+                       return;
+               }
+               soundOpened = true;
+       }
+       SDL_PauseAudio(0);
+
+}
+
+void   SDL_sound_handler::detach_aux_streamer(void* owner)
+{
+       boost::mutex::scoped_lock lock(_mutex);
+
+       CallbacksMap::iterator it2=m_aux_streamer.find(owner);
+       if ( it2 != m_aux_streamer.end() )
+       {
+               // WARNING: erasing would break any iteration in the map
+               --soundsPlaying;
+               m_aux_streamer.erase(it2);
+       }
+}
+
+unsigned int SDL_sound_handler::get_duration(int sound_handle)
+{
+       boost::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 SDL_sound_handler::get_position(int sound_handle)
+{
+       boost::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_active_sounds.size() == 0) return 0;
+
+       // We use the first active sound of this.
+       active_sound* asound = sounddata->m_active_sounds[0];
+
+       // Return the playhead position in milliseconds
+       unsigned int ret = asound->samples_played / audioSpec.freq * 1000;
+       ret += ((asound->samples_played % audioSpec.freq) * 1000) / 
audioSpec.freq;
+       if (audioSpec.channels > 1) ret = ret / audioSpec.channels;
+       return ret;
+}
+
+sound_handler*
+create_sound_handler_sdl()
+// Factory.
+{
+       return new SDL_sound_handler;
+}
+
+// Pointer handling and checking functions
+boost::uint8_t*
+active_sound::get_raw_data_ptr(unsigned long int pos)
+{
+       if ( _decodedData.get() )
+       {
+               return _decodedData->data(pos);
+       }
+       else return 0;
+}
+
+boost::uint8_t*
+active_sound::get_data_ptr(unsigned long int pos)
+{
+       assert(_undecodedData);
+       return _undecodedData->data(pos);
+}
+
+void active_sound::set_data(sound_data* idata)
+{
+       _undecodedData = idata;
+}
+
+void active_sound::deleteDecodedData()
+{
+       _decodedData.reset();
+}
+
+// AS-volume adjustment
+void adjust_volume(boost::int16_t* data, int size, int volume)
+{
+       for (int i=0; i < size*0.5; i++) {
+               data[i] = data[i] * volume/100;
+       }
+}
+
+// envelope-volume adjustment
+static void
+use_envelopes(active_sound* sound, unsigned int length)
+{
+       // Check if this is the time to use envelopes yet
+       if (sound->current_env == 0 && (*sound->envelopes)[0].m_mark44 > 
sound->samples_played+length/2)
+       {
+               return;
+
+       }
+       // switch to the next envelope if needed and possible
+       else if (sound->current_env < sound->envelopes->size()-1 && 
(*sound->envelopes)[sound->current_env+1].m_mark44 >= sound->samples_played)
+       {
+               sound->current_env++;
+       }
+
+       // Current envelope position
+       boost::int32_t cur_env_pos = 
sound->envelopes->operator[](sound->current_env).m_mark44;
+
+       // Next envelope position
+       boost::uint32_t next_env_pos = 0;
+       if (sound->current_env == (sound->envelopes->size()-1)) {
+               // If there is no "next envelope" then set the next envelope 
start point to be unreachable
+               next_env_pos = cur_env_pos + length;
+       } else {
+               next_env_pos = 
(*sound->envelopes)[sound->current_env+1].m_mark44;
+       }
+
+       unsigned int startpos = 0;
+       // Make sure we start adjusting at the right sample
+       if (sound->current_env == 0 && 
(*sound->envelopes)[sound->current_env].m_mark44 > sound->samples_played) {
+               startpos = sound->raw_position + 
((*sound->envelopes)[sound->current_env].m_mark44 - sound->samples_played)*2;
+       } else {
+               startpos = sound->raw_position;
+       }
+
+       boost::int16_t* data = 
reinterpret_cast<boost::int16_t*>(sound->get_raw_data_ptr(startpos));
+
+       for (unsigned int i=0; i < length/2; i+=2) {
+               float left = 
static_cast<float>((*sound->envelopes)[sound->current_env].m_level0 / 32768.0);
+               float right = 
static_cast<float>((*sound->envelopes)[sound->current_env].m_level1 / 32768.0);
+
+               data[i] = static_cast<boost::int16_t>(data[i] * left); // Left
+               data[i+1] = static_cast<boost::int16_t>(data[i+1] * right); // 
Right
+
+               if ((sound->samples_played+(length/2-i)) >= next_env_pos && 
sound->current_env != (sound->envelopes->size()-1)) {
+                       sound->current_env++;
+                       // Next envelope position
+                       if (sound->current_env == (sound->envelopes->size()-1)) 
{
+                               // If there is no "next envelope" then set the 
next envelope start point to be unreachable
+                               next_env_pos = cur_env_pos + length;
+                       } else {
+                               next_env_pos = 
(*sound->envelopes)[sound->current_env+1].m_mark44;
+                       }
+               }
+       }
+}
+
+
+// Prepare for mixing/adding (volume adjustments) and mix/add.
+static void
+do_mixing(Uint8* stream, active_sound* sound, Uint8* data, unsigned int 
mix_length, unsigned int volume) {
+       // If the volume needs adjustments we call a function to do that
+       if (volume != 100) {
+               adjust_volume(reinterpret_cast<boost::int16_t*>(data), 
mix_length, volume);
+       } else if (sound->envelopes != NULL) {
+               use_envelopes(sound, mix_length);
+       }
+
+       // Mix the raw data
+       SDL_MixAudio(static_cast<Uint8*>(stream),static_cast<const 
Uint8*>(data), mix_length, SDL_MIX_MAXVOLUME);
+
+       // Update sound info
+       sound->raw_position += mix_length;
+
+       // Sample size is always 2
+       sound->samples_played += mix_length / 2;
+}
+
+
+// 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 )
+       {
+               log_error(_("Negative buffer length in sdl_audio_callback 
(%d)"), buffer_length_in);
+               return;
+       }
+
+       if ( buffer_length_in == 0 )
+       {
+               log_error(_("Zero buffer length in sdl_audio_callback"));
+               return;
+       }
+
+       unsigned int buffer_length = static_cast<unsigned 
int>(buffer_length_in);
+
+       // Get the soundhandler
+       SDL_sound_handler* handler = static_cast<SDL_sound_handler*>(udata);
+
+       // If nothing to play there is no reason to play
+       // Is this a potential deadlock problem?
+       if (handler->soundsPlaying == 0 && handler->m_aux_streamer.size() == 0) 
{
+               SDL_PauseAudio(1);
+               return;
+       }
+
+       boost::mutex::scoped_lock lock(handler->_mutex);
+
+       // Mixed sounddata buffer
+       Uint8* buffer = stream;
+       memset(buffer, 0, buffer_length);
+
+       // call NetStream or Sound audio callbacks
+       if ( !handler->m_aux_streamer.empty() )
+       {
+               boost::scoped_array<boost::uint8_t> buf ( new 
boost::uint8_t[buffer_length] );
+
+               // Loop through the attached sounds
+               CallbacksMap::iterator it = handler->m_aux_streamer.begin();
+               CallbacksMap::iterator end = handler->m_aux_streamer.end();
+               while (it != end) {
+                       memset(buf.get(), 0, buffer_length);
+
+                       SDL_sound_handler::aux_streamer_ptr aux_streamer = 
it->second; 
+                       void* owner = it->first;
+
+                       // If false is returned the sound doesn't want to be 
attached anymore
+                       bool ret = (aux_streamer)(owner, buf.get(), 
buffer_length);
+                       if (!ret) {
+                               CallbacksMap::iterator it2=it;
+                               ++it2; // before we erase it
+                               handler->m_aux_streamer.erase(it); // FIXME: 
isn't this terribly wrong ?
+                               it = it2;
+                               handler->soundsPlaying--;
+                       } else {
+                               ++it;
+                       }
+                       SDL_MixAudio(stream, buf.get(), buffer_length, 
SDL_MIX_MAXVOLUME);
+
+               }
+       }
+
+       // Run through all the sounds. TODO: don't call .size() at every 
iteration !
+       for(boost::uint32_t i=0; i < handler->m_sound_data.size(); i++) {
+               sound_data* sounddata = handler->m_sound_data[i];
+               for(boost::uint32_t j = 0; j < 
sounddata->m_active_sounds.size(); j++) {
+
+                       // Temp variables to make the code simpler and easier 
to read
+                       active_sound* sound = sounddata->m_active_sounds[j];
+
+                       // If there exist no decoder, then we can't decode!
+                       if (sound->decoder == NULL) continue;
+
+                       // When the current sound dont have enough decoded data 
to fill the buffer, 
+                       // we first mix what is already decoded, then decode 
some more data, and
+                       // mix some more until the buffer is full. If a sound 
loops the magic
+                       // happens here ;)
+                       if (sound->rawDataSize() - sound->raw_position < 
buffer_length 
+                               && (sound->position < sound->dataSize() || 
sound->loop_count != 0)) {
+                               // First we mix what is decoded
+                               unsigned int index = 0;
+                               if (sound->rawDataSize() - sound->raw_position 
> 0)
+                               {
+                                       index = sound->rawDataSize() - 
sound->raw_position;
+
+                                       do_mixing(stream, sound, 
sound->get_raw_data_ptr(sound->raw_position),
+                                               index, sounddata->volume);
+
+                               }
+
+                               // Then we decode some data
+                               // We loop until the size of the decoded sound 
is greater than the buffer size,
+                               // or there is no more to decode.
+                               unsigned int decoded_size = 0;
+
+                               // Delete any previous raw_data
+                               sound->deleteDecodedData();
+
+                               while(decoded_size < buffer_length)
+                               {
+
+                                       // If we need to loop, we reset the 
data pointer
+                                       if (sound->dataSize() == 
sound->position && sound->loop_count != 0) {
+                                               sound->loop_count--;
+                                               sound->position = 0;
+                                               sound->samples_played = 0;
+                                       }
+
+                                       // Test if we will get problems... 
Should not happen...
+                                       assert(sound->dataSize() > 
sound->position);
+                                       
+                                       // temp raw buffer
+                                       Uint8* tmp_raw_buffer;
+                                       boost::uint32_t tmp_raw_buffer_size = 0;
+                                       boost::uint32_t decodedBytes = 0;
+
+                                       boost::uint32_t inputSize = 0;
+                                       bool parse = true;
+                                       if (sounddata->soundinfo->getFormat() 
== AUDIO_CODEC_ADPCM) {
+                                               parse = false;
+                                               if 
(sounddata->m_frames_size.size() > 0) inputSize = 
sounddata->m_frames_size[sound->position];
+                                               else inputSize = 
sound->dataSize() - sound->position;
+                                       } else {
+                                               inputSize = sound->dataSize() - 
sound->position;
+                                       }
+
+                                       tmp_raw_buffer = 
sound->decoder->decode(sound->get_data_ptr(sound->position), 
+                                                                               
                        inputSize, tmp_raw_buffer_size, decodedBytes, parse);
+
+                                       sound->position += decodedBytes;
+
+                                       
sound->appendDecodedData(tmp_raw_buffer, tmp_raw_buffer_size);
+
+                                       decoded_size += tmp_raw_buffer_size;
+
+                                       // no more to decode from this sound, 
so we break the loop
+                                       if (sound->dataSize() <= 
sound->position && sound->loop_count == 0 || tmp_raw_buffer_size == 0 && 
decodedBytes == 0) {
+                                               sound->position = 
sound->dataSize();
+                                               break;
+                                       }
+
+                               } // end of "decode min. bufferlength data" 
while loop
+
+                               sound->raw_position = 0;
+
+                               // Determine how much should be mixed
+                               unsigned int mix_length = 0;
+                               if (decoded_size >= buffer_length - index) {
+                                       mix_length = buffer_length - index;
+                               } else { 
+                                       mix_length = decoded_size;
+                               }
+                               if (sound->rawDataSize() < 2) continue; // 
something went terrible wrong
+                               do_mixing(stream+index, sound, 
sound->get_raw_data_ptr(0), mix_length, sounddata->volume);
+
+                       // When the current sound has enough decoded data to 
fill 
+                       // the buffer, we do just that.
+                       } else if (sound->rawDataSize() > sound->raw_position 
&& sound->rawDataSize() - sound->raw_position > buffer_length ) {
+
+                               do_mixing(stream, sound, 
sound->get_raw_data_ptr(sound->raw_position), 
+                                       buffer_length, sounddata->volume);
+
+                       // When the current sound doesn't have anymore data to 
decode,
+                       // and doesn't loop (anymore), but still got unplayed 
data,
+                       // we put the last data on the stream
+                       } else if (sound->rawDataSize() - sound->raw_position 
<= buffer_length && sound->rawDataSize() > sound->raw_position+1) {
+                       
+
+                               do_mixing(stream, sound, 
sound->get_raw_data_ptr(sound->raw_position), 
+                                       sound->rawDataSize() - 
sound->raw_position, sounddata->volume);
+
+                               sound->raw_position = sound->rawDataSize();
+                       } 
+
+                       // Sound is done, remove it from the active list
+                       if (sound->position == sound->dataSize() && 
sound->raw_position == sound->rawDataSize() && sound->loop_count == 0) {
+                               
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + j);
+                               handler->soundsPlaying--;
+                               handler->_soundsStopped++;
+
+                       } 
+               } // active sounds loop
+       } // existing sounds loop
+
+}
+
+} // gnash.media namespace 
+} // namespace gnash
+
+// Local Variables:
+// mode: C++
+// End:
+

Index: libmedia/ffmpeg/sound_handler_sdl.h
===================================================================
RCS file: libmedia/ffmpeg/sound_handler_sdl.h
diff -N libmedia/ffmpeg/sound_handler_sdl.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/ffmpeg/sound_handler_sdl.h 22 Feb 2008 14:16:37 -0000      1.1.2.1
@@ -0,0 +1,401 @@
+// sound_handler_sdl.h: Sound handling using standard SDL
+//
+//   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_sdl.h,v 1.1.2.1 2008/02/22 14:16:37 strk Exp $
+
+#ifndef SOUND_HANDLER_SDL_H
+#define SOUND_HANDLER_SDL_H
+
+
+#include "sound_handler.h" // for inheritance
+#include "AudioDecoder.h"
+
+#include "log.h"
+
+#ifdef USE_FFMPEG
+extern "C" {
+#include <ffmpeg/avcodec.h>
+}
+#elif defined(USE_MAD)
+#include <mad.h>
+#endif
+
+#include <vector>
+#include <map> // for composition
+
+#include <SDL_audio.h>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+
+namespace gnash {
+namespace media {
+
+class active_sound;
+
+/// Used to hold the sounddata when doing on-demand-decoding
+class sound_data
+{
+       /// The undecoded data
+       Buffer _buf;
+
+public:
+
+       sound_data()
+       {}
+
+       ~sound_data();
+
+       /// Object holding information about the sound
+       std::auto_ptr<SoundInfo> soundinfo;
+
+       std::map<boost::uint32_t,boost::uint32_t> m_frames_size;
+
+       /// Append size bytes to this sound
+       //
+       /// @param data
+       ///     Data bytes, allocated with new[]. Ownership transferred.
+       ///
+       /// @param size
+       ///     Size of the 'data' buffer.
+       ///
+       void append(boost::uint8_t* data, unsigned int size)
+       {
+               _buf.append(data, size);
+       }
+
+       /// Return size of the data buffer
+       size_t size() const 
+       {
+               return _buf.size();
+       }
+
+       /// Return a pointer to the underlying buffer
+       const boost::uint8_t* data() const {
+               return _buf.data();
+       }
+
+       /// Return a pointer to the underlying buffer
+       boost::uint8_t* data() {
+               return _buf.data();
+       }
+
+       /// Return a pointer to an offset in the underlying buffer
+       //
+       /// @param pos The offset value.
+       ///     An assertion will fail if pos > size()
+       ///
+       const boost::uint8_t* data(size_t pos) const {
+               return _buf.data(pos);
+       }
+
+       /// Return a pointer to an offset in the underlying buffer
+       //
+       /// @param pos The offset value.
+       ///     An assertion will fail if pos > size()
+       ///
+       boost::uint8_t* data(size_t pos) {
+               return _buf.data(pos);
+       }
+
+       /// Volume for AS-sounds, range: 0-100.
+       /// It's the SWF range that is represented here.
+       int volume;
+
+       /// Vector containing the active instances of this sounds being played
+       //
+       /// NOTE: This class *owns* all active sounds
+       ///
+       typedef std::vector<active_sound*> ActiveSounds;
+
+       ActiveSounds m_active_sounds;
+
+};
+
+/// Used to hold the info about active sounds
+//
+/// This class contains a pointer to the sound_data used for playing
+/// and an optional Buffer to use when decoding is needed.
+///
+/// When the Buffer is NULL we'll play the sound_data bytes directly
+/// (we assume they are decoded already)
+///
+class active_sound
+{
+public:
+       active_sound()
+               :
+               position(0),
+               raw_position(0),
+               loop_count(0),
+               offset(0),
+               current_env(0),
+               samples_played(0),
+               _undecodedData(0)
+       {}
+
+       ~active_sound()
+       {
+               deleteDecodedData();
+               if (decoder) delete decoder;
+       }
+
+       /// The decoder object used to convert the data into the playable format
+       AudioDecoder* decoder;
+
+       /// Current decoding position in the stream
+       unsigned long position;
+
+       /// Current playing position in the decoded stream
+       unsigned long raw_position;
+
+       /// Numbers of loops: -1 means loop forever, 0 means play once.
+       /// For every loop completed, it is decremented.
+       long loop_count;
+
+       /// Offset to make playback start in-sync, only used with mp3 streams.
+       unsigned int offset;
+
+       /// Sound envelopes for the current sound, which determine the volume 
level
+       /// from a given position. Only used with sound events.
+       const std::vector<sound_handler::sound_envelope>* envelopes;
+
+       /// Index of current envelope.
+       boost::uint32_t current_env;
+
+       /// Number of samples played so far.
+       unsigned long samples_played;
+
+       /// Set the undecoded data pointer
+       //
+       /// @param newUndecodedData
+       ///     Pointer to a sound_data being the undecoded data
+       ///     Ownership will NOT be transferred.
+       ///
+       void set_data(sound_data* newUndecodedData);
+
+       /// Returns the data pointer in the undecoded datastream
+       /// for the given position. Boundaries are checked.
+       boost::uint8_t* get_data_ptr(unsigned long int pos);
+
+       /// Returns the data pointer in the decoded datastream
+       /// for the given position. Boundaries are checked.
+       boost::uint8_t* get_raw_data_ptr(unsigned long int pos);
+
+       /// Release resources associated with decoded data, if any.
+       //
+       /// After this call, the active_sound will have no decoded data
+       /// buffer, thus any pointer to the decoded data will be fetched
+       /// from the undecoded one.
+       ///
+       void deleteDecodedData();
+
+       /// Append size bytes to this raw data 
+       //
+       /// @param data
+       ///     Data bytes, allocated with new[]. Ownership transferred.
+       ///
+       /// @param size
+       ///     Size of the 'data' buffer.
+       ///
+       void appendDecodedData(boost::uint8_t* data, unsigned int size)
+       {
+               if ( ! _decodedData.get() )
+               {
+                       _decodedData.reset( new Buffer );
+               }
+  
+               _decodedData->append(data, size);
+       }
+  
+       /// Set decoded data
+       //
+       /// @param data
+       ///     Data bytes, allocated with new[]. Ownership transferred.
+       ///
+       /// @param size
+       ///     Size of the 'data' buffer.
+       ///
+       void setDecodedData(boost::uint8_t* data, unsigned int size)
+       {
+               if ( ! _decodedData.get() )
+               {
+                       _decodedData.reset( new Buffer(data, size) );
+               }
+               else
+               {
+                       _decodedData->assign(data, size);
+               }
+       }
+
+       size_t rawDataSize() const
+       {
+               if ( _decodedData.get() )
+               {
+                       return _decodedData->size();
+               }
+               else return 0;
+       }
+  
+       size_t dataSize() const
+       {
+               return _undecodedData ? _undecodedData->size() : 0;
+       }
+  
+private:
+
+       /// The undecoded data
+       sound_data* _undecodedData;
+
+       /// The decoded buffer
+       //
+       /// If NULL, the _undecodedData will be considered
+       /// decoded instead
+       ///
+       std::auto_ptr<Buffer> _decodedData;
+
+};
+
+// This is here as it needs definition of active_sound
+sound_data::~sound_data()
+{
+       for (ActiveSounds::iterator i=m_active_sounds.begin(), 
e=m_active_sounds.end(); i!=e; ++i)
+       {
+               delete *i;
+       }
+}
+
+// Use SDL and ffmpeg/mad/nothing to handle sounds.
+class SDL_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;
+
+       /// Vector containing all sounds.
+       //
+       /// Elemenst of the vector are owned by this class
+       ///
+       std::vector<sound_data*>        m_sound_data;
+
+       /// Is sound device opened?
+       bool soundOpened;
+
+       /// The SDL_audio specs
+       SDL_AudioSpec audioSpec;
+       
+       /// Keeps track of numbers of playing sounds
+       int soundsPlaying;
+
+       /// Is the audio muted?
+       bool muted;
+       
+       /// Mutex for making sure threads doesn't mess things up
+       boost::mutex _mutex;
+
+       // stop and delete all sounds
+       void delete_all_sounds();
+
+public:
+       SDL_sound_handler();
+       virtual ~SDL_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);
+
+       // See dox in sound_handler.h
+       virtual void reset();
+
+       /// This will stop all sounds playing.
+       virtual void    stop_all_sounds();
+
+       /// 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); 
//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.media namespace 
+} // namespace gnash
+
+#endif // SOUND_HANDLER_SDL_H




reply via email to

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