gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libbase/Makefile.am libmedia/Au...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog libbase/Makefile.am libmedia/Au...
Date: Tue, 03 Jun 2008 12:39:55 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  08/06/03 12:39:55

Modified files:
        .              : ChangeLog 
        libbase        : Makefile.am 
        libmedia       : AudioDecoder.h AudioDecoderNellymoser.h 
                         Makefile.am MediaParser.h SoundInfo.h 
                         VideoDecoder.h 
        libmedia/ffmpeg: AudioDecoderFfmpeg.cpp VideoDecoderFfmpeg.cpp 
                         VideoDecoderFfmpeg.h 
        libmedia/gst   : VideoDecoderGst.cpp VideoDecoderGst.h 
        server/asobj   : NetConnection.cpp NetConnection.h NetStream.h 
                         NetStreamFfmpeg.cpp 
        server/parser  : video_stream_def.h 
Added files:
        libmedia       : FLVParser.cpp FLVParser.h 
Removed files:
        libbase        : FLVParser.cpp FLVParser.h 
        libmedia       : MediaDecoder.cpp MediaDecoder.h 
        libmedia/gst   : MediaDecoderGst.cpp MediaDecoderGst.h 

Log message:
        * libbase/FLVParser.{cpp,h} => libmedia/FLVParser.{cpp,h},
          libbase/Makefile.am, libmedia/Makefile.am:
          Moved FLVParser under libmedia and make it a MediaParser.
        * libmedia/AudioDecoder.h, libmedia/AudioDecoderNellymoser.h,
          libmedia/SoundInfo.h
          Streamline headers inclusion.
        * libmedia/VideoDecoder.h: drop EncodedVideoFrame, moved to
           MediaParser
        * libmedia/MediaDecoder.{cpp,h}, libmedia/gst/MediaDecoderGst.{cpp,h}:
          drop unused files.
        * libmedia/MediaParser.h: extend MediaParser interface to expose all
          needed stuff.
        * libmedia/ffmpeg/AudioDecoderFfmpeg.cpp,
          libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h},
          libmedia/gst/VideoDecoderGst.{cpp,h}: minor cleanups
        * server/asobj/NetConnection.{cpp,h}: cleanups
        * server/asobj/NetStream.h: m_parser is a MediaParser now.
        * server/asobj/NetStreamFfmpeg.cpp: update use of the parser
        * server/parser/video_stream_def.h: include MediaParser for enums.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6789&r2=1.6790
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/Makefile.am?cvsroot=gnash&r1=1.115&r2=1.116
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/FLVParser.cpp?cvsroot=gnash&r1=1.43&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/FLVParser.h?cvsroot=gnash&r1=1.32&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/AudioDecoder.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/AudioDecoderNellymoser.h?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/Makefile.am?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/MediaParser.h?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/SoundInfo.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/VideoDecoder.h?cvsroot=gnash&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/FLVParser.cpp?cvsroot=gnash&rev=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/FLVParser.h?cvsroot=gnash&rev=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/MediaDecoder.cpp?cvsroot=gnash&r1=1.6&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/MediaDecoder.h?cvsroot=gnash&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/AudioDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/MediaDecoderGst.cpp?cvsroot=gnash&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/MediaDecoderGst.h?cvsroot=gnash&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.cpp?cvsroot=gnash&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.h?cvsroot=gnash&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.h?cvsroot=gnash&r1=1.64&r2=1.65
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.cpp?cvsroot=gnash&r1=1.138&r2=1.139
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&r1=1.27&r2=1.28

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6789
retrieving revision 1.6790
diff -u -b -r1.6789 -r1.6790
--- ChangeLog   3 Jun 2008 12:27:25 -0000       1.6789
+++ ChangeLog   3 Jun 2008 12:39:51 -0000       1.6790
@@ -1,3 +1,25 @@
+2008-06-03 Sandro Santilli <address@hidden>
+
+       * libbase/FLVParser.{cpp,h} => libmedia/FLVParser.{cpp,h},
+         libbase/Makefile.am, libmedia/Makefile.am:
+         Moved FLVParser under libmedia and make it a MediaParser.
+       * libmedia/AudioDecoder.h, libmedia/AudioDecoderNellymoser.h,
+         libmedia/SoundInfo.h
+         Streamline headers inclusion.
+       * libmedia/VideoDecoder.h: drop EncodedVideoFrame, moved to
+          MediaParser
+       * libmedia/MediaDecoder.{cpp,h}, libmedia/gst/MediaDecoderGst.{cpp,h}:
+         drop unused files.
+       * libmedia/MediaParser.h: extend MediaParser interface to expose all
+         needed stuff.
+       * libmedia/ffmpeg/AudioDecoderFfmpeg.cpp,
+         libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h},
+         libmedia/gst/VideoDecoderGst.{cpp,h}: minor cleanups
+       * server/asobj/NetConnection.{cpp,h}: cleanups
+       * server/asobj/NetStream.h: m_parser is a MediaParser now.
+       * server/asobj/NetStreamFfmpeg.cpp: update use of the parser
+       * server/parser/video_stream_def.h: include MediaParser for enums.
+
 2008-06-03 Benjamin Wolsey <address@hidden>
 
        * server/cxform.{cpp,h}: drop cxform::print().

Index: libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libbase/Makefile.am,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -b -r1.115 -r1.116
--- libbase/Makefile.am 27 May 2008 16:13:15 -0000      1.115
+++ libbase/Makefile.am 3 Jun 2008 12:39:52 -0000       1.116
@@ -125,7 +125,6 @@
        zlib_adapter.cpp \
        URL.cpp \
        LoadThread.cpp \
-       FLVParser.cpp \
        GC.cpp \
        BitsReader.cpp \
        arg_parser.cpp \
@@ -162,7 +161,6 @@
        zlib_adapter.h \
        URL.h \
        LoadThread.h \
-       FLVParser.h \
        GC.h \
        BitsReader.h \
        arg_parser.h \

Index: libmedia/AudioDecoder.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/AudioDecoder.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- libmedia/AudioDecoder.h     6 Mar 2008 05:22:51 -0000       1.10
+++ libmedia/AudioDecoder.h     3 Jun 2008 12:39:52 -0000       1.11
@@ -20,10 +20,16 @@
 #ifndef __AUDIODECODER_H__
 #define __AUDIODECODER_H__
 
-#include "MediaParser.h"
 #include "SoundInfo.h"
 #include "Util.h"
 
