? media.patch
? gui/Info.plist
? gui/massif.20239.aux
? gui/massif.20243.aux
? gui/massif.9095.aux
? libltdl/COPYING.LIB
? libltdl/Makefile.am
? libltdl/Makefile.in
? libltdl/README
? libltdl/acinclude.m4
? libltdl/aclocal.m4
? libltdl/config-h.in
? libltdl/config.guess
? libltdl/config.sub
? libltdl/configure
? libltdl/configure.ac
? libltdl/install-sh
? libltdl/ltdl.c
? libltdl/ltdl.h
? libltdl/ltmain.sh
? libltdl/missing
? libmedia/.deps
? libmedia/breaksound.patch
? testsuite/misc-mtasc.all/bogustests-runner
? testsuite/misc-mtasc.all/sanetests-runner
Index: libbase/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libbase/Makefile.am,v
retrieving revision 1.94
diff -u -r1.94 Makefile.am
--- libbase/Makefile.am	10 Dec 2007 10:54:33 -0000	1.94
+++ libbase/Makefile.am	10 Dec 2007 22:49:29 -0000
@@ -101,7 +101,6 @@
 	zlib_adapter.cpp \
 	URL.cpp \
 	LoadThread.cpp \
-	FLVParser.cpp \
 	GC.cpp \
 	BitsReader.cpp \
 	$(NULL)
@@ -141,7 +140,6 @@
 	zlib_adapter.h \
 	URL.h \
 	LoadThread.h \
-	FLVParser.h \
 	GC.h \
 	BitsReader.h \
 	$(NULL)
Index: libbase/curl_adapter.cpp
===================================================================
RCS file: /sources/gnash/gnash/libbase/curl_adapter.cpp,v
retrieving revision 1.45
diff -u -r1.45 curl_adapter.cpp
--- libbase/curl_adapter.cpp	3 Dec 2007 19:05:01 -0000	1.45
+++ libbase/curl_adapter.cpp	10 Dec 2007 22:49:29 -0000
@@ -339,6 +339,7 @@
 #endif
 
 	gnash::WallClockTimer lastProgress; // timer since last progress
+
 	while (_cached < size && _running)
 	{
 		do
@@ -391,7 +392,7 @@
 
 		// If we'll need to sleep again we'll sleep more next time...
 		// Up to a max (maxSleep)
-		sleepTime = std::min(sleepTime*2, maxSleep);
+		//sleepTime = std::min(sleepTime*2, maxSleep);
 
 	}
 
@@ -662,7 +663,7 @@
 
 	if ( _cached < pos )
 	{
-		fprintf(stderr, "Warning: could not cache anough bytes on seek\n");
+		fprintf(stderr, "Warning: could not cache enough bytes on seek\n");
 		return false; // couldn't cache so many bytes
 	}
 
Index: libmedia/FLVParser.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/FLVParser.cpp,v
retrieving revision 1.4
diff -u -r1.4 FLVParser.cpp
--- libmedia/FLVParser.cpp	4 Dec 2007 11:45:25 -0000	1.4
+++ libmedia/FLVParser.cpp	10 Dec 2007 22:49:29 -0000
@@ -125,7 +125,7 @@
 	return _audioFrames[_nextAudioFrame-1]->timestamp - _audioFrames[_nextAudioFrame-2]->timestamp;
 }
 
-MediaFrame* FLVParser::parseMediaFrame()
+std::auto_ptr<MediaFrame> FLVParser::parseMediaFrame()
 {
 	boost::mutex::scoped_lock lock(_mutex);
 
@@ -161,14 +161,14 @@
 		useAudio = true;
 	} else {
 		// If no frames are next we have reached EOF
-		return NULL;
+		return std::auto_ptr<MediaFrame>(NULL);
 	}
 
 	// Find the next frame in the file a return it
 
 	if (useAudio) {
 
-		MediaFrame* frame = new MediaFrame;
+		std::auto_ptr<MediaFrame> frame(new MediaFrame);
 		frame->dataSize = _audioFrames[_nextAudioFrame]->dataSize;
 		frame->timestamp = _audioFrames[_nextAudioFrame]->timestamp;
 
@@ -183,7 +183,7 @@
 		return frame;
 
 	} else {
-		MediaFrame* frame = new MediaFrame;
+		std::auto_ptr<MediaFrame> frame(new MediaFrame);
 		frame->dataSize = _videoFrames[_nextVideoFrame]->dataSize;
 		frame->timestamp = _videoFrames[_nextVideoFrame]->timestamp;
 
@@ -199,12 +199,12 @@
 	}
 }
 
-MediaFrame* FLVParser::nextAudioFrame()
+std::auto_ptr<MediaFrame> FLVParser::nextAudioFrame()
 {
 	boost::mutex::scoped_lock lock(_mutex);
 
 	// If there are no audio in this FLV return NULL
-	if (!_audio && _lastParsedPosition > 0) return NULL;
+	if (!_audio && _lastParsedPosition > 0) return std::auto_ptr<MediaFrame>(NULL);
 
 	// Make sure that there are parsed enough frames to return the need frame
 	while(_audioFrames.size() <= _nextAudioFrame && !_parsingComplete) {
@@ -212,9 +212,9 @@
 	}
 
 	// If the needed frame can't be parsed (EOF reached) return NULL
-	if (_audioFrames.size() <= _nextAudioFrame || _audioFrames.size() == 0) return NULL;
+	if (_audioFrames.size() <= _nextAudioFrame || _audioFrames.size() == 0) return std::auto_ptr<MediaFrame>(NULL);
 
-	MediaFrame* frame = new MediaFrame;
+	std::auto_ptr<MediaFrame> frame(new MediaFrame);
 	frame->dataSize = _audioFrames[_nextAudioFrame]->dataSize;
 	frame->timestamp = _audioFrames[_nextAudioFrame]->timestamp;
 	frame->tag = 8;
@@ -230,7 +230,7 @@
 
 }
 
