gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libmedia/MediaParser.h server/a...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog libmedia/MediaParser.h server/a...
Date: Thu, 19 Jun 2008 17:45:09 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  08/06/19 17:45:08

Modified files:
        .              : ChangeLog 
        libmedia       : MediaParser.h 
        server/asobj   : Sound.cpp Sound.h SoundFfmpeg.cpp SoundFfmpeg.h 

Log message:
                * libmedia/MediaParser.h: document setBufferTime unit.
                * server/asobj/Sound.{cpp,h}: document and fix signature
                  of getBytes{Loaded/Total}.
                * server/asobj/SoundFfmpeg.{cpp,h}: drop any FFMPEG-specific
                  reference, convert to be a pure MediaHandler user.
                  Test: http://foo.keybit.net/~strk/tmp/SoundTest.swf (and .as)
                  Should fix bug #23636.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6982&r2=1.6983
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/MediaParser.h?cvsroot=gnash&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.cpp?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.h?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundFfmpeg.cpp?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/SoundFfmpeg.h?cvsroot=gnash&r1=1.15&r2=1.16

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6982
retrieving revision 1.6983
diff -u -b -r1.6982 -r1.6983
--- ChangeLog   19 Jun 2008 17:40:14 -0000      1.6982
+++ ChangeLog   19 Jun 2008 17:45:06 -0000      1.6983
@@ -1,3 +1,13 @@
+2008-06-19 Sandro Santilli <address@hidden>
+
+       * libmedia/MediaParser.h: document setBufferTime unit.
+       * server/asobj/Sound.{cpp,h}: document and fix signature
+         of getBytes{Loaded/Total}.
+       * server/asobj/SoundFfmpeg.{cpp,h}: drop any FFMPEG-specific
+         reference, convert to be a pure MediaHandler user.
+         Test: http://foo.keybit.net/~strk/tmp/SoundTest.swf (and .as)
+         Should fix bug #23636.
+
 2008-06-19 Benjamin Wolsey <address@hidden>
 
        * testsuite/actionscript.all/BitmapData.as: some initial tests.

Index: libmedia/MediaParser.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/MediaParser.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- libmedia/MediaParser.h      16 Jun 2008 14:41:53 -0000      1.27
+++ libmedia/MediaParser.h      19 Jun 2008 17:45:07 -0000      1.28
@@ -297,6 +297,10 @@
        }
 
        /// Set the time we want the parser thread to maintain in the buffer
+       //
+       /// @param t
+       ///     Number of milliseconds to keep in the buffers.
+       ///
        DSOEXPORT void setBufferTime(boost::uint64_t t)
        {
                boost::mutex::scoped_lock lock(_bufferTimeMutex);

Index: server/asobj/Sound.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- server/asobj/Sound.cpp      19 Jun 2008 16:05:29 -0000      1.35
+++ server/asobj/Sound.cpp      19 Jun 2008 17:45:07 -0000      1.36
@@ -88,26 +88,18 @@
        soundName = name;
 }
 
-void
+long
 Sound::getBytesLoaded()
 {
-       static bool warned = false;
-       if ( ! warned )
-       {
-               log_unimpl (__FUNCTION__);
-               warned = true;
-       }
+       LOG_ONCE( log_unimpl("Sound.getBytesLoaded() [default impl]") );
+       return 0;
 }
 
-void
+long
 Sound::getBytesTotal()
 {
-       static bool warned = false;
-       if ( ! warned )
-       {
-               log_unimpl (__FUNCTION__);
-               warned = true;
-       }
+       LOG_ONCE( log_unimpl("Sound.getBytesTotal() [default impl]") );
+       return -1;
 }
 
 void

Index: server/asobj/Sound.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- server/asobj/Sound.h        19 Jun 2008 16:05:29 -0000      1.12
+++ server/asobj/Sound.h        19 Jun 2008 17:45:07 -0000      1.13
@@ -60,8 +60,16 @@
 
        virtual ~Sound() {}
        virtual void attachSound(int si, const std::string& name);
-       virtual void getBytesLoaded();
-       virtual void getBytesTotal();
+
+       /// Get number of bytes loaded from the external sound (if any)
+       virtual long getBytesLoaded();
+
+       /// Get total number of bytes in the external sound being loaded
+       //
+       /// @return -1 if unknown
+       ///
+       virtual long getBytesTotal();
+
        virtual void getPan();
        virtual void getTransform();
 