+// Forward declarations
+namespace gnash {
+       namespace media {
+               class AudioInfo;
+       }
+}
+
 namespace gnash {
 namespace media {
 

Index: libmedia/AudioDecoderNellymoser.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/AudioDecoderNellymoser.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- libmedia/AudioDecoderNellymoser.h   5 Mar 2008 03:55:53 -0000       1.9
+++ libmedia/AudioDecoderNellymoser.h   3 Jun 2008 12:39:52 -0000       1.10
@@ -59,6 +59,12 @@
 #define NELLY_BASE_OFF 4228
 #define NELLY_BASE_SHIFT 19
 
+// Forward declarations
+namespace gnash {
+       namespace media {
+               class AudioInfo;
+       }
+}
 
 
 typedef struct nelly_handle_struct {

Index: libmedia/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libmedia/Makefile.am,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- libmedia/Makefile.am        9 May 2008 17:28:21 -0000       1.21
+++ libmedia/Makefile.am        3 Jun 2008 12:39:53 -0000       1.22
@@ -75,6 +75,7 @@
 libgnashmedia_la_SOURCES = \
        AudioDecoderNellymoser.cpp \
        AudioDecoderSimple.cpp \
+       FLVParser.cpp \
        Util.cpp \
        $(NULL)
 
@@ -83,6 +84,7 @@
        AudioDecoder.h \
        VideoDecoder.h \
        MediaParser.h \
+       FLVParser.h \
        AudioDecoderNellymoser.h \
        AudioDecoderSimple.h \
        sound_handler.h \

Index: libmedia/MediaParser.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaParser.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- libmedia/MediaParser.h      23 May 2008 05:58:08 -0000      1.15
+++ libmedia/MediaParser.h      3 Jun 2008 12:39:53 -0000       1.16
@@ -24,25 +24,11 @@
 #include "gnashconfig.h"
 #endif
 
-#include <boost/shared_ptr.hpp>
-#include "tu_file.h"
-
-#ifdef USE_FFMPEG
-#ifdef HAVE_FFMPEG_AVCODEC_H
-extern "C" {
-# include "ffmpeg/avcodec.h"
-}
-#endif
-
-#ifdef HAVE_LIBAVCODEC_AVCODEC_H
-extern "C" {
-# include "libavcodec/avcodec.h"
-}
-#endif
-#endif // USE_FFMPEG
-
+#include <boost/scoped_array.hpp>
 #include <memory>
 
+#include "tu_file.h"
+
 namespace gnash {
 namespace media {
 
@@ -66,6 +52,9 @@
        FLASH,
 
        /// Ffmpegs codecs ids
+       //
+       /// TODO: make this media-handler agnostic
+       ///
        FFMPEG
 };
 
@@ -110,19 +99,6 @@
        AUDIO_CODEC_NELLYMOSER = 6
 };
 
-/// Type of frame in FLVs. Also type of the frame contained in the MediaFrame 
class.
-enum tagType
-{
-       /// Audio frame
-       AUDIO_TAG = 0x08,
-
-       /// Video frame
-       VIDEO_TAG = 0x09,
-
-       /// Meta frame
-       META_TAG = 0x12
-};
-
 /// \brief
 /// The AudioInfo class contains information about the audiostream
 /// in the file being parsed. The information stored is codec-id,
@@ -137,9 +113,6 @@
                sampleSize(sampleSizei),
                stereo(stereoi),
                duration(durationi),
-#ifdef USE_FFMPEG
-               audioCodecCtx(NULL),
-#endif
                type(typei)
                {
                }
@@ -149,9 +122,6 @@
        boost::uint16_t sampleSize;
        bool stereo;
        boost::uint64_t duration;
-#ifdef USE_FFMPEG
-       AVCodecContext* audioCodecCtx; // If videoCodecCtx is ugly, so is this.
-#endif
        codecType type;
 };
 
@@ -169,9 +139,6 @@
                height(heighti),
                frameRate(frameRatei),
                duration(durationi),
-#ifdef USE_FFMPEG
-               videoCodecCtx(NULL),
-#endif
                type(typei)
                {
                }
@@ -181,35 +148,88 @@
        boost::uint16_t height;
        boost::uint16_t frameRate;
        boost::uint64_t duration;
-#ifdef USE_FFMPEG
-       AVCodecContext* videoCodecCtx; // UGLY!!
-#endif
        codecType type;
 };
 
-/// \brief
-/// The MediaFrame class contains a video or audio frame, its size, its
-/// timestamp. Ownership of the data is in the parser.
-class MediaFrame
+/// An encoded video frame
+class EncodedVideoFrame
+{
+public:
+
+       /// Create an encoded video frame
+       //
+       /// @param data
+       ///     Data buffer, ownership transferred
+       ///
+       /// @param size
+       ///     Size of the data buffer
+       ///
+       /// @param frameNum
+       ///     Frame number.
+       ///
+       /// @param type
+       ///     Video frame type
+       ///
+       /// @param timestamp
+       ///     Presentation timestamp, in milliseconds.
+       ///
+       EncodedVideoFrame(boost::uint8_t* data, boost::uint32_t size,
+                       unsigned int frameNum,
+                       boost::uint64_t timestamp=0)
+               :
+               _size(size),
+               _data(data),
+               _frameNum(frameNum),
+               _timestamp(timestamp)
+       {}
+
+       /// Return pointer to actual data. Ownership retained by this class.
+       const boost::uint8_t* data() const { return _data.get(); }
+
+       /// Return size of data buffer.
+       boost::uint32_t dataSize() const { return _size; }
+
+       /// Return video frame presentation timestamp
+       boost::uint64_t timestamp() const { return _timestamp; }
+
+       /// Return video frame number
+       unsigned frameNum() const { return _frameNum; }
+
+private:
+
+       boost::uint32_t _size;
+       boost::scoped_array<boost::uint8_t> _data;
+       unsigned int _frameNum;
+       boost::uint64_t _timestamp;
+};
+
+/// An encoded audio frame
+class EncodedAudioFrame
 {
 public:
        boost::uint32_t dataSize;
-       boost::uint8_t* data;
+       boost::scoped_array<boost::uint8_t> data;
        boost::uint64_t timestamp;
-       boost::uint8_t tag;
 };
 
-/// \brief
-/// The MediaParser class detects the format of the input file, and parses it 
on demand.
+/// The MediaParser class provides cursor-based access to encoded media frames 
+//
+/// Cursor-based access allow seeking as close as possible to a specified time
+/// and fetching frames from there on, sequentially.
+/// See seek(), nextVideoFrame(), nextAudioFrame() 
+///
+/// Input is received from a tu_file object.
 ///
 class MediaParser
 {
 public:
-       MediaParser(boost::shared_ptr<tu_file> stream)
+
+       MediaParser(std::auto_ptr<tu_file> stream)
        :
        _isAudioMp3(false),
        _isAudioNellymoser(false),
-       _stream(stream)
+               _stream(stream),
+               _parsingComplete(false)
        {}
 
        // Classes with virtual methods (virtual classes)
@@ -219,62 +239,132 @@
        //
        virtual ~MediaParser() {};
 
-       /// Used to parse the next media frame in the stream and return it
-       //
-       /// @return a pointer to a MediaFrame in which the undecoded frame data 
is.
-       virtual MediaFrame* parseMediaFrame() { return NULL; }
+       /// Returns the "bufferlength", meaning the difference between the
+       /// current frames timestamp and the timestamp of the last parseable
+       /// frame. Returns the difference in milliseconds.
+       //
+       virtual boost::uint32_t getBufferLength()=0;
+
+       /// Get timestamp of the video frame which would be returned on 
nextVideoFrame
+       //
+       /// @return false if there no video frame left
+       ///         (either none or no more)
+       ///
+       virtual bool nextVideoFrameTimestamp(boost::uint64_t& ts)=0;
+
+       /// Returns the next video frame in the parsed buffer, advancing video 
cursor.
+       //
+       /// If no frame has been played before the first frame is returned.
+       /// If there is no more frames in the parsed buffer NULL is returned.
+       /// you can check with parsingCompleted() to know wheter this is due to 
+       /// EOF reached.
+       ///
+       virtual std::auto_ptr<EncodedVideoFrame> nextVideoFrame()=0;
+
+       /// Get timestamp of the audio frame which would be returned on 
nextAudioFrame
+       //
+       /// @return false if there no video frame left
+       ///         (either none or no more)
+       ///
+       virtual bool nextAudioFrameTimestamp(boost::uint64_t& ts)=0;
+
+       /// Returns the next audio frame in the parsed buffer, advancing audio 
cursor.
+       //
+       /// If no frame has been played before the first frame is returned.
+       /// If there is no more frames in the parsed buffer NULL is returned.
+       /// you can check with parsingCompleted() to know wheter this is due to 
+       /// EOF reached.
+       ///
+       virtual std::auto_ptr<EncodedAudioFrame> nextAudioFrame()=0;
 
        /// Is the input MP3?
        //
        /// @return if the input audio is MP3
+       ///
        bool isAudioMp3() { return _isAudioMp3; }
 
        /// Is the input Nellymoser?
        //
        /// @return if the input audio is Nellymoser
+       ///
        bool isAudioNellymoser() { return _isAudioNellymoser; }
 
        /// Setup the parser
        //
        /// @return whether we'll be able to parse the file.
+       ///
        virtual bool setupParser() { return false; }
 
        /// Returns a VideoInfo class about the videostream
        //
-       /// @return a VideoInfo class about the videostream
-       virtual std::auto_ptr<VideoInfo> getVideoInfo() { return 
std::auto_ptr<VideoInfo>(NULL); }
+       /// @return a VideoInfo class about the videostream,
+       ///         or zero if stream contains no video
+       ///
+       virtual VideoInfo* getVideoInfo() { return 0; }
 
        /// Returns a AudioInfo class about the audiostream
        //
-       /// @return a AudioInfo class about the audiostream
-       virtual std::auto_ptr<AudioInfo> getAudioInfo() { return 
std::auto_ptr<AudioInfo>(NULL); }
-
-       /// Seeks to the closest possible position the given position,
-       /// and returns the new position.
-       //
+       /// @return a AudioInfo class about the audiostream,
+       ///         or zero if stream contains no audio
+       ///
+       virtual AudioInfo* getAudioInfo() { return 0; }
+
+       /// Seeks to the closest possible position the given position.
+       //
+       /// Valid seekable position are constrained by key-frames when
+       /// video data is available. Actual seek position should be always
+       /// less of equal the requested one.
+       ///
        /// @return the position the seek reached
+       ///
        virtual boost::uint32_t seek(boost::uint32_t) { return 0; }
 
        /// Returns the framedelay from the last to the current
        /// audioframe in milliseconds. This is used for framerate.
        //
        /// @return the diff between the current and last frame
+       ///
        virtual boost::uint32_t audioFrameDelay() { return 0; }
 
        /// Returns the framedelay from the last to the current
        /// videoframe in milliseconds. 
        //
        /// @return the diff between the current and last frame
+       ///
        virtual boost::uint32_t videoFrameDelay() { return 0; }
 
        /// Returns the framerate of the video
        //
        /// @return the framerate of the video
+       ///
        virtual boost::uint16_t videoFrameRate() { return 0; }
 
        /// Returns the last parsed position in the file in bytes
        virtual boost::uint32_t getLastParsedPos() { return 0; }
 
+       /// Parse next input chunk
+       //
+       /// Returns true if something was parsed, false otherwise.
+       /// See parsingCompleted().
+       ///
+       virtual bool parseNextChunk() { return false; }
+
+       /// Return true of parsing is completed
+       //
+       /// If this function returns true, any call to nextVideoFrame()
+       /// or nextAudioFrame() will always return NULL
+       ///
+       bool parsingCompleted() const { return _parsingComplete; }
+
+       /// Return number of bytes parsed so far
+       virtual boost::uint64_t getBytesLoaded() const { return 0; }
+
+       /// Return total number of bytes in input
+       boost::uint64_t getBytesTotal() const
+       {
+               return _stream->get_size();
+       }
+
 protected:
 
        /// Is the input audio MP3?
@@ -284,7 +374,10 @@
        bool _isAudioNellymoser;
 
        /// The stream used to access the file
-       boost::shared_ptr<tu_file> _stream;
+       std::auto_ptr<tu_file> _stream;
+
+       /// Whether the parsing is complete or not
+       bool _parsingComplete;
 };
 
 

Index: libmedia/SoundInfo.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/SoundInfo.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libmedia/SoundInfo.h        5 Mar 2008 03:55:54 -0000       1.6
+++ libmedia/SoundInfo.h        3 Jun 2008 12:39:53 -0000       1.7
@@ -22,7 +22,7 @@
 #ifndef __SOUNDINFO_H__
 #define __SOUNDINFO_H__
 
-#include "MediaParser.h"
+#include "MediaParser.h" // for audioCodecType enum
 
 namespace gnash {
 namespace media {

Index: libmedia/VideoDecoder.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/VideoDecoder.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- libmedia/VideoDecoder.h     5 Mar 2008 03:55:54 -0000       1.16
+++ libmedia/VideoDecoder.h     3 Jun 2008 12:39:53 -0000       1.17
@@ -20,15 +20,19 @@
 #ifndef __VIDEODECODER_H__
 #define __VIDEODECODER_H__
 
-#include "MediaParser.h"
 #include "image.h"
 
 #include <boost/noncopyable.hpp>
 
+// Forward declarations
 namespace gnash {
-namespace media {
+       namespace media {
+               class EncodedVideoFrame;
+       }
+}
 
-class EncodedVideoFrame;
+namespace gnash {
+namespace media {
 
 /// Abstract base class for embedded video decoders.
 //
@@ -68,44 +72,6 @@
 };
 
 
-/// This class represents a video frame that has not yet been decoded.
-class EncodedVideoFrame : public boost::noncopyable
-{
-public:
-  /// @param buffer Pointer to the video data corresponding to this frame. This
-  ///               class takes ownership of the pointer.
-  /// @param buf_size The size, in bytes, of the data pointed to in the buffer
-  ///                 argument
-  /// @param frame_number The number of the frame in the video stream.
-  EncodedVideoFrame(boost::uint8_t* buffer, size_t buf_size, size_t frame_num)
-    : _buffer(buffer),
-      _buffer_size(buf_size),
-      _frame_number(frame_num)
-  {}
-  
-  uint8_t* data() const
-  {
-    return _buffer.get();
-  }
-  
-  size_t dataSize() const
-  {
-    return _buffer_size;
-  }
-  
-  size_t frameNum() const
-  {
-    return _frame_number;
-  }
-
-private:
-  boost::scoped_array<uint8_t> _buffer;
-  size_t _buffer_size;
-  size_t _frame_number;
-};
-
-
-       
 } // gnash.media namespace 
 } // gnash namespace
 

Index: libmedia/ffmpeg/AudioDecoderFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/ffmpeg/AudioDecoderFfmpeg.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- libmedia/ffmpeg/AudioDecoderFfmpeg.cpp      5 Mar 2008 03:55:54 -0000       
1.3
+++ libmedia/ffmpeg/AudioDecoderFfmpeg.cpp      3 Jun 2008 12:39:53 -0000       
1.4
@@ -143,16 +143,8 @@
                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
-       {
+       // Create an audioCodecCtx from the ffmpeg parser if exists/possible
                _audioCodecCtx = avcodec_alloc_context();
-       }
 
        if (!_audioCodecCtx) {
                log_error(_("libavcodec couldn't allocate context"));

Index: libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- libmedia/ffmpeg/VideoDecoderFfmpeg.cpp      23 May 2008 05:58:09 -0000      
1.9
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.cpp      3 Jun 2008 12:39:54 -0000       
1.10
@@ -160,7 +160,7 @@
 }
 
 std::auto_ptr<image::rgb>
-VideoDecoderFfmpeg::decode(boost::uint8_t* input, boost::uint32_t input_size)
+VideoDecoderFfmpeg::decode(const boost::uint8_t* input, boost::uint32_t 
input_size)
 {
   std::auto_ptr<image::rgb> ret;
 
@@ -171,7 +171,8 @@
   }
 
   int bytes = 0;  
-  avcodec_decode_video(_videoCodecCtx, frame, &bytes, input, input_size);
+  // no idea why avcodec_decode_video wants a non-const input...
+  avcodec_decode_video(_videoCodecCtx, frame, &bytes, 
const_cast<boost::uint8_t*>(input), input_size);
   
   if (!bytes) {
     log_error("Decoding of a video frame failed");

Index: libmedia/ffmpeg/VideoDecoderFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/ffmpeg/VideoDecoderFfmpeg.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- libmedia/ffmpeg/VideoDecoderFfmpeg.h        23 May 2008 05:58:09 -0000      
1.10
+++ libmedia/ffmpeg/VideoDecoderFfmpeg.h        3 Jun 2008 12:39:54 -0000       
1.11
@@ -27,6 +27,7 @@
 #include "dsodefs.h" //For DSOEXPORT
 #include "log.h"
 #include "VideoDecoder.h"
+#include "MediaParser.h" // for videoCodecType enum
 
 #ifdef HAVE_FFMPEG_AVCODEC_H
 extern "C" {
@@ -70,7 +71,7 @@
 
 private:
 
-  std::auto_ptr<image::rgb> decode(boost::uint8_t* input, boost::uint32_t 
input_size);
+  std::auto_ptr<image::rgb> decode(const boost::uint8_t* input, 
boost::uint32_t input_size);
 
   std::auto_ptr<image::rgb> decode(const EncodedVideoFrame* vf)
   {

Index: libmedia/gst/VideoDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- libmedia/gst/VideoDecoderGst.cpp    7 May 2008 01:28:02 -0000       1.19
+++ libmedia/gst/VideoDecoderGst.cpp    3 Jun 2008 12:39:54 -0000       1.20
@@ -133,7 +133,8 @@
   
   GstBuffer* buffer = gst_buffer_new();
   
-  GST_BUFFER_DATA(buffer) = frame.data();
+  // dunno why gst needs non-const here
+  GST_BUFFER_DATA(buffer) = const_cast<uint8_t*>(frame.data());
        GST_BUFFER_SIZE(buffer) = frame.dataSize();     
        GST_BUFFER_OFFSET(buffer) = frame.frameNum();
        GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;

Index: libmedia/gst/VideoDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- libmedia/gst/VideoDecoderGst.h      28 Mar 2008 16:23:07 -0000      1.17
+++ libmedia/gst/VideoDecoderGst.h      3 Jun 2008 12:39:54 -0000       1.18
@@ -26,11 +26,12 @@
 #endif
 
 #include "image.h"
-#include <gst/gst.h>
 #include "log.h"
-#include "MediaParser.h"
 #include "VideoDecoder.h"
 #include "dsodefs.h"
+#include "MediaParser.h" // for videoCodecType enum
+
+#include <gst/gst.h>
 
 
 namespace gnash {

Index: server/asobj/NetConnection.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- server/asobj/NetConnection.cpp      27 May 2008 11:58:45 -0000      1.62
+++ server/asobj/NetConnection.cpp      3 Jun 2008 12:39:54 -0000       1.63
@@ -194,6 +194,7 @@
 
 
 /*public*/
+/// TODO: drop
 size_t
 NetConnection::tell()
 {
@@ -203,6 +204,7 @@
 
 
 /*public*/
+/// TODO: drop
 long
 NetConnection::getBytesLoaded()
 {
@@ -212,6 +214,7 @@
 
 
 /*public*/
+/// TODO: drop
 long
 NetConnection::getBytesTotal()
 {
@@ -221,6 +224,7 @@
 
 
 /*public*/
+/// TODO: drop
 bool
 NetConnection::loadCompleted()
 {
@@ -233,20 +237,6 @@
 }
 
 
-std::auto_ptr<FLVParser>
-NetConnection::getConnectedParser()
-{
-  std::auto_ptr<FLVParser> ret;
-
-  if ( _loader.get() ) {
-    ret.reset( new FLVParser(_loader) ); // transfer loader ownership
-    assert(!_loader.get());
-  }
-
-  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.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- server/asobj/NetConnection.h        27 May 2008 11:58:46 -0000      1.43
+++ server/asobj/NetConnection.h        3 Jun 2008 12:39:54 -0000       1.44
@@ -20,8 +20,6 @@
 #define __NETCONNECTION_H__
 
 #include "tu_file.h"
-//#include "LoadThread.h"
-//#include "FLVParser.h"
 
 #include <stdexcept>
 #include <cstdio>
@@ -39,7 +37,6 @@
 // Forward declarations
 namespace gnash {
        //class NetStream;
-       class FLVParser;
 }
 
 namespace gnash {
@@ -111,6 +108,8 @@
        ///
        /// Return number of actually read bytes
        ///
+       /// TODO: drop
+       ///
        size_t read(void *dst, size_t bytes);
 
        /// Return true if EOF has been reached
@@ -125,6 +124,8 @@
        /// This call never blocks.
        /// If not connected, 0 is returned (is this correct behaviour?)
        ///
+       /// TODO: drop
+       ///
        size_t tell();
 
        /// Returns the number of bytes cached
@@ -132,6 +133,8 @@
        /// This call never blocks.
        /// If not connected, 0 is returned (is this correct behaviour?)
        ///
+       /// TODO: drop
+       ///
        long getBytesLoaded();
 
        /// Returns the total size of the file
@@ -139,18 +142,16 @@
        /// 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.
+       /// TODO: drop
        ///
-       std::auto_ptr<FLVParser> getConnectedParser();
+       long getBytesTotal();
 
        /// Returns whether the load is complete
        //
        /// This call never blocks.
        ///
+       /// TODO: drop
+       ///
        bool loadCompleted();
 
 private:
@@ -165,6 +166,9 @@
        std::string _completeUrl;
 
        /// The file/stream loader thread and interface
+       //
+       /// TODO: drop
+       ///
        std::auto_ptr<tu_file> _loader;
 
        /// Attach ActionScript instance properties

Index: server/asobj/NetStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.h,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -b -r1.64 -r1.65
--- server/asobj/NetStream.h    23 May 2008 15:27:30 -0000      1.64
+++ server/asobj/NetStream.h    3 Jun 2008 12:39:54 -0000       1.65
@@ -31,7 +31,7 @@
 #include "impl.h"
 #include "video_stream_instance.h"
 #include "NetConnection.h"
-#include "FLVParser.h"
+#include "MediaParser.h"
 #include "as_function.h" // for visibility of destructor by intrusive_ptr
 
 #include <deque>
@@ -277,8 +277,8 @@
        // The video URL
        std::string url;
 
-       // The homegrown parser we use for FLV
-       std::auto_ptr<FLVParser> m_parser;
+       // The input media parser
+       std::auto_ptr<media::MediaParser> m_parser;
 
        // Are we playing a FLV?
        bool m_isFLV;

Index: server/asobj/NetStreamFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.cpp,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -b -r1.138 -r1.139
--- server/asobj/NetStreamFfmpeg.cpp    2 Jun 2008 12:51:07 -0000       1.138
+++ server/asobj/NetStreamFfmpeg.cpp    3 Jun 2008 12:39:55 -0000       1.139
@@ -305,6 +305,9 @@
 /// @param codec_id the codec ID to find
 /// @return the initialized context, or NULL on failure. The caller is 
 ///         responsible for deallocating!
+///
+/// TODO: drop, let VideoDecoder/AudioDecoder do this !
+///
 static AVCodecContext*
 initContext(enum CodecID codec_id)
 {
@@ -340,10 +343,10 @@
 /// @return the initialized context, or NULL on failure. The caller
 ///         is responsible for deallocating this pointer.
 static AVCodecContext* 
-initFlvVideo(FLVParser& parser)
+initVideoDecoder(media::MediaParser& parser)
 {
        // Get video info from the parser
-       FLVVideoInfo* videoInfo = parser.getVideoInfo();
+       media::VideoInfo* videoInfo = parser.getVideoInfo();
        if (!videoInfo)
        {
                return NULL;
@@ -374,12 +377,12 @@
 }
 
 
-/// Like initFlvVideo, but for audio.
+/// Like initVideoDecoder, but for audio.
 static AVCodecContext*
-initFlvAudio(FLVParser& parser)
+initAudioDecoder(media::MediaParser& parser)
 {
        // Get audio info from the parser
-       FLVAudioInfo* audioInfo =  parser.getAudioInfo();
+       media::AudioInfo* audioInfo =  parser.getAudioInfo();
        if (!audioInfo)
        {
                log_debug("No audio in FLV stream");
@@ -451,6 +454,10 @@
                return false;
        }
 
+       //
+       // TODO: let all of this be handled by a MediaParserFactory
+       // (ie: inspecting type of input)
+       // 
 
        _inputStream->set_position(0);
        if (std::string(head) == "FLV")
@@ -458,7 +465,7 @@
                m_isFLV = true;
                assert ( !m_parser.get() );
 
-               m_parser.reset( new FLVParser(_inputStream) ); 
+               m_parser.reset( new media::FLVParser(_inputStream) );
                assert(! _inputStream.get() ); // TODO: when ownership will be 
transferred...
 
                if (! m_parser.get() )
@@ -473,14 +480,14 @@
                avcodec_init();
                avcodec_register_all();
 
-               m_VCodecCtx = initFlvVideo(*m_parser);
+               m_VCodecCtx = initVideoDecoder(*m_parser); // TODO: let 
VideoDecoder do this !
                if (!m_VCodecCtx)
                {
                        log_error(_("Failed to initialize FLV video codec"));
                        return false;
                }
 
-               m_ACodecCtx = initFlvAudio(*m_parser);
+               m_ACodecCtx = initAudioDecoder(*m_parser); // TODO: let 
AudioDecoder do this !
                if (!m_ACodecCtx)
                {
                        // There might simply be no audio, no problem...
@@ -773,21 +780,21 @@
                return 0; // no parser, no party
        }
 
-       FLVVideoFrameInfo* info = m_parser->peekNextVideoFrameInfo();
-       if ( ! info )
+       boost::uint64_t nextTimestamp;
+       if ( ! m_parser->nextVideoFrameTimestamp(nextTimestamp) )
        {
 #ifdef GNASH_DEBUG_DECODING
-               log_debug("getDecodedVideoFrame(%d): no more video frames in 
input (peekNextVideoFrameInfo returned false)");
+               log_debug("getDecodedVideoFrame(%d): no more video frames in 
input (nextVideoFrameTimestamp returned false)");
 #endif // GNASH_DEBUG_DECODING
                decodingStatus(DEC_STOPPED);
                return 0;
        }
 
-       if ( info->timestamp > ts )
+       if ( nextTimestamp > ts )
        {
 #ifdef GNASH_DEBUG_DECODING
                log_debug("%p.getDecodedVideoFrame(%d): next video frame is in 
the future (%d)",
-                       this, ts, info->timestamp);
+                       this, ts, nextTimestamp);
 #endif // GNASH_DEBUG_DECODING
                return 0; // next frame is in the future
        }
@@ -799,14 +806,13 @@
                video = decodeNextVideoFrame();
                if ( ! video )
                {
-                       log_error("peekNextVideoFrameInfo returned some info, "
+                       log_error("nextVideoFrameTimestamp returned true, "
                                "but decodeNextVideoFrame returned null, "
                                "I don't think this should ever happen");
                        break;
                }
 
-               FLVVideoFrameInfo* info = m_parser->peekNextVideoFrameInfo();
-               if ( ! info )
+               if ( ! m_parser->nextVideoFrameTimestamp(nextTimestamp) )
                {
                        // the one we decoded was the last one
 #ifdef GNASH_DEBUG_DECODING
@@ -815,7 +821,7 @@
 #endif // GNASH_DEBUG_DECODING
                        break;
                }
-               if ( info->timestamp > ts )
+               if ( nextTimestamp > ts )
                {
                        // the next one is in the future, we'll return this one.
 #ifdef GNASH_DEBUG_DECODING
@@ -840,8 +846,8 @@
                return 0; // no parser, no party
        }
 
-       FLVFrame* frame = m_parser->nextVideoFrame(); 
-       if (frame == NULL)
+       std::auto_ptr<media::EncodedVideoFrame> frame = 
m_parser->nextVideoFrame(); 
+       if ( ! frame.get() )
        {
 #ifdef GNASH_DEBUG_DECODING
                log_debug("%p.decodeNextVideoFrame(): "
@@ -850,16 +856,15 @@
 #endif // GNASH_DEBUG_DECODING
                return 0;
        }
-       assert (frame->type == videoFrame);
 
        AVPacket packet;
 
        packet.destruct = avpacket_destruct; // needed ?
-       packet.size = frame->dataSize;
-       packet.data = frame->data;
+       packet.size = frame->dataSize();
+       // ffmpeg insist in requiring non-const AVPacket.data ...
+       packet.data = const_cast<boost::uint8_t*>(frame->data());
        // FIXME: is this the right value for packet.dts?
-       packet.pts = packet.dts = static_cast<boost::int64_t>(frame->timestamp);
-       assert (frame->type == videoFrame);
+       packet.pts = packet.dts = frame->timestamp();
        packet.stream_index = 0;
 
        return decodeVideo(&packet);
@@ -870,8 +875,8 @@
 {
        assert ( m_parser.get() );
 
-       FLVFrame* frame = m_parser->nextAudioFrame(); 
-       if (frame == NULL)
+       std::auto_ptr<media::EncodedAudioFrame> frame = 
m_parser->nextAudioFrame(); 
+       if ( ! frame.get() )
        {
 #ifdef GNASH_DEBUG_DECODING
                log_debug("%p.decodeNextAudioFrame: "
@@ -880,16 +885,14 @@
 #endif // GNASH_DEBUG_DECODING
                return 0;
        }
-       assert (frame->type == audioFrame);
 
        AVPacket packet;
 
        packet.destruct = avpacket_destruct;
        packet.size = frame->dataSize;
-       packet.data = frame->data;
+       packet.data = frame->data.get();
        // FIXME: is this the right value for packet.dts?
-       packet.pts = packet.dts = static_cast<boost::int64_t>(frame->timestamp);
-       assert(frame->type == audioFrame);
+       packet.pts = packet.dts = frame->timestamp;
        packet.stream_index = 1;
 
        return decodeAudio(&packet);
@@ -1385,9 +1388,7 @@
 {
        // TODO: parse as much as possible w/out blocking
        //       (will always block currently..)
-       const int tagsPerChunk = 2;
-       for (int i=0; i<tagsPerChunk; ++i)
-               m_parser->parseNextTag();
+       m_parser->parseNextChunk();
 }
 
 void
@@ -1444,15 +1445,15 @@
 
        bool consumed = false;
 
+       boost::uint64_t nextTimestamp;
        while ( 1 )
        {
-               FLVAudioFrameInfo* info = m_parser->peekNextAudioFrameInfo();
-               if ( ! info )
+               if ( ! m_parser->nextAudioFrameTimestamp(nextTimestamp) )
                {
 #ifdef GNASH_DEBUG_DECODING
                        log_debug("%p.pushDecodedAudioFrames(%d): "
                                "no more audio frames in input "
-                               "(peekNextAudioFrameInfo returned false)",
+                               "(nextAudioFrameTimestamp returned false)",
                                this, ts);
 #endif // GNASH_DEBUG_DECODING
                        consumed = true;
@@ -1464,12 +1465,12 @@
                        break;
                }
 
-               if ( info->timestamp > ts )
+               if ( nextTimestamp > ts )
                {
 #ifdef GNASH_DEBUG_DECODING
                        log_debug("%p.pushDecodedAudioFrames(%d): "
                                "next audio frame is in the future (%d)",
-                               this, ts, info->timestamp);
+                               this, ts, nextTimestamp);
 #endif // GNASH_DEBUG_DECODING
                        consumed = true;
                        break; // next frame is in the future
@@ -1501,7 +1502,7 @@
                media::raw_mediadata_t* audio = decodeNextAudioFrame();
                if ( ! audio )
                {
-                       log_error("peekNextAudioFrameInfo returned some info, "
+                       log_error("nextAudioFrameTimestamp returned true, "
                                "but decodeNextAudioFrame returned null, "
                                "I don't think this should ever happen");
                        break;
@@ -1510,7 +1511,7 @@
 #ifdef GNASH_DEBUG_DECODING
                // this one we might avoid :) -- a less intrusive logging could
                // be take note about how many things we're pushing over
-               log_debug("pushDecodedAudioFrames(%d) pushing frame with 
timestamp %d", ts, info->timestamp); 
+               log_debug("pushDecodedAudioFrames(%d) pushing frame with 
timestamp %d", ts, nextTimestamp); 
 #endif
                _audioQueue.push_back(audio);
        }

Index: server/parser/video_stream_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- server/parser/video_stream_def.h    5 Mar 2008 03:56:03 -0000       1.27
+++ server/parser/video_stream_def.h    3 Jun 2008 12:39:55 -0000       1.28
@@ -31,6 +31,7 @@
 #include "rect.h" // for composition
 #include "ControlTag.h"
 #include "VideoDecoder.h"
+#include "MediaParser.h" // for videoFrameType and videoCodecType enums
 
 #include "image.h"
 

Index: libmedia/FLVParser.cpp
===================================================================
RCS file: libmedia/FLVParser.cpp
diff -N libmedia/FLVParser.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/FLVParser.cpp      3 Jun 2008 12:39:52 -0000       1.9
@@ -0,0 +1,747 @@
+// FLVParser.cpp:  Flash Video file parser, for Gnash.
+//
+//   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
+//
+
+
+#include <string>
+#include <iosfwd>
+#include "FLVParser.h"
+#include "amf.h"
+#include "log.h"
+#include "utility.h"
+
+using namespace std;
+
+#define PADDING_BYTES 64
+#define READ_CHUNKS 64
+
+// Define the following macro the have seek() operations printed
+//#define GNASH_DEBUG_SEEK 1
+
+namespace gnash {
+namespace media {
+
+static std::auto_ptr<EncodedVideoFrame>
+makeVideoFrame(tu_file& in, const FLVVideoFrameInfo& frameInfo)
+{
+       std::auto_ptr<EncodedVideoFrame> frame;
+
+       boost::uint32_t dataSize = frameInfo.dataSize;
+       boost::uint64_t timestamp = frameInfo.timestamp;
+
+       if ( in.set_position(frameInfo.dataPosition) )
+       {
+               log_error(_("Failed seeking to videoframe in FLV input"));
+               return frame;
+       }
+
+       unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS, 
dataSize+PADDING_BYTES);
+
+       boost::uint8_t* data = new boost::uint8_t[chunkSize];
+       size_t bytesread = in.read_bytes(data, dataSize);
+
+       unsigned long int padding = chunkSize-dataSize;
+       assert(padding);
+       memset(data + bytesread, 0, padding);
+
+       // We won't need frameNum, so will set to zero...
+       // TODO: fix this ?
+       // NOTE: ownership of 'data' is transferred here
+       frame.reset( new EncodedVideoFrame(data, dataSize, 0, timestamp) );
+       return frame;
+}
+
+static std::auto_ptr<EncodedAudioFrame>
+makeAudioFrame(tu_file& in, const FLVAudioFrameInfo& frameInfo)
+{
+       std::auto_ptr<EncodedAudioFrame> frame ( new EncodedAudioFrame );
+       frame->dataSize = frameInfo.dataSize; 
+       frame->timestamp = frameInfo.timestamp;
+
+
+       if ( in.set_position(frameInfo.dataPosition) )
+       {
+               log_error(_("Failed seeking to audioframe in FLV input"));
+               frame.reset();
+               return frame;
+       }
+
+       unsigned long int dataSize = frameInfo.dataSize;
+       unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS, 
dataSize+PADDING_BYTES);
+
+       frame->data.reset( new boost::uint8_t[chunkSize] );
+       size_t bytesread = in.read_bytes(frame->data.get(), dataSize);
+
+       unsigned long int padding = chunkSize-dataSize;
+       assert(padding);
+       memset(frame->data.get() + bytesread, 0, padding);
+
+       return frame;
+}
+
+FLVParser::FLVParser(std::auto_ptr<tu_file> lt)
+       :
+       MediaParser(lt),
+       _lastParsedPosition(0),
+       _videoInfo(NULL),
+       _audioInfo(NULL),
+       _nextAudioFrame(0),
+       _nextVideoFrame(0),
+       _audio(false),
+       _video(false)
+{
+}
+
+FLVParser::~FLVParser()
+{
+       _videoFrames.clear();
+
+       _audioFrames.clear();
+}
+
+
+boost::uint32_t
+FLVParser::getBufferLength()
+{
+       if (_video) {
+               size_t size = _videoFrames.size();
+               if (size > 1 && size > _nextVideoFrame) {
+                       return _videoFrames.back()->timestamp; //  - 
_videoFrames[_nextVideoFrame]->timestamp;
+               }
+       }
+       if (_audio) {
+               size_t size = _audioFrames.size();
+               if (size > 1 && size > _nextAudioFrame) {
+                       return _audioFrames.back()->timestamp; //  - 
_audioFrames[_nextAudioFrame]->timestamp;
+               }
+       }
+       return 0;
+}
+boost::uint16_t
+FLVParser::videoFrameRate()
+{
+       // Make sure that there are parsed some frames
+       while(_videoFrames.size() < 2 && !_parsingComplete) {
+               parseNextTag();
+       }
+
+       if (_videoFrames.size() < 2) return 0;
+
+       boost::uint32_t framedelay = _videoFrames[1]->timestamp - 
_videoFrames[0]->timestamp;
+
+       return static_cast<boost::int16_t>(1000 / framedelay);
+}
+
+
+boost::uint32_t
+FLVParser::videoFrameDelay()
+{
+       // If there are no video in this FLV return 0
+       if (!_video && _lastParsedPosition > 0) return 0;
+
+       // Make sure that there are parsed some frames
+       while(_videoFrames.size() < 2 && !_parsingComplete) {
+               parseNextTag();
+       }
+
+       // If there is no video data return 0
+       if (_videoFrames.size() == 0 || !_video || _nextVideoFrame < 2) return 
0;
+
+       return _videoFrames[_nextVideoFrame-1]->timestamp - 
_videoFrames[_nextVideoFrame-2]->timestamp;
+}
+
+boost::uint32_t
+FLVParser::audioFrameDelay()
+{
+       // If there are no audio in this FLV return 0
+       if (!_audio && _lastParsedPosition > 0) return 0;
+
+       // Make sure that there are parsed some frames
+       while(_audioFrames.size() < 2 && !_parsingComplete) {
+               parseNextTag();
+       }
+
+       // If there is no video data return 0
+       if (_audioFrames.size() == 0 || !_audio || _nextAudioFrame < 2) return 
0;
+
+       return _audioFrames[_nextAudioFrame-1]->timestamp - 
_audioFrames[_nextAudioFrame-2]->timestamp;
+}
+
+bool
+FLVParser::nextAudioFrameTimestamp(boost::uint64_t& ts)
+{
+       // If there are no audio in this FLV return NULL
+       if (!_audio && _lastParsedPosition > 0) return false;
+
+       // Make sure that there are parsed enough frames to return the need 
frame
+       while(_audioFrames.size() <= _nextAudioFrame && !_parsingComplete) {
+               if (!parseNextTag()) break;
+       }
+
+       // If the needed frame can't be parsed (EOF reached) return NULL
+       if (_audioFrames.empty() || _audioFrames.size() <= _nextAudioFrame)
+       {
+               return false;
+       }
+
+       FLVAudioFrameInfo* info = _audioFrames[_nextAudioFrame];
+       ts = info->timestamp; 
+       return true;
+}
+
+std::auto_ptr<EncodedAudioFrame> 
+FLVParser::nextAudioFrame()
+{
+       std::auto_ptr<EncodedAudioFrame> frame;
+
+       FLVAudioFrameInfo* frameInfo = peekNextAudioFrameInfo();
+       if ( ! frameInfo ) return frame;
+
+       frame = makeAudioFrame(*_stream, *frameInfo);
+       if ( ! frame.get() )
+       {
+               log_error("Could not make audio frame %d", _nextAudioFrame);
+               return frame;
+       }
+
+       _nextAudioFrame++;
+       return frame;
+}
+
+bool
+FLVParser::nextVideoFrameTimestamp(boost::uint64_t& ts)
+{
+       // If there are no video in this FLV return NULL
+       if (!_video && _lastParsedPosition > 0)
+       {
+               //gnash::log_debug("no video, or lastParserPosition > 0");
+               return false;
+       }
+
+       // Make sure that there are parsed enough frames to return the need 
frame
+       while(_videoFrames.size() <= 
static_cast<boost::uint32_t>(_nextVideoFrame) && !_parsingComplete)
+       {
+               if (!parseNextTag()) break;
+       }
+
+       // If the needed frame can't be parsed (EOF reached) return NULL
+       if (_videoFrames.empty() || _videoFrames.size() <= _nextVideoFrame)
+       {
+               //gnash::log_debug("The needed frame (%d) can't be parsed (EOF 
reached)", _lastVideoFrame);
+               return false;
+       }
+
+       FLVVideoFrameInfo* info = _videoFrames[_nextVideoFrame];
+       ts = info->timestamp;
+       return true;
+}
+
+std::auto_ptr<EncodedVideoFrame> 
+FLVParser::nextVideoFrame()
+{
+       FLVVideoFrameInfo* frameInfo = peekNextVideoFrameInfo();
+       std::auto_ptr<EncodedVideoFrame> frame = makeVideoFrame(*_stream, 
*frameInfo);
+       if ( ! frame.get() )
+       {
+               log_error("Could not make video frame %d", _nextVideoFrame);
+               return frame;
+       }
+
+       _nextVideoFrame++;
+       return frame;
+}
+
+
+boost::uint32_t
+FLVParser::seekAudio(boost::uint32_t time)
+{
+
+       // If there is no audio data return NULL
+       if (_audioFrames.empty()) return 0;
+
+       // If there are no audio greater than the given time
+       // the last audioframe is returned
+       FLVAudioFrameInfo* lastFrame = _audioFrames.back();
+       if (lastFrame->timestamp < time) {
+               _nextAudioFrame = _audioFrames.size() - 1;
+               return lastFrame->timestamp;
+       }
+
+       // We try to guess where in the vector the audioframe
+       // with the correct timestamp is
+       size_t numFrames = _audioFrames.size();
+       double tpf = lastFrame->timestamp / numFrames; // time per frame
+       size_t guess = size_t(time / tpf);
+
+       // Here we test if the guess was ok, and adjust if needed.
+       size_t bestFrame = utility::clamp<size_t>(guess, 0, 
_audioFrames.size()-1);
+
+       // Here we test if the guess was ok, and adjust if needed.
+       long diff = _audioFrames[bestFrame]->timestamp - time;
+       if ( diff > 0 ) // our guess was too long
+       {
+               while ( bestFrame > 0 && _audioFrames[bestFrame-1]->timestamp > 
time ) --bestFrame;
+       }
+       else // our guess was too short
+       {
+               while ( bestFrame < _audioFrames.size()-1 && 
_audioFrames[bestFrame+1]->timestamp < time ) ++bestFrame;
+       }
+
+#ifdef GNASH_DEBUG_SEEK
+       gnash::log_debug("Seek (audio): " SIZET_FMT "/" SIZET_FMT " (%u/%u)", 
bestFrame, numFrames, _audioFrames[bestFrame]->timestamp, time);
+#endif
+       _nextAudioFrame = bestFrame;
+       return _audioFrames[bestFrame]->timestamp;
+
+}
+
+
+boost::uint32_t
+FLVParser::seekVideo(boost::uint32_t time)
+{
+       if ( _videoFrames.empty() ) return 0;
+
+       // If there are no videoframe greater than the given time
+       // the last key videoframe is returned
+       FLVVideoFrameInfo* lastFrame = _videoFrames.back();
+       size_t numFrames = _videoFrames.size();
+       if (lastFrame->timestamp < time)
+       {
+               size_t lastFrameNum = numFrames -1;
+               while (! lastFrame->isKeyFrame() )
+               {
+                       lastFrameNum--;
+                       lastFrame = _videoFrames[lastFrameNum];
+               }
+
+               _nextVideoFrame = lastFrameNum;
+               return lastFrame->timestamp;
+
+       }
+
+       // We try to guess where in the vector the videoframe
+       // with the correct timestamp is
+       double tpf = lastFrame->timestamp / numFrames; // time per frame
+       size_t guess = size_t(time / tpf);
+
+       size_t bestFrame = utility::clamp<size_t>(guess, 0, 
_videoFrames.size()-1);
+
+       // Here we test if the guess was ok, and adjust if needed.
+       long diff = _videoFrames[bestFrame]->timestamp - time;
+       if ( diff > 0 ) // our guess was too long
+       {
+               while ( bestFrame > 0 && _videoFrames[bestFrame-1]->timestamp > 
time ) --bestFrame;
+       }
+       else // our guess was too short
+       {
+               while ( bestFrame < _videoFrames.size()-1 && 
_videoFrames[bestFrame+1]->timestamp < time ) ++bestFrame;
+       }
+
+       // Find closest backward keyframe  
+       size_t rewindKeyframe = bestFrame;
+       while ( rewindKeyframe && ! _videoFrames[rewindKeyframe]->isKeyFrame() )
+       {
+               rewindKeyframe--;
+       }
+
+       // Find closest forward keyframe 
+       size_t forwardKeyframe = bestFrame;
+       size_t size = _videoFrames.size();
+       while (size > forwardKeyframe+1 && ! 
_videoFrames[forwardKeyframe]->isKeyFrame() )
+       {
+               forwardKeyframe++;
+       }
+
+       // We can't ensure we were able to find a key frame *after* the best 
position
+       // in that case we just use any previous keyframe instead..
+       if ( ! _videoFrames[forwardKeyframe]->isKeyFrame() )
+       {
+               bestFrame = rewindKeyframe;
+       }
+       else
+       {
+               boost::int32_t forwardDiff = 
_videoFrames[forwardKeyframe]->timestamp - time;
+               boost::int32_t rewindDiff = time - 
_videoFrames[rewindKeyframe]->timestamp;
+
+               if (forwardDiff < rewindDiff) bestFrame = forwardKeyframe;
+               else bestFrame = rewindKeyframe;
+       }
+
+#ifdef GNASH_DEBUG_SEEK
+       gnash::log_debug("Seek (video): " SIZET_FMT "/" SIZET_FMT " (%u/%u)", 
bestFrame, numFrames, _videoFrames[bestFrame]->timestamp, time);
+#endif
+
+       _nextVideoFrame = bestFrame;
+       assert( _videoFrames[bestFrame]->isKeyFrame() );
+       return _videoFrames[bestFrame]->timestamp;
+}
+
+
+
+VideoInfo*
+FLVParser::getVideoInfo()
+{
+       // If there are no video in this FLV return NULL
+       if (!_video && _lastParsedPosition > 0) return NULL;
+
+       // Make sure that there are parsed some video frames
+       while( ! _parsingComplete && !_videoInfo.get() ) parseNextTag();
+
+       return _videoInfo.get(); // may be null
+}
+
+AudioInfo*
+FLVParser::getAudioInfo()
+{
+       // If there are no audio in this FLV return NULL
+       if (!_audio && _lastParsedPosition > 0) return NULL;
+
+       // Make sure that there are parsed some audio frames
+       while (!_parsingComplete && ! _audioInfo.get() )
+       {
+               parseNextTag();
+       }
+
+       return _audioInfo.get(); // may be null
+}
+
+bool
+FLVParser::isTimeLoaded(boost::uint32_t time)
+{
+       // Parse frames until the need time is found, or EOF
+       while (!_parsingComplete) {
+               if (!parseNextTag()) break;
+               if ((_videoFrames.size() > 0 && _videoFrames.back()->timestamp 
>= time)
+                       || (_audioFrames.size() > 0 && 
_audioFrames.back()->timestamp >= time)) {
+                       return true;
+               }
+       }
+
+       if (_videoFrames.size() > 0 && _videoFrames.back()->timestamp >= time) {
+               return true;
+       }
+
+       if (_audioFrames.size() > 0 && _audioFrames.back()->timestamp >= time) {
+               return true;
+       }
+
+       return false;
+
+}
+
+boost::uint32_t
+FLVParser::seek(boost::uint32_t time)
+{
+       GNASH_REPORT_FUNCTION;
+
+       log_debug("FLVParser::seek(%d) ", time);
+
+       if (time == 0) {
+               if (_video) _nextVideoFrame = 0;
+               if (_audio) _nextAudioFrame = 0;
+       }
+
+       // Video, if present, has more constraints
+       // as to where we allow seeking (we only
+       // allow seek to closest *key* frame).
+       // So we first have video seeking tell us
+       // what time is best for that, and next
+       // we seek audio on that time
+
+       if (_video)
+       {
+               time = seekVideo(time);
+#ifdef GNASH_DEBUG_SEEK
+               log_debug("  seekVideo -> %d", time);
+#endif
+       }
+
+       if (_audio)
+       {
+               time = seekAudio(time);
+#ifdef GNASH_DEBUG_SEEK
+               log_debug("  seekAudio -> %d", time);
+#endif
+       }
+
+       return time;
+}
+
+bool FLVParser::parseNextTag()
+{
+       if ( _parsingComplete ) return false;
+
+       // Parse the header if not done already. If unsuccesfull return false.
+       if (_lastParsedPosition == 0 && !parseHeader()) return false;
+
+       // Seek to next frame and skip the size of the last tag
+       if ( _stream->set_position(_lastParsedPosition+4) )
+       {
+               log_error("FLVParser::parseNextTag: can't seek to %d", 
_lastParsedPosition+4);
+               _parsingComplete=true;
+               return false;
+       }
+
+       // Read the tag info
+       boost::uint8_t tag[12];
+       int actuallyRead = _stream->read_bytes(tag, 12);
+       if ( actuallyRead < 12 )
+       {
+               if ( actuallyRead )
+                       log_error("FLVParser::parseNextTag: can't read tag info 
(needed 12 bytes, only got %d)", actuallyRead);
+               // else { assert(_stream->get_eof(); } ?
+               _parsingComplete=true;
+               return false;
+       }
+
+       // Extract length and timestamp
+       boost::uint32_t bodyLength = getUInt24(&tag[1]);
+       boost::uint32_t timestamp = getUInt24(&tag[4]);
+
+       _lastParsedPosition += 15 + bodyLength;
+
+       // check for empty tag
+       if (bodyLength == 0) return true;
+
+       enum tagType
+       {
+               AUDIO_TAG = 0x08,
+               VIDEO_TAG = 0x09,
+               META_TAG = 0x12
+       };
+
+       if (tag[0] == AUDIO_TAG)
+       {
+               FLVAudioFrameInfo* frame = new FLVAudioFrameInfo;
+               frame->dataSize = bodyLength - 1;
+               frame->timestamp = timestamp;
+               frame->dataPosition = _stream->get_position();
+               _audioFrames.push_back(frame);
+
+               // If this is the first audioframe no info about the
+               // audio format has been noted, so we do that now
+               if ( !_audioInfo.get() )
+               {
+                       int samplerate = (tag[11] & 0x0C) >> 2;
+                       if (samplerate == 0) samplerate = 5500;
+                       else if (samplerate == 1) samplerate = 11000;
+                       else if (samplerate == 2) samplerate = 22050;
+                       else if (samplerate == 3) samplerate = 44100;
+
+                       int samplesize = (tag[11] & 0x02) >> 1;
+                       if (samplesize == 0) samplesize = 1;
+                       else samplesize = 2;
+
+                       _audioInfo.reset( new AudioInfo((tag[11] & 0xf0) >> 4, 
samplerate, samplesize, (tag[11] & 0x01) >> 0, 0, FLASH) );
+               }
+
+
+       }
+       else if (tag[0] == VIDEO_TAG)
+       {
+               FLVVideoFrameInfo* frame = new FLVVideoFrameInfo;
+               frame->dataSize = bodyLength - 1;
+               frame->timestamp = timestamp;
+               frame->dataPosition = _stream->get_position();
+               frame->frameType = (tag[11] & 0xf0) >> 4;
+               _videoFrames.push_back(frame);
+
+               // If this is the first videoframe no info about the
+               // video format has been noted, so we do that now
+               if ( ! _videoInfo.get() )
+               {
+                       boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
+                       // Set standard guessed size...
+                       boost::uint16_t width = 320;
+                       boost::uint16_t height = 240;
+
+                       // Extract the video size from the videodata header
+                       if (codec == VIDEO_CODEC_H263) {
+                               if ( _stream->set_position(frame->dataPosition) 
)
+                               {
+                                       log_error(" Couldn't seek to VideoTag 
data position");
+                                       _parsingComplete=true;
+                                       return false;
+                               }
+                               boost::uint8_t videohead[12];
+                               int actuallyRead = 
_stream->read_bytes(videohead, 12);
+                               if ( actuallyRead < 12 )
+                               {
+               log_error("FLVParser::parseNextTag: can't read H263 video 
header (needed 12 bytes, only got %d)", actuallyRead);
+               _parsingComplete=true;
+               return false;
+                               }
+
+                               bool sizebit1 = (videohead[3] & 0x02);
+                               bool sizebit2 = (videohead[3] & 0x01);
+                               bool sizebit3 = (videohead[4] & 0x80);
+
+                               // First some predefined sizes
+                               if (!sizebit1 && sizebit2 && !sizebit3 ) {
+                                       width = 352;
+                                       height = 288;
+                               } else if (!sizebit1 && sizebit2 && sizebit3 ) {
+                                       width = 176;
+                                       height = 144;
+                               } else if (sizebit1 && !sizebit2 && !sizebit3 ) 
{
+                                       width = 128;
+                                       height = 96;
+                               } else if (sizebit1 && !sizebit2 && sizebit3 ) {
+                                       width = 320;
+                                       height = 240;
+                               } else if (sizebit1 && sizebit2 && !sizebit3 ) {
+                                       width = 160;
+                                       height = 120;
+
+                               // Then the custom sizes (1 byte - untested and 
ugly)
+                               } else if (!sizebit1 && !sizebit2 && !sizebit3 
) {
+                                       width = (videohead[4] & 0x40) | 
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) | 
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) | 
(videohead[5] & 0x80);
+
+                                       height = (videohead[5] & 0x40) | 
(videohead[5] & 0x20) | (videohead[5] & 0x20) | (videohead[5] & 0x08) | 
(videohead[5] & 0x04) | (videohead[5] & 0x02) | (videohead[5] & 0x01) | 
(videohead[6] & 0x80);
+
+                               // Then the custom sizes (2 byte - untested and 
ugly)
+                               } else if (!sizebit1 && !sizebit2 && sizebit3 ) 
{
+                                       width = (videohead[4] & 0x40) | 
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) | 
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) | 
(videohead[5] & 0x80) | (videohead[5] & 0x40) | (videohead[5] & 0x20) | 
(videohead[5] & 0x20) | (videohead[5] & 0x08) | (videohead[5] & 0x04) | 
(videohead[5] & 0x02) | (videohead[5] & 0x01) | (videohead[6] & 0x80);
+
+                                       height = (videohead[6] & 0x40) | 
(videohead[6] & 0x20) | (videohead[6] & 0x20) | (videohead[6] & 0x08) | 
(videohead[6] & 0x04) | (videohead[6] & 0x02) | (videohead[6] & 0x01) | 
(videohead[7] & 0x80) | (videohead[7] & 0x40) | (videohead[7] & 0x20) | 
(videohead[7] & 0x20) | (videohead[7] & 0x08) | (videohead[7] & 0x04) | 
(videohead[7] & 0x02) | (videohead[7] & 0x01) | (videohead[8] & 0x80);
+                               }
+
+                       }
+
+                       // Create the videoinfo
+                       _videoInfo.reset( new VideoInfo(codec, width, height, 0 
/*frameRate*/, 0 /*duration*/, FLASH /*codec type*/) );
+               }
+
+       } else if (tag[0] == META_TAG) {
+               LOG_ONCE( log_unimpl("FLV MetaTag parser") );
+               // Extract information from the meta tag
+               /*_stream->seek(_lastParsedPosition+16);
+               char* metaTag = new char[bodyLength];
+               size_t actuallyRead = _stream->read(metaTag, bodyLength);
+               if ( actuallyRead < bodyLength )
+               {
+                       log_error("FLVParser::parseNextTag: can't read metaTag 
(%d) body (needed %d bytes, only got %d)",
+                               META_TAG, bodyLength, actuallyRead);
+                       _parsingComplete=true;
+                       return false;
+               }
+               amf::AMF* amfParser = new amf::AMF();
+               amfParser->parseAMF(metaTag);*/
+
+       } else {
+               log_error("Unknown FLV tag type %d", tag[0]);
+               //_parsingComplete = true;
+               //return false;
+       }
+
+       return true;
+}
+
+bool FLVParser::parseHeader()
+{
+       // seek to the begining of the file
+       _stream->set_position(0); // seek back ? really ?
+
+       // Read the header
+       boost::uint8_t header[9];
+       if ( _stream->read_bytes(header, 9) != 9 )
+       {
+               log_error("FLVParser::parseHeader: couldn't read 9 bytes of 
header");
+               return false;
+       }
+
+       // Check if this is really a FLV file
+       if (header[0] != 'F' || header[1] != 'L' || header[2] != 'V') return 
false;
+
+       int version = header[3];
+
+       // Parse the audio+video bitmask
+       _audio = header[4]&(1<<2);
+       _video = header[4]&(1<<0);
+
+       log_debug("Parsing FLV version %d, audio:%d, video:%d", version, 
_audio, _video);
+
+       _lastParsedPosition = 9;
+       return true;
+}
+
+inline boost::uint32_t FLVParser::getUInt24(boost::uint8_t* in)
+{
+       // The bits are in big endian order
+       return (in[0] << 16) | (in[1] << 8) | in[2];
+}
+
+boost::uint64_t
+FLVParser::getBytesLoaded() const
+{
+       return _lastParsedPosition;
+}
+
+/* private */
+FLVAudioFrameInfo*
+FLVParser::peekNextAudioFrameInfo()
+{
+       // If there are no audio in this FLV return NULL
+       if (!_audio && _lastParsedPosition > 0) return 0;
+
+       // Make sure that there are parsed enough frames to return the need 
frame
+       while(_audioFrames.size() <= _nextAudioFrame && !_parsingComplete) {
+               if (!parseNextTag()) break;
+       }
+
+       // If the needed frame can't be parsed (EOF reached) return NULL
+       if (_audioFrames.empty() || _audioFrames.size() <= _nextAudioFrame)
+       {
+               return 0;       
+       }
+
+       return _audioFrames[_nextAudioFrame];
+}
+
+/*private*/
+FLVVideoFrameInfo*
+FLVParser::peekNextVideoFrameInfo()
+{
+       // If there are no video in this FLV return NULL
+       if (!_video && _lastParsedPosition > 0)
+       {
+               //gnash::log_debug("no video, or lastParserPosition > 0");
+               return 0;
+       }
+
+       // Make sure that there are parsed enough frames to return the need 
frame
+       while(_videoFrames.size() <= 
static_cast<boost::uint32_t>(_nextVideoFrame) && !_parsingComplete)
+       {
+               if (!parseNextTag()) break;
+       }
+
+       // If the needed frame can't be parsed (EOF reached) return NULL
+       if (_videoFrames.empty() || _videoFrames.size() <= _nextVideoFrame)
+       {
+               //gnash::log_debug("The needed frame (%d) can't be parsed (EOF 
reached)", _lastVideoFrame);
+               return 0;
+       }
+
+       return _videoFrames[_nextVideoFrame];
+}
+
+} // end of gnash::media namespace
+} // end of gnash namespace
+
+#undef PADDING_BYTES
+#undef READ_CHUNKS 

Index: libmedia/FLVParser.h
===================================================================
RCS file: libmedia/FLVParser.h
diff -N libmedia/FLVParser.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/FLVParser.h        3 Jun 2008 12:39:53 -0000       1.11
@@ -0,0 +1,324 @@
+// FLVParser.h:  Flash Video file format parser, for Gnash.
+//
+//   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
+//
+
+
+// Information about the FLV format can be found at http://osflash.org/flv
+
+#ifndef __FLVPARSER_H__
+#define __FLVPARSER_H__
+
+#include "dsodefs.h"
+#include "MediaParser.h" // for inheritance
+
+#include <vector>
+#include <memory>
+
+namespace gnash {
+namespace media {
+
+/// Frame type
+enum FrameType {
+
+       /// Video frame
+       videoFrame,
+
+       /// Audio frame
+       audioFrame
+};
+
+/// \brief
+/// The FLVFrame class contains an encoded
+/// video or audio frame, its size, its
+/// timestamp,
+class FLVFrame
+{
+public:
+       /// Size of the encoded frame
+       boost::uint32_t dataSize;
+
+       /// Encoded data
+       boost::uint8_t* data;
+
+       /// Frame timestamp, in milliseconds
+       boost::uint64_t timestamp;
+
+       /// Frame type (audio/video)
+       FrameType type;
+};
+
+/// \brief
+/// The FLVAudioInfo class contains information about the audiostream
+/// in the FLV being parsed. The information stored is codec-type,
+/// samplerate, samplesize, stereo flag and duration.
+//
+/// TODO: drop
+///
+class FLVAudioInfo
+{
+public:
+       FLVAudioInfo(boost::uint16_t codeci, boost::uint16_t sampleRatei, 
boost::uint16_t sampleSizei, bool stereoi, boost::uint64_t durationi)
+               : codec(codeci),
+               sampleRate(sampleRatei),
+               sampleSize(sampleSizei),
+               stereo(stereoi),
+               duration(durationi)
+               {
+               }
+
+       boost::uint16_t codec;
+       boost::uint16_t sampleRate;
+       boost::uint16_t sampleSize;
+       bool stereo;
+       boost::uint64_t duration;
+};
+
+/// \brief
+/// The FLVVideoInfo class contains information about the videostream
+/// in the FLV being parsed. The information stored is codec-type,
+/// width, height, framerate and duration.
+//
+/// TODO: drop
+///
+class FLVVideoInfo
+{
+public:
+       FLVVideoInfo(boost::uint16_t codeci, boost::uint16_t widthi, 
boost::uint16_t heighti, boost::uint16_t frameRatei, boost::uint64_t durationi)
+               :
+               codec(codeci),
+               width(widthi),
+               height(heighti),
+               frameRate(frameRatei),
+               duration(durationi)
+               {
+               }
+
+       boost::uint16_t codec;
+       boost::uint16_t width;
+       boost::uint16_t height;
+       boost::uint16_t frameRate;
+       boost::uint64_t duration;
+};
+
+
+/// Information about an FLV Audio Frame
+class FLVVideoFrameInfo
+{
+public:
+
+       /// Type of this frame (should likely be videoFrameType)
+       boost::uint16_t frameType;
+
+       /// Size of the frame in bytes
+       boost::uint32_t dataSize;
+
+       /// Start of frame data in stream
+       boost::uint64_t dataPosition;
+
+       /// Timestamp in milliseconds 
+       boost::uint32_t timestamp;
+
+       /// Return true if this video frame is a key frame
+       bool isKeyFrame() const
+       {
+               return frameType == 1 /*KEY_FRAME*/;
+       }
+
+};
+
+/// Information about an FLV Audio Frame
+class FLVAudioFrameInfo
+{
+public:
+       /// Size of the frame in bytes
+       boost::uint32_t dataSize;
+
+       /// Start of frame data in stream
+       boost::uint64_t dataPosition;
+
+       /// Timestamp in milliseconds 
+       boost::uint32_t timestamp;
+
+};
+
+/// The FLVParser class parses FLV streams
+class DSOEXPORT FLVParser : public MediaParser
+{
+
+public:
+
+       /// \brief
+       /// Create an FLV parser reading input from
+       /// the given tu_file
+       //
+       /// @param lt
+       ///     tu_file to use for input.
+       ///     Ownership transferred.
+       ///
+       FLVParser(std::auto_ptr<tu_file> lt);
+
+       /// Kills the parser...
+       ~FLVParser();
+
+       // see dox in MediaParser.h
+       bool nextAudioFrameTimestamp(boost::uint64_t& ts);
+
+       // see dox in MediaParser.h
+       bool nextVideoFrameTimestamp(boost::uint64_t& ts);
+
+       // see dox in MediaParser.h
+       std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
+
+       // see dox in MediaParser.h
+       std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
+
+       /// Returns information about video in the stream.
+       //
+       /// The returned object is owned by the FLVParser object.
+       /// Can return NULL if video contains NO video frames.
+       /// Will block till either parsing finished or a video frame is found.
+       ///
+       VideoInfo* getVideoInfo();
+
+       /// Returns a FLVAudioInfo class about the audiostream
+       //
+       /// TODO: return a more abstract AudioInfo
+       ///
+       AudioInfo* getAudioInfo();
+
+       /// \brief
+       /// Asks if a frame with with a timestamp larger than
+       /// the given time is available.
+       //
+       /// If such a frame is not
+       /// available in list of already the parsed frames, we
+       /// parse some more. This is used to check how much is buffered.
+       ///
+       /// @param time
+       ///     Timestamp, in milliseconds.
+       ///
+       bool isTimeLoaded(boost::uint32_t time);
+
+       /// \brief
+       /// Seeks to the closest possible position the given position,
+       /// and returns the new position.
+       //
+       ///
+       /// TODO: throw something for sending Seek.InvalidTime ?
+       ///       (triggered by seeks beyond the end of video or beyond what's
+       ///        downloaded so far)
+       ///
+       boost::uint32_t seek(boost::uint32_t);
+
+       /// Returns the framedelay from the last to the current
+       /// audioframe in milliseconds. This is used for framerate.
+       //
+       boost::uint32_t audioFrameDelay();
+
+       /// \brief
+       /// Returns the framedelay from the last to the current
+       /// videoframe in milliseconds. 
+       //
+       boost::uint32_t videoFrameDelay();
+
+       /// Returns the framerate of the video
+       //
+       boost::uint16_t videoFrameRate();
+
+       /// Returns the "bufferlength", meaning the differens between the
+       /// current frames timestamp and the timestamp of the last parseable
+       /// frame. Returns the difference in milliseconds.
+       //
+       boost::uint32_t getBufferLength();
+
+       virtual bool parseNextChunk() {
+               return parseNextTag();
+       }
+
+       /// Parses next tag from the file
+       //
+       /// Returns true if something was parsed, false otherwise.
+       /// Sets _parsingComplete=true on end of file.
+       ///
+       bool parseNextTag();
+
+       /// Return number of bytes parsed so far
+       boost::uint64_t getBytesLoaded() const;
+
+private:
+
+       FLVAudioFrameInfo* peekNextAudioFrameInfo();
+
+       FLVVideoFrameInfo* peekNextVideoFrameInfo();
+
+       /// seeks to the closest possible position the given position,
+       /// and returns the new position.
+       boost::uint32_t seekAudio(boost::uint32_t time);
+
+       /// seeks to the closest possible position the given position,
+       /// and returns the new position.
+       boost::uint32_t seekVideo(boost::uint32_t time);
+
+       /// Parses the header of the file
+       bool parseHeader();
+
+       // Functions used to extract numbers from the file
+       inline boost::uint32_t getUInt24(boost::uint8_t* in);
+
+       // NOTE: FLVVideoFrameInfo is a relatively small structure,
+       //       chances are keeping by value here would reduce
+       //       memory fragmentation with no big cost
+       typedef std::vector<FLVVideoFrameInfo*> VideoFrames;
+
+       /// list of videoframes, does no contain the frame data.
+       VideoFrames _videoFrames;
+
+       // NOTE: FLVAudioFrameInfo is a relatively small structure,
+       //       chances are keeping by value here would reduce
+       //       memory fragmentation with no big cost
+       typedef std::vector<FLVAudioFrameInfo*> AudioFrames;
+
+       /// list of audioframes, does no contain the frame data.
+       AudioFrames _audioFrames;
+
+       /// The position where the parsing should continue from.
+       boost::uint64_t _lastParsedPosition;
+
+       /// Info about the video stream (if any)
+       std::auto_ptr<VideoInfo> _videoInfo;
+
+       /// Info about the audio stream (if any)
+       std::auto_ptr<AudioInfo> _audioInfo;
+
+       /// Last audio frame returned
+       size_t _nextAudioFrame;
+
+       /// Last video frame returned
+       size_t _nextVideoFrame;
+
+       /// Audio stream is present
+       bool _audio;
+
+       /// Audio stream is present
+       bool _video;
+};
+
+} // end of gnash::media namespace
+} // end of gnash namespace
+
+#endif // __FLVPARSER_H__

Index: libbase/FLVParser.cpp
===================================================================
RCS file: libbase/FLVParser.cpp
diff -N libbase/FLVParser.cpp
--- libbase/FLVParser.cpp       27 May 2008 13:24:59 -0000      1.43
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,752 +0,0 @@
-// FLVParser.cpp:  Flash Video file parser, for Gnash.
-//
-//   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
-//
-
-
-#include <string>
-#include <iosfwd>
-#include "FLVParser.h"
-#include "amf.h"
-#include "log.h"
-#include "utility.h"
-
-using namespace std;
-
-#define PADDING_BYTES 64
-#define READ_CHUNKS 64
-
-// Define the following macro the have seek() operations printed
-//#define GNASH_DEBUG_SEEK 1
-
-namespace gnash {
-
-static std::auto_ptr<FLVFrame>
-makeVideoFrame(tu_file& in, const FLVVideoFrameInfo& frameInfo)
-{
-       std::auto_ptr<FLVFrame> frame ( new FLVFrame );
-
-       frame->dataSize = frameInfo.dataSize;
-       frame->timestamp = frameInfo.timestamp;
-       frame->type = videoFrame;
-
-       if ( in.set_position(frameInfo.dataPosition) )
-       {
-               log_error(_("Failed seeking to videoframe in FLV input"));
-               frame.reset();
-               return frame;
-       }
-
-       unsigned long int dataSize = frameInfo.dataSize;
-       unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS, 
dataSize+PADDING_BYTES);
-
-       frame->data = new boost::uint8_t[chunkSize];
-       size_t bytesread = in.read_bytes(frame->data, dataSize);
-
-       unsigned long int padding = chunkSize-dataSize;
-       assert(padding);
-       memset(frame->data + bytesread, 0, padding);
-
-       return frame;
-}
-
-static std::auto_ptr<FLVFrame>
-makeAudioFrame(tu_file& in, const FLVAudioFrameInfo& frameInfo)
-{
-       std::auto_ptr<FLVFrame> frame ( new FLVFrame );
-       frame->dataSize = frameInfo.dataSize; 
-       frame->timestamp = frameInfo.timestamp;
-       frame->type = audioFrame;
-
-
-       if ( in.set_position(frameInfo.dataPosition) )
-       {
-               log_error(_("Failed seeking to audioframe in FLV input"));
-               frame.reset();
-               return frame;
-       }
-
-       unsigned long int dataSize = frameInfo.dataSize;
-       unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS, 
dataSize+PADDING_BYTES);
-
-       frame->data = new boost::uint8_t[chunkSize];
-       size_t bytesread = in.read_bytes(frame->data, dataSize);
-
-       unsigned long int padding = chunkSize-dataSize;
-       assert(padding);
-       memset(frame->data + bytesread, 0, padding);
-
-       return frame;
-}
-
-FLVParser::FLVParser(std::auto_ptr<tu_file> lt)
-       :
-       _lt(lt),
-       _lastParsedPosition(0),
-       _parsingComplete(false),
-       _videoInfo(NULL),
-       _audioInfo(NULL),
-       _nextAudioFrame(0),
-       _nextVideoFrame(0),
-       _audio(false),
-       _video(false)
-{
-}
-
-FLVParser::~FLVParser()
-{
-       _videoFrames.clear();
-
-       _audioFrames.clear();
-}
-
-
-boost::uint32_t
-FLVParser::getBufferLength()
-{
-       if (_video) {
-               size_t size = _videoFrames.size();
-               if (size > 1 && size > _nextVideoFrame) {
-                       return _videoFrames.back()->timestamp; //  - 
_videoFrames[_nextVideoFrame]->timestamp;
-               }
-       }
-       if (_audio) {
-               size_t size = _audioFrames.size();
-               if (size > 1 && size > _nextAudioFrame) {
-                       return _audioFrames.back()->timestamp; //  - 
_audioFrames[_nextAudioFrame]->timestamp;
-               }
-       }
-       return 0;
-}
-boost::uint16_t
-FLVParser::videoFrameRate()
-{
-       // Make sure that there are parsed some frames
-       while(_videoFrames.size() < 2 && !_parsingComplete) {
-               parseNextTag();
-       }
-
-       if (_videoFrames.size() < 2) return 0;
-
-       boost::uint32_t framedelay = _videoFrames[1]->timestamp - 
_videoFrames[0]->timestamp;
-
-       return static_cast<boost::int16_t>(1000 / framedelay);
-}
-
-
-boost::uint32_t
-FLVParser::videoFrameDelay()
-{
-       // If there are no video in this FLV return 0
-       if (!_video && _lastParsedPosition > 0) return 0;
-
-       // Make sure that there are parsed some frames
-       while(_videoFrames.size() < 2 && !_parsingComplete) {
-               parseNextTag();
-       }
-
-       // If there is no video data return 0
-       if (_videoFrames.size() == 0 || !_video || _nextVideoFrame < 2) return 
0;
-
-       return _videoFrames[_nextVideoFrame-1]->timestamp - 
_videoFrames[_nextVideoFrame-2]->timestamp;
-}
-
-boost::uint32_t
-FLVParser::audioFrameDelay()
-{
-       // If there are no audio in this FLV return 0
-       if (!_audio && _lastParsedPosition > 0) return 0;
-
-       // Make sure that there are parsed some frames
-       while(_audioFrames.size() < 2 && !_parsingComplete) {
-               parseNextTag();
-       }
-
-       // If there is no video data return 0
-       if (_audioFrames.size() == 0 || !_audio || _nextAudioFrame < 2) return 
0;
-
-       return _audioFrames[_nextAudioFrame-1]->timestamp - 
_audioFrames[_nextAudioFrame-2]->timestamp;
-}
-
-FLVAudioFrameInfo*
-FLVParser::peekNextAudioFrameInfo()
-{
-       // If there are no audio in this FLV return NULL
-       if (!_audio && _lastParsedPosition > 0) return 0;
-
-       // Make sure that there are parsed enough frames to return the need 
frame
-       while(_audioFrames.size() <= _nextAudioFrame && !_parsingComplete) {
-               if (!parseNextTag()) break;
-       }
-
-       // If the needed frame can't be parsed (EOF reached) return NULL
-       if (_audioFrames.empty() || _audioFrames.size() <= _nextAudioFrame)
-       {
-               return 0;       
-       }
-
-       return _audioFrames[_nextAudioFrame];
-}
-
-FLVFrame*
-FLVParser::nextAudioFrame()
-{
-       FLVAudioFrameInfo* frameInfo = peekNextAudioFrameInfo();
-       if ( ! frameInfo ) return 0;
-
-       std::auto_ptr<FLVFrame> frame = makeAudioFrame(*_lt, *frameInfo);
-       if ( ! frame.get() )
-       {
-               log_error("Could not make audio frame %d", _nextAudioFrame);
-               return 0;
-       }
-
-       _nextAudioFrame++;
-       return frame.release(); // TODO: return by auto_ptr
-
-}
-
-FLVVideoFrameInfo*
- FLVParser::peekNextVideoFrameInfo()
-{
-       // If there are no video in this FLV return NULL
-       if (!_video && _lastParsedPosition > 0)
-       {
-               //gnash::log_debug("no video, or lastParserPosition > 0");
-               return 0;
-       }
-
-       // Make sure that there are parsed enough frames to return the need 
frame
-       while(_videoFrames.size() <= 
static_cast<boost::uint32_t>(_nextVideoFrame) && !_parsingComplete)
-       {
-               if (!parseNextTag()) break;
-       }
-
-       // If the needed frame can't be parsed (EOF reached) return NULL
-       if (_videoFrames.empty() || _videoFrames.size() <= _nextVideoFrame)
-       {
-               //gnash::log_debug("The needed frame (%d) can't be parsed (EOF 
reached)", _lastVideoFrame);
-               return 0;
-       }
-
-       return _videoFrames[_nextVideoFrame];
-}
-
-FLVFrame* FLVParser::nextVideoFrame()
-{
-       FLVVideoFrameInfo* frameInfo = peekNextVideoFrameInfo();
-       std::auto_ptr<FLVFrame> frame = makeVideoFrame(*_lt, *frameInfo);
-       if ( ! frame.get() )
-       {
-               log_error("Could not make video frame %d", _nextVideoFrame);
-               return 0;
-       }
-
-       _nextVideoFrame++;
-       return frame.release(); // TODO: return by auto_ptr
-}
-
-
-boost::uint32_t
-FLVParser::seekAudio(boost::uint32_t time)
-{
-
-       // If there is no audio data return NULL
-       if (_audioFrames.empty()) return 0;
-
-       // If there are no audio greater than the given time
-       // the last audioframe is returned
-       FLVAudioFrameInfo* lastFrame = _audioFrames.back();
-       if (lastFrame->timestamp < time) {
-               _nextAudioFrame = _audioFrames.size() - 1;
-               return lastFrame->timestamp;
-       }
-
-       // We try to guess where in the vector the audioframe
-       // with the correct timestamp is
-       size_t numFrames = _audioFrames.size();
-       double tpf = lastFrame->timestamp / numFrames; // time per frame
-       size_t guess = size_t(time / tpf);
-
-       // Here we test if the guess was ok, and adjust if needed.
-       size_t bestFrame = utility::clamp<size_t>(guess, 0, 
_audioFrames.size()-1);
-
-       // Here we test if the guess was ok, and adjust if needed.
-       long diff = _audioFrames[bestFrame]->timestamp - time;
-       if ( diff > 0 ) // our guess was too long
-       {
-               while ( bestFrame > 0 && _audioFrames[bestFrame-1]->timestamp > 
time ) --bestFrame;
-       }
-       else // our guess was too short
-       {
-               while ( bestFrame < _audioFrames.size()-1 && 
_audioFrames[bestFrame+1]->timestamp < time ) ++bestFrame;
-       }
-
-#ifdef GNASH_DEBUG_SEEK
-       gnash::log_debug("Seek (audio): " SIZET_FMT "/" SIZET_FMT " (%u/%u)", 
bestFrame, numFrames, _audioFrames[bestFrame]->timestamp, time);
-#endif
-       _nextAudioFrame = bestFrame;
-       return _audioFrames[bestFrame]->timestamp;
-
-}
-
-
-boost::uint32_t
-FLVParser::seekVideo(boost::uint32_t time)
-{
-       if ( _videoFrames.empty() ) return 0;
-
-       // If there are no videoframe greater than the given time
-       // the last key videoframe is returned
-       FLVVideoFrameInfo* lastFrame = _videoFrames.back();
-       size_t numFrames = _videoFrames.size();
-       if (lastFrame->timestamp < time)
-       {
-               size_t lastFrameNum = numFrames -1;
-               while (! lastFrame->isKeyFrame() )
-               {
-                       lastFrameNum--;
-                       lastFrame = _videoFrames[lastFrameNum];
-               }
-
-               _nextVideoFrame = lastFrameNum;
-               return lastFrame->timestamp;
-
-       }
-
-       // We try to guess where in the vector the videoframe
-       // with the correct timestamp is
-       double tpf = lastFrame->timestamp / numFrames; // time per frame
-       size_t guess = size_t(time / tpf);
-
-       size_t bestFrame = utility::clamp<size_t>(guess, 0, 
_videoFrames.size()-1);
-
-       // Here we test if the guess was ok, and adjust if needed.
-       long diff = _videoFrames[bestFrame]->timestamp - time;
-       if ( diff > 0 ) // our guess was too long
-       {
-               while ( bestFrame > 0 && _videoFrames[bestFrame-1]->timestamp > 
time ) --bestFrame;
-       }
-       else // our guess was too short
-       {
-               while ( bestFrame < _videoFrames.size()-1 && 
_videoFrames[bestFrame+1]->timestamp < time ) ++bestFrame;
-       }
-
-       // Find closest backward keyframe  
-       size_t rewindKeyframe = bestFrame;
-       while ( rewindKeyframe && ! _videoFrames[rewindKeyframe]->isKeyFrame() )
-       {
-               rewindKeyframe--;
-       }
-
-       // Find closest forward keyframe 
-       size_t forwardKeyframe = bestFrame;
-       size_t size = _videoFrames.size();
-       while (size > forwardKeyframe+1 && ! 
_videoFrames[forwardKeyframe]->isKeyFrame() )
-       {
-               forwardKeyframe++;
-       }
-
-       // We can't ensure we were able to find a key frame *after* the best 
position
-       // in that case we just use any previous keyframe instead..
-       if ( ! _videoFrames[forwardKeyframe]->isKeyFrame() )
-       {
-               bestFrame = rewindKeyframe;
-       }
-       else
-       {
-               boost::int32_t forwardDiff = 
_videoFrames[forwardKeyframe]->timestamp - time;
-               boost::int32_t rewindDiff = time - 
_videoFrames[rewindKeyframe]->timestamp;
-
-               if (forwardDiff < rewindDiff) bestFrame = forwardKeyframe;
-               else bestFrame = rewindKeyframe;
-       }
-
-#ifdef GNASH_DEBUG_SEEK
-       gnash::log_debug("Seek (video): " SIZET_FMT "/" SIZET_FMT " (%u/%u)", 
bestFrame, numFrames, _videoFrames[bestFrame]->timestamp, time);
-#endif
-
-       _nextVideoFrame = bestFrame;
-       assert( _videoFrames[bestFrame]->isKeyFrame() );
-       return _videoFrames[bestFrame]->timestamp;
-}
-
-
-
-FLVVideoInfo* FLVParser::getVideoInfo()
-{
-       // If there are no video in this FLV return NULL
-       if (!_video && _lastParsedPosition > 0) return NULL;
-
-       // Make sure that there are parsed some video frames
-       while( ! _parsingComplete && !_videoInfo.get() ) parseNextTag();
-
-       return _videoInfo.get(); // may be null
-}
-
-FLVAudioInfo* FLVParser::getAudioInfo()
-{
-       // If there are no audio in this FLV return NULL
-       if (!_audio && _lastParsedPosition > 0) return NULL;
-
-       // Make sure that there are parsed some audio frames
-       while (!_parsingComplete && ! _audioInfo.get() )
-       {
-               parseNextTag();
-       }
-
-       return _audioInfo.get(); // may be null
-}
-
-bool
-FLVParser::isTimeLoaded(boost::uint32_t time)
-{
-       // Parse frames until the need time is found, or EOF
-       while (!_parsingComplete) {
-               if (!parseNextTag()) break;
-               if ((_videoFrames.size() > 0 && _videoFrames.back()->timestamp 
>= time)
-                       || (_audioFrames.size() > 0 && 
_audioFrames.back()->timestamp >= time)) {
-                       return true;
-               }
-       }
-
-       if (_videoFrames.size() > 0 && _videoFrames.back()->timestamp >= time) {
-               return true;
-       }
-
-       if (_audioFrames.size() > 0 && _audioFrames.back()->timestamp >= time) {
-               return true;
-       }
-
-       return false;
-
-}
-
-boost::uint32_t
-FLVParser::seek(boost::uint32_t time)
-{
-       GNASH_REPORT_FUNCTION;
-
-       log_debug("FLVParser::seek(%d) ", time);
-
-       if (time == 0) {
-               if (_video) _nextVideoFrame = 0;
-               if (_audio) _nextAudioFrame = 0;
-       }
-
-       // Video, if present, has more constraints
-       // as to where we allow seeking (we only
-       // allow seek to closest *key* frame).
-       // So we first have video seeking tell us
-       // what time is best for that, and next
-       // we seek audio on that time
-
-       if (_video)
-       {
-               time = seekVideo(time);
-#ifdef GNASH_DEBUG_SEEK
-               log_debug("  seekVideo -> %d", time);
-#endif
-       }
-
-       if (_audio)
-       {
-               time = seekAudio(time);
-#ifdef GNASH_DEBUG_SEEK
-               log_debug("  seekAudio -> %d", time);
-#endif
-       }
-
-       return time;
-}
-
-bool FLVParser::parseNextTag()
-{
-       if ( _parsingComplete ) return false;
-
-       // Parse the header if not done already. If unsuccesfull return false.
-       if (_lastParsedPosition == 0 && !parseHeader()) return false;
-
-       // Seek to next frame and skip the size of the last tag
-       if ( _lt->set_position(_lastParsedPosition+4) )
-       {
-               log_error("FLVParser::parseNextTag: can't seek to %d", 
_lastParsedPosition+4);
-               _parsingComplete=true;
-               return false;
-       }
-
-       // Read the tag info
-       boost::uint8_t tag[12];
-       int actuallyRead = _lt->read_bytes(tag, 12);
-       if ( actuallyRead < 12 )
-       {
-               if ( actuallyRead )
-                       log_error("FLVParser::parseNextTag: can't read tag info 
(needed 12 bytes, only got %d)", actuallyRead);
-               // else { assert(_lt->get_eof(); } ?
-               _parsingComplete=true;
-               return false;
-       }
-
-       // Extract length and timestamp
-       boost::uint32_t bodyLength = getUInt24(&tag[1]);
-       boost::uint32_t timestamp = getUInt24(&tag[4]);
-
-       _lastParsedPosition += 15 + bodyLength;
-
-       // check for empty tag
-       if (bodyLength == 0) return true;
-
-       if (tag[0] == AUDIO_TAG)
-       {
-               FLVAudioFrameInfo* frame = new FLVAudioFrameInfo;
-               frame->dataSize = bodyLength - 1;
-               frame->timestamp = timestamp;
-               frame->dataPosition = _lt->get_position();
-               _audioFrames.push_back(frame);
-
-               // If this is the first audioframe no info about the
-               // audio format has been noted, so we do that now
-               if ( !_audioInfo.get() )
-               {
-                       int samplerate = (tag[11] & 0x0C) >> 2;
-                       if (samplerate == 0) samplerate = 5500;
-                       else if (samplerate == 1) samplerate = 11000;
-                       else if (samplerate == 2) samplerate = 22050;
-                       else if (samplerate == 3) samplerate = 44100;
-
-                       int samplesize = (tag[11] & 0x02) >> 1;
-                       if (samplesize == 0) samplesize = 1;
-                       else samplesize = 2;
-
-                       _audioInfo.reset( new FLVAudioInfo((tag[11] & 0xf0) >> 
4, samplerate, samplesize, (tag[11] & 0x01) >> 0, 0) );
-               }
-
-
-       }
-       else if (tag[0] == VIDEO_TAG)
-       {
-               FLVVideoFrameInfo* frame = new FLVVideoFrameInfo;
-               frame->dataSize = bodyLength - 1;
-               frame->timestamp = timestamp;
-               frame->dataPosition = _lt->get_position();
-               frame->frameType = (tag[11] & 0xf0) >> 4;
-               _videoFrames.push_back(frame);
-
-               // If this is the first videoframe no info about the
-               // video format has been noted, so we do that now
-               if ( ! _videoInfo.get() )
-               {
-                       boost::uint16_t codec = (tag[11] & 0x0f) >> 0;
-                       // Set standard guessed size...
-                       boost::uint16_t width = 320;
-                       boost::uint16_t height = 240;
-
-                       // Extract the video size from the videodata header
-                       if (codec == VIDEO_CODEC_H263) {
-                               if ( _lt->set_position(frame->dataPosition) )
-                               {
-                                       log_error(" Couldn't seek to VideoTag 
data position");
-                                       _parsingComplete=true;
-                                       return false;
-                               }
-                               boost::uint8_t videohead[12];
-                               int actuallyRead = _lt->read_bytes(videohead, 
12);
-                               if ( actuallyRead < 12 )
-                               {
-               log_error("FLVParser::parseNextTag: can't read H263 video 
header (needed 12 bytes, only got %d)", actuallyRead);
-               _parsingComplete=true;
-               return false;
-                               }
-
-                               bool sizebit1 = (videohead[3] & 0x02);
-                               bool sizebit2 = (videohead[3] & 0x01);
-                               bool sizebit3 = (videohead[4] & 0x80);
-
-                               // First some predefined sizes
-                               if (!sizebit1 && sizebit2 && !sizebit3 ) {
-                                       width = 352;
-                                       height = 288;
-                               } else if (!sizebit1 && sizebit2 && sizebit3 ) {
-                                       width = 176;
-                                       height = 144;
-                               } else if (sizebit1 && !sizebit2 && !sizebit3 ) 
{
-                                       width = 128;
-                                       height = 96;
-                               } else if (sizebit1 && !sizebit2 && sizebit3 ) {
-                                       width = 320;
-                                       height = 240;
-                               } else if (sizebit1 && sizebit2 && !sizebit3 ) {
-                                       width = 160;
-                                       height = 120;
-
-                               // Then the custom sizes (1 byte - untested and 
ugly)
-                               } else if (!sizebit1 && !sizebit2 && !sizebit3 
) {
-                                       width = (videohead[4] & 0x40) | 
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) | 
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) | 
(videohead[5] & 0x80);
-
-                                       height = (videohead[5] & 0x40) | 
(videohead[5] & 0x20) | (videohead[5] & 0x20) | (videohead[5] & 0x08) | 
(videohead[5] & 0x04) | (videohead[5] & 0x02) | (videohead[5] & 0x01) | 
(videohead[6] & 0x80);
-
-                               // Then the custom sizes (2 byte - untested and 
ugly)
-                               } else if (!sizebit1 && !sizebit2 && sizebit3 ) 
{
-                                       width = (videohead[4] & 0x40) | 
(videohead[4] & 0x20) | (videohead[4] & 0x20) | (videohead[4] & 0x08) | 
(videohead[4] & 0x04) | (videohead[4] & 0x02) | (videohead[4] & 0x01) | 
(videohead[5] & 0x80) | (videohead[5] & 0x40) | (videohead[5] & 0x20) | 
(videohead[5] & 0x20) | (videohead[5] & 0x08) | (videohead[5] & 0x04) | 
(videohead[5] & 0x02) | (videohead[5] & 0x01) | (videohead[6] & 0x80);
-
-                                       height = (videohead[6] & 0x40) | 
(videohead[6] & 0x20) | (videohead[6] & 0x20) | (videohead[6] & 0x08) | 
(videohead[6] & 0x04) | (videohead[6] & 0x02) | (videohead[6] & 0x01) | 
(videohead[7] & 0x80) | (videohead[7] & 0x40) | (videohead[7] & 0x20) | 
(videohead[7] & 0x20) | (videohead[7] & 0x08) | (videohead[7] & 0x04) | 
(videohead[7] & 0x02) | (videohead[7] & 0x01) | (videohead[8] & 0x80);
-                               }
-
-                       }
-
-                       // Create the videoinfo
-                       _videoInfo.reset( new FLVVideoInfo(codec, width, 
height, 0 /*frameRate*/, 0 /*duration*/) );
-               }
-
-       } else if (tag[0] == META_TAG) {
-               LOG_ONCE( log_unimpl("FLV MetaTag parser") );
-               // Extract information from the meta tag
-               /*_lt->seek(_lastParsedPosition+16);
-               char* metaTag = new char[bodyLength];
-               size_t actuallyRead = _lt->read(metaTag, bodyLength);
-               if ( actuallyRead < bodyLength )
-               {
-                       log_error("FLVParser::parseNextTag: can't read metaTag 
(%d) body (needed %d bytes, only got %d)",
-                               META_TAG, bodyLength, actuallyRead);
-                       _parsingComplete=true;
-                       return false;
-               }
-               amf::AMF* amfParser = new amf::AMF();
-               amfParser->parseAMF(metaTag);*/
-
-       } else {
-               log_error("Unknown FLV tag type %d", tag[0]);
-               //_parsingComplete = true;
-               //return false;
-       }
-
-       return true;
-}
-
-bool FLVParser::parseHeader()
-{
-       // seek to the begining of the file
-       _lt->set_position(0); // seek back ? really ?
-
-       // Read the header
-       boost::uint8_t header[9];
-       if ( _lt->read_bytes(header, 9) != 9 )
-       {
-               log_error("FLVParser::parseHeader: couldn't read 9 bytes of 
header");
-               return false;
-       }
-
-       // Check if this is really a FLV file
-       if (header[0] != 'F' || header[1] != 'L' || header[2] != 'V') return 
false;
-
-       int version = header[3];
-
-       // Parse the audio+video bitmask
-       _audio = header[4]&(1<<2);
-       _video = header[4]&(1<<0);
-
-       log_debug("Parsing FLV version %d, audio:%d, video:%d", version, 
_audio, _video);
-
-       _lastParsedPosition = 9;
-       return true;
-}
-
-inline boost::uint32_t FLVParser::getUInt24(boost::uint8_t* in)
-{
-       // The bits are in big endian order
-       return (in[0] << 16) | (in[1] << 8) | in[2];
-}
-
-boost::uint64_t
-FLVParser::getBytesLoaded() const
-{
-       return _lastParsedPosition;
-}
-
-boost::uint64_t
-FLVParser::getBytesTotal() const
-{
-       return _lt->get_size();
-}
-
-FLVFrame* FLVParser::nextMediaFrame()
-{
-       boost::uint32_t video_size = _videoFrames.size();
-       boost::uint32_t audio_size = _audioFrames.size();
-
-       if (audio_size <= _nextAudioFrame && video_size <= _nextVideoFrame)
-       {
-
-               // Parse a media frame if any left or if needed
-               while(_videoFrames.size() <= _nextVideoFrame && 
_audioFrames.size() <= _nextAudioFrame && !_parsingComplete) {
-                       if (!parseNextTag()) break;
-               }
-       }
-
-       // Find the next frame in the file
-       bool audioReady = _audioFrames.size() > _nextAudioFrame;
-       bool videoReady = _videoFrames.size() > _nextVideoFrame;
-       bool useAudio = false;
-
-       if (audioReady && videoReady) {
-               useAudio = _audioFrames[_nextAudioFrame]->dataPosition < 
_videoFrames[_nextVideoFrame]->dataPosition;
-       } else if (!audioReady && videoReady) {
-               useAudio = false;
-       } else if (audioReady && !videoReady) {
-               useAudio = true;
-       } else {
-               // If no frames are next we have reached EOF
-               return NULL;
-       }
-
-       // Find the next frame in the file a return it
-
-       if (useAudio) {
-
-               FLVAudioFrameInfo* frameInfo = _audioFrames[_nextAudioFrame];
-
-               std::auto_ptr<FLVFrame> frame = makeAudioFrame(*_lt, 
*frameInfo);
-               if ( ! frame.get() )
-               {
-                       log_error("Could not make audio frame %d", 
_nextAudioFrame);
-                       return 0;
-               }
-
-               _nextAudioFrame++;
-               return frame.release(); // TODO: return by auto_ptr
-
-       } else {
-
-               FLVVideoFrameInfo* frameInfo = _videoFrames[_nextVideoFrame];
-               std::auto_ptr<FLVFrame> frame = makeVideoFrame(*_lt, 
*frameInfo);
-               if ( ! frame.get() )
-               {
-                       log_error("Could not make video frame %d", 
_nextVideoFrame);
-                       return 0;
-               }
-
-               _nextVideoFrame++;
-               return frame.release(); // TODO: return by auto_ptr
-       }
-
-
-}
-
-} // end of gnash namespace
-
-#undef PADDING_BYTES
-#undef READ_CHUNKS 

Index: libbase/FLVParser.h
===================================================================
RCS file: libbase/FLVParser.h
diff -N libbase/FLVParser.h
--- libbase/FLVParser.h 27 May 2008 11:58:45 -0000      1.32
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,407 +0,0 @@
-// FLVParser.h:  Flash Video file format parser, for Gnash.
-//
-//   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
-//
-
-
-// Information about the FLV format can be found at http://osflash.org/flv
-
-#ifndef __FLVPARSER_H__
-#define __FLVPARSER_H__
-
-#include "LoadThread.h"
-#include "dsodefs.h"
-#include <vector>
-#include <memory>
-
-namespace gnash {
-
-/// Frame type
-enum FrameType {
-
-       /// Video frame
-       videoFrame,
-
-       /// Audio frame
-       audioFrame
-};
-
-/// \brief
-/// The FLVFrame class contains an encoded
-/// video or audio frame, its size, its
-/// timestamp,
-class FLVFrame
-{
-public:
-       /// Size of the encoded frame
-       boost::uint32_t dataSize;
-
-       /// Encoded data
-       boost::uint8_t* data;
-
-       /// Frame timestamp, in milliseconds
-       boost::uint64_t timestamp;
-
-       /// Frame type (audio/video)
-       FrameType type;
-};
-
-/// \brief
-/// The FLVAudioInfo class contains information about the audiostream
-/// in the FLV being parsed. The information stored is codec-type,
-/// samplerate, samplesize, stereo flag and duration.
-class FLVAudioInfo
-{
-public:
-       FLVAudioInfo(boost::uint16_t codeci, boost::uint16_t sampleRatei, 
boost::uint16_t sampleSizei, bool stereoi, boost::uint64_t durationi)
-               : codec(codeci),
-               sampleRate(sampleRatei),
-               sampleSize(sampleSizei),
-               stereo(stereoi),
-               duration(durationi)
-               {
-               }
-
-       boost::uint16_t codec;
-       boost::uint16_t sampleRate;
-       boost::uint16_t sampleSize;
-       bool stereo;
-       boost::uint64_t duration;
-};
-
-/// \brief
-/// The FLVVideoInfo class contains information about the videostream
-/// in the FLV being parsed. The information stored is codec-type,
-/// width, height, framerate and duration.
-class FLVVideoInfo
-{
-public:
-       FLVVideoInfo(boost::uint16_t codeci, boost::uint16_t widthi, 
boost::uint16_t heighti, boost::uint16_t frameRatei, boost::uint64_t durationi)
-               : codec(codeci),
-               width(widthi),
-               height(heighti),
-               frameRate(frameRatei),
-               duration(durationi)
-               {
-               }
-
-       boost::uint16_t codec;
-       boost::uint16_t width;
-       boost::uint16_t height;
-       boost::uint16_t frameRate;
-       boost::uint64_t duration;
-};
-
-
-/// Information about an FLV Audio Frame
-class FLVVideoFrameInfo
-{
-public:
-
-       /// Type of this frame (should likely be videoFrameType)
-       boost::uint16_t frameType;
-
-       /// Size of the frame in bytes
-       boost::uint32_t dataSize;
-
-       /// Start of frame data in stream
-       boost::uint64_t dataPosition;
-
-       /// Timestamp in milliseconds 
-       boost::uint32_t timestamp;
-
-       /// Return true if this video frame is a key frame
-       bool isKeyFrame() const
-       {
-               return frameType == 1 /*KEY_FRAME*/;
-       }
-
-};
-
-/// Information about an FLV Audio Frame
-class FLVAudioFrameInfo
-{
-public:
-       /// Size of the frame in bytes
-       boost::uint32_t dataSize;
-
-       /// Start of frame data in stream
-       boost::uint64_t dataPosition;
-
-       /// Timestamp in milliseconds 
-       boost::uint32_t timestamp;
-
-};
-
-/// \brief
-/// The FLVParser class parses an FLV stream, buffers audio/video frames
-/// and provides cursor-based access to them.
-//
-/// Cursor-based access allow seeking as close as possible to a specified time
-/// and fetching frames from there on, sequentially.
-/// See seek(), nextVideoFrame(), nextAudioFrame() and nextMediaFrame().
-///
-/// Input is received from a tu_file object.
-///
-class DSOEXPORT FLVParser
-{
-
-public:
-
-       enum videoCodecType
-       {
-               VIDEO_CODEC_H263 = 2,   // H263/SVQ3 video codec
-               VIDEO_CODEC_SCREENVIDEO = 3,    // Screenvideo codec
-               VIDEO_CODEC_VP6 = 4,            // On2 VP6 video codec
-               VIDEO_CODEC_VP6A = 5,           // On2 VP6 Alpha video codec
-               VIDEO_CODEC_SCREENVIDEO2 = 6    // Screenvideo2 codec
-       };
-
-       enum audioCodecType
-       {
-               AUDIO_CODEC_RAW = 0,            // unspecified format.  Useful 
for 8-bit sounds???
-               AUDIO_CODEC_ADPCM = 1,  // gnash doesn't pass this through; it 
uncompresses and sends FORMAT_NATIVE16
-               AUDIO_CODEC_MP3 = 2,
-               AUDIO_CODEC_UNCOMPRESSED = 3,   // 16 bits/sample, little-endian
-               AUDIO_CODEC_NELLYMOSER_8HZ_MONO = 5,    // According to ffmpeg
-               AUDIO_CODEC_NELLYMOSER = 6      // Mystery proprietary format; 
see nellymoser.com
-       };
-
-       enum tagType
-       {
-               AUDIO_TAG = 0x08,
-               VIDEO_TAG = 0x09,
-               META_TAG = 0x12
-       };
-
-       enum videoFrameType
-       {
-               KEY_FRAME = 1,
-               INTER_FRAME = 2,
-               DIS_INTER_FRAME = 3
-       };
-
-
-       /// \brief
-       /// Create an FLV parser reading input from
-       /// the given LoadThread
-       //
-       /// @param lt
-       ///     LoadThread to use for input.
-       ///     Ownership transferred.
-       ///
-       FLVParser(std::auto_ptr<tu_file> lt);
-
-       /// Kills the parser...
-       ~FLVParser();
-
-       /// Return next media frame
-       //
-       /// Locks the _mutex
-       ///
-       FLVFrame* nextMediaFrame();
-
-       /// \brief
-       /// Return the next audio frame info in the parsed buffer.
-       //
-       /// If no frame has been played before the first frame is returned.
-       /// If there is no more frames in the parsed buffer NULL is returned,
-       /// you can check with parsingCompleted() to know wheter this is due to 
-       /// EOF reached.
-       ///
-       /// TODO: return a more abstract EncodedAudioFrameInfo
-       ///
-       FLVAudioFrameInfo* peekNextAudioFrameInfo();
-
-       /// \brief
-       /// Returns the next audio frame in the parsed buffer, advancing audio 
cursor.
-       //
-       /// If no frame has been played before the first frame is returned.
-       /// If there is no more frames in the parsed buffer NULL is returned,
-       /// you can check with parsingCompleted() to know wheter this is due to 
-       /// EOF reached.
-       ///
-       /// TODO: return a more abstract EncodedAudioFrame
-       ///
-       FLVFrame* nextAudioFrame();
-
-       /// Returns the next video frame info in the parsed buffer.
-       //
-       /// If no frame has been played before the first frame is returned.
-       /// If there is no more frames in the parsed buffer NULL is returned.
-       /// you can check with parsingCompleted() to know wheter this is due to 
-       /// EOF reached.
-       ///
-       /// TODO: return a more abstract EncodedVideoFrameInfo
-       ///
-       FLVVideoFrameInfo* peekNextVideoFrameInfo();
-
-       /// Returns the next video frame in the parsed buffer, advancing video 
cursor.
-       //
-       /// If no frame has been played before the first frame is returned.
-       /// If there is no more frames in the parsed buffer NULL is returned.
-       /// you can check with parsingCompleted() to know wheter this is due to 
-       /// EOF reached.
-       ///
-       /// TODO: return a more abstract EncodedVideoFrame
-       ///
-       FLVFrame* nextVideoFrame();
-
-       /// Return true of parsing is completed
-       //
-       /// If this function returns true, any call to nextVideoFrame() or 
nextAudioFrame
-       /// will always return NULL
-       ///
-       bool parsingCompleted() const { return _parsingComplete; }
-
-       /// Returns information about video in the stream.
-       //
-       /// The returned object is owned by the FLVParser object.
-       /// Can return NULL if video contains NO video frames.
-       /// Will block till either parsing finished or a video frame is found.
-       ///
-       /// TODO: return a more abstract VideoInfo
-       ///
-       FLVVideoInfo* getVideoInfo();
-
-       /// Returns a FLVAudioInfo class about the audiostream
-       //
-       /// TODO: return a more abstract AudioInfo
-       ///
-       FLVAudioInfo* getAudioInfo();
-
-       /// \brief
-       /// Asks if a frame with with a timestamp larger than
-       /// the given time is available.
-       //
-       /// If such a frame is not
-       /// available in list of already the parsed frames, we
-       /// parse some more. This is used to check how much is buffered.
-       ///
-       /// @param time
-       ///     Timestamp, in milliseconds.
-       ///
-       bool isTimeLoaded(boost::uint32_t time);
-
-       /// \brief
-       /// Seeks to the closest possible position the given position,
-       /// and returns the new position.
-       //
-       ///
-       /// TODO: throw something for sending Seek.InvalidTime ?
-       ///       (triggered by seeks beyond the end of video or beyond what's
-       ///        downloaded so far)
-       ///
-       boost::uint32_t seek(boost::uint32_t);
-
-       /// Returns the framedelay from the last to the current
-       /// audioframe in milliseconds. This is used for framerate.
-       //
-       boost::uint32_t audioFrameDelay();
-
-       /// \brief
-       /// Returns the framedelay from the last to the current
-       /// videoframe in milliseconds. 
-       //
-       boost::uint32_t videoFrameDelay();
-
-       /// Returns the framerate of the video
-       //
-       boost::uint16_t videoFrameRate();
-
-       /// Returns the "bufferlength", meaning the differens between the
-       /// current frames timestamp and the timestamp of the last parseable
-       /// frame. Returns the difference in milliseconds.
-       //
-       boost::uint32_t getBufferLength();
-
-       /// Parses next tag from the file
-       //
-       /// Returns true if something was parsed, false otherwise.
-       /// Sets _parsingComplete=true on end of file.
-       ///
-       bool parseNextTag();
-
-       /// Return number of bytes parsed so far
-       boost::uint64_t getBytesLoaded() const;
-
-       /// Return total number of bytes in input
-       boost::uint64_t getBytesTotal() const;
-
-private:
-
-       /// seeks to the closest possible position the given position,
-       /// and returns the new position.
-       boost::uint32_t seekAudio(boost::uint32_t time);
-
-       /// seeks to the closest possible position the given position,
-       /// and returns the new position.
-       boost::uint32_t seekVideo(boost::uint32_t time);
-
-       /// Parses the header of the file
-       bool parseHeader();
-
-       // Functions used to extract numbers from the file
-       inline boost::uint32_t getUInt24(boost::uint8_t* in);
-
-       /// The interface to the file, externally owned
-       std::auto_ptr<tu_file> _lt;
-
-       // NOTE: FLVVideoFrameInfo is a relatively small structure,
-       //       chances are keeping by value here would reduce
-       //       memory fragmentation with no big cost
-       typedef std::vector<FLVVideoFrameInfo*> VideoFrames;
-
-       /// list of videoframes, does no contain the frame data.
-       VideoFrames _videoFrames;
-
-       // NOTE: FLVAudioFrameInfo is a relatively small structure,
-       //       chances are keeping by value here would reduce
-       //       memory fragmentation with no big cost
-       typedef std::vector<FLVAudioFrameInfo*> AudioFrames;
-
-       /// list of audioframes, does no contain the frame data.
-       AudioFrames _audioFrames;
-
-       /// The position where the parsing should continue from.
-       boost::uint64_t _lastParsedPosition;
-
-       /// Whether the parsing is complete or not
-       bool _parsingComplete;
-
-       /// Info about the video stream (if any)
-       std::auto_ptr<FLVVideoInfo> _videoInfo;
-
-       /// Info about the audio stream (if any)
-       std::auto_ptr<FLVAudioInfo> _audioInfo;
-
-       /// Last audio frame returned
-       size_t _nextAudioFrame;
-
-       /// Last video frame returned
-       size_t _nextVideoFrame;
-
-       /// Audio stream is present
-       bool _audio;
-
-       /// Audio stream is present
-       bool _video;
-};
-
-} // end of gnash namespace
-
-#endif // __FLVPARSER_H__

Index: libmedia/MediaDecoder.cpp
===================================================================
RCS file: libmedia/MediaDecoder.cpp
diff -N libmedia/MediaDecoder.cpp
--- libmedia/MediaDecoder.cpp   5 Mar 2008 03:55:54 -0000       1.6
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,176 +0,0 @@
-// MediaDecoder.cpp: Media decoding generic code
-// 
-//   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
-
-
-#include "MediaDecoder.h"
-
-#include "log.h"
-
-namespace gnash {
-namespace media {
-
-std::vector<StatusCode> MediaDecoder::getOnStatusEvents()
-{
-       boost::mutex::scoped_lock lock(_onStatusMutex);
-
-       const std::vector<StatusCode> statusQueue(_onStatusQueue);
-       _onStatusQueue.clear();
-       return statusQueue;
-}
-
-void MediaDecoder::decodingLoop()
-{
-
-       bool decodingFailed = false;
-       
-       // The decode loop
-       while (_running)
-       {
-
-               // If the buffer is not full, put something into it!
-               if (!_buffer->isFull())
-               {
-                       while (!_buffer->isFull() && _running)
-                       {
-                               if (!decodeAndBufferFrame())
-                               {
-                                       decodingFailed = true;
-                                       break;
-                               }
-                               //log_debug("decoded a frame");
-                       }
-               
-               }
-               // "Warm up" the data.
-               else if (_streamSize > _lastConfirmedPosition)
-               {
-                       if (_stream->set_position(_lastConfirmedPosition+2048) 
!= 0)
-                       {
-                               // We assume we're done now
-                               // TODO: check for errors
-                               _lastConfirmedPosition = _streamSize;
-                       }
-                       else
-                       {
-                               _lastConfirmedPosition += 2048;
-                       }
-                       //log_debug("warming up the file");
-               }
-               
-               if (_buffer->isFull())
-               {
-                       pushOnStatus(bufferFull);
-
-                       // If download is complete there is nothing to do, so 
we take a break.
-                       if (_streamSize <= _lastConfirmedPosition)
-                       {
-                               relax();
-                               continue;
-                       }
-               }
-
-               // If decoding failed, there's a good chance playback has 
ended, so
-               // we take a breake until someone tells us to wake up.
-               if (decodingFailed)
-               {
-                       relax();
-               }
-
-       }
-       log_debug("Left the decoding loop");
-}
-
-bool MediaDecoder::decodeAndBufferFrame()
-{
-       MediaFrame* frame = _parser->parseMediaFrame();
-       boost::uint32_t parserPosition = _parser->getLastParsedPos();
-       if (parserPosition > _lastConfirmedPosition) _lastConfirmedPosition = 
parserPosition;
-
-       if (frame == NULL) {
-               if (_lastConfirmedPosition+1 >= _streamSize)
-               {
-#ifdef GNASH_DEBUG_THREADS
-                       log_debug("decodeFLVFrame: load completed, stopping");
-#endif
-                       pushOnStatus(playStop);
-               } else {
-                       pushOnStatus(streamNotFound);
-                       log_error("FLV parsing problems! stopping buffering.");
-                       _running = false;
-               }
-               return false;
-       }
-
-       if (frame->tag == 9) {
-               decodeVideo(frame);
-       } else {
-               decodeAudio(frame);
-       }
-       return true;
-
-}
-
-
-void MediaDecoder::decodeAudio(MediaFrame* packet)
-{
-       // We don't handle audio
-       if (!_audioDecoder.get()) return;
-
-       boost::uint32_t datasize;
-       boost::uint32_t bufsize;
-
-       boost::uint8_t* ptr = _audioDecoder->decode(packet->data, 
packet->dataSize, bufsize, datasize, false);
-
-       if (bufsize > 0 && ptr != NULL)
-       {
-               raw_audiodata_t* raw = new raw_audiodata_t();
-               
-               raw->m_data = ptr;
-               raw->m_ptr = raw->m_data;
-               raw->m_size = bufsize;
-               raw->m_pts = packet->timestamp;
-               _buffer->pushAudio(raw);
-               return;
-       }
-       log_debug(_("Problems decoding audio frame."));
-
-}
-
-void MediaDecoder::decodeVideo(MediaFrame* packet)
-{
-       // We don't handle video decoding today
-       if (!_videoDecoder.get()) return;
-
-       std::auto_ptr<image::image_base> img = 
_videoDecoder->decodeToImage(packet->data, packet->dataSize);
-
-       if (img.get() != NULL)
-       {
-               raw_videodata_t* raw = new raw_videodata_t();
-
-               raw->image = img;
-               raw->timestamp = packet->timestamp;
-               _buffer->pushVideo(raw);
-               return;
-       }
-       log_debug(_("Problems decoding video frame."));
-
-}
-
-} // media namespace
-} // gnash namespace
-

Index: libmedia/MediaDecoder.h
===================================================================
RCS file: libmedia/MediaDecoder.h
diff -N libmedia/MediaDecoder.h
--- libmedia/MediaDecoder.h     5 Mar 2008 03:55:54 -0000       1.8
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,275 +0,0 @@
-// MediaDecoder.h: Media decoding base class.
-// 
-//   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
-
-
-#ifndef __MEDIADECODER_H__
-#define __MEDIADECODER_H__
-
-#include <boost/thread/thread.hpp>
-#include <boost/bind.hpp> 
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/shared_ptr.hpp>
-#include <vector> 
-
-#include "MediaBuffer.h"
-#include "MediaParser.h"
-#include "FLVParser.h"
-#include "AudioDecoder.h"
-#include "VideoDecoder.h"
-#include "log.h"
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-namespace gnash {
-namespace media {
-
-/// Status codes used for NetStream onStatus notifications
-enum StatusCode {
-
-       // Internal status, not a valid ActionScript value
-       invalidStatus,
-
-       /// NetStream.Buffer.Empty (level: status)
-       bufferEmpty,
-
-       /// NetStream.Buffer.Full (level: status)
-       bufferFull,
-
-       /// NetStream.Buffer.Flush (level: status)
-       bufferFlush,
-
-       /// NetStream.Play.Start (level: status)
-       playStart,
-
-       /// NetStream.Play.Stop  (level: status)
-       playStop,
-
-       /// NetStream.Seek.Notify  (level: status)
-       seekNotify,
-
-       /// NetStream.Play.StreamNotFound (level: error)
-       streamNotFound,
-
-       /// NetStream.Seek.InvalidTime (level: error)
-       invalidTime
-};
-
-/// \brief
-/// The MediaDecoder class decodes media data and puts it on a given buffer.
-///
-/// We need to be able to handle event stuff, so we store the events that
-/// need to be handled, and then NetStream can ask for it on ::advance()
-/// or whenever it is appropriate. Eventhandling is different from AS2 to AS3,
-/// but in this first draft only AS2 will be supported.
-///
-class MediaDecoder
-{
-
-public:
-       /// This is copied from the render and should be changed if the 
original is.
-       enum videoOutputFormat
-       {
-               NONE,
-               YUV,
-               RGB
-       };
-
-       /// Internal error codes
-       enum MediaDecoderErrorCode {
-       
-               /// All is fine
-               noError,
-
-               /// Stream/connection error
-               streamError,
-
-               /// Error while decoding
-               decodingError,
-
-               /// Error while parsing
-               parsingError
-       };
-
-       /// \brief
-       /// Create a MediaDecoder reading input from
-       /// the given tu_file
-       //
-       /// @param stream
-       ///     tu_file to use for input.
-       ///     Ownership left to the caller.
-       ///
-       /// @param buffer
-       ///     The buffer we will use.
-       ///     Ownership left to the caller.
-       ///
-       MediaDecoder(boost::shared_ptr<tu_file> stream, MediaBuffer* buffer, 
boost::uint16_t swfVersion, int format)
-               :
-       _buffer(buffer),
-       _stream(stream),
-       _swfVersion(swfVersion),
-       _videoFrameFormat(format),
-       _parser(NULL),
-       _lastConfirmedPosition(0),
-       _streamSize(0),
-       _error(noError),
-       _isFLV(true),
-       _inputPos(0),
-       _audio(false),
-       _video(false),
-       _running(true),
-       _audioDecoder(NULL),
-       _videoDecoder(NULL),
-       _decodeThread(NULL)
-       {
-       }
-
-       /// Destroys the Decoder
-#if !defined(sgi) || defined(__GNUC__)
-       virtual ~MediaDecoder() {}
-#endif
-       /// Seeks to pos, returns the new position
-       virtual boost::uint32_t seek(boost::uint32_t /*pos*/) { return 0;}
-
-       virtual std::pair<boost::uint32_t, boost::uint32_t> getWidthAndHeight() 
{ return std::pair<boost::uint32_t, boost::uint32_t>(0,0); }
-
-       /// Returns the size of the file being loaded, in bytes
-       boost::uint32_t getBytesTotal()
-       {
-               return _streamSize;
-       }
-
-       /// Returns the amount of bytes of the current file that has been 
loaded.
-       boost::uint32_t getBytesLoaded() {
-               return _lastConfirmedPosition;
-       }
-
-       /// Returns a vector with the waiting onStatus events (AS2)
-       std::vector<StatusCode> getOnStatusEvents();
-
-       /// Returns whether we got audio
-       bool gotAudio() {
-               return _audio;
-       }
-
-       /// Returns whether we got video
-       bool gotVideo() {
-               return _video;
-       }
-
-       /// Used to wake up the decoder when it is needed
-       void wakeUp()
-       {
-               boost::mutex::scoped_lock lock(_monitor);
-               _nothingToDo.notify_all();
-       }
-
-protected:
-
-       /// Decodes data with the decoders that has been setup and pushes the 
data
-       /// unto the buffer. Returns when decoding stops.
-       void decodingLoop();
-
-       /// Decodes a frame and push it unto the buffer
-       bool decodeAndBufferFrame();
-
-       // Used to decode a video frame and push it on the videoqueue
-       void decodeVideo(MediaFrame* packet);
-
-       // Used to decode a audio frame and push it on the audioqueue
-       void decodeAudio(MediaFrame* packet);
-
-       /// Push an event to the onStatus event queue (AS2)
-       void pushOnStatus(StatusCode code) {
-               boost::mutex::scoped_lock lock(_onStatusMutex);
-               _onStatusQueue.push_back(code); 
-       }
-
-       /// used to wait for something to do
-       void relax()
-       {
-               boost::mutex::scoped_lock lock(_monitor);
-               _nothingToDo.wait(lock);
-       }
-
-       /// The media buffer
-       MediaBuffer* _buffer;
-
-       /// The stream we decode
-       boost::shared_ptr<tu_file> _stream;
-
-       /// Version of the SWF playing
-       boost::uint16_t _swfVersion;
-       
-       /// The output format
-       int _videoFrameFormat;
-
-       /// The parser used
-       std::auto_ptr<MediaParser> _parser;
-
-       /// The last confirmed size of the downloaded file
-       boost::uint32_t _lastConfirmedPosition;
-
-       /// total size of the file being downloaded
-       boost::uint32_t _streamSize;
-
-       /// Is everything ok?
-       MediaDecoderErrorCode _error;
-
-       /// Waiting NetStream onStatus events (AS2)
-       std::vector<StatusCode> _onStatusQueue;
-
-       /// Mutex protecting _onStatusQueue
-       boost::mutex _onStatusMutex;
-
-       /// Are we decoding a FLV?
-       bool _isFLV;
-
-       /// The position in the inputfile, only used when not playing a FLV
-       long _inputPos;
-
-       /// Do we have audio ?
-       bool _audio;
-
-       /// Do we have video ?
-       bool _video;
-
-       /// Used to wait when there is nothing to do
-       boost::condition _nothingToDo;
-       boost::mutex _monitor;
-
-       // Should the decode loop run or not
-       volatile bool _running;
-       
-       // An audio decoder
-       std::auto_ptr<AudioDecoder> _audioDecoder;
-
-       // A video decoder
-       std::auto_ptr<VideoDecoder> _videoDecoder;
-
-       // The decoding thread
-       boost::thread* _decodeThread;
-};
-
-
-} // gnash.media namespace 
-} // namespace gnash
-
-#endif // __MEDIADECODER_H__

Index: libmedia/gst/MediaDecoderGst.cpp
===================================================================
RCS file: libmedia/gst/MediaDecoderGst.cpp
diff -N libmedia/gst/MediaDecoderGst.cpp
--- libmedia/gst/MediaDecoderGst.cpp    5 Mar 2008 03:55:55 -0000       1.5
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,183 +0,0 @@
-// MediaDecoderGst.cpp: Media decoding using Gstreamer
-// 
-//   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
-
-
-#include "MediaDecoderGst.h"
-#include "AudioDecoderNellymoser.h"
-#include "AudioDecoderSimple.h"
-
-#include "AudioDecoderGst.h"
-#include "VideoDecoderGst.h"
-
-#include "log.h"
-
-#include "gnash.h"
-
-namespace gnash {
-namespace media {
-
-MediaDecoderGst::MediaDecoderGst(boost::shared_ptr<tu_file> stream, 
MediaBuffer* buffer, boost::uint16_t swfVersion, int format)
-       :
-       MediaDecoder(stream, buffer, swfVersion, format)
-{
-       // Start the decoding thread which will also setup the decoder and 
parser
-       _decodeThread = new 
boost::thread(boost::bind(MediaDecoderGst::decodeThread, this)); 
-}
-
-MediaDecoderGst::~MediaDecoderGst()
-{
-       _running = false;
-
-       if (_decodeThread) {
-               wakeUp();
-               _decodeThread->join();
-               delete _decodeThread;
-               _decodeThread = NULL;
-       }
-}
-
-bool MediaDecoderGst::setupParser()
-{
-       // Buffer a bit to make sure the stream is accessable
-       if (_stream->set_position(512) != 0) {
-               _error = streamError;
-               pushOnStatus(streamNotFound);
-               return false;
-       }
-
-       _lastConfirmedPosition = 512;
-       _streamSize = _stream->get_size();
-
-       // Check if the file is a FLV, in which case we use our own parser
-       char head[4] = {0, 0, 0, 0};
-       _stream->set_position(0);
-       _stream->read_bytes(head, 3);
-       _stream->set_position(0);
-
-       // Setup the decoding and parser
-       if (std::string(head) == "FLV") {
-               _parser.reset(new FLVParser(_stream));
-               return _parser->setupParser();
-       } else {
-               return false;
-       }
-}
-
-bool MediaDecoderGst::setupDecoding()
-{
-#if 0
-       std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
-       if (vInfo.get() != NULL) {
-
-               _videoDecoder.reset(new VideoDecoderGst());
-
-               if (_videoDecoder.get() != NULL) {
-                       if (!_videoDecoder->setup(vInfo.get())) {
-                               _videoDecoder.reset(NULL); // Delete the 
videoDecoder if it is of no use
-                               log_error("No video decoder could be created, 
since no decoder for this format is available.");
-                       }
-                       _video = true;
-               } else {
-                       log_error("No video decoder could be created, since no 
decoder is enabled.");
-               }
-       }
-#endif
-       std::auto_ptr<AudioInfo> aInfo = _parser->getAudioInfo();
-       if (get_sound_handler() && aInfo.get() != NULL) {
-
-               if (_parser->isAudioNellymoser()) {
-                       _audioDecoder.reset(new AudioDecoderNellymoser());
-               }
-
-               if (_audioDecoder.get() == NULL) _audioDecoder.reset(new 
AudioDecoderGst());
-
-               if (_audioDecoder.get() != NULL) {
-                       if (!_audioDecoder->setup(aInfo.get())) {
-                               _audioDecoder.reset(NULL); // Delete the 
audioDecoder if it is of no use
-                               log_error("No audio decoder could be created, 
since no decoder for this format is available.");
-                       }
-                       _audio = true;
-               } else {
-                       log_error("No audio decoder could be created, since no 
decoder is enabled.");
-               }
-       }
-
-       // We don't need both audio and video to be happy :)
-       return (_audio || _video);
-}
-
-
-boost::uint32_t MediaDecoderGst::seek(boost::uint32_t pos)
-{
-       boost::uint32_t ret = 0;
-       if (_parser.get()) ret = _parser->seek(pos);
-       else ret = 0;
-
-       // Flush the buffer
-       _buffer->flush();
-
-       return ret;
-}
-
-void MediaDecoderGst::decodeThread(MediaDecoderGst* decoder)
-{
-printf("\t in the decode thread\n");
-
-       // If the destructor has been called at this point, exit the thread
-       if (!decoder->_running) return;
-
-       // Setup the decoder and parser
-
-       if (decoder->setupParser()) {
-               if (!decoder->setupDecoding()) {
-                       decoder->pushOnStatus(streamNotFound);
-                       log_error("Setup of media decoder failed");
-                       return;
-               }
-
-       // If the parser setup failed, it is perhaps because it is not a FLV 
file,
-       // so we set up an gstreamer pipeline instead.
-       } else {
-/*             if (!decoder->setupGstPipeline()) {
-                       decoder->pushOnStatus(streamNotFound);*/
-                       log_error("Setup of media parser failed");
-                       return;
-//             }
-       }
-
-       // Everything is setup, so let's play!
-
-       decoder->pushOnStatus(playStart);
-
-       decoder->decodingLoop();
-}
-
-std::pair<boost::uint32_t, boost::uint32_t>
-MediaDecoderGst::getWidthAndHeight()
-{
-       if (_parser.get()) {
-               std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
-               if (vInfo.get()) return std::pair<boost::uint32_t, 
boost::uint32_t>(vInfo->width, vInfo->height);
-       }
-       return std::pair<boost::uint32_t, boost::uint32_t>(0,0);
-}
-       
-
-} // namespace media
-
-} // namespace gnash

Index: libmedia/gst/MediaDecoderGst.h
===================================================================
RCS file: libmedia/gst/MediaDecoderGst.h
diff -N libmedia/gst/MediaDecoderGst.h
--- libmedia/gst/MediaDecoderGst.h      5 Mar 2008 03:55:55 -0000       1.4
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,61 +0,0 @@
-// MediaDecoderGst.h: Media decoding using Gstreamer
-// 
-//   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
-
-
-#ifndef __MEDIADECODERGST_H__
-#define __MEDIADECODERGST_H__
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "MediaDecoder.h"
-#include "MediaParser.h"
-#include "AudioDecoder.h"
-#include "VideoDecoder.h"
-
-#include "image.h"
-
-namespace gnash {
-namespace media {
-
-///  Media decoding using Gstreamer
-class MediaDecoderGst: public MediaDecoder {
-public:
-       MediaDecoderGst(boost::shared_ptr<tu_file> stream, MediaBuffer* buffer, 
boost::uint16_t swfVersion, int format);
-       ~MediaDecoderGst();
-
-       /// Seeks to pos
-       boost::uint32_t seek(boost::uint32_t pos);
-
-       std::pair<boost::uint32_t, boost::uint32_t> getWidthAndHeight();
-
-private:
-       /// Sets up the parser
-       bool setupParser();
-
-       /// The decoding thread. Sets up the decoder, and decodes.
-       static void decodeThread(MediaDecoderGst* decoder);
-
-       /// Sets up the decoder and parser
-       bool setupDecoding();
-};
-
-} // namespace media
-} // namespace gnash
-#endif // __MEDIADECODERGST_H__




reply via email to

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