-MediaFrame* FLVParser::nextVideoFrame()
+std::auto_ptr<MediaFrame> FLVParser::nextVideoFrame()
 {
 	boost::mutex::scoped_lock lock(_mutex);
 
@@ -238,7 +238,7 @@
 	if (!_video && _lastParsedPosition > 0)
 	{
 		//gnash::log_debug("no video, or lastParserPosition > 0");
-		return NULL;
+		return std::auto_ptr<MediaFrame>(NULL);
 	}
 
 	// Make sure that there are parsed enough frames to return the need frame
@@ -251,11 +251,11 @@
 	if (_videoFrames.size() <= _nextVideoFrame || _videoFrames.size() == 0)
 	{
 		//gnash::log_debug("The needed frame (%d) can't be parsed (EOF reached)", _lastVideoFrame);
-		return NULL;
+		return std::auto_ptr<MediaFrame>(NULL);
 	}
 
 
-	MediaFrame* frame = new MediaFrame;
+	std::auto_ptr<MediaFrame> frame(new MediaFrame);
 	frame->dataSize = _videoFrames[_nextVideoFrame]->dataSize;
 	frame->timestamp = _videoFrames[_nextVideoFrame]->timestamp;
 	frame->tag = 9;
Index: libmedia/FLVParser.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/FLVParser.h,v
retrieving revision 1.5
diff -u -r1.5 FLVParser.h
--- libmedia/FLVParser.h	4 Dec 2007 11:45:25 -0000	1.5
+++ libmedia/FLVParser.h	10 Dec 2007 22:49:29 -0000
@@ -98,7 +98,7 @@
 	//
 	/// Locks the _mutex
 	///
-	MediaFrame* parseMediaFrame();
+	std::auto_ptr<MediaFrame> parseMediaFrame();
 
 	/// \brief
 	/// Returns the next audio frame in the parsed buffer.
@@ -110,7 +110,7 @@
 	///
 	/// Locks the _mutex
 	///
-	MediaFrame* nextAudioFrame();
+	std::auto_ptr<MediaFrame> nextAudioFrame();
 
 	/// \brief
 	/// Returns the next video frame in the parsed buffer.
@@ -122,7 +122,7 @@
 	///
 	/// Locks the _mutex
 	///
-	MediaFrame* nextVideoFrame();
+	std::auto_ptr<MediaFrame> nextVideoFrame();
 
 	/// Return true of parsing is completed
 	//
Index: libmedia/MediaBuffer.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaBuffer.h,v
retrieving revision 1.7
diff -u -r1.7 MediaBuffer.h
--- libmedia/MediaBuffer.h	4 Dec 2007 11:45:25 -0000	1.7
+++ libmedia/MediaBuffer.h	10 Dec 2007 22:49:29 -0000
@@ -98,7 +98,8 @@
 public:
 	MediaBuffer()
 			:
-	_bufferTime(100) // Deafault value is 100 milliseconds
+	_bufferTime(100) // Default value is 100 milliseconds
+	
 	{
 	}
 
@@ -111,7 +112,7 @@
 	//
 	/// @return the size of the audio queue
 	///
-	size_t audioSize() {
+	size_t audioSize() const {
 		boost::mutex::scoped_lock lock(_mutex);
 		return audioQueue.size();
 	}
@@ -120,7 +121,7 @@
 	//
 	/// @return the size of the video queue
 	///
-	size_t videoSize() {
+	size_t videoSize() const {
 		boost::mutex::scoped_lock lock(_mutex);
 		return videoQueue.size();
 	}
@@ -151,7 +152,7 @@
 	///
 	/// @return a pointer to the first element on the audio queue, NULL if queue is empty.
 	///
-	raw_audiodata_t* audioFront() {
+	raw_audiodata_t* audioFront() const {
 		boost::mutex::scoped_lock lock(_mutex);
 		if (audioQueue.empty()) return NULL;
 		return audioQueue.front();
@@ -163,7 +164,7 @@
 	///
 	/// @return a pointer to the first element on the video queue, NULL if queue is empty.
 	///
-	raw_videodata_t* videoFront() {
+	raw_videodata_t* videoFront() const {
 		boost::mutex::scoped_lock lock(_mutex);
 		if (videoQueue.empty()) return NULL;
 		return videoQueue.front();
@@ -269,7 +270,7 @@
 
 
 	/// Mutex used for locking
-	boost::mutex _mutex;
+	mutable boost::mutex _mutex;
 
 	/// The queues of audio and video data.
 	std::queue <raw_audiodata_t*> audioQueue;
Index: libmedia/MediaDecoder.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaDecoder.cpp,v
retrieving revision 1.3
diff -u -r1.3 MediaDecoder.cpp
--- libmedia/MediaDecoder.cpp	4 Dec 2007 11:45:26 -0000	1.3
+++ libmedia/MediaDecoder.cpp	10 Dec 2007 22:49:29 -0000
@@ -98,11 +98,11 @@
 
 bool MediaDecoder::decodeAndBufferFrame()
 {
-	MediaFrame* frame = _parser->parseMediaFrame();
+	std::auto_ptr<MediaFrame> frame = _parser->parseMediaFrame();
 	boost::uint32_t parserPosition = _parser->getLastParsedPos();
 	if (parserPosition > _lastConfirmedPosition) _lastConfirmedPosition = parserPosition;
 
-	if (frame == NULL) {
+	if (frame.get() == NULL) {
 		if (_lastConfirmedPosition+1 >= _streamSize)
 		{
 #ifdef GNASH_DEBUG_THREADS
@@ -117,9 +117,12 @@
 		return false;
 	}
 
-	if (frame->tag == 9) {
+	if (frame->tag == VIDEO_TAG)
+	{
 		decodeVideo(frame);
-	} else {
+	}
+	else
+	{
 		decodeAudio(frame);
 	}
 	return true;
@@ -127,15 +130,17 @@
 }
 
 
-void MediaDecoder::decodeAudio(MediaFrame* packet)
+void MediaDecoder::decodeAudio(std::auto_ptr<MediaFrame> packet)
 {
 	// We don't handle audio
 	if (!_audioDecoder.get()) return;
 
 	boost::uint32_t datasize;
 	boost::uint32_t bufsize;
+	
+	log_debug("datasize: %d", datasize);
 
-	uint8_t* ptr = _audioDecoder->decode(packet->data, packet->dataSize, bufsize, datasize, false);
+	boost::uint8_t* ptr = _audioDecoder->decode(packet->data, packet->dataSize, bufsize, datasize, false);
 
 	if (bufsize > 0 && ptr != NULL)
 	{
@@ -146,19 +151,22 @@
 		raw->m_size = bufsize;
 		raw->m_pts = packet->timestamp;
 		_buffer->pushAudio(raw);
+		packet.reset();
 		return;
 	}
 	log_debug(_("Problems decoding audio frame."));
 
 }
 
-void MediaDecoder::decodeVideo(MediaFrame* packet)
+void MediaDecoder::decodeVideo(std::auto_ptr<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);
 
+	log_debug("video datasize: %d", packet->dataSize);
+
 	if (img.get() != NULL)
 	{
 	  	raw_videodata_t* raw = new raw_videodata_t();
@@ -166,6 +174,8 @@
 		raw->image = img;
 		raw->timestamp = packet->timestamp;
 		_buffer->pushVideo(raw);
+		log_debug("pushed");
+		packet.reset();
 		return;
 	}
 	log_debug(_("Problems decoding video frame."));
Index: libmedia/MediaDecoder.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaDecoder.h,v
retrieving revision 1.6
diff -u -r1.6 MediaDecoder.h
--- libmedia/MediaDecoder.h	4 Dec 2007 11:45:26 -0000	1.6
+++ libmedia/MediaDecoder.h	10 Dec 2007 22:49:29 -0000
@@ -152,26 +152,33 @@
 	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()
+	boost::uint32_t getBytesTotal () const
 	{
 		return _streamSize;
 	}
 
 	/// Returns the amount of bytes of the current file that has been loaded.
-	boost::uint32_t getBytesLoaded() {
+
+	boost::uint32_t getBytesLoaded () const
+	{
 		return _lastConfirmedPosition;
 	}
 
 	/// Returns a vector with the waiting onStatus events (AS2)
 	std::vector<StatusCode> getOnStatusEvents();
 
-	/// Returns whether we got audio
-	bool gotAudio() {
+	/// Returns whether we set up an audio decoder.
+	/// If false, there is either no audio stream or we
+	/// can't decode it.
+	bool gotAudio() const
+	{
 		return _audio;
 	}
 
-	/// Returns whether we got video
-	bool gotVideo() {
+	/// Returns whether we set up a video decoder
+	/// If false, there is either no video stream or we
+	/// can't decode it.
+	bool gotVideo() const {
 		return _video;
 	}
 
@@ -192,10 +199,10 @@
 	bool decodeAndBufferFrame();
 
 	// Used to decode a video frame and push it on the videoqueue
-	void decodeVideo(MediaFrame* packet);
+	void decodeVideo(std::auto_ptr<MediaFrame> packet);
 
 	// Used to decode a audio frame and push it on the audioqueue
-	void decodeAudio(MediaFrame* packet);
+	void decodeAudio(std::auto_ptr<MediaFrame> packet);
 
 	/// Push an event to the onStatus event queue (AS2)
 	void pushOnStatus(StatusCode code) {
@@ -246,10 +253,10 @@
 	/// The position in the inputfile, only used when not playing a FLV
 	long _inputPos;
 
-	/// Do we have audio ?
+	/// Do we have an audio decoder?
 	bool _audio;
 
-	/// Do we have video ?
+	/// Do we have a video decoder?
 	bool _video;
 
 	/// Used to wait when there is nothing to do
Index: libmedia/MediaParser.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaParser.h,v
retrieving revision 1.11
diff -u -r1.11 MediaParser.h
--- libmedia/MediaParser.h	4 Dec 2007 11:45:26 -0000	1.11
+++ libmedia/MediaParser.h	10 Dec 2007 22:49:29 -0000
@@ -26,6 +26,7 @@
 #endif
 
 #include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
 #include "tu_file.h"
 
 #ifdef USE_FFMPEG
@@ -187,10 +188,23 @@
 class MediaFrame
 {
 public:
+	MediaFrame():
+	dataSize(0),
+	data(NULL),
+	timestamp(0),
+	tag(0)
+	{
+	}
+	
+	~MediaFrame()
+	{
+		if (data) delete [] data;
+	} 
+
 	boost::uint32_t dataSize;
-	uint8_t* data;
+	boost::uint8_t* data;
 	boost::uint64_t timestamp;
-	uint8_t tag;
+	boost::uint8_t tag;
 };
 
 /// \brief
@@ -216,7 +230,7 @@
 	/// 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; }
+	virtual std::auto_ptr<MediaFrame> parseMediaFrame() { return std::auto_ptr<MediaFrame>(NULL); }
 
 	/// Is the input MP3?
 	//
Index: libmedia/gst/AudioDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/AudioDecoderGst.cpp,v
retrieving revision 1.2
diff -u -r1.2 AudioDecoderGst.cpp
--- libmedia/gst/AudioDecoderGst.cpp	4 Dec 2007 11:45:26 -0000	1.2
+++ libmedia/gst/AudioDecoderGst.cpp	10 Dec 2007 22:49:29 -0000
@@ -49,9 +49,9 @@
 AudioDecoderGst::~AudioDecoderGst()
 {
 
-	if (_pipeline) {
+	if (_pipeline)
+	{
 		_stop = true;
-		delete input_lock;
 		gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_NULL);
 		gst_object_unref (GST_OBJECT (_pipeline));
 	}
@@ -77,7 +77,8 @@
 	g_signal_connect (_input, "handoff", G_CALLBACK (AudioDecoderGst::callback_handoff), this);
 
 	_decoder = gst_element_factory_make ("mad", NULL);
-	if (_decoder == NULL) {
+	if (_decoder == NULL)
+	{
 		_decoder = gst_element_factory_make ("flump3dec", NULL);
 		if (_decoder != NULL && !gst_default_registry_check_feature_version("flump3dec", 0, 10, 4))
 		{
@@ -91,7 +92,8 @@
 		}
 	}
 	// Check if the element was correctly created
-	if (!_decoder) {
+	if (!_decoder)
+	{
 		log_error(_("A gstreamer mp3-decoder element could not be created.  You probably need to install a mp3-decoder plugin like gstreamer0.10-mad or gstreamer0.10-fluendo-mp3."));
 		return false;
 	}
@@ -132,12 +134,6 @@
 	// link the elements
 	gst_element_link_many(_input, _inputcaps, _decoder, _resampler, _converter, _outputcaps, _output, NULL);
 
-	// This make callback_handoff wait for data
-	input_lock = new boost::mutex::scoped_lock(input_mutex);
-
-	// This make decodeFrame wait for data
-	output_lock = new boost::mutex::scoped_lock(output_mutex);
-
 	// Start "playing"
 	gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_PLAYING);
 
@@ -145,7 +141,9 @@
 
 }
 
-uint8_t* AudioDecoderGst::decode(uint8_t* input, boost::uint32_t inputSize, boost::uint32_t& outputSize, boost::uint32_t& decodedData, bool /*parse*/)
+uint8_t* AudioDecoderGst::decode(uint8_t* input,
+			boost::uint32_t inputSize, boost::uint32_t& outputSize,
+			boost::uint32_t& decodedData, bool /*parse*/)
 {
 	// If there is nothing to decode in the new data we return NULL
 	if (input == NULL || inputSize == 0 || !_decoder)
@@ -158,10 +156,7 @@
 	_undecodedData = input;
 	_undecodedDataSize = inputSize;
 
-	delete input_lock;
 printf("waiting for decoded data\n");
-	output_lock = new boost::mutex::scoped_lock(output_mutex);
-printf("decoded data arrived\n");
 
 	decodedData = inputSize;
 	outputSize = _decodedDataSize;
@@ -174,9 +169,7 @@
 {
 	AudioDecoderGst* decoder = static_cast<AudioDecoderGst*>(user_data);
 
-	if (decoder->_stop) return;
-
-	decoder->input_lock = new boost::mutex::scoped_lock(decoder->input_mutex);
+	if (decoder->_stop || decoder->_undecodedDataSize == 0 || decoder->_undecodedData == NULL) return;
 
 	GST_BUFFER_SIZE(buffer) = decoder->_undecodedDataSize;
 
@@ -189,14 +182,12 @@
 {
 	AudioDecoderGst* decoder = static_cast<AudioDecoderGst*>(user_data);
 
-	if (decoder->_stop) return;
-
+	if (decoder->_stop || decoder->_undecodedDataSize == 0 || decoder->_undecodedData == NULL) return;
+	
 	decoder->_decodedDataSize = GST_BUFFER_SIZE(buffer);
 
 	decoder->_decodedData = GST_BUFFER_DATA(buffer);
 
-	delete decoder->output_lock;
-
 }
 
 } // end of media namespace
Index: libmedia/gst/AudioDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/AudioDecoderGst.h,v
retrieving revision 1.2
diff -u -r1.2 AudioDecoderGst.h
--- libmedia/gst/AudioDecoderGst.h	4 Dec 2007 11:45:26 -0000	1.2
+++ libmedia/gst/AudioDecoderGst.h	10 Dec 2007 22:49:30 -0000
@@ -66,13 +66,7 @@
 	GstElement* _resampler;
 	GstElement* _converter;
 
-	/// mutexes and locks used to handle input and output.
-	boost::mutex input_mutex;
-	boost::mutex output_mutex;
-	boost::mutex::scoped_lock* input_lock;
-	boost::mutex::scoped_lock* output_lock;
-
-	/// Info from the video tag header. Might be usefull...
+	/// Info from the video tag header. Might be useful...
 	bool _stereo;
 	boost::uint32_t _sampleRate;
 	audioCodecType _format;
Index: libmedia/gst/MediaDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/MediaDecoderGst.cpp,v
retrieving revision 1.2
diff -u -r1.2 MediaDecoderGst.cpp
--- libmedia/gst/MediaDecoderGst.cpp	4 Dec 2007 11:45:26 -0000	1.2
+++ libmedia/gst/MediaDecoderGst.cpp	10 Dec 2007 22:49:30 -0000
@@ -82,37 +82,56 @@
 bool MediaDecoderGst::setupDecoding()
 {
 	std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
-	if (vInfo.get() != NULL) {
+	if (vInfo.get() != NULL)
+	{
 
 		_videoDecoder.reset(new VideoDecoderGst());
 
-		if (_videoDecoder.get() != NULL) {
-			if (!_videoDecoder->setup(vInfo.get())) {
+		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 {
+			else
+			{
+				// Video decoder setup true
+				_video = true;
+			}
+		}
+		else
+		{
 			log_error("No video decoder could be created, since no decoder is enabled.");
 		}
 	}
 
 	std::auto_ptr<AudioInfo> aInfo = _parser->getAudioInfo();
-	if (get_sound_handler() && aInfo.get() != NULL) {
+	if (get_sound_handler() && aInfo.get() != NULL)
+	{
 
-		if (_parser->isAudioNellymoser()) {
+		if (_parser->isAudioNellymoser())
+		{
 			_audioDecoder.reset(new AudioDecoderNellymoser());
 		}
 
 		if (_audioDecoder.get() == NULL) _audioDecoder.reset(new AudioDecoderGst());
 
-		if (_audioDecoder.get() != NULL) {
-			if (!_audioDecoder->setup(aInfo.get())) {
+		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 {
+			else
+			{
+				// Audio decoder setup successful
+				_audio = true;
+			}
+		}
+		else
+		{
 			log_error("No audio decoder could be created, since no decoder is enabled.");
 		}
 	}
@@ -143,8 +162,10 @@
 
 	// Setup the decoder and parser
 
-	if (decoder->setupParser()) {
-		if (!decoder->setupDecoding()) {
+	if (decoder->setupParser())
+	{
+		if (!decoder->setupDecoding())
+		{
 			decoder->pushOnStatus(streamNotFound);
 			log_error("Setup of media decoder failed");
 			return;
@@ -152,7 +173,9 @@
 
 	// If the parser setup failed, it is perhaps because it is not a FLV file,
 	// so we set up an gstreamer pipeline instead.
-	} else {
+	}
+	else
+	{
 /*		if (!decoder->setupGstPipeline()) {
 			decoder->pushOnStatus(streamNotFound);*/
 			log_error("Setup of media parser failed");
@@ -170,7 +193,8 @@
 std::pair<boost::uint32_t, boost::uint32_t>
 MediaDecoderGst::getWidthAndHeight()
 {
-	if (_parser.get()) {
+	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);
 	}
Index: libmedia/gst/VideoDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v
retrieving revision 1.7
diff -u -r1.7 VideoDecoderGst.cpp
--- libmedia/gst/VideoDecoderGst.cpp	4 Dec 2007 11:45:26 -0000	1.7
+++ libmedia/gst/VideoDecoderGst.cpp	10 Dec 2007 22:49:30 -0000
@@ -38,6 +38,7 @@
 	decoder(NULL),
 	colorspace(NULL),
 	decodedFrame(NULL),
+	frameNeeded(true),
 	stop(false)
 
 {
@@ -46,9 +47,9 @@
 VideoDecoderGst::~VideoDecoderGst()
 {
 
-	if (pipeline) {
+	if (pipeline)
+	{
 		stop = true;
-		delete input_lock;
 		gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
 		gst_object_unref (GST_OBJECT (pipeline));
 	}
@@ -62,6 +63,7 @@
 bool
 VideoDecoderGst::setup(int widthi, int heighti, int deblockingi, bool smoothingi, videoCodecType formati, int outputFormati)
 {
+
 	// Save video attributes
 	width = widthi;
 	height = heighti;
@@ -84,6 +86,7 @@
 	// setup fake source
 	input = gst_element_factory_make ("fakesrc", NULL);
 	g_object_set (G_OBJECT (input),	"sizetype", 3, /*"can-activate-pull", FALSE,*/ "signal-handoffs", TRUE, NULL);
+	
 	// Setup the callback
 	g_signal_connect (input, "handoff", G_CALLBACK (VideoDecoderGst::callback_handoff), this);
 
@@ -131,9 +134,9 @@
 	assert(caps); // ok, this is a silly assertion *now*, but as long as 
 	              // the code is implemented with such long function bodies
 	              // a day will come in which someone will change something
-	              // a few screefulls above and the assertion would make
+	              // a few screenfuls above and the assertion would make
 	              // sense (maybe boost compile-time assertions could help
-	              // in this reguard).
+	              // in this regard).
 
 	g_object_set (G_OBJECT (videocaps), "caps", caps, NULL);
 	gst_caps_unref (caps);
@@ -146,40 +149,46 @@
 	// setup the video colorspaceconverter converter
 	colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
 
+	//log_debug ("Format: %d", format);
+
 	// Find the decoder, use auto plugin loader? use plugin-downloader?
-	if (format == VIDEO_CODEC_H263) {
+	if (format == VIDEO_CODEC_H263)
+	{
 		decoder = gst_element_factory_make ("ffdec_flv", NULL);
-	} else if (format == VIDEO_CODEC_VP6) {
+		//log_debug("flv");
+	}
+	else if (format == VIDEO_CODEC_VP6)
+	{
 		decoder = gst_element_factory_make ("ffdec_vp6f", NULL);
-	} else if (format == VIDEO_CODEC_SCREENVIDEO) {
+	}
+	else if (format == VIDEO_CODEC_SCREENVIDEO)
+	{
 		decoder = gst_element_factory_make ("ffdec_flashsv", NULL);
-	} else {
+	}
+	else
+	{
 		gnash::log_error("Unsupported embedded video format");
 		return false;
 	}
 
-	if (!pipeline || !input || !inputcaps || !videocaps || !output || !colorspace) {
-		gnash::log_error("Creation of Gstreamer baisc elements failed, is your Gstreamer installation complete?");
+	if (!pipeline || !input || !inputcaps || !videocaps || !output || !colorspace)
+	{
+		gnash::log_error("Creation of Gstreamer basic elements failed, is your Gstreamer installation complete?");
 		return false;
 	}
 
-	if (!decoder) {
+	if (!decoder)
+	{
 		gnash::log_error("Creation of decoder element failed, do you have gstreamer-0.10-ffmpeg installed?");
 		return false;
 	}
 
-	// Put the elemets in the pipeline and link them
+	// Put the elements in the pipeline
 	gst_bin_add_many (GST_BIN (pipeline), input, inputcaps, decoder, colorspace, videocaps, output, NULL);
 
 	// link the elements
 	gst_element_link_many(input, inputcaps, decoder, colorspace, videocaps, output, NULL);
 
-	// This make callback_handoff wait for data
-	input_lock = new boost::mutex::scoped_lock(input_mutex);
-
-	// This make decodeFrame wait for data
-	output_lock = new boost::mutex::scoped_lock(output_mutex);
-
 	// Determine required buffer size and allocate buffer
 	decodedFrame.reset(new image::rgb(width, height));
 
@@ -195,10 +204,12 @@
 VideoDecoderGst::decodeToImage(uint8_t* data, boost::uint32_t size)
 {
 
+	//log_debug("decodeToImage");
+	
 	std::auto_ptr<image::image_base> ret_image(new image::rgb(width, height));
 
 	// If there is nothing to decode in the new frame
-	// we just return the lastest.
+	// we just return the latest.
 	if (data == NULL || size == 0 || !decoder)
 	{
 		// If we never decoded any frame return a NULL
@@ -214,10 +225,6 @@
 
 	frame = data;
 	frameSize = size;
-//printf("datasize: %d\n", size);
-	delete input_lock;
-
-	output_lock = new boost::mutex::scoped_lock(output_mutex);
 
 	// If we never decoded any frame return a NULL
 	// auto pointer ..
@@ -227,6 +234,7 @@
 	}
 
 	// return decodedFrame->clone() ?
+
 	ret_image->update(*decodedFrame);
 	return ret_image;
 }
@@ -237,29 +245,25 @@
 {
 	VideoDecoderGst* decoder = static_cast<VideoDecoderGst*>(user_data);
 
-	if (decoder->stop) return;
-
-	decoder->input_lock = new boost::mutex::scoped_lock(decoder->input_mutex);
-
-	GST_BUFFER_SIZE(buffer) = decoder->frameSize;
+	if (decoder->stop || decoder->frameSize == 0 || decoder->frame == NULL) return;
+	
+	gst_buffer_set_data(buffer, decoder->frame, decoder->frameSize);
 
-	GST_BUFFER_DATA(buffer) = decoder->frame;
 }
 
 // The callback function which passes the decoded video frame
 void
 VideoDecoderGst::callback_output (GstElement * /*c*/, GstBuffer *buffer, GstPad* /*pad*/, gpointer user_data)
 {
+
 	VideoDecoderGst* decoder = static_cast<VideoDecoderGst*>(user_data);
-//printf("datadecoded\n");
-	if (decoder->stop) return;
 
-	if (decoder->decodedFrame.get())
-	{
-		decoder->decodedFrame->update(GST_BUFFER_DATA(buffer));
-	}
+	if (decoder->stop || decoder->frameSize == 0|| decoder->frame == NULL) return;
 
-	delete decoder->output_lock;
+	decoder->decodedFrame->update(GST_BUFFER_DATA(buffer));
+	
+	decoder->frameSize = 0;
+	decoder->frame = NULL;
 
 }
 
Index: libmedia/gst/VideoDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v
retrieving revision 1.9
diff -u -r1.9 VideoDecoderGst.h
--- libmedia/gst/VideoDecoderGst.h	4 Dec 2007 11:45:26 -0000	1.9
+++ libmedia/gst/VideoDecoderGst.h	10 Dec 2007 22:49:30 -0000
@@ -75,13 +75,7 @@
 	GstElement *decoder;
 	GstElement *colorspace;
 
-	/// mutexes and locks used to handle input and output.
-	boost::mutex input_mutex;
-	boost::mutex output_mutex;
-	boost::mutex::scoped_lock* input_lock;
-	boost::mutex::scoped_lock* output_lock;
-
-	/// Info from the video tag header. Might be usefull...
+	/// Info from the video tag header. Might be useful...
 	boost::uint32_t width;
 	boost::uint32_t height;
 	int deblocking;
@@ -91,10 +85,14 @@
 
 	/// Input data and size for current frame
 	uint8_t* frame;
+		
 	int frameSize;
 	
 	/// Last decoded frame
 	std::auto_ptr<image::image_base> decodedFrame;
+	
+	// New frame ready
+	bool frameNeeded;
 
 	/// If we should stop this will be true
 	volatile bool stop;
Index: libmedia/sdl/AudioDecoderFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/AudioDecoderFfmpeg.cpp,v
retrieving revision 1.10
diff -u -r1.10 AudioDecoderFfmpeg.cpp
--- libmedia/sdl/AudioDecoderFfmpeg.cpp	4 Dec 2007 11:45:26 -0000	1.10
+++ libmedia/sdl/AudioDecoderFfmpeg.cpp	10 Dec 2007 22:49:30 -0000
@@ -186,14 +186,13 @@
 	decodedBytes = 0;
 
 	if (parse) {
-	
+
 		if (!_parser)
 		{	
 			log_error(_("libavcodec can't parse the current audio format"));
 			return NULL;
 		}
-	
-	
+
 		bufsize = 0;
 		while (bufsize == 0 && decodedBytes < inputSize) {
 			uint8_t* frame;
Index: libmedia/sdl/MediaParserFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/MediaParserFfmpeg.cpp,v
retrieving revision 1.9
diff -u -r1.9 MediaParserFfmpeg.cpp
--- libmedia/sdl/MediaParserFfmpeg.cpp	4 Dec 2007 11:45:27 -0000	1.9
+++ libmedia/sdl/MediaParserFfmpeg.cpp	10 Dec 2007 22:49:30 -0000
@@ -45,7 +45,7 @@
 
 MediaParserFfmpeg::~MediaParserFfmpeg()
 {
-
+	if (_formatCtx) av_free(_formatCtx);
 }
 
 
@@ -97,13 +97,17 @@
 
 	// Setup the filereader/seeker mechanism. 7th argument (NULL) is the writer function,
 	// which isn't needed.
-	init_put_byte(&_byteIOCxt, new uint8_t[500000], 500000, 0, this, MediaParserFfmpeg::readPacket, NULL, MediaParserFfmpeg::seekMedia);
+
+	_buf.reset(new uint8_t[500000]);
+
+	init_put_byte(&_byteIOCxt, _buf.get(), 500000, 0, this, MediaParserFfmpeg::readPacket, NULL, MediaParserFfmpeg::seekMedia);
 	_byteIOCxt.is_streamed = 1;
 
 	_formatCtx = av_alloc_format_context();
 
 	// Open the stream. the 4th argument is the filename, which we ignore.
-	if(av_open_input_stream(&_formatCtx, &_byteIOCxt, "", inputFmt, NULL) < 0){
+	if (av_open_input_stream(&_formatCtx, &_byteIOCxt, "", inputFmt, NULL) < 0)
+	{
 		log_error(_("Couldn't open stream for decoding"));
 		//pushOnStatus(streamNotFound);
 		return false;
@@ -199,17 +203,18 @@
 		}*/
 
 	}
+	
 	return true;
 }	
 
-MediaFrame* MediaParserFfmpeg::parseMediaFrame()
+std::auto_ptr<MediaFrame> MediaParserFfmpeg::parseMediaFrame()
 {
 	AVPacket packet;
 	int rc = av_read_frame(_formatCtx, &packet);
 	
 	if (rc >= 0)
 	{
-		MediaFrame* ret = new MediaFrame;
+		std::auto_ptr<MediaFrame> ret(new MediaFrame);
 		ret->dataSize = packet.size;
 		
 		// "The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE
@@ -276,13 +281,15 @@
 			_lastVideoTimestamp += frame_delay;
 
 		} else {
-			delete ret;
-			return NULL;
+			//delete ret;
+			av_free_packet(&packet);
+			return std::auto_ptr<MediaFrame>(NULL);
 		}
 		av_free_packet(&packet);
 		return ret;
 	} else {
-		return NULL;
+
+		return std::auto_ptr<MediaFrame>(NULL);
 	}
 
 }
@@ -308,7 +315,7 @@
 	double newtime = 0;
 	while (newtime == 0) {
 		if ( av_read_frame(_formatCtx, &Packet) < 0) {
-			av_seek_frame(_formatCtx, -1, 0,AVSEEK_FLAG_BACKWARD);
+			av_seek_frame(_formatCtx, -1, 0, AVSEEK_FLAG_BACKWARD);
 			av_free_packet(&Packet);
 			return 0;
 		}
@@ -333,11 +340,11 @@
 	if (!_videoCodecCtx || !_videoStream) return std::auto_ptr<VideoInfo>(NULL);
 
 	std::auto_ptr<VideoInfo> ret (new VideoInfo(_videoCodecCtx->codec_id,
-												_videoCodecCtx->width, 
-												_videoCodecCtx->height,
-												static_cast<boost::int16_t>(as_double(_videoStream->r_frame_rate)), // Is this correct? What do we use the framerate for?
-												_videoStream->duration,
-												FFMPEG));
+						_videoCodecCtx->width, 
+						_videoCodecCtx->height,
+						static_cast<int16_t>(as_double(_videoStream->r_frame_rate)), // Is this correct? What do we use the framerate for?
+						_videoStream->duration,
+						FFMPEG));
 	ret->videoCodecCtx = _videoCodecCtx;
 	return ret;
 }
@@ -349,12 +356,15 @@
 
 	if (_audioCodecCtx->codec_id == CODEC_ID_MP3) _isAudioMp3 = true;
 
-	return std::auto_ptr<AudioInfo>(new AudioInfo(_audioCodecCtx->codec_id,
-												_audioCodecCtx->sample_rate,
-												_audioCodecCtx->sample_fmt + 1, // see definition of SampleFormat in avcodec.h
-												_audioCodecCtx->channels > 1 ? true : false,
-												_audioStream->duration,
-												FFMPEG));
+	std::auto_ptr<AudioInfo> ret (new AudioInfo(_audioCodecCtx->codec_id,
+						_audioCodecCtx->sample_rate,
+						_audioCodecCtx->sample_fmt + 1, // see definition of SampleFormat in avcodec.h
+						_audioCodecCtx->channels > 1 ? true : false,
+						_audioStream->duration,
+						FFMPEG));
+	ret->audioCodecCtx = _audioCodecCtx;
+	return ret;						
+						
 }
 
 
Index: libmedia/sdl/MediaParserFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/MediaParserFfmpeg.h,v
retrieving revision 1.7
diff -u -r1.7 MediaParserFfmpeg.h
--- libmedia/sdl/MediaParserFfmpeg.h	4 Dec 2007 11:45:27 -0000	1.7
+++ libmedia/sdl/MediaParserFfmpeg.h	10 Dec 2007 22:49:30 -0000
@@ -31,6 +31,7 @@
 
 #include "MediaParser.h"
 #include "MediaBuffer.h"
+#include <boost/shared_array.hpp>
 
 extern "C" {
 #include <ffmpeg/avformat.h>
@@ -56,7 +57,7 @@
 	bool setupParser();
 
 	/// Used to parse the next media frame in the stream and return it
-	MediaFrame* parseMediaFrame();
+	std::auto_ptr<MediaFrame> parseMediaFrame();
 
 	/// Try to seek to the given millisecond. Returns the millisecond where the
 	/// seek got to.
@@ -103,6 +104,9 @@
 	// the format (mp3, avi, etc.)
 	AVFormatContext *_formatCtx;
 
+	// Buffer for file reading
+	boost::shared_array<uint8_t> _buf;
+
 	// A ffmpeg thingy
 	ByteIOContext _byteIOCxt;
 
Index: libmedia/sdl/VideoDecoderFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/VideoDecoderFfmpeg.cpp,v
retrieving revision 1.11
diff -u -r1.11 VideoDecoderFfmpeg.cpp
--- libmedia/sdl/VideoDecoderFfmpeg.cpp	6 Dec 2007 12:50:24 -0000	1.11
+++ libmedia/sdl/VideoDecoderFfmpeg.cpp	10 Dec 2007 22:49:30 -0000
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-// $Id: VideoDecoderFfmpeg.cpp,v 1.11 2007/12/06 12:50:24 bwy Exp $
+// $Id: VideoDecoderFfmpeg.cpp,v 1.10 2007/12/04 11:45:27 strk Exp $
 
 #include "VideoDecoderFfmpeg.h"
 
@@ -74,8 +74,7 @@
 			codec_id = CODEC_ID_FLASHSV;
 			break;
 		default:
-			log_error(_("Unsupported video codec %d"),
-						static_cast<int>(format));
+			log_error(_("Unsupported video codec %d"), static_cast<int>(format));
 			return false;
 	}
 
@@ -128,16 +127,14 @@
 				codec_id = CODEC_ID_FLASHSV;
 				break;
 			default:
-				log_error(_("Unsupported video codec %d"),
-						static_cast<int>(info->codec));
+				log_error(_("Unsupported video codec %d"), static_cast<int>(info->codec));
 				return false;
 		}
 		_videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id));
 	} else if (info->type == FFMPEG) {
 		_videoCodec = avcodec_find_decoder(static_cast<CodecID>(info->codec));
 	} else {
-		//log_error("Video codecType unknown: %d, %d, %d",
-		//				info->type, FLASH, FFMPEG);
+		//log_error("Video codecType unknown: %d, %d, %d", info->type, FLASH, FFMPEG);
 		return false;
 	}
 
@@ -186,21 +183,17 @@
 	AVPicture picture;
 
 	avpicture_fill(&picture, buffer, PIX_FMT_RGB24, width, height);
-
 #ifndef HAVE_SWSCALE_H
-	img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) srcFrame,
-			srcCtx->pix_fmt, width, height);
+	img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) srcFrame, srcCtx->pix_fmt,
+		    width, height);
 #else
 	static SwsContext* context = NULL;
 
-	if (!context)
-	{
+	if (!context) {
 		context = sws_getContext(width, height, srcCtx->pix_fmt,
 					 width, height, PIX_FMT_RGB24,
 					 SWS_FAST_BILINEAR, NULL, NULL, NULL);
-		
-		if (!context)
-		{
+		if (!context) {
 			delete [] buffer;
 			return NULL;
 		}
@@ -208,8 +201,7 @@
 
 	int rv = sws_scale(context, srcFrame->data, srcFrame->linesize, 0, 
 			   width, picture.data, picture.linesize);
-	if (rv == -1)
-	{
+	if (rv == -1) {
 		delete [] buffer;
 		return NULL;
 	}
@@ -222,9 +214,7 @@
 	return buffer;
 }
 
-uint8_t* VideoDecoderFfmpeg::decode(uint8_t* input,
-				boost::uint32_t inputSize,
-				boost::uint32_t& outputSize)
+uint8_t* VideoDecoderFfmpeg::decode(uint8_t* input, boost::uint32_t inputSize, boost::uint32_t& outputSize)
 {
 	// Allocate a frame to store the decoded frame in
 	AVFrame* frame = avcodec_alloc_frame();
@@ -235,34 +225,28 @@
 	}
 
 	int got = 0;
-	
 	avcodec_decode_video(_videoCodecCtx, frame, &got, input, inputSize);
-	
-	if (got)
-	{
+	if (got) {
 		boost::scoped_array<uint8_t> buffer;
 		
-		// Set to the next multiple of four. Some videos have
+		// Set to the next multiple of four. Why? Some videos have
 		// padding bytes, so that the source width is more than three times
-		// the video width. A likely explanation (supported by
-		// tests) is that it is always padded out to a multiple of 4.
-		// Have found no documenation on this.
-		unsigned int srcwidth = (_videoCodecCtx->width * 3 + 3) &~ 3; 
+		// the width of the video. A likely explanation (supported by
+		// some tests) is that it is always padded out to a multiple of 4.
+		// Have found no documentation on this.
+		unsigned int srcwidth = (_videoCodecCtx->width * 3 + 3) &~3; 
 
-		uint8_t* decodedData = new uint8_t[srcwidth * _videoCodecCtx->height];
+		uint8_t* decodedData = new uint8_t[srcwidth * _videoCodecCtx->height * 3];
 		buffer.reset(convertRGB24(_videoCodecCtx, frame));
 
 		// Copy the data to the buffer in the correct RGB format
 		uint8_t* srcptr = frame->data[0];
-		uint8_t* srcend = frame->data[0]
-					+ frame->linesize[0]
-					* _videoCodecCtx->height;
+		uint8_t* srcend = frame->data[0] + frame->linesize[0] * _videoCodecCtx->height;
 		uint8_t* dstptr = decodedData;
-
+		
 		outputSize = 0;
 
-		while (srcptr < srcend)
-		{
+		while (srcptr < srcend) {
 			memcpy(dstptr, srcptr, srcwidth);
 			srcptr += frame->linesize[0];
 			dstptr += srcwidth;
@@ -336,9 +320,7 @@
 			}
 
 		}*/
-	}
-	else
-	{
+	} else {
 		log_error("Decoding of a video frame failed");
 		av_free(frame);
 		return NULL;
@@ -351,15 +333,11 @@
 	boost::uint32_t outputSize = 0;
 	uint8_t* decodedData = decode(input, inputSize, outputSize);
 
-	if (!decodedData || outputSize == 0)
-	{
+	if (!decodedData || outputSize == 0) {
 		return std::auto_ptr<image::image_base>(NULL);
 	}
 
-	std::auto_ptr<image::image_base> ret(new image::rgb(
-						_videoCodecCtx->width,
-						_videoCodecCtx->height
-						));
+	std::auto_ptr<image::image_base> ret(new image::rgb(_videoCodecCtx->width, _videoCodecCtx->height));
 	ret->update(decodedData);
 	delete [] decodedData;
 	return ret;
Index: libmedia/sdl/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/sound_handler_sdl.cpp,v
retrieving revision 1.8
diff -u -r1.8 sound_handler_sdl.cpp
--- libmedia/sdl/sound_handler_sdl.cpp	4 Dec 2007 11:45:27 -0000	1.8
+++ libmedia/sdl/sound_handler_sdl.cpp	10 Dec 2007 22:49:30 -0000
@@ -99,14 +99,14 @@
 		return -1;
 #endif
 #endif
-		sounddata->append(reinterpret_cast<uint8_t*>(data), data_bytes);
+		sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
 		break;
 
 	case AUDIO_CODEC_RAW:
 	case AUDIO_CODEC_ADPCM:
 	case AUDIO_CODEC_UNCOMPRESSED:
 	case AUDIO_CODEC_NELLYMOSER:
-		sounddata->append(reinterpret_cast<uint8_t*>(data), data_bytes);
+		sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
 		break;
 
 	default:
@@ -144,7 +144,7 @@
 
 	// Handling of the sound data
 	size_t start_size = sounddata->size();
-	sounddata->append(reinterpret_cast<uint8_t*>(data), data_bytes);
+	sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
 
 	return start_size;
 }
@@ -500,7 +500,7 @@
 }
 
 // Pointer handling and checking functions
-uint8_t*
+boost::uint8_t*
 active_sound::get_raw_data_ptr(unsigned long int pos)
 {
 	if ( _decodedData.get() )
@@ -510,7 +510,7 @@
 	else return 0;
 }
 
-uint8_t*
+boost::uint8_t*
 active_sound::get_data_ptr(unsigned long int pos)
 {
 	assert(_undecodedData);
@@ -651,7 +651,7 @@
 	// call NetStream or Sound audio callbacks
 	if ( !handler->m_aux_streamer.empty() )
 	{
-		boost::scoped_array<uint8_t> buf ( new uint8_t[buffer_length] );
+		boost::scoped_array<boost::uint8_t> buf ( new boost::uint8_t[buffer_length] );
 
 		// Loop through the attached sounds
 		CallbacksMap::iterator it = handler->m_aux_streamer.begin();
Index: libmedia/sdl/sound_handler_sdl.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/sdl/sound_handler_sdl.h,v
retrieving revision 1.7
diff -u -r1.7 sound_handler_sdl.h
--- libmedia/sdl/sound_handler_sdl.h	4 Dec 2007 11:45:27 -0000	1.7
+++ libmedia/sdl/sound_handler_sdl.h	10 Dec 2007 22:49:30 -0000
@@ -74,7 +74,7 @@
 	/// @param size
 	///	Size of the 'data' buffer.
 	///
-	void append(uint8_t* data, unsigned int size)
+	void append(boost::uint8_t* data, unsigned int size)
 	{
 		_buf.append(data, size);
 	}
@@ -86,12 +86,12 @@
 	}
 
 	/// Return a pointer to the underlying buffer
-	const uint8_t* data() const {
+	const boost::uint8_t* data() const {
 		return _buf.data();
 	}
 
 	/// Return a pointer to the underlying buffer
-	uint8_t* data() {
+	boost::uint8_t* data() {
 		return _buf.data();
 	}
 
@@ -100,7 +100,7 @@
 	/// @param pos The offset value.
 	/// 	An assertion will fail if pos > size()
 	///
-	const uint8_t* data(size_t pos) const {
+	const boost::uint8_t* data(size_t pos) const {
 		return _buf.data(pos);
 	}
 
@@ -109,7 +109,7 @@
 	/// @param pos The offset value.
 	/// 	An assertion will fail if pos > size()
 	///
-	uint8_t* data(size_t pos) {
+	boost::uint8_t* data(size_t pos) {
 		return _buf.data(pos);
 	}
 
@@ -191,11 +191,11 @@
 
 	/// Returns the data pointer in the undecoded datastream
 	/// for the given position. Boundaries are checked.
-	uint8_t* get_data_ptr(unsigned long int pos);
+	boost::uint8_t* get_data_ptr(unsigned long int pos);
 
 	/// Returns the data pointer in the decoded datastream
 	/// for the given position. Boundaries are checked.
-	uint8_t* get_raw_data_ptr(unsigned long int pos);
+	boost::uint8_t* get_raw_data_ptr(unsigned long int pos);
 
 	/// Release resources associated with decoded data, if any.
 	//
@@ -213,7 +213,7 @@
 	/// @param size
 	///	Size of the 'data' buffer.
 	///
-	void appendDecodedData(uint8_t* data, unsigned int size)
+	void appendDecodedData(boost::uint8_t* data, unsigned int size)
 	{
 		if ( ! _decodedData.get() )
 		{
@@ -231,7 +231,7 @@
 	/// @param size
 	///	Size of the 'data' buffer.
 	///
-	void setDecodedData(uint8_t* data, unsigned int size)
+	void setDecodedData(boost::uint8_t* data, unsigned int size)
 	{
 		if ( ! _decodedData.get() )
 		{
Index: server/video_stream_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/video_stream_instance.cpp,v
retrieving revision 1.44
diff -u -r1.44 video_stream_instance.cpp
--- server/video_stream_instance.cpp	10 Dec 2007 20:17:17 -0000	1.44
+++ server/video_stream_instance.cpp	10 Dec 2007 22:49:30 -0000
@@ -190,14 +190,16 @@
 	{
 		boost::intrusive_ptr<NetStream> nso = _ns;
 
-		std::auto_ptr<image::image_base> i ( nso->get_video() );
+		std::auto_ptr<image::image_base> i ( nso->getVideo() );
 		if (i.get())
 		{
 			gnash::render::drawVideoFrame(i.get(), &m, &bounds);
 		}
 
 	// If this is a video from a VideoFrame tag, retrieve a video frame from there.
-	} else if (_embeddedStream) {
+	}
+	else if (_embeddedStream)
+	{
 		character* parent = get_parent();
 		assert(parent);
 		sprite_instance* sprite = parent->to_movie();
@@ -211,7 +213,9 @@
 		if (img.get())
 		{
 			gnash::render::drawVideoFrame(img.get(), &m, &bounds);
-		} else {
+		}
+		else
+		{
 			log_debug(_("Video frame data is missing in frame %d"),current_frame);
 		}
 	}
Index: server/asobj/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Makefile.am,v
retrieving revision 1.47
diff -u -r1.47 Makefile.am
--- server/asobj/Makefile.am	1 Dec 2007 23:21:49 -0000	1.47
+++ server/asobj/Makefile.am	10 Dec 2007 22:49:30 -0000
@@ -118,17 +118,12 @@
 	MovieClipLoader.h \
 	NetConnection.h	\
 	NetStream.h	\
-	NetStreamFfmpeg.h \
-	NetStreamGst.h \
 	Number.h	\
 	Object.h	\
 	prophelper.h \
 	Selection.h	\
 	SharedObject.h	\
 	Sound.h 	\
-	SoundFfmpeg.h \
-	SoundGst.h \
-	SoundMad.h \
 	Stage.h		\
 	System.h	\
 	TextSnapshot.h	\
@@ -145,19 +140,19 @@
 	$(LIBXML_LIBS)
 
 if USE_FFMPEG_ENGINE
-libgnashasobjs_la_SOURCES += NetStreamFfmpeg.cpp SoundFfmpeg.cpp
+#libgnashasobjs_la_SOURCES += SoundFfmpeg.cpp
 AM_CPPFLAGS += $(FFMPEG_CFLAGS)
 # libgnashasobjs_la_LIBADD += $(FFMPEG_LIBS)
 endif
 
 if USE_SOUND_GST
-libgnashasobjs_la_SOURCES += NetStreamGst.cpp SoundGst.cpp
+#libgnashasobjs_la_SOURCES += NetStreamGst.cpp SoundGst.cpp
 AM_CPPFLAGS += $(GSTREAMER_CFLAGS)
 libgnashasobjs_la_LIBADD += $(GSTREAMER_LIBS)
 endif
 
 if USE_MAD_ENGINE
-libgnashasobjs_la_SOURCES += SoundMad.cpp
+#libgnashasobjs_la_SOURCES += SoundMad.cpp
 AM_CPPFLAGS += $(MAD_CFLAGS)
 libgnashasobjs_la_LIBADD += $(MAD_LIBS)
 endif
Index: server/asobj/NetConnection.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.cpp,v
retrieving revision 1.51
diff -u -r1.51 NetConnection.cpp
--- server/asobj/NetConnection.cpp	20 Nov 2007 00:44:04 -0000	1.51
+++ server/asobj/NetConnection.cpp	10 Dec 2007 22:49:30 -0000
@@ -52,10 +52,10 @@
 
 NetConnection::NetConnection()
 	:
-	as_object(getNetConnectionInterface()),
-	_loader()
+	as_object(getNetConnectionInterface())
 {
 	attachProperties();
+	_stream.reset();
 }
 
 NetConnection::~NetConnection()
@@ -66,24 +66,10 @@
 bool NetConnection::openConnection(const std::string& url)
 {
 
-	// if already running there is no need to setup things again
-	if (_loader.get())
-	{
-		log_debug("NetConnection::openConnection() called when already connected to a stream. Checking if the existing connection can be used.");
-		std::string newurl;
-		if (_prefixUrl.size() > 0) {
-			newurl += _prefixUrl + "/" + url;
-		} else {
-			newurl += url;
-		}
-		if (newurl.compare(_completeUrl) == 0) return true;
-		else return false;
-	}
-
 	if (_prefixUrl.size() > 0) {
-		_completeUrl += _prefixUrl + "/" + url;
+		_completeUrl = _prefixUrl + "/" + url;
 	} else {
-		_completeUrl += url;
+		_completeUrl = url;
 	}
 
 	URL uri(_completeUrl, get_base_url());
@@ -99,11 +85,10 @@
 
 	log_msg(_("Connecting to movie: %s"), uriStr.c_str());
 
-	_loader.reset( new LoadThread() );
+	_stream.reset( StreamProvider::getDefaultInstance().getStream(uri) );
 	
-	if (!_loader->setStream(std::auto_ptr<tu_file>(StreamProvider::getDefaultInstance().getStream(uri)))) {
+	if (!_stream.get()) {
 		log_error(_("Gnash could not open this url: %s"), uriStr.c_str());
-		_loader.reset();
 		return false;
 	}
 
@@ -126,74 +111,10 @@
 	_prefixUrl += url;
 }
 
-/*public*/
-bool
-NetConnection::eof()
-{
-	if (!_loader.get()) return true; // @@ correct ?
-	return _loader->eof();
-}
-
-/*public*/
-size_t
-NetConnection::read(void *dst, size_t bytes)
-{
-	if (!_loader.get()) return 0; // @@ correct ?
-	return _loader->read(dst, bytes);
-}
-
-/*public*/
-bool
-NetConnection::seek(size_t pos)
-{
-	if (!_loader.get()) return false; // @@ correct ?
-	return _loader->seek(pos);
-}
-
-/*public*/
-size_t
-NetConnection::tell()
-{
-	if (!_loader.get()) return 0; // @@ correct ?
-	return _loader->tell();
-}
-
-/*public*/
-long
-NetConnection::getBytesLoaded()
-{
-	if (!_loader.get()) return 0; // @@ correct ?
-	return _loader->getBytesLoaded();
-}
-
-
-/*public*/
-long
-NetConnection::getBytesTotal()
+boost::shared_ptr<tu_file>
+NetConnection::getStream()
 {
-	if (!_loader.get()) return 0; // @@ correct ?
-	return _loader->getBytesTotal();
-}
-
-/*public*/
-bool
-NetConnection::loadCompleted()
-{
-	if ( !_loader.get() ) return false; // @@ correct ?
-	return _loader->completed();
-}
-
-std::auto_ptr<FLVParser>
-NetConnection::getConnectedParser() const
-{
-	std::auto_ptr<FLVParser> ret;
-
-	if ( _loader.get() )
-	{
-		ret.reset(new FLVParser(*_loader));
-	}
-
-	return ret;
+	return _stream;
 }
 
 /// \brief callback to instantiate a new NetConnection object.
@@ -217,12 +138,15 @@
 
 	boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
     
-	if (fn.nargs < 1)
+	// If AS3 we need at least one argument. If not AS3 no arguments is ok.
+	if (fn.nargs < 1 /*&& ptr->_vm.getSWFVersion() >= 9*/)
 	{
 		IF_VERBOSE_ASCODING_ERRORS(
 		log_aserror(_("NetConnection.connect(): needs at least one argument"));
 		);
 		return as_value(false);
+	} else if (fn.nargs < 1) {
+		return as_value();
 	}
 
 	as_value& url_val = fn.arg(0);
@@ -234,7 +158,10 @@
 		std::stringstream ss; fn.dump_args(ss);
 		log_aserror(_("NetConnection.connect(%s): invalid first arg"), ss.str().c_str());
 		);
-		return as_value(false);
+
+		// If AS3 we return boolean
+		/*if (ptr->_vm.getSWFVersion() >= 9) return as_value(false);
+		else*/ return as_value();
 	}
 
 	/// .. TODO: checkme ... addToURL ?? shoudnl't we attempt a connection ??
@@ -248,9 +175,12 @@
 
 
 	// TODO: FIXME: should return true *or false* for RTMP connections
-	return as_value(true);
+	// If AS3 we return boolean
+	/*if (ptr->_vm.getSWFVersion() >= 9) return as_value(true);
+	else*/ return as_value();
 }
 
+// AS 3 only
 as_value
 NetConnection::addHeader_method(const fn_call& fn)
 {
@@ -261,6 +191,7 @@
 	return as_value();
 }
 
+// AS 3 only
 as_value
 NetConnection::call_method(const fn_call& fn)
 {
@@ -271,34 +202,38 @@
 	return as_value();
 }
 
+// AS 3 only
 as_value
 NetConnection::close_method(const fn_call& fn)
 {
 	boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
 	UNUSED(ptr);
 
-	log_unimpl("NetConnection.close()");
+	ptr->_stream.reset();
+
+	// TODO: Send a netStatus event.
 	return as_value();
 }
 
+// AS 3 only
 as_value
-NetConnection::isConnected_getset(const fn_call& fn)
+NetConnection::connected_getset(const fn_call& fn)
 {
 	boost::intrusive_ptr<NetConnection> ptr = ensureType<NetConnection>(fn.this_ptr); 
 	UNUSED(ptr);
 
 	if ( fn.nargs == 0 ) // getter
 	{
-		log_unimpl("NetConnection.isConnected get");
-		return as_value();
+		return as_value(ptr->_stream.get() != NULL);
 	}
 	else // setter
 	{
-		log_unimpl("NetConnection.isConnected set");
+		log_aserror("NetConnection.connected cannot be set, is read-only");
 		return as_value();
 	}
 }
 
+// AS 3 only
 as_value
 NetConnection::uri_getset(const fn_call& fn)
 {
@@ -307,12 +242,11 @@
 
 	if ( fn.nargs == 0 ) // getter
 	{
-		log_unimpl("NetConnection.uri get");
-		return as_value();
+		return as_value(ptr->_prefixUrl);
 	}
 	else // setter
 	{
-		log_unimpl("NetConnection.uri set");
+		log_aserror("NetConnection.uri cannot be set, is read-only");
 		return as_value();
 	}
 
@@ -333,8 +267,8 @@
 {
 	boost::intrusive_ptr<builtin_function> gettersetter;
 
-	gettersetter = new builtin_function(NetConnection::isConnected_getset, NULL);
-	init_property("isConnected", *gettersetter, *gettersetter);
+	gettersetter = new builtin_function(NetConnection::connected_getset, NULL);
+	init_property("connected", *gettersetter, *gettersetter);
 
 	gettersetter = new builtin_function(NetConnection::uri_getset, NULL);
 	init_property("uri", *gettersetter, *gettersetter);
Index: server/asobj/NetConnection.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.h,v
retrieving revision 1.36
diff -u -r1.36 NetConnection.h
--- server/asobj/NetConnection.h	2 Aug 2007 06:03:43 -0000	1.36
+++ server/asobj/NetConnection.h	10 Dec 2007 22:49:30 -0000
@@ -25,14 +25,13 @@
 #endif
 
 #include "tu_file.h"
-#include "LoadThread.h"
-#include "FLVParser.h"
 
 #include <stdexcept>
 #include <cstdio>
 #include <cerrno>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <boost/shared_ptr.hpp>
 
 #include <string>
 
@@ -41,11 +40,6 @@
 #include "as_object.h" // for inheritance
 #include "fn_call.h"
 
-// Forward declarations
-namespace gnash {
-	//class NetStream;
-}
-
 namespace gnash {
 
 /// NetConnection ActionScript class
@@ -77,63 +71,11 @@
 	///
 	bool openConnection(const std::string& url);
 
-	/// Put read pointer at given position
-	//
-	/// If the position has not been loaded yet
-	/// this call blocks. If not connected false
-	/// is returned w/out blocking.
-	///
-	bool seek(size_t pos);
-
-	/// Read 'bytes' bytes into the given buffer.
-	//
-	/// If not enough bytes have been loaded yet
-	/// this call blocks. If not connected false
-	/// is returned w/out blocking.
-	///
-	/// Return number of actually read bytes
-	///
-	size_t read(void *dst, size_t bytes);
-
-	/// Return true if EOF has been reached
-	//
-	/// This call never blocks.
-	/// If not connected, true is returned (is this correct behaviour?)
-	///
-	bool eof();
-
-	/// Report global position within the file
-	//
-	/// This call never blocks.
-	/// If not connected, 0 is returned (is this correct behaviour?)
-	///
-	size_t tell();
-
-	/// Returns the number of bytes cached
-	//
-	/// This call never blocks.
-	/// If not connected, 0 is returned (is this correct behaviour?)
-	///
-	long getBytesLoaded();
-
-	/// Returns the total size of the file
-	//
-	/// This call never blocks.
-	/// If not connected, 0 is returned (is this correct behaviour?)
-	///
-	long getBytesTotal();
-
-	/// Return an FLVParser using our LoadThread for input
+	/// Return the tu_file stream to the media file.
 	//
 	/// If not connected, a NULL auto_ptr is returned.
 	///
-	std::auto_ptr<FLVParser> getConnectedParser() const;
-
-	/// Returns whether the load is complete
-	//
-	/// This call never blocks.
-	///
-	bool loadCompleted();
+	boost::shared_ptr<tu_file> getStream();
 
 	/// Register the "NetConnection" constructor to the given global object
 	static void registerConstructor(as_object& global);
@@ -149,8 +91,8 @@
 	/// the complete url of the file
 	std::string _completeUrl;
 
-	/// The file/stream loader thread and interface
-	std::auto_ptr<LoadThread> _loader;
+	/// The stream/file we want to access
+	boost::shared_ptr<tu_file> _stream;
 
 	/// Attach ActionScript instance properties
 	void attachProperties();
@@ -162,7 +104,7 @@
 	static as_object* getNetConnectionInterface();
 
 	/// NetConnection.isConnected ActionScript Property
-	static as_value isConnected_getset(const fn_call& fn);
+	static as_value connected_getset(const fn_call& fn);
 
 	/// NetConnection.uri ActionScript Property
 	static as_value uri_getset(const fn_call& fn);
Index: server/asobj/NetStream.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.cpp,v
retrieving revision 1.77
diff -u -r1.77 NetStream.cpp
--- server/asobj/NetStream.cpp	4 Dec 2007 11:45:31 -0000	1.77
+++ server/asobj/NetStream.cpp	10 Dec 2007 22:49:31 -0000
@@ -27,16 +27,18 @@
 
 #include "log.h"
 #ifdef SOUND_GST
-# include "NetStreamGst.h"
+# include "MediaDecoderGst.h"
 #elif defined(USE_FFMPEG)
-# include "NetStreamFfmpeg.h"
+# include "MediaDecoderSdl.h"
 #endif
+
 #include "fn_call.h"
 #include "builtin_function.h"
 #include "GnashException.h"
 #include "NetConnection.h"
 #include "action.h" // for call_method
 #include "render.h"	// for gnash::render::videoFrameFormat()
+#include "sound_handler.h"
 #include "Object.h" // for getObjectInterface
 #include "namedStrings.h"
 #include "movie_root.h"
@@ -67,19 +69,20 @@
 	:
 	as_object(getNetStreamInterface()),
 	_netCon(NULL),
-	m_env(NULL),
-	m_bufferTime(100), // The default size needed to begin playback of media is 100 miliseconds
-	m_videoFrameFormat(gnash::render::videoFrameFormat()),
-	m_newFrameReady(false),
-	m_go(false),
-	m_imageframe(NULL),
-	m_pause(false),
-	m_parser(NULL),
-	m_isFLV(false),
-	m_start_onbuffer(false),
-	inputPos(0),
-	_lastStatus(invalidStatus)
-{
+	_env(NULL),
+	_videoFrameFormat(gnash::render::videoFrameFormat()),
+	_newFrameReady(false),
+	_imageframe(NULL),
+	_pause(false),
+	_startOnbuffer(false),
+	_lastStatus(media::invalidStatus),
+	_currentTimestamp(0),
+	_startTime(0),
+	_pauseTime(0)
+{
+	_buffer.reset(new media::MediaBuffer());
+	_decoder.reset(NULL);
+	_imageframe.reset(NULL);
 }
 
 static as_value
@@ -88,14 +91,9 @@
 
 	boost::intrusive_ptr<NetStream> netstream_obj;
        
-#ifdef SOUND_GST
-	netstream_obj = new NetStreamGst();
-#elif defined(USE_FFMPEG)
-	netstream_obj = new NetStreamFfmpeg();
-#else
 	netstream_obj = new NetStream();
-#endif
-
+	
+	log_debug("New NetStream");
 
 	if (fn.nargs > 0)
 	{
@@ -291,7 +289,7 @@
 {
 	boost::intrusive_ptr<NetStream> ns = ensureType<NetStream>(fn.this_ptr);
 
-	long ret = ns->bytesLoaded();
+	boost::uint32_t ret = ns->bytesLoaded();
 	return as_value(ret);
 }
 
@@ -301,7 +299,7 @@
 {
 	boost::intrusive_ptr<NetStream> ns = ensureType<NetStream>(fn.this_ptr);
 
-	long ret = ns->bytesTotal();
+	boost::uint32_t ret = ns->bytesTotal();
 	return as_value(ret);
 }
 
@@ -313,7 +311,7 @@
 
 	bool warned = false;
 	if ( ! warned ) {
-		log_unimpl("NetStream.currentFPS getter/setter");
+		log_unimpl("NetStream.currentFps getter/setter");
 		warned = true;
 	}
 	if ( fn.nargs == 0 ) // getter
@@ -451,8 +449,179 @@
 
 }
 
+NetStream::~NetStream()
+{
+	close();
+}
+
+void NetStream::play(const std::string& source)
+{
+	if (!_netCon) {
+		log_aserror("Trying to play using NetStream without a NetConnection element!");
+		return;
+	}
+
+	// Kill the decoder if it already exists, since it won't work when the
+	// connection/stream is changed.
+	_decoder.reset(NULL);
+
+	// Pass stuff from/to the NetConnection object.
+	if ( !_netCon->openConnection(source) ) {
+		log_error(_("Gnash could not open movie: %s"), source.c_str());
+		setStatus(media::streamNotFound);
+		return;
+	}
+
+	// Create the decoder
+
+#ifdef SOUND_GST
+	_decoder.reset(new media::MediaDecoderGst(_netCon->getStream(), _buffer.get(), (boost::uint16_t)7 /*_vm->getSWFVersion()*/, _videoFrameFormat));
+#elif defined(USE_FFMPEG)
+	_decoder.reset(new media::MediaDecoderSdl(_netCon->getStream(), _buffer.get(), (boost::uint16_t)7 /*_vm->getSWFVersion()*/, _videoFrameFormat));
+#else
+	_decoder.reset(new media::MediaDecoder(_netCon->getStream(), _buffer.get(), (boost::uint16_t)7 /*_vm->getSWFVersion()*/, _videoFrameFormat));
+#endif
+
+	// Connect to the soundhandler
+	media::sound_handler* s = get_sound_handler();
+	if (s) {
+		s->attach_aux_streamer(getAudio, (void*) this);
+	} 
+}
+
+void NetStream::pause(int mode)
+{
+	// -1 : toogle mode
+	// 0 : switch to pause
+	// 1 : switch to play
+	if (mode == -1)
+	{
+		_pause = !_pause;
+	} else {
+		if (mode == 0) _pause = true;
+		else _pause = false;
+	}
+
+	if (_pause && _startTime > 0 && _pauseTime == 0) {
+		_pauseTime = tu_timer::get_ticks();
+	}
+
+	if (!_pause && _startTime != 0 && _pauseTime != 0) {
+		_startTime = tu_timer::get_ticks() - _pauseTime;
+		_pauseTime = 0;
+	}
+
+}
+
+void NetStream::close()
+{
+	media::sound_handler* s = get_sound_handler();
+	if (s) {
+		s->detach_aux_streamer((void*) this);
+	}
+
+	_decoder.reset(NULL);
+	_buffer->flush();
+}
+
+boost::uint32_t NetStream::time()
+{
+	return _currentTimestamp;
+}
+
+void NetStream::seek(boost::uint32_t pos)
+{
+	_currentTimestamp = _decoder->seek(pos);
+}
+
 void
-NetStream::processStatusNotifications()
+NetStream::refreshVideoFrame()
+{
+
+	// If we're paused or not running, there is no need to do this
+	if (_pause || !_decoder.get()) {
+		return;
+	}
+
+	// Loop until a good frame is found
+	while(1)
+	{
+		// If the queue is empty we have nothing to do
+		if (_buffer->videoSize() == 0)
+		{
+			_decoder->wakeUp();
+			return;
+		}
+
+		// Get video frame from queue, will have the lowest timestamp
+		// will return NULL if empty(). See multithread_queue::front
+		media::raw_videodata_t* video = _buffer->videoFront();
+
+		// Caclulate the current time
+		boost::uint64_t current_clock;
+		if (_decoder->gotAudio() && get_sound_handler()) {
+			current_clock = _currentTimestamp;
+		} else {
+			if (_startTime == 0) _startTime = tu_timer::get_ticks();
+			current_clock = tu_timer::get_ticks() - _startTime;
+			_currentTimestamp = current_clock;
+		}
+
+		boost::uint64_t video_clock = video->timestamp;
+
+		if (_buffer->getReqBufferTime() *0.5 > _buffer->getBufferTime()) {
+			_decoder->wakeUp();
+		}
+
+		// If the timestamp on the videoframe is smaller than the
+		// current time, we put it in the output image.
+		if (current_clock >= video_clock)
+		{
+			_imageframe.reset(NULL);
+			_imageframe = video->image->clone();
+
+			// Delete the frame from the queue
+			_buffer->videoPop();
+			delete video;
+
+			// A frame is ready for pickup
+			_newFrameReady = true;
+
+		} else {
+			// The timestamp on the first frame in the queue is greater
+			// than the current time, so no need to do anything.
+			return;
+		}
+
+	}
+}
+
+void
+NetStream::advance()
+{
+	// If play() hasn't been called or failed, 
+	// there's no need to do anything.
+	if (!_decoder.get()) return;
+
+	log_debug("Advance");
+
+	// Check if there are any new status messages, and if we should
+	// pass them to a event handler
+	processOnStatusNotifications();
+
+	// If there's no video, there's nothing to do.	
+	if (_decoder->gotVideo())
+	{
+	
+		log_debug("Refresh");
+		// Find video frame with the most suited timestamp
+		// in the video queue, and put it in the output image frame.
+		refreshVideoFrame();
+	}
+}
+
+void
+NetStream::processOnStatusNotifications()
 {
 	// TODO: check for System.onStatus too ! use a private getStatusHandler() method for this.
 	as_value status;
@@ -462,42 +631,41 @@
 		return;
 	}
 
-	size_t initialStackSize = m_env->stack_size();
+	size_t initialStackSize = _env->stack_size();
 	if ( initialStackSize > 0 )
 	{
-		log_debug("NetStream environment stack not empty at start of processStatusNotifications");
+		//log_debug("NetStream environment stack not empty at start of processStatusNotifications");
 	}
 
-	StatusCode code;
-	while (1)
+	std::vector<media::StatusCode> eventList = _decoder->getOnStatusEvents();
+
+	for(boost::uint32_t i = 0; i < eventList.size(); ++i)
 	{
-		code = popNextPendingStatusNotification();
-		if ( code == invalidStatus ) break; // no more pending notifications
 
 #ifdef GNASH_DEBUG_STATUS
 		log_debug(" Invoking onStatus(%s)", getStatusCodeInfo(code).first);
 #endif
 
 		// TODO: optimize by reusing the same as_object ?
-		boost::intrusive_ptr<as_object> o = getStatusObject(code);
-
-		m_env->push_val(as_value(o.get()));
-		call_method(status, m_env, this, 1, m_env->get_top_index() );
+		boost::intrusive_ptr<as_object> o = getStatusObject(eventList[i]);
 
+		_env->push_val(as_value(o.get()));
+		call_method(status, _env, this, 1, _env->get_top_index() );
+		
 	}
 
 	// clear the stack after method execution
-	if ( m_env->stack_size() > initialStackSize )
+	if ( _env->stack_size() > initialStackSize )
 	{
-		log_debug("NetStream environment stack not empty at end of processStatusNotifications");
-		m_env->drop(m_env->stack_size() - initialStackSize);
+		//log_debug("NetStream environment stack not empty at end of processStatusNotifications");
+		_env->drop(_env->stack_size() - initialStackSize);
 	}
 
 
 }
 
 void
-NetStream::setStatus(StatusCode status)
+NetStream::setStatus(media::StatusCode status)
 {
 	// Get a lock to avoid messing with statuses while processing them
 	boost::mutex::scoped_lock lock(statusMutex);
@@ -513,38 +681,44 @@
 NetStream::setBufferTime(boost::uint32_t time)
 {
 	// The argument is in milliseconds,
-	m_bufferTime = time;
+	_buffer->setBufferTime(time);
+}
+
+boost::uint32_t NetStream::bufferTime()
+{
+	// Must return length of requested buffer
+	return _buffer->getReqBufferTime();
 }
 
-long
+boost::uint32_t
 NetStream::bytesLoaded()
 {
-	if (_netCon == NULL) return 0;
-	return _netCon->getBytesLoaded();
+	if (_decoder.get() == NULL) return 0;
+	return _decoder->getBytesLoaded();
 }
 
-long
+boost::uint32_t
 NetStream::bytesTotal()
 {
-	if (_netCon == NULL) return 0;
-	return _netCon->getBytesTotal();
+	if (_decoder.get() == NULL) return 0;
+	return _decoder->getBytesTotal();
 }
 
-long
+boost::uint32_t
 NetStream::bufferLength()
 {
-	if (m_parser.get() == NULL) return 0;
+	if (_decoder.get() == NULL) return 0;
 
-	// m_parser will lock a mutex
-	// FLVParser::getBufferLength returns milliseconds already
-	return m_parser->getBufferLength();
+	// _decoder will lock a mutex
+	// MediaBuffer::getBufferLength returns milliseconds already
+	return _buffer->getBufferTime();
 }
 
 bool
 NetStream::newFrameReady()
 {
-	if (m_newFrameReady) {
-		m_newFrameReady = false;
+	if (_newFrameReady) {
+		_newFrameReady = false;
 		return true;
 	} else {
 		return false;
@@ -552,44 +726,42 @@
 }
 
 std::auto_ptr<image::image_base>
-NetStream::get_video()
+NetStream::getVideo()
 {
-	boost::mutex::scoped_lock lock(image_mutex);
-
-	if (!m_imageframe) return std::auto_ptr<image::image_base>(0);
+	if (!_imageframe.get()) return std::auto_ptr<image::image_base>(0);
 
 	// TODO: inspect if we could return m_imageframe directly...
-	return m_imageframe->clone();
+	return _imageframe->clone();
 }
 
 std::pair<const char*, const char*>
-NetStream::getStatusCodeInfo(StatusCode code)
+NetStream::getStatusCodeInfo(media::StatusCode code)
 {
 	switch (code)
 	{
 	
-		case bufferEmpty:
+		case media::bufferEmpty:
 			return std::pair<const char*, const char*>("NetStream.Buffer.Empty", "status");
 
-		case bufferFull:
+		case media::bufferFull:
 			return std::pair<const char*, const char*>("NetStream.Buffer.Full", "status");
 
-		case bufferFlush:
+		case media::bufferFlush:
 			return std::pair<const char*, const char*>("NetStream.Buffer.Flush", "status");
 
-		case playStart:
+		case media::playStart:
 			return std::pair<const char*, const char*>("NetStream.Play.Start", "status");
 
-		case playStop:
+		case media::playStop:
 			return std::pair<const char*, const char*>("NetStream.Play.Stop", "status");
 
-		case seekNotify:
+		case media::seekNotify:
 			return std::pair<const char*, const char*>("NetStream.Seek.Notify", "status");
 
-		case streamNotFound:
+		case media::streamNotFound:
 			return std::pair<const char*, const char*>("NetStream.Play.StreamNotFound", "error");
 
-		case invalidTime:
+		case media::invalidTime:
 			return std::pair<const char*, const char*>("NetStream.Seek.InvalidTime", "error");
 
 		default:
@@ -598,7 +770,7 @@
 }
 
 boost::intrusive_ptr<as_object>
-NetStream::getStatusObject(StatusCode code)
+NetStream::getStatusObject(media::StatusCode code)
 {
 	// code, level
 	std::pair<const char*, const char*> info = getStatusCodeInfo(code);
@@ -610,16 +782,16 @@
 	return o;
 }
 
-NetStream::StatusCode
+media::StatusCode
 NetStream::popNextPendingStatusNotification()
 {
 	// Get an exclusive lock on the queue
 	boost::mutex::scoped_lock lock(statusMutex);
 
 	// No queued statuses to notify ...
-	if ( _statusQueue.empty() ) return invalidStatus;
+	if ( _statusQueue.empty() ) return media::invalidStatus;
 
-	StatusCode nextCode = _statusQueue.front();
+	media::StatusCode nextCode = _statusQueue.front();
 	_statusQueue.pop_front();
 	return nextCode;
 }
@@ -640,13 +812,53 @@
 
 	if ( _netCon ) _netCon->setReachable();
 
-	if ( m_statusHandler ) m_statusHandler->setReachable();
+	if ( _statusHandler ) _statusHandler->setReachable();
 
-	if ( m_env ) m_env->markReachableResources();
+	if ( _env ) _env->markReachableResources();
 
 	// Invoke generic as_object marker
 	markAsObjectReachable();
 }
 #endif // GNASH_USE_GC
 
+// audio callback is running in sound handler thread
+bool NetStream::getAudio(void *owner, boost::uint8_t *stream, int len)
+{
+
+	NetStream* ns = static_cast<NetStream*>(owner);
+
+	if (!ns->_decoder.get()) return false;
+
+	if (ns->_pause)
+	{
+		return true;
+	}
+
+	while (len > 0 && ns->_buffer->audioSize() > 0)
+	{
+		media::raw_audiodata_t* samples = ns->_buffer->audioFront();
+
+		int n = imin(samples->m_size, len);
+		memcpy(stream, samples->m_ptr, n);
+		stream += n;
+		samples->m_ptr += n;
+		samples->m_size -= n;
+		len -= n;
+
+		ns->_currentTimestamp = samples->m_pts;
+
+		if (samples->m_size == 0)
+		{
+			ns->_buffer->audioPop();
+			delete samples;
+		}
+
+	}
+
+	if (ns->_buffer->getReqBufferTime() *0.5 > ns->_buffer->getBufferTime()) ns->_decoder->wakeUp();
+
+	return true;
+}
+
 } // end of gnash namespace
+
Index: server/asobj/NetStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.h,v
retrieving revision 1.53
diff -u -r1.53 NetStream.h
--- server/asobj/NetStream.h	4 Dec 2007 11:45:31 -0000	1.53
+++ server/asobj/NetStream.h	10 Dec 2007 22:49:31 -0000
@@ -35,7 +35,8 @@
 #include "impl.h"
 #include "video_stream_instance.h"
 #include "NetConnection.h"
-#include "FLVParser.h"
+#include "MediaBuffer.h"
+#include "MediaDecoder.h"
 
 #include <deque>
 
@@ -56,7 +57,7 @@
 
 protected:
 	
-	/// Status codes used for notifications
+/*	/// Status codes used for notifications
 	enum StatusCode {
 	
 		// Internal status, not a valid ActionScript value
@@ -85,115 +86,16 @@
 
 		/// NetStream.Seek.InvalidTime (level: error)
 		invalidTime
-	};
-
-	boost::intrusive_ptr<NetConnection> _netCon;
-
-	/// Set stream status.
-	//
-	/// Valid statuses are:
-	///
-	/// Status level:
-	///  - NetStream.Buffer.Empty
-	///  - NetStream.Buffer.Full
-	///  - NetStream.Buffer.Flush
-	///  - NetStream.Play.Start
-	///  - NetStream.Play.Stop 
-	///  - NetStream.Seek.Notify 
-	///
-	/// Error level:
-	///  - NetStream.Play.StreamNotFound
-	///  - NetStream.Seek.InvalidTime
-	///
-	/// This method locks the statusMutex during operations
-	///
-	void setStatus(StatusCode code);
-
-	/// \brief
-	/// Call any onStatus event handler passing it
-	/// any queued status change, see _statusQueue
-	//
-	/// Will NOT lock the statusMutex itself, rather it will
-	/// iteratively call the popNextPendingStatusNotification()
-	/// private method, which will take care of locking it.
-	/// This is to make sure onStatus handler won't call methods
-	/// possibly trying to obtain the lock again (::play, ::pause, ...)
-	///
-	void processStatusNotifications();
-
-	/// The actionscript enviroment for the AS callbacks
-	//
-	/// TODO: research on safety of this: who's the owner of the as_environment ?
-	///       can we be sure that the environment won't be prematurely deleted ?
-	///       We'd need an as_environment::testInvariant() to call in our own
-	///       testInvariant() method (also TODO).
-	///
-	as_environment* m_env;
-
-	// The size of the buffer in milliseconds
-	boost::uint32_t m_bufferTime;
-
-	// The video outputformat
-	int m_videoFrameFormat;
-
-	// Are a new frame ready to be returned?
-	volatile bool m_newFrameReady;
-
-	// Mutex to insure we don't corrupt the image
-	boost::mutex image_mutex;
-
-	// Are the playing loop running or not
-	volatile bool m_go;
-
-	// The image/videoframe which is given to the renderer
-	image::image_base* m_imageframe;
-
-	// paused or not
-	volatile bool m_pause;
-
-	// The video URL
-	std::string url;
-
-	// The homegrown parser we use for FLV
-	std::auto_ptr<FLVParser> m_parser;
-
-	// Are we playing a FLV?
-	bool m_isFLV;
-
-	// The handler which is invoked on status change
-	boost::intrusive_ptr<as_function> m_statusHandler;
-
-	// should we start when the FLVParser has buffered/parsed enough frames,
-	// so that the differens between the current frames timestamp (0 at the 
-	// beginning) and the last parseable frames timestamp i bigger than 
-	// m_bufferTime.
-	bool m_start_onbuffer;
-
-	// The position in the inputfile, only used when not playing a FLV
-	long inputPos;
-
-#ifdef GNASH_USE_GC
-	/// Mark all reachable resources of a NetStream, for the GC
-	//
-	/// Reachable resources are:
-	///	- associated NetConnection object (_netCon)
-	///	- onStatus event handler (m_statusHandler)
-	///	- The associated as_environment (m_env)
-	///
-	virtual void markReachableResources() const;
-
-#endif // GNASH_USE_GC
+	};*/
 
 public:
 
 	NetStream();
 
-#if !defined(sgi) || defined(__GNUC__)
-	virtual ~NetStream(){}
-#endif
-	/// Closes the video session and frees all ressources used for decoding
-	/// except the FLV-parser (this might not be correct).
-	virtual void close(){}
+	~NetStream();
+
+	/// Closes the video session and frees all ressources used for decoding.
+	void close();
 
 	/// Pauses/starts the playback of the media played by the current instance
 	//
@@ -203,32 +105,32 @@
 	/// 0 : switch to pause
 	/// 1 : switch to play
 	///
-	virtual void pause(int /*mode*/){}
+	virtual void pause(int mode);
 
 	/// Starts the playback of the media
 	//
 	/// @param source
 	///	Defines what file to play
 	///
-	virtual void play(const std::string& /*source*/){ log_error(_("FFMPEG or Gstreamer is needed to play video")); }
+	void play(const std::string& source);
 
 	/// Seek in the media played by the current instance
 	//
 	/// @param position
 	///	Defines in milliseconds where to seek to
 	///
-	virtual void seek(boost::uint32_t /*pos*/){}
+	void seek(boost::uint32_t pos);
 
 	/// Tells where the playhead currently is
 	//
 	/// @return The time in milliseconds of the current playhead position
 	///
-	virtual boost::int32_t time() { return 0; }
+	boost::uint32_t time();
 
 	/// Called at the SWF framerate. Used to process queued status messages
 	/// and (re)start after a buffering pause. In NetStreamFfmpeg it is also
 	/// used to find the next video frame to be shown, though this might change.
-	virtual void advance(){}
+	void advance();
 
 	/// Sets the NetConnection needed to access external files
 	//
@@ -247,7 +149,7 @@
 	void setEnvironment(as_environment* env)
 	{
 		assert(env);
-		m_env = env;
+		_env = env;
 	}
 
 	/// Specifies the number of milliseconds to buffer before starting to display the stream.
@@ -261,19 +163,19 @@
 	//
 	/// @return The size of the buffer in milliseconds.
 	///
-	boost::uint32_t bufferTime() { return m_bufferTime; }
+	boost::uint32_t bufferTime();
 
 	/// Returns the number of bytes loaded of the media file
 	//
 	/// @return the number of bytes loaded of the media file
 	///
-	long bytesLoaded();
+	boost::uint32_t bytesLoaded();
 
 	/// Returns the total number of bytes (size) of the media file
 	//
 	/// @return the total number of bytes (size) of the media file
 	///
-	long bytesTotal();
+	boost::uint32_t bytesTotal();
 
 	/// Returns the number of millisecond of the media file that is buffered and 
 	/// yet to be played
@@ -281,7 +183,7 @@
 	/// @return Returns the number of millisecond of the media file that is 
 	/// buffered and yet to be played
 	///
-	long bufferLength();
+	boost::uint32_t bufferLength();
 
 	/// Tells us if there is a new video frame ready
 	//
@@ -292,10 +194,79 @@
 	//
 	/// @return a image containing the video frame, a NULL auto_ptr if none were ready
 	///
-	std::auto_ptr<image::image_base> get_video();
+	std::auto_ptr<image::image_base> getVideo();
 
+	/// Callback function used by the soundhandler to fetch raw audio data.
+	//
+	/// @param owner
+	/// A pointer to the Sound object which is being called.
+	///
+	/// @param stream
+	/// The buffer which should be filled with raw audio data.
+	///
+	/// @param len
+	/// The lenght of the buffer.
+	///
+	static bool getAudio(void *owner, boost::uint8_t *stream, int len);
 private:
 
+	boost::intrusive_ptr<NetConnection> _netCon;
+
+	/// Set stream status.
+	//
+	/// Valid statuses are:
+	///
+	/// Status level:
+	///  - NetStream.Buffer.Empty
+	///  - NetStream.Buffer.Full
+	///  - NetStream.Buffer.Flush
+	///  - NetStream.Play.Start
+	///  - NetStream.Play.Stop 
+	///  - NetStream.Seek.Notify 
+	///
+	/// Error level:
+	///  - NetStream.Play.StreamNotFound
+	///  - NetStream.Seek.InvalidTime
+	///
+	/// This method locks the statusMutex during operations
+	///
+	void setStatus(media::StatusCode code);
+
+	/// \brief
+	/// Call any onStatus event handler passing it
+	/// any queued status change, see _statusQueue
+	//
+	/// Will NOT lock the statusMutex itself, rather it will
+	/// iteratively call the popNextPendingStatusNotification()
+	/// private method, which will take care of locking it.
+	/// This is to make sure onStatus handler won't call methods
+	/// possibly trying to obtain the lock again (::play, ::pause, ...)
+	///
+	void processOnStatusNotifications();
+
+#ifdef GNASH_USE_GC
+	/// Mark all reachable resources of a NetStream, for the GC
+	//
+	/// Reachable resources are:
+	///	- associated NetConnection object (_netCon)
+	///	- onStatus event handler (_statusHandler)
+	///     - The associated as_environment (m_env)
+	///
+	virtual void markReachableResources() const;
+
+#endif // GNASH_USE_GC
+
+	/// Update the image/videoframe to be returned by next getVideo() call.
+	//
+	/// Uses by ::advance().
+	///
+	/// Note that getVideo will be called by video_stream_instance::display, which
+	/// is usually called right after video_stream_instance::advance, so  the result
+	/// is that  refreshVideoFrame() is called right before getVideo(). This is important
+	/// to ensure timing is correct..
+	///
+	void refreshVideoFrame();
+
 	/// Pop next queued status notification from the queue
 	//
 	/// Lock the statusMutex during operations
@@ -303,7 +274,7 @@
 	/// @return The status code to notify, or invalidStatus when
 	///	    the queue is empty
 	///
-	StatusCode popNextPendingStatusNotification();
+	media::StatusCode popNextPendingStatusNotification();
 
 	/// Clear status notification queue
 	//
@@ -311,8 +282,44 @@
 	///
 	void clearStatusQueue();
 
+	/// The actionscript enviroment for the 
+	//
+	/// TODO: research on safety of this: who's the owner of the as_environment ?
+	///       can we be sure that the environment won't be prematurely deleted ?
+	///       We'd need an as_environment::testInvariant() to call in our own
+	///       testInvariant() method (also TODO).
+	///
+	as_environment* _env;
+
+	/// The size of the buffer in milliseconds
+	boost::uint32_t _bufferTime;
+
+	/// The video outputformat
+	int _videoFrameFormat;
+
+	/// Are a new frame ready to be returned?
+	bool _newFrameReady;
+
+	/// The image/videoframe which is given to the renderer
+	std::auto_ptr<image::image_base> _imageframe;
+
+	/// paused or not
+	bool _pause;
+
+	/// The media file URL
+	std::string url;
+
+	/// The handler which is invoked on status change
+	boost::intrusive_ptr<as_function> _statusHandler;
+
+	// should we start when the FLVParser has buffered/parsed enough frames,
+	// so that the differens between the current frames timestamp (0 at the 
+	// beginning) and the last parseable frames timestamp i bigger than 
+	// _bufferTime.
+	bool _startOnbuffer;
+
 	// TODO: change to a container with fast pop_front()
-	typedef std::deque<StatusCode> StatusQueue;
+	typedef std::deque<media::StatusCode> StatusQueue;
 
 	/// List of status messages to be processed
 	StatusQueue _statusQueue;
@@ -321,7 +328,7 @@
 	boost::mutex statusMutex;
 
 	/// Last status code (to avoid consecutively notifying the same event)
-	StatusCode _lastStatus;
+	media::StatusCode _lastStatus;
 
 	/// Get 'status' (first) and 'level' (second) strings for given status code
 	//
@@ -329,11 +336,25 @@
 	/// Any invalid code, out of bound or explicitly invalid (invalidCode) 
 	/// returns two empty C strings.
 	///
-	std::pair<const char*, const char*> getStatusCodeInfo(StatusCode code);
+	std::pair<const char*, const char*> getStatusCodeInfo(media::StatusCode code);
 
 	/// Return a newly allocated information object for the given status
-	boost::intrusive_ptr<as_object> getStatusObject(StatusCode code);
+	boost::intrusive_ptr<as_object> getStatusObject(media::StatusCode code);
+
+	/// The media decoder
+	std::auto_ptr<media::MediaDecoder> _decoder;
 
+	/// The media buffer
+	std::auto_ptr<media::MediaBuffer> _buffer;
+
+	/// The current time
+	boost::uint64_t _currentTimestamp;
+
+	/// Time when playback started (only used if soundhandler isn't available)
+	boost::uint64_t _startTime;
+
+	/// Time when pause started (only used if soundhandler isn't available)
+	boost::uint64_t _pauseTime;
 };
 
 
@@ -344,4 +365,3 @@
 
 // __NETSTREAM_H__
 #endif
-
Index: server/asobj/Sound.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.cpp,v
retrieving revision 1.24
diff -u -r1.24 Sound.cpp
--- server/asobj/Sound.cpp	10 Dec 2007 17:45:33 -0000	1.24
+++ server/asobj/Sound.cpp	10 Dec 2007 22:49:31 -0000
@@ -1,4 +1,4 @@
-// Sound.cpp:  ActionScript Sound output stub class, for Gnash.
+// Sound.cpp:  ActionScript Sound output class, for Gnash.
 // 
 //   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
 //
@@ -21,7 +21,14 @@
 #include "config.h"
 #endif
 
+#ifdef SOUND_GST
+# include "MediaDecoderGst.h"
+#else 
+# include "MediaDecoderSdl.h"
+#endif
+
 #include "Sound.h"
+
 #include "log.h"
 #include "sound_handler.h"
 #include "sound_definition.h" // for sound_sample
@@ -31,16 +38,12 @@
 #include "GnashException.h"
 #include "builtin_function.h"
 #include "Object.h" // for getObjectInterface
+#include "render_handler.h"
 #include "VM.h"
 
-#ifdef SOUND_GST
-#include "SoundGst.h"
-#elif defined(USE_FFMPEG)
-#include "SoundFfmpeg.h"
-#elif defined(USE_MAD)
-#include "SoundMad.h"
-#endif
-
+#include "StreamProvider.h"
+#include "URLAccessManager.h"
+#include "URL.h"
 #include <string>
 
 
@@ -63,10 +66,16 @@
 
 Sound::Sound() 	:
 	as_object(getSoundInterface()),
-	connection(),
-	soundId(-1),
-	externalSound(false),
-	isStreaming(false)
+	_connection(),
+	_soundId(-1),
+	_externalSound(false),
+	_isAttached(false),
+	_globalControl(false),
+	_soundName(),
+	_decoder(NULL),
+	_buffer(NULL),
+	_currentTimestamp(0),
+	_remainingLoops(0)
 {
 }
 
@@ -78,30 +87,26 @@
 void
 Sound::attachSound(int si, const std::string& name)
 {
-	soundId = si;
-	soundName = name;
+	_soundId = si;
+	_soundName = name;
 }
 
-void
+uint32_t
 Sound::getBytesLoaded()
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_unimpl (__FUNCTION__);
-		warned = true;
+	if (_decoder.get()) {
+		return _decoder->getBytesLoaded();
 	}
+	return 0;
 }
 
-void
+uint32_t
 Sound::getBytesTotal()
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_unimpl (__FUNCTION__);
-		warned = true;
+	if (_decoder.get()) {
+		return _decoder->getBytesTotal();
 	}
+	return 0;
 }
 
 void
@@ -133,7 +138,7 @@
 	media::sound_handler* s = get_sound_handler();
 	if (s != NULL)
 	{
-		volume = s->get_volume(soundId);
+		volume = s->get_volume(_soundId);
 	}
 	return volume;
 }
@@ -141,15 +146,37 @@
 void
 Sound::loadSound(std::string file, bool /*streaming*/)
 {
-	log_msg(_("%s is still testing!"), __FUNCTION__);
+	URL uri(file);
 
-	if (connection) {
-		log_error(_("%s: This sound already has a connection?  (We try to handle this by overriding the old one...)"), __FUNCTION__);
+	// Check if we're allowed to open url
+	if (!URLAccessManager::allow(uri)) {
+		log_security(_("Gnash is not allowed to open this url: %s"), file.c_str());
+		return;
 	}
-	externalURL = file;
 
-	connection = new NetConnection();
-	connection->openConnection(externalURL);
+	log_msg(_("Connecting to movie: %s"), file.c_str());
+
+	_connection.reset( StreamProvider::getDefaultInstance().getStream(uri) );
+	
+	if (!_connection.get()) {
+		log_error(_("Gnash could not open this url: %s"), file.c_str());
+		return;
+	}
+
+	log_msg(_("Connection etablished to movie: %s"), file.c_str());
+
+	_externalURL = file;
+
+	_buffer.reset(new media::MediaBuffer());
+	
+//#ifdef SOUND_GST
+//	_decoder.reset(new media::MediaDecoderGst(_connection, _buffer.get(), (uint16_t)7 /*_vm->getSWFVersion()*/, 0));
+//#elif defined(USE_FFMPEG)
+#ifdef USE_FFMPEG
+	_decoder.reset(new media::MediaDecoderSdl(_connection, _buffer.get(), (uint16_t)7 /*_vm->getSWFVersion()*/, 0));
+#else
+	_decoder.reset(new media::MediaDecoder(_connection, _buffer.get(), (uint16_t)7 /*_vm->getSWFVersion()*/, 0));
+#endif
 }
 
 void
@@ -183,7 +210,7 @@
 		media::sound_handler* s = get_sound_handler();
 		if (s != NULL)
 		{
-			s->set_volume(soundId, volume);
+			s->set_volume(_soundId, volume);
 		}
 	}
 }
@@ -191,9 +218,31 @@
 void
 Sound::start(int offset, int loops)
 {
-	    media::sound_handler* s = get_sound_handler();
-	    if (s) s->play_sound(soundId, loops, offset, 0, NULL);
-    
+
+	if (_externalSound) {
+		if (offset > 0) {
+			// Seek to offset position
+			_decoder->seek(offset*1000);
+		}
+		// Save how many loops to do
+		if (loops > 0) {
+			_remainingLoops = loops;
+		}
+	}
+
+	// Start sound
+	media::sound_handler* s = get_sound_handler();
+	if (s) {
+		if (_externalSound) {
+			if (_decoder->gotAudio())
+			{
+				s->attach_aux_streamer(getAudio, (void*) this);
+				_isAttached = true;
+			} 
+		} else {
+	    	s->play_sound(_soundId, loops, offset, 0, NULL);
+	    }
+	}
 }
 
 void
@@ -204,7 +253,7 @@
 	if (s != NULL)
 	{
 	    if (si > -1) {
-			s->stop_sound(soundId);
+			s->stop_sound(_soundId);
 		} else {
 			s->stop_sound(si);
 		}
@@ -214,42 +263,85 @@
 unsigned int
 Sound::getDuration()
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_error(_("%s: only works when ffmpeg, gstreamer or libmad is enabled"), __FUNCTION__);
-		warned = true;
+
+	// If this is a event sound get the info from the soundhandler
+	if (!_externalSound) {
+		media::sound_handler* s = get_sound_handler();
+		if (s) {		
+	    	return (s->get_duration(_soundId));
+	    } else {
+	    	return 0; // just in case
+		}
 	}
-	return 0;
+
+	// Return the duration of the file in milliseconds
+	/*if (_decoder.get()) {
+		return _decoder.getDuration();
+	} else {*/
+		return 0;
+	//}
 }
 
 unsigned int
 Sound::getPosition()
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_error(_("%s: only works when ffmpeg, gstreamer or libmad is enabled"), __FUNCTION__);
-		warned = true;
+	// If this is a event sound get the info from the soundhandler
+	if (!_externalSound) {
+		media::sound_handler* s = get_sound_handler();
+		if (s) {
+			return s->get_position(_soundId);
+	    } else {
+	    	return 0; // just in case
+		}
+	}
+
+	// Return the position in the file in milliseconds
+	if (_buffer.get()) {
+		return _currentTimestamp;
+	} else {
+		return 0;
 	}
-	return 0;
 }
 
+// audio callback is running in sound handler thread
+bool Sound::getAudio(void *owner, uint8_t *stream, int len)
+{
+
+	Sound* so = static_cast<Sound*>(owner);
+
+/*	if (!ns->m_go || ns->m_pause)
+	{
+		return false;
+	}*/
+
+	while (len > 0 && so->_buffer->audioSize() > 0)
+	{
+		media::raw_audiodata_t* samples = so->_buffer->audioFront();
+
+		int n = imin(samples->m_size, len);
+		memcpy(stream, samples->m_ptr, n);
+		stream += n;
+		samples->m_ptr += n;
+		samples->m_size -= n;
+		len -= n;
+
+		so->_currentTimestamp = samples->m_pts;
+
+		if (samples->m_size == 0)
+		{
+			so->_buffer->audioPop();
+			delete samples;
+		}
+
+	}
+	return true;
+}
 
 as_value
 sound_new(const fn_call& /* fn */)
 {
-	Sound* sound_obj;
-       
-#ifdef SOUND_GST
-	sound_obj = new SoundGst();
-#elif defined(USE_FFMPEG)
-	sound_obj = new SoundFfmpeg();
-#elif defined(USE_MAD)
-	sound_obj = new SoundMad();
-#else
-	sound_obj = new Sound();
-#endif
+	Sound* sound_obj = new Sound();
+
 	return as_value(sound_obj);
 }
 
@@ -377,27 +469,19 @@
 }
 
 as_value
-sound_getbytesloaded(const fn_call& /*fn*/)
+sound_getbytesloaded(const fn_call& fn)
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_unimpl (__FUNCTION__);
-		warned = true;
-	}
-	return as_value();
+	boost::intrusive_ptr<Sound> so = ensureType<Sound>(fn.this_ptr);
+
+	return as_value(so->getBytesLoaded());
 }
 
 as_value
-sound_getbytestotal(const fn_call& /*fn*/)
+sound_getbytestotal(const fn_call& fn)
 {
-	static bool warned = false;
-	if ( ! warned )
-	{
-		log_unimpl (__FUNCTION__);
-		warned = true;
-	}
-	return as_value();
+	boost::intrusive_ptr<Sound> so = ensureType<Sound>(fn.this_ptr);
+
+	return as_value(so->getBytesTotal());
 }
 
 as_value
Index: server/asobj/Sound.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.h,v
retrieving revision 1.7
diff -u -r1.7 Sound.h
--- server/asobj/Sound.h	1 Jul 2007 10:54:30 -0000	1.7
+++ server/asobj/Sound.h	10 Dec 2007 22:49:31 -0000
@@ -23,13 +23,10 @@
 #include "config.h"
 #endif
 
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
+#include "MediaDecoder.h"
 
 #include "impl.h"
 #include "as_object.h" // for inheritance
-#include "NetConnection.h"
 
 namespace gnash {
 
@@ -40,24 +37,104 @@
 public:
 	Sound();
 	~Sound();
-	virtual void attachSound(int si, const std::string& name);
-	virtual void getBytesLoaded();
-	virtual void getBytesTotal();
-	virtual void getPan();
-	virtual void getTransform();
-	virtual int getVolume();
-	virtual void loadSound(std::string file, bool streaming);
-	virtual void setPan();
-	virtual void setTransform();
-	virtual void setVolume(int volume);
-	virtual void start(int offset, int loops);
-	virtual void stop(int si);
-	virtual unsigned int getDuration();
-	virtual unsigned int getPosition();
 
-	std::string soundName;
+	/// Attaches an event sound to the sound object.
+	//
+	/// @param si
+	/// Soundhandler ID of the sound.
+	///
+	/// @param names
+	/// Name of the event sound.
+	///
+	void attachSound(int si, const std::string& name);
+
+	/// Returns the number of bytes loaded of the external audiofile, or
+	/// 0 if there is no external file attached.
+	//
+	/// @return the number of bytes loaded of the external audiofile.
+	///
+	uint32_t getBytesLoaded();
+
+	/// Returns the total size of the external audiofile in bytes, or
+	/// 0 if there is no external file attached.
+	//
+	/// @return total size of the external audiofile in bytes.
+	///
+	uint32_t getBytesTotal();
+
+	// not implemented
+	void getPan();
+	void setPan();
+	void getTransform();
+	void setTransform();
+
+	/// Returns the volume for this Sound object, in the interval 0-100.
+	// 
+	/// @return the volume for this Sound object.
+	///
+	int getVolume();
+
+	/// Sets the volume for this Sound object, in the interval 0-100.
+	//
+	/// @param volume
+	/// The new volume for this Sound object.
+	///
+	void setVolume(int volume);
+
+	/// Attaches an external audiofile to the sound object.
+	//
+	/// @param file
+	/// The URL of the file
+	///
+	/// @param streaming
+	/// Is it a streaming file (needed?)
+	///
+	void loadSound(std::string file, bool streaming);
+
+	/// Start playing the sound
+	//
+	/// @param offset
+	/// Number of seconds to skip.
+	///
+	/// @param loops
+	/// Number of times the playback should loop.
+	///
+	void start(int offset, int loops);
+
+	/// Stop playing the sounds associated with this object, or just
+	/// stop the sound with the specified id (>= 0).
+	//
+	/// @param si
+	/// If >= 0 the ID of a eventsound that should be stopped.
+	///
+	void stop(int si);
+
+	/// Returns the duration of the sound attached to this object.
+	// 
+	/// @return the duration of the sound attached to this object.
+	///
+	unsigned int getDuration();
+
+	/// Returns the playback position in the sound attached to this object.
+	// 
+	/// @return the playback position in the sound attached to this object.
+	///
+	unsigned int getPosition();
+
+	/// Callback function used by the soundhandler to fetch raw audio data.
+	//
+	/// @param owner
+	/// A pointer to the Sound object which is being called.
+	///
+	/// @param stream
+	/// The buffer which should be filled with raw audio data.
+	///
+	/// @param len
+	/// The lenght of the buffer.
+	///
+	static bool getAudio(void *owner, uint8_t *stream, int len);
 
-protected:
+private:
 
 #ifdef GNASH_USE_GC
 	/// Mark all reachable resources of a Sound, for the GC
@@ -67,22 +144,45 @@
 	///
 	void markReachableResources() const
 	{
-		if ( connection ) connection->setReachable();
+		//if ( _connection ) _connection->setReachable();
 	}
 #endif // GNASH_USE_GC
 
-	bool _duration;
-	bool _id3;
-	bool _onID3;
-	bool _onLoad;
-	bool _onComplete;
-	bool _position;
-	boost::intrusive_ptr<NetConnection> connection;
-
-	int soundId;
-	bool externalSound;
-	std::string externalURL;
-	bool isStreaming;
+	/// The connection to the external file
+	boost::shared_ptr<tu_file> _connection;
+
+	/// The connection to the external file
+	//boost::intrusive_ptr<as_object> _movieClip;
+
+	/// Soundhandler ID of the sound being controlled
+	int _soundId;
+
+	/// Is this an external sound?
+	bool _externalSound;
+
+	/// URL of the external soundfile
+	std::string _externalURL;
+
+	/// Is the sound attached to the soundhandler?
+	bool _isAttached;
+
+	/// Are we controlling all sounds in the movie?
+	bool _globalControl;
+
+	/// Name of the attached eventsound
+	std::string _soundName;
+
+	/// The media decoder
+	std::auto_ptr<media::MediaDecoder> _decoder;
+
+	/// The media buffer
+	std::auto_ptr<media::MediaBuffer> _buffer;
+
+	/// The current time
+	uint32_t _currentTimestamp;
+
+	/// Number of times the external sound should loop
+	uint32_t _remainingLoops;
 };
 
 void sound_class_init(as_object& global);
Index: server/parser/video_stream_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v
retrieving revision 1.29
diff -u -r1.29 video_stream_def.cpp
--- server/parser/video_stream_def.cpp	4 Dec 2007 21:42:18 -0000	1.29
+++ server/parser/video_stream_def.cpp	10 Dec 2007 22:49:31 -0000
@@ -99,7 +99,7 @@
 	unsigned int frameNum = in->read_u16(); // in->skip_bytes(2); 
 	if ( m->get_loading_frame() != frameNum )
 	{
-		log_debug("frameNum field in tag is %d, currently loading frame is %d, we'll use the latter.");
+		//log_debug("frameNum field in tag is %d, currently loading frame is %d, we'll use the latter.");
 		frameNum = m->get_loading_frame();
 	}
 
@@ -107,11 +107,11 @@
 	// bigger than the data to avoid libavcodec (ffmpeg) making
 	// illegal reads. Also, we must ensure first 23 bits to be 
 	// zeroed out. We'll zero out all padding.
-	unsigned int padding =  _decoder->getPaddingBytes();
+	unsigned int padding = _decoder->getPaddingBytes();
 	unsigned int dataSize = in->get_tag_end_position() - in->get_position();
 	unsigned int totSize = dataSize+padding;
 
-	boost::shared_array<uint8_t> data ( new uint8_t[totSize] );
+	boost::shared_array<boost::uint8_t> data ( new boost::uint8_t[totSize] );
 	in->read((char*)data.get(), dataSize);
 	if ( padding ) memset(&data[dataSize], 0, padding);  // pad with zeroes if needed
 
@@ -169,7 +169,12 @@
 	}
 
 	// rewind to the nearest keyframe, or the last frame we decoded
-	while (static_cast<boost::uint32_t>(m_last_decoded_frame+1) != it->first && it->second->frameType != media::KEY_FRAME && it != m_video_frames.begin()) it--;
+	while (static_cast<boost::uint32_t>(m_last_decoded_frame+1) != it->first &&
+					it->second->frameType != media::KEY_FRAME &&
+					it != m_video_frames.begin())
+	{
+		it--;
+	}
 
 	std::auto_ptr<image::image_base> ret(NULL);
 
@@ -191,7 +196,10 @@
 }
 
 void
-video_stream_definition::setFrameData(boost::uint32_t frameNum, boost::shared_array<uint8_t> data, boost::uint32_t size, media::videoFrameType ft)
+video_stream_definition::setFrameData(boost::uint32_t frameNum,
+					boost::shared_array<boost::uint8_t> data,
+					boost::uint32_t size,
+					media::videoFrameType ft)
 {
 	EmbedFrameMap::iterator it = m_video_frames.find(frameNum);
 	if( it != m_video_frames.end() )
Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.162
diff -u -r1.162 tag_loaders.cpp
--- server/swf/tag_loaders.cpp	6 Dec 2007 13:23:35 -0000	1.162
+++ server/swf/tag_loaders.cpp	10 Dec 2007 22:49:31 -0000
@@ -1255,7 +1255,7 @@
     int latency = 0;
     if (format == media::AUDIO_CODEC_MP3)
     {
-        in->ensureBytes(2);
+        //in->ensureBytes(2);
         latency = in->read_s16(); // UNUSED !!
         //garbage = in->read_uint(16);
     }
