[Top][All Lists]
[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libmedia/MediaParser.h server/a...,
Sandro Santilli <=