Index: server/asobj/SoundFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/SoundFfmpeg.cpp,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- server/asobj/SoundFfmpeg.cpp        9 Jun 2008 18:12:57 -0000       1.23
+++ server/asobj/SoundFfmpeg.cpp        19 Jun 2008 17:45:08 -0000      1.24
@@ -29,484 +29,288 @@
 #include "fn_call.h"
 #include "GnashException.h"
 #include "builtin_function.h"
+#include "URL.h"
+#include "StreamProvider.h"
 
 #include <string>
 
 namespace gnash {
 
-// ffmpeg callback function
-int 
-SoundFfmpeg::readPacket(void* opaque, boost::uint8_t* buf, int buf_size)
-{
-
-       SoundFfmpeg* so = static_cast<SoundFfmpeg*>(opaque);
-       boost::intrusive_ptr<NetConnection> nc = so->connection;
-
-       size_t ret = nc->read(static_cast<void*>(buf), buf_size);
-       so->inputPos += ret;
-       return ret;
-
-}
-
-// ffmpeg callback function
-offset_t 
-SoundFfmpeg::seekMedia(void *opaque, offset_t offset, int whence){
-
-       SoundFfmpeg* so = static_cast<SoundFfmpeg*>(opaque);
-       boost::intrusive_ptr<NetConnection> nc = so->connection;
-
-
-       // Offset is absolute new position in the file
-       if (whence == SEEK_SET) {
-               nc->seek(offset);
-               so->inputPos = offset;
+SoundFfmpeg::SoundFfmpeg()
+       : // REMEMBER TO ALWAYS INITIALIZE ALL MEMBERS !
+       _mediaHandler(media::MediaHandler::get()),
+       _leftOverData(),
+       _leftOverPtr(0),
+       _leftOverSize(0),
+       isAttached(false),
+       remainingLoops(0)
+{}
 
-       // New position is offset + old position
-       } else if (whence == SEEK_CUR) {
-               nc->seek(so->inputPos + offset);
-               so->inputPos = so->inputPos + offset;
 
-       //      // New position is offset + end of file
-       } else if (whence == SEEK_END) {
-               // This is (most likely) a streamed file, so we can't seek to 
the end!
-               // Instead we seek to 50.000 bytes... seems to work fine...
-               nc->seek(50000);
-               so->inputPos = 50000;
-               
-       }
-
-       return so->inputPos;
-}
-
-
-void
-SoundFfmpeg::setupDecoder()
+bool
+SoundFfmpeg::getAudio(boost::uint8_t* stream, int len)
 {
-       SoundFfmpeg* so = this;
+       //GNASH_REPORT_FUNCTION;
 
-       boost::intrusive_ptr<NetConnection> nc = so->connection;
-       assert(nc);
-
-       // Pass stuff from/to the NetConnection object.
-       assert(so);
-       if ( !nc->openConnection(so->externalURL) ) {
-               log_error(_("%s could not open audio url: %s"), 
-                               __FUNCTION__, so->externalURL.c_str());
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
-       }
-
-       so->inputPos = 0;
-
-       // This registers all available file formats and codecs 
-       // with the library so they will be used automatically when
-       // a file with the corresponding format/codec is opened
-
-       av_register_all();
-
-       // Open video file
-
-       // Probe the file to detect the format
-       AVProbeData probe_data, *pd = &probe_data;
-       pd->filename = "";
-       pd->buf = new boost::uint8_t[2048];
-       pd->buf_size = 2048;
-
-       if (readPacket(so, pd->buf, pd->buf_size) < 1){
-               log_error(_("%s: could not read from audio url: %s"), 
-                               __FUNCTION__, so->externalURL.c_str());
-               delete[] pd->buf;
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
-       }
-
-       AVInputFormat* inputFmt = av_probe_input_format(pd, 1);
-
-       // After the format probe, reset to the beginning of the file.
-       nc->seek(0);
-
-       // Setup the filereader/seeker mechanism. 7th argument (NULL) is the 
writer function,
-       // which isn't needed.
-       init_put_byte(&so->ByteIOCxt, new boost::uint8_t[500000], 500000, 0, 
so, SoundFfmpeg::readPacket, NULL, SoundFfmpeg::seekMedia);
-       so->ByteIOCxt.is_streamed = 1;
-
-       so->formatCtx = av_alloc_format_context();
-
-       // Open the stream. the 4th argument is the filename, which we ignore.
-       if(av_open_input_stream(&so->formatCtx, &so->ByteIOCxt, "", inputFmt, 
NULL) < 0){
-               log_error(_("Couldn't open file '%s' for decoding"), 
so->externalURL.c_str());
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
-       }
-
-       // Next, we need to retrieve information about the streams contained in 
the file
-       // This fills the streams field of the AVFormatContext with valid 
information
-       int ret = av_find_stream_info(so->formatCtx);
-       if (ret < 0)
-       {
-               log_error(_("Couldn't find stream information from '%s', error 
code: %d"), so->externalURL.c_str(), ret);
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
-       }
-
-       // Find the first audio stream
-       so->audioIndex = -1;
-
-       for (unsigned int i = 0; i < (unsigned)so->formatCtx->nb_streams; i++)
+       while (len > 0)
        {
-               AVCodecContext* enc = so->formatCtx->streams[i]->codec; 
-
-               switch (enc->codec_type)
+               if ( ! _leftOverData )
                {
-                       case CODEC_TYPE_AUDIO:
-                               if (so->audioIndex < 0)
+                       std::auto_ptr<media::EncodedAudioFrame> frame = 
_mediaParser->nextAudioFrame();
+                       if ( ! frame.get() )
                                {
-                                       so->audioIndex = i;
-                                       so->audioStream = 
so->formatCtx->streams[i];
-                               }
-                               break;
+                               // just wait some more if parsing isn't 
complete yet
+                               if ( ! _mediaParser->parsingCompleted() ) break;
 
-                       default:
-                               log_error(_("Non-audio data (type %d) found in 
file %s"),
-                                  enc->codec_type, so->externalURL.c_str());
-               
-                               break;
-               }
+                               // or detach and stop here...
+                               _soundHandler->detach_aux_streamer(this);
+                               return true; // return false might do the 
detach itself actually...
        }
 
-       if (so->audioIndex < 0)
+                       _leftOverData.reset( _audioDecoder->decode(*frame, 
_leftOverSize) );
+                       _leftOverPtr = _leftOverData.get();
+                       if ( ! _leftOverData )
        {
-               log_error(_("Didn't find a audio stream from '%s'"), 
so->externalURL.c_str());
-               return;
+                               log_error("No samples decoded from input of %d 
bytes", frame->dataSize);
+                               continue;
+                       }
        }
 
-       // Get a pointer to the audio codec context for the video stream
-       so->audioCodecCtx = so->formatCtx->streams[so->audioIndex]->codec;
+               int n = std::min<int>(_leftOverSize, len);
+               memcpy(stream, _leftOverPtr, n);
+               stream += n;
+               _leftOverPtr += n;
+               _leftOverSize -= n;
+               len -= n;
 
-       // Find the decoder for the audio stream
-       AVCodec* pACodec = avcodec_find_decoder(so->audioCodecCtx->codec_id);
-    if(pACodec == NULL)
-       {
-               log_error(_("No available audio decoder %d to process file: 
'%s'"),
-                  so->audioCodecCtx->codec_id, so->externalURL.c_str());
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
+               if (_leftOverSize == 0)
+               {
+                       _leftOverData.reset();
+                       _leftOverPtr = 0;
        }
     
-       // Open codec
-       if (avcodec_open(so->audioCodecCtx, pACodec) < 0)
-       {
-               log_error(_("Could not open audio codec %d for %s"),
-                  so->audioCodecCtx->codec_id, so->externalURL.c_str());
-#ifdef LOADS_IN_SEPARATE_THREAD
-               delete so->lock;
-#endif
-               return;
        }
 
-       // By deleting this lock we allow start() to start playback
-#ifdef LOADS_IN_SEPARATE_THREAD
-       delete so->lock;
-#endif
-       return;
+       // drop any queued video frame
+       while (_mediaParser->nextVideoFrame().get());
+
+       return true;
 }
 
 // audio callback is running in sound handler thread
-bool SoundFfmpeg::getAudio(void* owner, boost::uint8_t* stream, int len)
+bool
+SoundFfmpeg::getAudioWrapper(void* owner, boost::uint8_t* stream, int len)
 {
        SoundFfmpeg* so = static_cast<SoundFfmpeg*>(owner);
-
-       int pos = 0;
-
-       // First use the data left over from last time
-       if (so->leftOverSize > 0) {
-
-               // If we have enough "leftover" data to fill the buffer,
-               // we don't bother to decode some new.
-               if (so->leftOverSize >= len) {
-                       memcpy(stream, so->leftOverData, len);
-                       int rest = so->leftOverSize - len;
-                       if (rest < 1) {
-                               delete[] so->leftOverData;
-                               so->leftOverSize = 0;
-                       } else {
-                               boost::uint8_t* buf = new boost::uint8_t[rest];
-                               memcpy(stream, so->leftOverData+len, rest);
-                               delete[] so->leftOverData;
-                               so->leftOverData = buf;
-                               so->leftOverSize -= len;
-                       }       
-                       return true;
-               } else {
-                       memcpy(stream, so->leftOverData, so->leftOverSize);
-                       pos += so->leftOverSize;
-                       so->leftOverSize = 0;
-                       delete[] so->leftOverData;
-               }
-       }
-
-       AVPacket packet;
-       int rc;
-       bool loop = true;
-       boost::uint8_t* ptr = new boost::uint8_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
-       bool ret = true;
-       while (loop) {
-               // Parse file
-               rc = av_read_frame(so->formatCtx, &packet);
-               if (rc >= 0)
-               {
-                       if (packet.stream_index == so->audioIndex)
-                       {
-                               media::sound_handler* s = get_sound_handler();
-                               if (s)
-                               {
-                                       // Decode audio
-                                       int frame_size;
-#ifdef FFMPEG_AUDIO2
-                                       frame_size = 
(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
-                                       if 
(avcodec_decode_audio2(so->audioCodecCtx, (boost::int16_t*) ptr, &frame_size, 
packet.data, packet.size) >= 0)
-#else
-                                       if 
(avcodec_decode_audio(so->audioCodecCtx, (boost::int16_t*) ptr, &frame_size, 
packet.data, packet.size) >= 0)
-#endif
-                                       {
-
-                                               bool stereo = 
so->audioCodecCtx->channels > 1 ? true : false;
-                                               int samples = stereo ? 
frame_size >> 2 : frame_size >> 1;
-                                               int newDataSize = 0;
-                                               boost::int16_t* output_data = 
NULL;
-                                               bool output_data_allocated = 
false;
-
-                                               // Resample if needed
-                                               if (so->audioCodecCtx->channels 
!= 2 || so->audioCodecCtx->sample_rate != 44100) {
-                                                       // Resampeling using 
ffmpegs (libavcodecs) resampler
-                                                       if (!so->resampleCtx) {
-                                                               // arguments: 
(output channels, input channels, output rate, input rate)
-                                                               so->resampleCtx 
= audio_resample_init (2, so->audioCodecCtx->channels, 44100, 
so->audioCodecCtx->sample_rate);
-                                                       }
-                                                       // The size of this is 
a guess, we don't know yet... Lets hope it's big enough
-                                                       output_data = new 
boost::int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
-                                                       output_data_allocated = 
true;
-                                                       samples = 
audio_resample (so->resampleCtx, output_data, (boost::int16_t*)ptr, samples);
-                                                       newDataSize =  samples 
* 2 * 2; // 2 for stereo and 2 for samplesize = 2 bytes
-                                               } else {
-                                                       output_data = 
(boost::int16_t*)ptr;
-                                                       newDataSize = samples * 
2 * 2;
-                                               }
-
-                                               // Copy the data to buffer
-                                               // If the decoded data isn't 
enough to fill the buffer, we put the decoded
-                                               // data into the buffer, and 
continues decoding.
-                                               if (newDataSize <= len-pos) {
-                                                       memcpy(stream+pos, 
(boost::uint8_t*)output_data, newDataSize);
-                                                       pos += newDataSize;
-                                               } else {
-                                               // If we can fill the buffer, 
and still have "leftovers", we save them
-                                               // and use them later.
-                                                       int rest = len-pos;
-                                                       so->leftOverSize = 
newDataSize - rest;
-                                                       memcpy(stream+pos, 
(boost::uint8_t*)output_data, rest);
-                                                       so->leftOverData = new 
boost::uint8_t[so->leftOverSize];
-                                                       
memcpy(so->leftOverData, ((boost::uint8_t*)output_data)+rest, so->leftOverSize);
-                                                       loop = false;
-                                                       pos += rest;
-                                               }
-                                               if ( output_data_allocated ) 
delete[] output_data;
-                                       }
-                               }
-                       }
-               } else {
-                       // If we should loop we make sure we do.
-                       if (so->remainingLoops != 0) {
-                               so->remainingLoops--;
-
-                               // Seek to begining of file
-                               if (av_seek_frame(so->formatCtx, 
so->audioIndex, 0, 0) < 0) {
-                                       log_error(_("seeking to start of file 
(for looping) failed"));
-                                       so->remainingLoops = 0;
-                               }
-                       } else {
-                        // Stops playback by returning false which makes the 
soundhandler
-                        // detach this sound.
-                        ret = false;
-                        so->isAttached = false;
-                        break;
-                       }
-               } 
-       } // while
-       delete[] ptr;
-       return ret;
+       return so->getAudio(stream, len);
 }
 
-SoundFfmpeg::~SoundFfmpeg() {
-       if (externalSound) {
-                if (leftOverData && leftOverSize) delete[] leftOverData;
-
-               if (audioCodecCtx) avcodec_close(audioCodecCtx);
-               audioCodecCtx = NULL;
-
-               if (formatCtx) {
-                       formatCtx->iformat->flags = AVFMT_NOFILE;
-                       av_close_input_file(formatCtx);
-                       formatCtx = NULL;
-               }
-
-               if (resampleCtx) {
-                       audio_resample_close (resampleCtx);
-               }
+SoundFfmpeg::~SoundFfmpeg()
+{
+       //GNASH_REPORT_FUNCTION;
 
-               if (isAttached) {
-                       media::sound_handler* s = get_sound_handler();
-                       if (s) {
-                               s->detach_aux_streamer(this);
-                       }
-               }
+       if (isAttached && _soundHandler)
+       {
+               _soundHandler->detach_aux_streamer(this);
        }
 }
 
 void
 SoundFfmpeg::loadSound(const std::string& file, bool streaming)
 {
-       leftOverData = NULL;
-       leftOverSize = 0;
-       audioIndex = -1;
-       resampleCtx = NULL;
-       remainingLoops = 0;
+       if ( ! _mediaHandler || ! _soundHandler ) 
+       {
+               log_debug("No media or sound handlers, won't load any sound");
+               return;
+       }
 
-       if (connection) {
-               log_error(_("This sound already has a connection.  (We try to 
handle this by overriding the old one...)"));
+       if (_mediaParser)
+       {
+               // TODO: check what to do in these cases
+               log_error("FIXME: Sound.loadSound() called while already 
streaming");
+               return;
        }
-       externalURL = file;
 
-       connection = new NetConnection();
+       URL url(file, get_base_url());
+       externalURL = url.str(); // what for ? bah!
+
+       StreamProvider& streamProvider = StreamProvider::getDefaultInstance();
+       std::auto_ptr<IOChannel> inputStream( streamProvider.getStream( 
externalURL ) );
+       if ( ! inputStream.get() )
+       {
+               log_error( _("Gnash could not open this url: %s"), url );
+               return;
+       }
 
        externalSound = true;
        isStreaming = streaming;
 
-#ifdef LOADS_IN_SEPARATE_THREAD
-       lock = new boost::mutex::scoped_lock(setupMutex);
+       _mediaParser.reset( 
_mediaHandler->createMediaParser(inputStream).release() );
+       if ( ! _mediaParser )
+       {
+               log_error(_("Unable to create parser for Sound input"));
+               // not necessarely correct, the stream might have been found...
+               return;
+       }
+       _mediaParser->setBufferTime(60000); // one minute buffer... should be 
fine
 
-       // To avoid blocking while connecting, we use a thread.
-       setupThread = new boost::thread(boost::bind(&SoundFfmpeg::setupDecoder, 
this));
-#else
-       setupDecoder();
-#endif
+       media::AudioInfo* audioInfo =  _mediaParser->getAudioInfo();
+       if (!audioInfo) {
+               log_debug("No audio in Sound input");
+               return;
+       }
+
+       _audioDecoder.reset( 
_mediaHandler->createAudioDecoder(*audioInfo).release() );
+       if ( ! _audioDecoder.get() )
+       {
+               log_error(_("Could not create audio decoder for codec %d"), 
audioInfo->codec);
+       }
 
 }
 
 void
 SoundFfmpeg::start(int offset, int loops)
 {
-#ifdef LOADS_IN_SEPARATE_THREAD
-       boost::mutex::scoped_lock lock(setupMutex);
-#endif
-
-       if (externalSound) {
-               if (offset > 0) {
-                       // Seek to offset position
-                       double timebase = 
(double)formatCtx->streams[audioIndex]->time_base.num / 
(double)formatCtx->streams[audioIndex]->time_base.den;
-
-                       long newpos = (long)(offset / timebase);
-
-                       if (av_seek_frame(formatCtx, audioIndex, newpos, 0) < 
0) {
-                               log_error(_("%s: seeking to offset failed"),
-                                       __FUNCTION__);
+       if ( ! _soundHandler )
+       {
+               log_error("No sound handler, nothing to start...");
+               return;
                        }
+
+       if (externalSound)
+       {
+               if ( ! _mediaParser )
+               {
+                       log_error("No MediaParser initialized, can't start an 
external sound");
+                       return;
                }
-               // Save how many loops to do
-               if (loops > 0) {
-                       remainingLoops = loops;
+               if ( ! _audioDecoder )
+               {
+                       log_error("No AudioDecoder initialized, can't start an 
external sound");
+                       return;
                }
+
+               if (offset > 0)
+               {
+                       boost::uint32_t seekms = boost::uint32_t(offset*1000);
+                       // TODO: boost::mutex::scoped_lock 
parserLock(_parserMutex);
+                       _mediaParser->seek(seekms); // well, we try...
        }
 
-       // Start sound
-       media::sound_handler* s = get_sound_handler();
-       if (s) {
-               if (externalSound) {
-                       if (audioIndex >= 0)
+               // Save how many loops to do
+               if (loops > 0)
                        {
-                               s->attach_aux_streamer(getAudio, (void*) this);
-                               isAttached = true;
+                       remainingLoops = loops;
                        } 
-               } else {
-               s->play_sound(soundId, loops, offset, 0, NULL);
+
+               _soundHandler->attach_aux_streamer(getAudioWrapper, (void*) 
this);
+               isAttached = true;
            }
+       else
+       {
+               _soundHandler->play_sound(soundId, loops, offset, 0, NULL);
        }
 }
 
 void
 SoundFfmpeg::stop(int si)
 {
+       if ( ! _soundHandler )
+       {
+               log_error("No sound handler, nothing to stop...");
+               return;
+       }
+
        // stop the sound
-       media::sound_handler* s = get_sound_handler();
-       if (s != NULL)
+       if (si < 0)
        {
-           if (si < 0) {
-               if (externalSound) {
-                       s->detach_aux_streamer(this);
-               } else {
-                               s->stop_sound(soundId);
+               if (externalSound)
+               {
+                       _soundHandler->detach_aux_streamer(this);
                        }
-               } else {
-                       s->stop_sound(si);
+               else
+               {
+                       _soundHandler->stop_sound(soundId);
                }
        }
+       else
+       {
+               _soundHandler->stop_sound(si);
+       }
 }
 
 unsigned int
 SoundFfmpeg::getDuration()
 {
+       if ( ! _soundHandler )
+       {
+               log_error("No sound handler, can't check duration...");
+               return 0;
+       }
 
        // 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
+       if (!externalSound)
+       {
+               return _soundHandler->get_duration(soundId);
+       }
+
+       // If we have a media parser (we'd do for an externalSound)
+       // try fetching duration from it
+       if ( _mediaParser )
+       {
+               media::AudioInfo* info = _mediaParser->getAudioInfo();
+               if ( info )
+               {
+                       return info->duration;
                }
        }
 
-       // Return the duration of the file in milliseconds
-       if (formatCtx && audioIndex) {
-               return static_cast<unsigned int>(formatCtx->duration * 1000);
-       } else {
                return 0;
-       }
 }
 
 unsigned int
 SoundFfmpeg::getPosition()
 {
-       // 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->tell(soundId);
-           } else {
-               return 0; // just in case
-               }
+       if ( ! _soundHandler )
+       {
+               log_error("No sound handler, can't check position (we're likely 
not playing anyway)...");
+               return 0;
        }
 
-       // Return the position in the file in milliseconds
-       if (formatCtx && audioIndex >= 0)
+       // If this is a event sound get the info from the soundhandler
+       if (!externalSound)
        {
-               double time = 
(double)formatCtx->streams[audioIndex]->time_base.num / 
formatCtx->streams[audioIndex]->time_base.den * 
(double)formatCtx->streams[audioIndex]->cur_dts;
-               return static_cast<unsigned int>(time * 1000);
+               return _soundHandler->tell(soundId);
        }
-       else
+
+       if ( _mediaParser )
        {
-               return 0;
+               boost::uint64_t ts;
+               if ( _mediaParser->nextAudioFrameTimestamp(ts) )
+               {
+                       return ts;
        }
+       }
+
+       return 0;
+
 }
 
+long
+SoundFfmpeg::getBytesLoaded()
+{
+       if ( _mediaParser ) return _mediaParser->getBytesLoaded();
+       return 0;
+}
+
+long
+SoundFfmpeg::getBytesTotal()
+{
+       if ( _mediaParser ) return _mediaParser->getBytesTotal();
+       return -1;
+}
+
+
+
+
 } // end of gnash namespace

Index: server/asobj/SoundFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/SoundFfmpeg.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/asobj/SoundFfmpeg.h  23 May 2008 05:58:09 -0000      1.15
+++ server/asobj/SoundFfmpeg.h  19 Jun 2008 17:45:08 -0000      1.16
@@ -24,13 +24,15 @@
 #endif
 #include "log.h"
 #include "Sound.h" // for inheritance
+#include "MediaHandler.h"
+#include "MediaParser.h"
+#include "AudioDecoder.h"
+
 #include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
 #include <boost/bind.hpp> 
 #include <boost/thread/mutex.hpp>
-
-// Undefined the following macro to disable threading
-// TODO: use a global define for disabling all threads at once
-#define LOADS_IN_SEPARATE_THREAD
+#include <boost/scoped_ptr.hpp>
 
 #ifdef HAVE_FFMPEG_AVFORMAT_H
 extern "C" {
@@ -52,25 +54,7 @@
 class SoundFfmpeg : public Sound {
 public:
 
-       SoundFfmpeg()
-               : // REMEMBER TO ALWAYS INITIALIZE ALL MEMBERS !
-               audioCodecCtx(NULL),
-               audioStream(NULL),
-               formatCtx(NULL),
-               audioFrame(NULL),
-               resampleCtx(NULL)
-#ifdef LOADS_IN_SEPARATE_THREAD
-               ,setupThread(NULL)
-               ,lock(NULL)
-#endif
-               ,inputPos(0),
-               ByteIOCxt(), // ?
-               audioIndex(-1),
-               leftOverData(NULL),
-               leftOverSize(0),
-               isAttached(false),
-               remainingLoops(0)
-       {}
+       SoundFfmpeg();
 
        ~SoundFfmpeg();
 
@@ -80,43 +64,25 @@
        unsigned int getDuration();
        unsigned int getPosition();
 
-       // Used for ffmpeg data read and seek callbacks
-       static int readPacket(void* opaque, boost::uint8_t* buf, int buf_size);
-       static offset_t seekMedia(void *opaque, offset_t offset, int whence);
-
-private:
-
-       void setupDecoder();
-       static bool getAudio(void *owner, boost::uint8_t *stream, int len);
+       // see dox in Sound.h
+       virtual long getBytesLoaded();
 
-       // audio
-       AVCodecContext *audioCodecCtx;
-       AVStream* audioStream;
+       // see dox in Sound.h
+       virtual long getBytesTotal();
 
-       AVFormatContext *formatCtx;
-
-       AVFrame* audioFrame;
-
-       ReSampleContext *resampleCtx;
-
-#ifdef LOADS_IN_SEPARATE_THREAD
-       boost::thread *setupThread;
-       boost::mutex setupMutex;
-
-       // TODO: it makes NO SENSE for a scoped_lock to be allocated on the 
heap !
-       boost::mutex::scoped_lock *lock;
-#endif
+private:
 
-       long inputPos;
+       media::MediaHandler* _mediaHandler;
+       boost::scoped_ptr<media::MediaParser> _mediaParser;
+       boost::scoped_ptr<media::AudioDecoder> _audioDecoder;
 
-       ByteIOContext ByteIOCxt;
+       boost::scoped_array<boost::uint8_t> _leftOverData;
+       boost::uint8_t* _leftOverPtr;
+       size_t _leftOverSize;
 
-       // The stream in the file that we use
-       int audioIndex;
+       static bool getAudioWrapper(void *owner, boost::uint8_t *stream, int 
len);
 
-       // If the decoded data doesn't fit the buffer we put the leftovers here
-       boost::uint8_t* leftOverData;
-       int leftOverSize;
+       bool getAudio(boost::uint8_t *stream, int len);
 
        // Are this sound attached to the soundhandler?
        bool isAttached;




reply via email to

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