[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libmedia/sdl/AudioDecoderFfmpeg...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog libmedia/sdl/AudioDecoderFfmpeg... |
Date: |
Mon, 25 Feb 2008 07:34:06 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 08/02/25 07:34:06
Modified files:
. : ChangeLog
Removed files:
libmedia/sdl : AudioDecoderFfmpeg.cpp AudioDecoderFfmpeg.h
AudioDecoderMad.cpp AudioDecoderMad.h
MediaDecoderSdl.cpp MediaDecoderSdl.h
MediaParserFfmpeg.cpp MediaParserFfmpeg.h
VideoDecoderFfmpeg.cpp VideoDecoderFfmpeg.h
sound_handler_sdl.cpp sound_handler_sdl.h
Log message:
drop unused code.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5738&r2=1.5739
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/AudioDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.12&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/AudioDecoderFfmpeg.h?cvsroot=gnash&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/AudioDecoderMad.cpp?cvsroot=gnash&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/AudioDecoderMad.h?cvsroot=gnash&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/MediaDecoderSdl.cpp?cvsroot=gnash&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/MediaDecoderSdl.h?cvsroot=gnash&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/MediaParserFfmpeg.cpp?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/MediaParserFfmpeg.h?cvsroot=gnash&r1=1.9&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.cpp?cvsroot=gnash&r1=1.13&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/VideoDecoderFfmpeg.h?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/sdl/sound_handler_sdl.h?cvsroot=gnash&r1=1.10&r2=0
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5738
retrieving revision 1.5739
diff -u -b -r1.5738 -r1.5739
--- ChangeLog 25 Feb 2008 00:06:06 -0000 1.5738
+++ ChangeLog 25 Feb 2008 07:34:03 -0000 1.5739
@@ -1,3 +1,7 @@
+2008-02-25 Sandro Santilli <address@hidden>
+
+ * libmedia/sdl: drop unused code.
+
2008-02-24 Bastiaan Jacques <address@hidden>
* libmedia/ffmpeg/VideoDecoderFfmpeg.{cpp,h}: Fix up convertRGB24 so
Index: libmedia/sdl/AudioDecoderFfmpeg.cpp
===================================================================
RCS file: libmedia/sdl/AudioDecoderFfmpeg.cpp
diff -N libmedia/sdl/AudioDecoderFfmpeg.cpp
--- libmedia/sdl/AudioDecoderFfmpeg.cpp 21 Jan 2008 23:10:15 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,284 +0,0 @@
-// AudioDecoderFfmpeg.cpp: Audio decoding using the FFMPEG library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-// $Id: AudioDecoderFfmpeg.cpp,v 1.12 2008/01/21 23:10:15 rsavoye Exp $
-
-#include "AudioDecoderFfmpeg.h"
-
-namespace gnash {
-namespace media {
-
-AudioDecoderFfmpeg::AudioDecoderFfmpeg ()
- :
- _audioCodec(NULL),
- _audioCodecCtx(NULL),
- _parser(NULL)
-{}
-
-AudioDecoderFfmpeg::~AudioDecoderFfmpeg()
-{
- if (_audioCodecCtx)
- {
- avcodec_close(_audioCodecCtx);
- av_free(_audioCodecCtx);
- }
- if (_parser) av_parser_close(_parser);
-}
-
-bool AudioDecoderFfmpeg::setup(SoundInfo* info)
-{
- // Init the avdecoder-decoder
- avcodec_init();
- avcodec_register_all();// change this to only register need codec?
-
- enum CodecID codec_id;
-
- switch(info->getFormat()) {
- case AUDIO_CODEC_RAW:
- codec_id = CODEC_ID_PCM_U16LE;
- break;
- case AUDIO_CODEC_ADPCM:
- codec_id = CODEC_ID_ADPCM_SWF;
- break;
- case AUDIO_CODEC_MP3:
- codec_id = CODEC_ID_MP3;
- // Init the parser
- _parser = av_parser_init(codec_id);
-
- if (!_parser) {
- log_error(_("libavcodec can't parse the current
audio format"));
- return false;
- }
- break;
- default:
- log_error(_("Unsupported audio codec %d"),
static_cast<int>(info->getFormat()));
- return false;
- }
- _audioCodec = avcodec_find_decoder(codec_id);
-
- if (!_audioCodec) {
- log_error(_("libavcodec can't decode the current audio
format"));
- return false;
- }
-
- _audioCodecCtx = avcodec_alloc_context();
- if (!_audioCodecCtx) {
- log_error(_("libavcodec couldn't allocate context"));
- return false;
- }
-
- int ret = avcodec_open(_audioCodecCtx, _audioCodec);
- if (ret < 0) {
- avcodec_close(_audioCodecCtx);
- log_error(_("libavcodec failed to initialize codec"));
- return false;
- }
-
- if (_audioCodecCtx->codec->id != CODEC_ID_MP3) {
- _audioCodecCtx->channels = (info->isStereo() ? 2 : 1);
- _audioCodecCtx->sample_rate = info->getSampleRate();
- _audioCodecCtx->sample_fmt = SAMPLE_FMT_S16;
- }
-
- return true;
-}
-
-bool AudioDecoderFfmpeg::setup(AudioInfo* info)
-{
- // Init the avdecoder-decoder
- avcodec_init();
- avcodec_register_all();// change this to only register need codec?
-
- if (info->type == FLASH) {
- enum CodecID codec_id;
-
- switch(info->codec)
- {
- case AUDIO_CODEC_RAW:
- codec_id = CODEC_ID_PCM_U16LE;
- break;
- case AUDIO_CODEC_ADPCM:
- codec_id = CODEC_ID_ADPCM_SWF;
- break;
- case AUDIO_CODEC_MP3:
- codec_id = CODEC_ID_MP3;
- break;
- default:
- log_error(_("Unsupported audio codec %d"),
static_cast<int>(info->codec));
- return false;
- }
- _audioCodec = avcodec_find_decoder(codec_id);
- // Init the parser
- _parser = av_parser_init(codec_id);
- }
- else if (info->type == FFMPEG)
- {
- _audioCodec =
avcodec_find_decoder(static_cast<CodecID>(info->codec));
- // Init the parser
- _parser = av_parser_init(static_cast<CodecID>(info->codec));
- }
- else
- {
- return false;
- }
-
- if (!_audioCodec)
- {
- log_error(_("libavcodec can't decode the current audio
format"));
- return false;
- }
-
- // Reuse the audioCodecCtx from the ffmpeg parser if exists/possible
- if (info->audioCodecCtx)
- {
- log_debug("re-using the parser's audioCodecCtx");
- _audioCodecCtx = info->audioCodecCtx;
- }
- else
- {
- _audioCodecCtx = avcodec_alloc_context();
- }
-
- if (!_audioCodecCtx) {
- log_error(_("libavcodec couldn't allocate context"));
- return false;
- }
-
- int ret = avcodec_open(_audioCodecCtx, _audioCodec);
- if (ret < 0) {
- avcodec_close(_audioCodecCtx);
- log_error(_("libavcodec failed to initialize codec"));
- return false;
- }
-
- if (_audioCodecCtx->codec->id != CODEC_ID_MP3) {
- _audioCodecCtx->channels = (info->stereo ? 2 : 1);
- _audioCodecCtx->sample_rate = info->sampleRate;
- //_audioCodecCtx->sample_fmt = SAMPLE_FMT_S16;
- }
-
- return true;
-}
-
-boost::uint8_t* AudioDecoderFfmpeg::decode(boost::uint8_t* input,
boost::uint32_t inputSize, boost::uint32_t& outputSize, boost::uint32_t&
decodedBytes, bool parse)
-{
-
- long bytes_decoded = 0;
- int bufsize = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
- boost::uint8_t* output = new boost::uint8_t[bufsize];
- boost::uint32_t orgbufsize = bufsize;
- decodedBytes = 0;
-
- if (parse) {
-
- if (!_parser)
- {
- log_error(_("libavcodec can't parse the current audio
format"));
- return NULL;
- }
-
-
- bufsize = 0;
- while (bufsize == 0 && decodedBytes < inputSize) {
- boost::uint8_t* frame;
- int framesize;
-
- bytes_decoded = av_parser_parse(_parser,
_audioCodecCtx, &frame, &framesize, input+decodedBytes, inputSize-decodedBytes,
0, 0); //the last 2 is pts & dts
-
- int tmp = 0;
-#ifdef FFMPEG_AUDIO2
- bufsize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
- tmp = avcodec_decode_audio2(_audioCodecCtx,
reinterpret_cast<boost::int16_t*>(output), &bufsize, frame, framesize);
-#else
- tmp = avcodec_decode_audio(_audioCodecCtx,
reinterpret_cast<boost::int16_t*>(output), &bufsize, frame, framesize);
-#endif
-
- if (bytes_decoded < 0 || tmp < 0 || bufsize < 0) {
- log_error(_("Error while decoding audio data.
Upgrading ffmpeg/libavcodec might fix this issue."));
- // Setting data position to data size will get
the sound removed
- // from the active sound list later on.
- decodedBytes = inputSize;
- break;
- }
-
- decodedBytes += bytes_decoded;
- }
-
- } else {
-
- int tmp = 0;
-
-#ifdef FFMPEG_AUDIO2
- tmp = avcodec_decode_audio2(_audioCodecCtx,
reinterpret_cast<boost::int16_t*>(output), &bufsize, input, inputSize);
-#else
- tmp = avcodec_decode_audio(_audioCodecCtx,
reinterpret_cast<boost::int16_t*>(output), &bufsize, input, inputSize);
-#endif
-
-
-
- if (bytes_decoded < 0 || tmp < 0 || bufsize < 0) {
- log_error(_("Error while decoding audio data. Upgrading
ffmpeg/libavcodec might fix this issue."));
- // Setting data position to data size will get the
sound removed
- // from the active sound list later on.
- decodedBytes = 0;
- outputSize = 0;
- delete [] output;
- return NULL;
- }
-
- decodedBytes = inputSize;
- }
-
- // Error handling
- if (bufsize < 1) {
- log_error(_("Error while decoding audio data."));
- delete [] output;
- decodedBytes = 0;
- outputSize = 0;
- return NULL;
- }
-
- // Resampling is needed.
- if (_resampler.init(_audioCodecCtx)) {
- bool stereo = _audioCodecCtx->channels > 1 ? true : false;
- int samples = stereo ? bufsize >> 2 : bufsize >> 1;
-
- boost::uint8_t* tmp = new boost::uint8_t[orgbufsize];
-
- samples =
_resampler.resample(reinterpret_cast<boost::int16_t*>(output),
-
reinterpret_cast<boost::int16_t*>(tmp),
- samples);
- outputSize = samples *2 *2; // the resampled audio has
samplesize 2, and is stereo
- boost::uint8_t* ret = new boost::uint8_t[outputSize];
- memcpy(ret, tmp, outputSize);
- delete [] tmp;
- delete [] output;
- return ret;
- } else {
- outputSize = bufsize;
- boost::uint8_t* ret = new boost::uint8_t[outputSize];
- memcpy(ret, output, outputSize);
- delete [] output;
- return ret;
- }
-}
-
-
-} // gnash.media namespace
-} // gnash namespace
Index: libmedia/sdl/AudioDecoderFfmpeg.h
===================================================================
RCS file: libmedia/sdl/AudioDecoderFfmpeg.h
diff -N libmedia/sdl/AudioDecoderFfmpeg.h
--- libmedia/sdl/AudioDecoderFfmpeg.h 21 Jan 2008 23:10:15 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,117 +0,0 @@
-// AudioDecoderFfmpeg.h: Audio decoding using the FFMPEG library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: AudioDecoderFfmpeg.h,v 1.7 2008/01/21 23:10:15 rsavoye Exp $
-
-#ifndef __AUDIODECODERFFMPEG_H__
-#define __AUDIODECODERFFMPEG_H__
-
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-extern "C" {
-#include <ffmpeg/avcodec.h>
-}
-
-#include "log.h"
-#include "AudioDecoder.h"
-
-namespace gnash {
-namespace media {
-
-/// This class is used to provide an easy interface to libavcodecs audio
resampler.
-///
-class AudioResampler
-{
-public:
- AudioResampler() : _context(NULL) {}
- ~AudioResampler()
- {
- if(_context) {
- audio_resample_close (_context);
- }
- }
-
- /// Initializes the resampler
- //
- /// @param ctx
- /// The audio format container.
- ///
- /// @return true if resampling is needed, if not false
- ///
- bool init(AVCodecContext* ctx)
- {
- if (ctx->sample_rate != 44100 || ctx->channels != 2) {
- if (!_context) {
- _context = audio_resample_init(2,
ctx->channels,
- 44100, ctx->sample_rate);
- }
- return true;
- }
- return false;
- }
-
- /// Resamples audio
- //
- /// @param input
- /// A pointer to the audio data that needs resampling
- ///
- /// @param output
- /// A pointer to where the resampled output should be placed
- ///
- /// @param samples
- /// Number of samples in the audio
- ///
- /// @return the number of samples in the output data.
- ///
- int resample(boost::int16_t* input, boost::int16_t* output, int samples)
- {
- return audio_resample (_context, output, input, samples);
- }
-
-private:
- /// The container of the resample format information.
- ReSampleContext* _context;
-};
-
-class AudioDecoderFfmpeg : public AudioDecoder {
-
-public:
- AudioDecoderFfmpeg();
- ~AudioDecoderFfmpeg();
-
- bool setup(AudioInfo* info);
- bool setup(SoundInfo* info);
-
- boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize, boost::uint32_t& decodedBytes, bool
parse);
-
-private:
-
- AVCodec* _audioCodec;
- AVCodecContext* _audioCodecCtx;
- AVCodecParserContext* _parser;
-
- // Use for resampling audio
- AudioResampler _resampler;
-};
-
-} // gnash.media namespace
-} // gnash namespace
-
-#endif // __AUDIODECODERFFMPEG_H__
Index: libmedia/sdl/AudioDecoderMad.cpp
===================================================================
RCS file: libmedia/sdl/AudioDecoderMad.cpp
diff -N libmedia/sdl/AudioDecoderMad.cpp
--- libmedia/sdl/AudioDecoderMad.cpp 21 Jan 2008 23:10:15 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,176 +0,0 @@
-// AudioDecoderMad.cpp: Audio decoding using the mad library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-// $Id: AudioDecoderMad.cpp,v 1.8 2008/01/21 23:10:15 rsavoye Exp $
-
-#include "AudioDecoderMad.h"
-#include "utility.h"
-#ifdef USE_FFMPEG
-#include <ffmpeg/avcodec.h>
-#endif
-
-namespace gnash {
-namespace media {
-
-AudioDecoderMad::AudioDecoderMad ()
-{
- // Init the mad decoder
- mad_stream_init(&_stream);
- mad_frame_init(&_frame);
- mad_synth_init(&_synth);
-}
-
-AudioDecoderMad::~AudioDecoderMad()
-{
- mad_synth_finish(&_synth);
- mad_frame_finish(&_frame);
- mad_stream_finish(&_stream);
-}
-
-
-bool AudioDecoderMad::setup(SoundInfo* info)
-{
- if (info->getFormat() == AUDIO_CODEC_MP3) return true;
- else return false;
-}
-
-bool AudioDecoderMad::setup(AudioInfo* info)
-{
-#ifdef USE_FFMPEG
- if (info->type == FFMPEG && info->codec == CODEC_ID_MP3) {
- return true;
- }
-#endif
- if (info->type == FLASH && info->codec == AUDIO_CODEC_MP3) {
- return true;
- } else {
- return false;
- }
-}
-
-boost::uint8_t* AudioDecoderMad::decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize, boost::uint32_t& decodedBytes, bool
parse)
-{
- // Setup the mad decoder
- mad_stream_buffer(&_stream, input, inputSize);
-
- int ret;
- const unsigned char* old_next_frame = _stream.next_frame;
- int loops = 0;
- while(true) {
-
- ret = mad_frame_decode(&_frame, &_stream);
- loops++;
-
- // There is always some junk in front of the data,
- // so we continue until we get past it.
- if (ret && _stream.error == MAD_ERROR_LOSTSYNC) continue;
-
- // Error handling is done by relooping (max. 8 times) and just
hooping that it will work...
- if (loops > 8) break;
- if (ret == -1 && _stream.error != MAD_ERROR_BUFLEN &&
MAD_RECOVERABLE(_stream.error)) {
- log_debug(_("Recoverable error while decoding
MP3-stream, MAD error: %s"), mad_stream_errorstr (&_stream));
- continue;
- }
-
- break;
- }
-
- if (ret == -1 && _stream.error != MAD_ERROR_BUFLEN) {
- log_error(_("Unrecoverable error while decoding MP3-stream, MAD
error: %s"), mad_stream_errorstr (&_stream));
- outputSize = 0;
- decodedBytes = 0;
- return NULL;
- } else if (ret == -1 && _stream.error == MAD_ERROR_BUFLEN) {
- // the buffer is empty, no more to decode!
- decodedBytes = inputSize;
- } else {
- decodedBytes = _stream.next_frame - old_next_frame;
- }
-
- mad_synth_frame (&_synth, &_frame);
-
- boost::uint32_t outsize = _synth.pcm.length * _synth.pcm.channels * 2;
-
- boost::uint8_t* tmp_raw_buffer = new boost::uint8_t[outsize];
- boost::uint32_t tmp_raw_buffer_size = 0;
- int sample;
-
- boost::int16_t* dst = reinterpret_cast<boost::int16_t*>(tmp_raw_buffer);
-
- // transfer the decoded samples into the sound-struct, and do some
- // scaling while we're at it.
- for(int f = 0; f < _synth.pcm.length; f++)
- {
- for (int e = 0; e < _synth.pcm.channels; e++) { // channels
(stereo/mono)
-
- mad_fixed_t mad_sample = _synth.pcm.samples[e][f];
-
- // round
- mad_sample += (1L << (MAD_F_FRACBITS - 16));
-
- // clip
- if (mad_sample >= MAD_F_ONE) mad_sample = MAD_F_ONE - 1;
- else if (mad_sample < -MAD_F_ONE) mad_sample =
-MAD_F_ONE;
-
- // quantize
- sample = mad_sample >> (MAD_F_FRACBITS + 1 - 16);
-
- if ( sample != static_cast<boost::int16_t>(sample) )
sample = sample < 0 ? -32768 : 32767;
-
- *dst++ = sample;
- }
- }
-
- // If we need to convert samplerate or/and from mono to stereo...
- if (outsize > 0 && ( _synth.pcm.samplerate != 44100 ||
_synth.pcm.channels != 2)) {
-
- boost::int16_t* adjusted_data = 0;
- int adjusted_size = 0;
- int sample_count = outsize / (_synth.pcm.channels * 2); //
samples are of size 2
-
- // Convert to needed samplerate - this converter only support
standard flash samplerates
- convert_raw_data(&adjusted_data, &adjusted_size,
tmp_raw_buffer, sample_count, 0,
- _synth.pcm.samplerate, (_synth.pcm.channels ==
2 ? true : false),
- 44100, true /* stereo */);
-
- // Hopefully this wont happen
- if (!adjusted_data) {
- log_error(_("Error in sound sample conversion"));
- delete[] tmp_raw_buffer;
- outputSize = 0;
- decodedBytes = 0;
- return NULL;
- }
-
- // Move the new data to the sound-struct
- delete[] tmp_raw_buffer;
- tmp_raw_buffer =
reinterpret_cast<boost::uint8_t*>(adjusted_data);
- tmp_raw_buffer_size = adjusted_size;
-
- } else {
- tmp_raw_buffer_size = outsize;
- }
-
- outputSize = tmp_raw_buffer_size;
- return tmp_raw_buffer;
-}
-
-} // gnash.media namespace
-} // gnash namespace
-
Index: libmedia/sdl/AudioDecoderMad.h
===================================================================
RCS file: libmedia/sdl/AudioDecoderMad.h
diff -N libmedia/sdl/AudioDecoderMad.h
--- libmedia/sdl/AudioDecoderMad.h 21 Jan 2008 23:10:16 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,56 +0,0 @@
-// AudioDecoderMad.h: Audio decoding using the mad library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: AudioDecoderMad.h,v 1.7 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifndef __AUDIODECODERMAD_H__
-#define __AUDIODECODERMAD_H__
-
-#include "log.h"
-#include "AudioDecoder.h"
-
-#include <mad.h>
-
-
-namespace gnash {
-namespace media {
-
-class AudioDecoderMad : public AudioDecoder {
-
-public:
- AudioDecoderMad();
- ~AudioDecoderMad();
-
- bool setup(AudioInfo* info);
- bool setup(SoundInfo* info);
-
- boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize, boost::uint32_t& decodedBytes, bool
parse);
-
-private:
-
- /// mad stuff
- mad_stream _stream;
- mad_frame _frame;
- mad_synth _synth;
-};
-
-} // gnash.media namespace
-} // gnash namespace
-
-#endif // __AUDIODECODERMAD_H__
-
Index: libmedia/sdl/MediaDecoderSdl.cpp
===================================================================
RCS file: libmedia/sdl/MediaDecoderSdl.cpp
diff -N libmedia/sdl/MediaDecoderSdl.cpp
--- libmedia/sdl/MediaDecoderSdl.cpp 21 Jan 2008 23:10:16 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,208 +0,0 @@
-// MediaDecoderSdl.cpp: Media decoding using libs, used with sdl soundhandler.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: MediaDecoderSdl.cpp,v 1.8 2008/01/21 23:10:16 rsavoye Exp $
-
-#include "MediaDecoderSdl.h"
-#include "AudioDecoderNellymoser.h"
-#include "AudioDecoderSimple.h"
-
-#ifdef USE_FFMPEG
-#include "AudioDecoderFfmpeg.h"
-#include "VideoDecoderFfmpeg.h"
-#include "MediaParserFfmpeg.h"
-#endif
-
-#ifdef USE_MAD
-#include "AudioDecoderMad.h"
-#endif
-
-#include "log.h"
-
-#include "gnash.h"
-
-namespace gnash {
-namespace media {
-
-MediaDecoderSdl::MediaDecoderSdl(boost::shared_ptr<tu_file> stream,
MediaBuffer* buffer, boost::uint16_t swfVersion, int format)
- :
- MediaDecoder(stream, buffer, swfVersion, format)
-{
- // Start the decoding thread which will also setup the decoder and
parser
- _decodeThread = new
boost::thread(boost::bind(MediaDecoderSdl::decodeThread, this));
-}
-
-MediaDecoderSdl::~MediaDecoderSdl()
-{
- _running = false;
-
- if (_decodeThread) {
- wakeUp();
- _decodeThread->join();
- delete _decodeThread;
- _decodeThread = NULL;
- }
-}
-
-bool MediaDecoderSdl::setupDecoding()
-{
- std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
- if (vInfo.get() != NULL) {
-#ifdef USE_FFMPEG
- _videoDecoder.reset(new VideoDecoderFfmpeg());
-#endif
- 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.");
- }
- else
- {
- // Video decoder setup succeeded
- _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) {
-#ifdef USE_MAD
- if (_parser->isAudioMp3()) {
- _audioDecoder.reset(new AudioDecoderMad());
- }
-#endif
- if (_parser->isAudioNellymoser()) {
- _audioDecoder.reset(new AudioDecoderNellymoser());
- }
-
-#ifdef USE_FFMPEG
- if (_audioDecoder.get() == NULL) _audioDecoder.reset(new
AudioDecoderFfmpeg());
-#endif
- 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.");
- }
- else
- {
- // Audio decoder setup succeeded
- _audio = true;
- }
- }
- else
- {
- log_error("No audio decoder could be created, since no
decoder is enabled.");
- }
- }
-
- // We don't need both audio and video to be happy :)
- return (_audio || _video);
-}
-
-bool MediaDecoderSdl::setupParser()
-{
- // Buffer a bit to make sure the stream is accessible
- if (_stream->set_position(512) != 0) {
- _error = streamError;
- pushOnStatus(streamNotFound);
- return false;
- }
-
- _lastConfirmedPosition = 512;
- _streamSize = _stream->get_size();
-
- // Check if the file is a FLV, in which case we use our own parser
- char head[4] = {0, 0, 0, 0};
- _stream->set_position(0);
- _stream->read_bytes(head, 3);
- _stream->set_position(0);
-
- // Setup the decoding and parser
- if (std::string(head) == "FLV") {
- _parser.reset(new FLVParser(_stream));
-#ifdef USE_FFMPEG
- } else {
- _parser.reset(new MediaParserFfmpeg(_stream));
-#endif
- }
-
- return _parser->setupParser();
-}
-
-boost::uint32_t MediaDecoderSdl::seek(boost::uint32_t pos)
-{
- boost::uint32_t ret = 0;
- if (_parser.get()) ret = _parser->seek(pos);
- else ret = 0;
-
- // Flush the buffer
- _buffer->flush();
-
- return ret;
-}
-
-void MediaDecoderSdl::decodeThread(MediaDecoderSdl* decoder)
-{
-printf("\t in the decode thread\n");
-
- // If the destructor has been called at this point, exit the thread
- if (!decoder->_running) return;
-
- // Setup the decoder and parser
- if (decoder->setupParser()) {
- if (!decoder->setupDecoding()) {
- decoder->pushOnStatus(streamNotFound);
- log_error("Setup of media decoder failed");
- return;
- }
- } else {
- decoder->pushOnStatus(streamNotFound);
- log_error("Setup of media parser failed");
- return;
- }
-
- // Everything is setup, so let's play!
-
- decoder->pushOnStatus(playStart);
-
- decoder->decodingLoop();
-}
-
-std::pair<boost::uint32_t, boost::uint32_t>
-MediaDecoderSdl::getWidthAndHeight()
-{
- if (_parser.get()) {
- std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
- if (vInfo.get()) return std::pair<boost::uint32_t,
boost::uint32_t>(vInfo->width, vInfo->height);
- }
- return std::pair<boost::uint32_t, boost::uint32_t>(0,0);
-}
-
-
-} // gnash.media namespace
-} // namespace gnash
-
Index: libmedia/sdl/MediaDecoderSdl.h
===================================================================
RCS file: libmedia/sdl/MediaDecoderSdl.h
diff -N libmedia/sdl/MediaDecoderSdl.h
--- libmedia/sdl/MediaDecoderSdl.h 21 Jan 2008 23:10:16 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,67 +0,0 @@
-// MediaDecoderSdl.h: Media decoding using libs, used with sdl soundhandler.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: MediaDecoderSdl.h,v 1.7 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifndef __MEDIADECODERSDL_H__
-#define __MEDIADECODERSDL_H__
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "MediaDecoder.h"
-#include "MediaParser.h"
-#include "AudioDecoder.h"
-#include "VideoDecoder.h"
-
-#include "image.h"
-
-namespace gnash {
-namespace media {
-
-/// Media decoding using libs, used with sdl soundhandler.
-class MediaDecoderSdl: public MediaDecoder {
-public:
- MediaDecoderSdl(boost::shared_ptr<tu_file> stream, MediaBuffer* buffer,
boost::uint16_t swfVersion, int format);
- ~MediaDecoderSdl();
-
- /// Seeks to pos
- boost::uint32_t seek(boost::uint32_t pos);
-
- std::pair<boost::uint32_t, boost::uint32_t> getWidthAndHeight();
-
-private:
- /// Sets up the parser
- bool setupParser();
-
- /// The decoding thread. Sets up the decoder, and decodes.
- static void decodeThread(MediaDecoderSdl* decoder);
-
- /// Sets up the decoder
- bool setupDecoding();
-};
-
-} // gnash.media namespace
-} // namespace gnash
-
-#endif // __MEDIADECODERSDL_H__
Index: libmedia/sdl/MediaParserFfmpeg.cpp
===================================================================
RCS file: libmedia/sdl/MediaParserFfmpeg.cpp
diff -N libmedia/sdl/MediaParserFfmpeg.cpp
--- libmedia/sdl/MediaParserFfmpeg.cpp 21 Jan 2008 23:10:16 -0000 1.11
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,417 +0,0 @@
-// MediaParserFfmpeg.cpp: Media parser using ffmpeg
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: MediaParserFfmpeg.cpp,v 1.11 2008/01/21 23:10:16 rsavoye Exp $
-
-#include "MediaParserFfmpeg.h"
-#include "log.h"
-#include <boost/scoped_array.hpp>
-
-namespace gnash {
-namespace media {
-
-MediaParserFfmpeg::MediaParserFfmpeg(boost::shared_ptr<tu_file> stream)
- :
- MediaParser(stream),
- _videoIndex(-1),
- _audioIndex(-1),
-
- _videoCodecCtx(NULL),
- _audioCodecCtx(NULL),
- _formatCtx(NULL),
-
- _lastVideoTimestamp(0),
- _lastAudioTimestamp(0),
-
- _inputPos(0),
- _maxInputPos(0)
-{
-}
-
-MediaParserFfmpeg::~MediaParserFfmpeg()
-{
-
-}
-
-
-/// Probe the stream and try to figure out what the format is.
-//
-/// @param stream the tu_file to use for reading
-/// @return a pointer to the AVInputFormat structure containing
-/// information about the input format, or NULL.
-static AVInputFormat*
-probeStream(tu_file* stream)
-{
- boost::scoped_array<boost::uint8_t> buffer(new boost::uint8_t[4096]);
-
- // Probe the file to detect the format
- AVProbeData probe_data;
- probe_data.filename = "";
- probe_data.buf = buffer.get();
- probe_data.buf_size = 4096;
-
- // Get probe data, making sure the necessary data is available
- if (stream->read_bytes(probe_data.buf, probe_data.buf_size)
- < probe_data.buf_size)
- {
- log_error(_("Stream too short to determine input format"));
- return NULL;
- }
-
- return av_probe_input_format(&probe_data, 1);
-}
-
-bool MediaParserFfmpeg::setupParser()
-{
-
- // 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
- // XXX should we call avcodec_init() first?
- av_register_all();
-
- AVInputFormat* inputFmt = probeStream(_stream.get());
- if (!inputFmt) {
- log_error(_("Couldn't determine stream input format"));
- //pushOnStatus(streamNotFound);
- return false;
- }
-
- // After the format probe, reset to the beginning of the file.
- _stream->set_position(0);
-
- // Setup the filereader/seeker mechanism. 7th argument (NULL) is the
writer function,
- // which isn't needed.
- init_put_byte(&_byteIOCxt, new boost::uint8_t[500000], 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){
- log_error(_("Couldn't open stream for decoding"));
- //pushOnStatus(streamNotFound);
- return false;
- }
-
- // 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(_formatCtx);
- if (ret < 0)
- {
- log_error(_("Couldn't find stream information, error code:
%d"), ret);
- //pushOnStatus(streamNotFound);
- return false;
- }
-
-// _formatCtx->pb.eof_reached = 0;
-// av_read_play(_formatCtx);
-
- // Find the first video & audio stream
- _videoIndex = -1;
- _audioIndex = -1;
- //assert(_formatCtx->nb_streams >= 0); useless assert.
- for (unsigned int i = 0; i < static_cast<unsigned
int>(_formatCtx->nb_streams); i++)
- {
- AVCodecContext* enc = _formatCtx->streams[i]->codec;
-
- switch (enc->codec_type)
- {
- case CODEC_TYPE_AUDIO:
- if (_audioIndex < 0)
- {
- _audioIndex = i;
- _audioStream = _formatCtx->streams[i];
- }
- break;
-
- case CODEC_TYPE_VIDEO:
- if (_videoIndex < 0)
- {
- _videoIndex = i;
- _videoStream = _formatCtx->streams[i];
- }
- break;
- default:
- break;
- }
- }
-
- if (_videoIndex >= 0)
- {
-
- // Get a pointer to the codec context for the video stream
- _videoCodecCtx = _formatCtx->streams[_videoIndex]->codec;
-
-/* // Find the decoder for the video stream
- AVCodec* pCodec =
avcodec_find_decoder(_videoCodecCtx->codec_id);
- if (pCodec == NULL)
- {
- _videoCodecCtx = NULL;
- log_error(_("Video decoder %d not found"),
_videoCodecCtx->codec_id);
- return false;
- }
-
- // Open codec
- if (avcodec_open(_videoCodecCtx, pCodec) < 0)
- {
- log_error(_("Could not open codec %d"),
_videoCodecCtx->codec_id);
- return false;
- }
-
- // Allocate a frame to store the decoded frame in
- _frame = avcodec_alloc_frame();*/
-
- }
-
- if (_audioIndex >= 0) {
- // Get a pointer to the audio codec context for the video stream
- _audioCodecCtx = _formatCtx->streams[_audioIndex]->codec;
-
-/* // Find the decoder for the audio stream
- AVCodec* pACodec =
avcodec_find_decoder(_audioCodecCtx->codec_id);
- if(pACodec == NULL)
- {
- log_error(_("No available audio decoder %d to process
stream"), _audioCodecCtx->codec_id);
- return false;
- }
-
- // Open codec
- if (avcodec_open(_audioCodecCtx, pACodec) < 0)
- {
- log_error(_("Could not open audio codec %d for
stream"),_audioCodecCtx->codec_id);
- return false;
- }*/
-
- }
- return true;
-}
-
-MediaFrame* MediaParserFfmpeg::parseMediaFrame()
-{
- AVPacket packet;
- int rc = av_read_frame(_formatCtx, &packet);
-
- if (rc >= 0)
- {
- MediaFrame* ret = new MediaFrame;
- ret->dataSize = packet.size;
-
- // "The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE
- // larger than the actual read bytes because some optimized
bitstream
- // readers read 32 or 64 bits at once and could read over the
end."
- ret->data = new boost::uint8_t[packet.size +
FF_INPUT_BUFFER_PADDING_SIZE];
-
- memcpy(ret->data, packet.data, packet.size);
-
- // "The end of the input buffer should be set to 0 to ensure
- // that no overreading happens for damaged MPEG streams."
- memset(ret->data + packet.size, 0,
FF_INPUT_BUFFER_PADDING_SIZE);
-
- if (packet.stream_index == _audioIndex)
- {
- ret->tag = AUDIO_TAG;
-
- // set presentation timestamp
- if (packet.dts != static_cast<signed
long>(AV_NOPTS_VALUE))
- {
- ret->timestamp =
static_cast<boost::uint64_t>(as_double(_audioStream->time_base) * packet.dts *
1000.0);
- }
-
- if (ret->timestamp != 0)
- {
- // update audio clock with pts, if present
- _lastAudioTimestamp = ret->timestamp;
- } else {
- ret->timestamp = _lastAudioTimestamp;
- }
-
- // update video clock for next frame
- boost::uint32_t frame_delay;
- frame_delay =
static_cast<boost::uint32_t>((as_double(_audioStream->time_base) * packet.dts)
* 1000.0);
-
- _lastAudioTimestamp += frame_delay;
-
- } else if (packet.stream_index == _videoIndex) {
- ret->tag = VIDEO_TAG;
-
- ret->timestamp = 0;
-
- // set presentation timestamp
- if (packet.dts != static_cast<signed
long>(AV_NOPTS_VALUE))
- {
- ret->timestamp =
static_cast<boost::uint32_t>((as_double(_videoStream->time_base) * packet.dts)
* 1000.0);
- }
-
- if (ret->timestamp != 0)
- {
- // update video clock with pts, if present
- _lastVideoTimestamp = ret->timestamp;
- } else {
- ret->timestamp = _lastVideoTimestamp;
- }
-
- // update video clock for next frame
- boost::uint32_t frame_delay;
- frame_delay =
static_cast<boost::uint32_t>(as_double(_videoStream->codec->time_base) *
1000.0);
-
- // for MPEG2, the frame can be repeated, so we update
the clock accordingly
- //frame_delay +=
static_cast<boost::uint32_t>(_frame->repeat_pict * (frame_delay * 0.5) *
1000.0);
-
- _lastVideoTimestamp += frame_delay;
-
- } else {
- delete ret;
- return NULL;
- }
- av_free_packet(&packet);
- return ret;
- } else {
- return NULL;
- }
-
-}
-
-boost::uint32_t MediaParserFfmpeg::seek(boost::uint32_t pos)
-{
- long newpos = 0;
- double timebase = 0;
- boost::uint32_t ret = 0;
-
- AVStream* videostream = _formatCtx->streams[_videoIndex];
- timebase = static_cast<double>(videostream->time_base.num /
videostream->time_base.den);
- newpos = static_cast<long>(pos / timebase);
-
- if (av_seek_frame(_formatCtx, _videoIndex, newpos, 0) < 0) {
- log_error(_("%s: seeking failed"), __FUNCTION__);
- return 0;
- }
- // We have to do parse a new frame to get
- // the new position. This is kindof hackish and ugly :-(
- AVPacket Packet;
- av_init_packet(&Packet);
- double newtime = 0;
- while (newtime == 0) {
- if ( av_read_frame(_formatCtx, &Packet) < 0) {
- av_seek_frame(_formatCtx, -1, 0,AVSEEK_FLAG_BACKWARD);
- av_free_packet(&Packet);
- return 0;
- }
-
- newtime = timebase *
static_cast<double>(_formatCtx->streams[_videoIndex]->cur_dts);
- }
-
- av_free_packet(&Packet);
- av_seek_frame(_formatCtx, _videoIndex, newpos, 0);
- boost::uint32_t newtime_ms = static_cast<boost::int32_t>(newtime /
1000.0);
-
- _lastAudioTimestamp = newtime_ms;
- _lastVideoTimestamp = newtime_ms;
- ret = newtime_ms;
-
- return ret;
-}
-
-std::auto_ptr<VideoInfo>
-MediaParserFfmpeg::getVideoInfo()
-{
- 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));
- ret->videoCodecCtx = _videoCodecCtx;
- return ret;
-}
-
-std::auto_ptr<AudioInfo>
-MediaParserFfmpeg::getAudioInfo()
-{
- if (!_audioCodecCtx || !_audioStream) return
std::auto_ptr<AudioInfo>(NULL);
-
- 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));
-}
-
-
-// ffmpeg callback function
-int
-MediaParserFfmpeg::readPacket(void* opaque, boost::uint8_t* buf, int buf_size)
-{
-
- MediaParserFfmpeg* decoder = static_cast<MediaParserFfmpeg*>(opaque);
-
- size_t ret = decoder->_stream->read_bytes(static_cast<void*>(buf),
buf_size);
- decoder->_inputPos += ret;
-
- if (decoder->_inputPos > decoder->_maxInputPos) decoder->_maxInputPos =
decoder->_inputPos;
-
- return ret;
-
-}
-
-// ffmpeg callback function
-offset_t
-MediaParserFfmpeg::seekMedia(void *opaque, offset_t offset, int whence){
-
- MediaParserFfmpeg* decoder = static_cast<MediaParserFfmpeg*>(opaque);
-
- // Offset is absolute new position in the file
- if (whence == SEEK_SET) {
- if (decoder->_stream->set_position(offset) != 0) {
- decoder->_inputPos = decoder->_stream->get_position();
- } else {
- decoder->_inputPos = offset;
- }
-
- // New position is offset + old position
- } else if (whence == SEEK_CUR) {
- if (decoder->_stream->set_position(decoder->_inputPos + offset)
!= 0) {
- decoder->_inputPos = decoder->_stream->get_position();
- } else {
- decoder->_inputPos += offset;
- }
-
- // // New position is offset + end of file
- } else if (whence == SEEK_END) {
- // This is (most likely) a file being downloaded, so we can't
seek to the end
- // without causing big delays! Instead we seek to 50.000
bytes... seems to work fine...
- if (decoder->_stream->set_position(50000) != 0) {
- decoder->_inputPos = decoder->_stream->get_position();
- } else {
- decoder->_inputPos = 50000;
- }
-
- }
-
- if (decoder->_inputPos > decoder->_maxInputPos) decoder->_maxInputPos =
decoder->_inputPos;
-
- return decoder->_inputPos;
-}
-
-} // gnash.media namespace
-} // namespace gnash
Index: libmedia/sdl/MediaParserFfmpeg.h
===================================================================
RCS file: libmedia/sdl/MediaParserFfmpeg.h
diff -N libmedia/sdl/MediaParserFfmpeg.h
--- libmedia/sdl/MediaParserFfmpeg.h 21 Jan 2008 23:10:16 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,127 +0,0 @@
-// MediaParserFfmpeg.h: Media parser using ffmpeg
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: MediaParserFfmpeg.h,v 1.9 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifndef __MEDIAPARSERFFMPEG_H__
-#define __MEDIAPARSERFFMPEG_H__
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "MediaParser.h"
-#include "MediaBuffer.h"
-
-extern "C" {
-#include <ffmpeg/avformat.h>
-}
-
-namespace gnash {
-namespace media {
-
-
-
-/// \brief
-/// The MediaParser class detects the format of the input file, and parses it
on demand.
-///
-class MediaParserFfmpeg : public MediaParser
-{
-public:
- MediaParserFfmpeg(boost::shared_ptr<tu_file> stream);
- ~MediaParserFfmpeg();
-
- /// Setup the parser
- //
- /// @return whether we'll be able to parse the file.
- bool setupParser();
-
- /// Used to parse the next media frame in the stream and return it
- MediaFrame* parseMediaFrame();
-
- /// Try to seek to the given millisecond. Returns the millisecond where
the
- /// seek got to.
- boost::uint32_t seek(boost::uint32_t);
-
- /// Returns a VideoInfo class about the videostream
- //
- /// @return a VideoInfo class about the videostream
- std::auto_ptr<VideoInfo> getVideoInfo();
-
- /// Returns a AudioInfo class about the audiostream
- //
- /// @return a AudioInfo class about the audiostream
- std::auto_ptr<AudioInfo> getAudioInfo();
-
- // Used for ffmpeg data read and seek callbacks
- static int readPacket(void* opaque, boost::uint8_t* buf, int buf_size);
-
- // Used for ffmpeg data read and seek callbacks
- static offset_t seekMedia(void *opaque, offset_t offset, int whence);
-
- /// Returns the last parsed position in the file in bytes
- boost::uint32_t getLastParsedPos() { return _maxInputPos; }
-
-private:
-
- // Used to calculate a decimal value from a ffmpeg fraction
- inline double as_double(AVRational time)
- {
- return time.num / (double) time.den;
- }
-
- int _videoIndex;
- int _audioIndex;
-
- // video
- AVCodecContext* _videoCodecCtx;
- AVStream* _videoStream;
-
- // audio
- AVCodecContext* _audioCodecCtx;
- AVStream* _audioStream;
-
- // the format (mp3, avi, etc.)
- AVFormatContext *_formatCtx;
-
- // A ffmpeg thingy
- ByteIOContext _byteIOCxt;
-
- // The timestamp of the last parsed video frame, in milliseconds.
- boost::uint32_t _lastVideoTimestamp;
-
- // The timestamp of the last parsed audio frame, in seconds.
- boost::uint32_t _lastAudioTimestamp;
-
- // The position of the parserhead.
- boost::uint32_t _inputPos;
-
- // The max value inputPos ever had.
- boost::uint32_t _maxInputPos;
-};
-
-
-
-} // gnash.media namespace
-} // namespace gnash
-
-#endif // __MEDIAPARSERFFMPEG_H__
Index: libmedia/sdl/VideoDecoderFfmpeg.cpp
===================================================================
RCS file: libmedia/sdl/VideoDecoderFfmpeg.cpp
diff -N libmedia/sdl/VideoDecoderFfmpeg.cpp
--- libmedia/sdl/VideoDecoderFfmpeg.cpp 21 Jan 2008 23:10:16 -0000 1.13
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,370 +0,0 @@
-// VideoDecoderFfmpeg.cpp: Video decoding using the FFMPEG library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-// $Id: VideoDecoderFfmpeg.cpp,v 1.13 2008/01/21 23:10:16 rsavoye Exp $
-
-#include "VideoDecoderFfmpeg.h"
-
-#ifdef HAVE_SWSCALE_H
-extern "C" {
-#include <ffmpeg/swscale.h>
-}
-#endif
-#include <boost/scoped_array.hpp>
-
-namespace gnash {
-namespace media {
-
-VideoDecoderFfmpeg::VideoDecoderFfmpeg ()
- :
- _videoCodec(NULL),
- _videoCodecCtx(NULL)
-{}
-
-VideoDecoderFfmpeg::~VideoDecoderFfmpeg()
-{
- if (_videoCodecCtx)
- {
- avcodec_close(_videoCodecCtx);
- av_free(_videoCodecCtx);
- }
-}
-
-bool VideoDecoderFfmpeg::setup(
- int width,
- int height,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType format, // should this argument be of codecType
type ?
- int /*outputFormat*/)
-{
- // Init the avdecoder-decoder
- avcodec_init();
- avcodec_register_all();// change this to only register need codec?
-
- enum CodecID codec_id;
-
- // Find the decoder and init the parser
- switch(format) {
- case VIDEO_CODEC_H263:
- codec_id = CODEC_ID_FLV1;
- break;
-#ifdef FFMPEG_VP6
- case VIDEO_CODEC_VP6:
- codec_id = CODEC_ID_VP6F;
- break;
-#endif
- case VIDEO_CODEC_SCREENVIDEO:
- codec_id = CODEC_ID_FLASHSV;
- break;
- default:
- log_error(_("Unsupported video codec %d"),
- static_cast<int>(format));
- return false;
- }
-
- _videoCodec = avcodec_find_decoder(static_cast<CodecID>(codec_id));
-
- if (!_videoCodec) {
- log_error(_("libavcodec can't decode the current video
format"));
- return false;
- }
-
- _videoCodecCtx = avcodec_alloc_context();
- if (!_videoCodecCtx) {
- log_error(_("libavcodec couldn't allocate context"));
- return false;
- }
-
- int ret = avcodec_open(_videoCodecCtx, _videoCodec);
- if (ret < 0) {
- log_error(_("libavcodec failed to initialize codec"));
- return false;
- }
- _videoCodecCtx->width = width;
- _videoCodecCtx->height = height;
-
- assert(_videoCodecCtx->width > 0);
- assert(_videoCodecCtx->height > 0);
- return true;
-}
-
-bool VideoDecoderFfmpeg::setup(VideoInfo* info)
-{
- // Init the avdecoder-decoder
- avcodec_init();
- avcodec_register_all();// change this to only register need codec?
-
- if (info->type == FLASH) {
- enum CodecID codec_id;
-
- // Find the decoder and init the parser
- switch(info->codec) {
- case VIDEO_CODEC_H263:
- codec_id = CODEC_ID_FLV1;
- break;
-#ifdef FFMPEG_VP6
- case VIDEO_CODEC_VP6:
- codec_id = CODEC_ID_VP6F;
- break;
-#endif
- case VIDEO_CODEC_SCREENVIDEO:
- codec_id = CODEC_ID_FLASHSV;
- break;
- default:
- log_error(_("Unsupported video codec %d"),
- static_cast<int>(info->codec));
- return false;
- }
- _videoCodec =
avcodec_find_decoder(static_cast<CodecID>(codec_id));
- } else if (info->type == FFMPEG) {
- _videoCodec =
avcodec_find_decoder(static_cast<CodecID>(info->codec));
- } else {
- //log_error("Video codecType unknown: %d, %d, %d",
- // info->type, FLASH, FFMPEG);
- return false;
- }
-
- if (!_videoCodec) {
- log_error(_("libavcodec can't decode the current video
format"));
- return false;
- }
-
- // Reuse the videoCodecCtx from the ffmpeg parser if exists/possible
- if (info->videoCodecCtx) {
- log_debug("re-using the parsers videoCodecCtx");
- _videoCodecCtx = info->videoCodecCtx;
- } else {
- _videoCodecCtx = avcodec_alloc_context();
- }
-
- if (!_videoCodecCtx) {
- log_error(_("libavcodec couldn't allocate context"));
- return false;
- }
-
- int ret = avcodec_open(_videoCodecCtx, _videoCodec);
- if (ret < 0) {
- log_error(_("libavcodec failed to initialize codec"));
- return false;
- }
-
- return true;
-}
-
-boost::uint8_t*
-VideoDecoderFfmpeg::convertRGB24(AVCodecContext* srcCtx, AVFrame* srcFrame)
-{
- int width = srcCtx->width, height = srcCtx->height;
-
- int bufsize = avpicture_get_size(PIX_FMT_RGB24, width, height);
- if (bufsize == -1) {
- return NULL;
- }
-
- boost::uint8_t* buffer = new boost::uint8_t[bufsize];
- if (!buffer) {
- return NULL;
- }
-
- AVPicture picture;
-
- avpicture_fill(&picture, buffer, PIX_FMT_RGB24, width, height);
-
-#ifndef HAVE_SWSCALE_H
- img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) srcFrame,
- srcCtx->pix_fmt, width, height);
-#else
- static SwsContext* context = NULL;
-
- if (!context)
- {
- context = sws_getContext(width, height, srcCtx->pix_fmt,
- width, height, PIX_FMT_RGB24,
- SWS_FAST_BILINEAR, NULL, NULL, NULL);
-
- if (!context)
- {
- delete [] buffer;
- return NULL;
- }
- }
-
- int rv = sws_scale(context, srcFrame->data, srcFrame->linesize, 0,
- width, picture.data, picture.linesize);
- if (rv == -1)
- {
- delete [] buffer;
- return NULL;
- }
-
-#endif // HAVE_SWSCALE_H
-
- srcFrame->linesize[0] = picture.linesize[0];
- srcFrame->data[0] = picture.data[0];
-
- return buffer;
-}
-
-boost::uint8_t* VideoDecoderFfmpeg::decode(boost::uint8_t* input,
- boost::uint32_t inputSize,
- boost::uint32_t& outputSize)
-{
- // Allocate a frame to store the decoded frame in
- AVFrame* frame = avcodec_alloc_frame();
- if ( ! frame )
- {
- log_error(_("Out of memory while allocating avcodec frame"));
- throw std::bad_alloc();
- }
-
- int got = 0;
-
- avcodec_decode_video(_videoCodecCtx, frame, &got, input, inputSize);
-
- if (got)
- {
- boost::scoped_array<boost::uint8_t> buffer;
-
- // Set to the next multiple of four. Some videos have
- // padding bytes, so that the source width is more than three
times
- // the video width. A likely explanation (supported by
- // tests) is that it is always padded out to a multiple of 4.
- // Have found no documenation on this.
- unsigned int srcwidth = (_videoCodecCtx->width * 3 + 3) &~ 3;
-
- boost::uint8_t* decodedData = new boost::uint8_t[srcwidth *
_videoCodecCtx->height];
- buffer.reset(convertRGB24(_videoCodecCtx, frame));
-
- // Copy the data to the buffer in the correct RGB format
- boost::uint8_t* srcptr = frame->data[0];
- boost::uint8_t* srcend = frame->data[0]
- + frame->linesize[0]
- * _videoCodecCtx->height;
- boost::uint8_t* dstptr = decodedData;
-
- outputSize = 0;
-
- while (srcptr < srcend)
- {
- memcpy(dstptr, srcptr, srcwidth);
- srcptr += frame->linesize[0];
- dstptr += srcwidth;
- outputSize += srcwidth;
- }
-
- av_free(frame);
- return decodedData;
-
-/* if (_videoFrameFormat == NONE) { // NullGui?
- return;
-
- } else if (_videoFrameFormat == YUV && _videoCodecCtx->pix_fmt
!= PIX_FMT_YUV420P) {
- abort(); // TODO
- //img_convert((AVPicture*) pFrameYUV, PIX_FMT_YUV420P,
(AVPicture*) pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
- // Don't use depreceted img_convert, use sws_scale
-
- } else if (_videoFrameFormat == RGB && _videoCodecCtx->pix_fmt
!= PIX_FMT_RGB24) {
- buffer.reset(convertRGB24(_videoCodecCtx, frame));
- }
-
- raw_mediadata_t* video = new raw_mediadata_t;
- if (_videoFrameFormat == YUV) {
- abort(); // See image.cpp to see what yuv size is
- //video->m_data = new
boost::uint8_t[static_cast<image::yuv*>(m_imageframe)->size()];
- } else if (_videoFrameFormat == RGB) {
- video->m_data = new
boost::uint8_t[_videoCodecCtx->width * _videoCodecCtx->height * 3];
- //}
-
- video->m_ptr = video->m_data;
- video->m_stream_index = _videoIndex;
- video->m_pts = 0;
-
- video->m_pts =
static_cast<boost::uint32_t>((as_double(_videoStream->time_base) * packet->dts)
* 1000.0);
-
-
- if (_videoFrameFormat == YUV) {
- //image::yuv* yuvframe =
static_cast<image::yuv*>(_imageframe);
- int copied = 0;
- boost::uint8_t* ptr = video->m_data;
- for (int i = 0; i < 3 ; i++)
- {
- int shift = (i == 0 ? 0 : 1);
- boost::uint8_t* yuv_factor = _frame->data[i];
- int h = _videoCodecCtx->height >> shift;
- int w = _videoCodecCtx->width >> shift;
- for (int j = 0; j < h; j++)
- {
- copied += w;
- //assert(copied <= yuvframe->size());
- memcpy(ptr, yuv_factor, w);
- yuv_factor += _frame->linesize[i];
- ptr += w;
- }
- }
- video->m_size = copied;
- } else if (_videoFrameFormat == RGB) {
-
- boost::uint8_t* srcptr = _frame->data[0];
- boost::uint8_t* srcend = _frame->data[0] +
_frame->linesize[0] * _videoCodecCtx->height;
- boost::uint8_t* dstptr = video->m_data;
- unsigned int srcwidth = _videoCodecCtx->width * 3;
-
- video->m_size = 0;
-
- while (srcptr < srcend) {
- memcpy(dstptr, srcptr, srcwidth);
- srcptr += _frame->linesize[0];
- dstptr += srcwidth;
- video->m_size += srcwidth;
- }
-
- }*/
- }
- else
- {
- log_error("Decoding of a video frame failed");
- av_free(frame);
- return NULL;
- }
-}
-
-std::auto_ptr<image::image_base>
-VideoDecoderFfmpeg::decodeToImage(boost::uint8_t* input, boost::uint32_t
inputSize)
-{
- boost::uint32_t outputSize = 0;
- boost::uint8_t* decodedData = decode(input, inputSize, outputSize);
-
- if (!decodedData || outputSize == 0)
- {
- return std::auto_ptr<image::image_base>(NULL);
- }
-
- std::auto_ptr<image::image_base> ret(new image::rgb(
- _videoCodecCtx->width,
- _videoCodecCtx->height
- ));
- ret->update(decodedData);
- delete [] decodedData;
- return ret;
-
-}
-
-} // gnash.media namespace
-} // gnash namespace
Index: libmedia/sdl/VideoDecoderFfmpeg.h
===================================================================
RCS file: libmedia/sdl/VideoDecoderFfmpeg.h
diff -N libmedia/sdl/VideoDecoderFfmpeg.h
--- libmedia/sdl/VideoDecoderFfmpeg.h 21 Jan 2008 23:10:16 -0000 1.11
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,74 +0,0 @@
-// VideoDecoderFfmpeg.h: Video decoding using the FFMPEG library.
-//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: VideoDecoderFfmpeg.h,v 1.11 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifndef __VIDEODECODERFFMPEG_H__
-#define __VIDEODECODERFFMPEG_H__
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "log.h"
-#include "VideoDecoder.h"
-
-extern "C" {
-#include <ffmpeg/avcodec.h>
-}
-
-
-namespace gnash {
-namespace media {
-
-
-class VideoDecoderFfmpeg : public VideoDecoder {
-
-public:
- VideoDecoderFfmpeg();
- ~VideoDecoderFfmpeg();
-
- virtual unsigned getPaddingBytes() const { return
FF_INPUT_BUFFER_PADDING_SIZE; }
-
- bool setup(VideoInfo* info);
-
- bool setup(
- int /*width*/,
- int /*height*/,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType /*format*/,
- int /*outputFormat*/);
-
- boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize);
-
- std::auto_ptr<image::image_base> decodeToImage(boost::uint8_t*
/*input*/, boost::uint32_t /*inputSize*/);
-
- static boost::uint8_t* convertRGB24(AVCodecContext* srcCtx, AVFrame*
srcFrame);
-
-private:
-
- AVCodec* _videoCodec;
- AVCodecContext* _videoCodecCtx;
-
-};
-
-} // gnash.media namespace
-} // gnash namespace
-
-#endif // __VIDEODECODERFFMPEG_H__
Index: libmedia/sdl/sound_handler_sdl.cpp
===================================================================
RCS file: libmedia/sdl/sound_handler_sdl.cpp
diff -N libmedia/sdl/sound_handler_sdl.cpp
--- libmedia/sdl/sound_handler_sdl.cpp 21 Jan 2008 23:10:16 -0000 1.11
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,826 +0,0 @@
-// sound_handler_sdl.cpp: Sound handling using standard SDL
-//
-// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-// Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
-// which has been donated to the Public Domain.
-
-// $Id: sound_handler_sdl.cpp,v 1.11 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "sound_handler_sdl.h"
-#include "utility.h" // for convert_raw_data
-#include "AudioDecoderSimple.h"
-#include "AudioDecoderNellymoser.h"
-
-#ifdef USE_FFMPEG
-#include "AudioDecoderFfmpeg.h"
-#endif
-
-#ifdef USE_MAD
-#include "AudioDecoderMad.h"
-#endif
-
-#include "log.h"
-#include <cmath>
-#include <vector>
-#include <boost/scoped_array.hpp>
-#include <SDL.h>
-
-namespace gnash {
-namespace media {
-
-SDL_sound_handler::SDL_sound_handler()
- : soundOpened(false),
- soundsPlaying(0),
- muted(false)
-{
- // This is our sound settings
- audioSpec.freq = 44100;
- audioSpec.format = AUDIO_S16SYS; // AUDIO_S8 AUDIO_U8;
- audioSpec.channels = 2;
- audioSpec.callback = SDL_sound_handler::sdl_audio_callback;
- audioSpec.userdata = this;
- audioSpec.samples = 2048; //512 - not enough for
videostream
-}
-
-void
-SDL_sound_handler::reset()
-{
- //delete_all_sounds();
- stop_all_sounds();
-}
-
-void
-SDL_sound_handler::delete_all_sounds()
-{
- stop_all_sounds();
- for (size_t i=0, e=m_sound_data.size(); i < e; ++i)
- {
- stop_sound(i);
- delete_sound(i);
- }
- m_sound_data.clear();
-}
-
-SDL_sound_handler::~SDL_sound_handler()
-{
- delete_all_sounds();
- if (soundOpened) SDL_CloseAudio();
-}
-
-
-int SDL_sound_handler::create_sound(
- void* data,
- unsigned int data_bytes,
- std::auto_ptr<SoundInfo> sinfo)
-// Called to create a sample. We'll return a sample ID that
-// can be use for playing it.
-{
-
- assert(sinfo.get());
- std::auto_ptr<sound_data> sounddata ( new sound_data );
-
- //sounddata->data_size = data_bytes;
- sounddata->volume = 100;
- sounddata->soundinfo = sinfo;
-
- boost::mutex::scoped_lock lock(_mutex);
-
- switch (sounddata->soundinfo->getFormat())
- {
- case AUDIO_CODEC_MP3:
-#ifndef USE_FFMPEG
-#ifndef USE_MAD
- log_error(_("gnash has not been compiled to handle mp3 audio"));
- return -1;
-#endif
-#endif
- sounddata->append(reinterpret_cast<boost::uint8_t*>(data),
data_bytes);
- break;
-
- case AUDIO_CODEC_RAW:
- case AUDIO_CODEC_ADPCM:
- case AUDIO_CODEC_UNCOMPRESSED:
- case AUDIO_CODEC_NELLYMOSER:
- sounddata->append(reinterpret_cast<boost::uint8_t*>(data),
data_bytes);
- break;
-
- default:
- // Unhandled format.
- log_error(_("unknown sound format %d requested; gnash does not
handle it"), (int)sounddata->soundinfo->getFormat());
- return -1; // Unhandled format, set to NULL.
- }
-
- m_sound_data.push_back(sounddata.release()); // the vector takes
ownership
- int sound_id = m_sound_data.size()-1;
-
- return sound_id;
-
-}
-
-// this gets called when a stream gets more data
-long SDL_sound_handler::fill_stream_data(unsigned char* data, unsigned int
data_bytes, unsigned int /*sample_count*/, int handle_id)
-
-{
-
- boost::mutex::scoped_lock lock(_mutex);
- // @@ does a negative handle_id have any meaning ?
- // should we change it to unsigned instead ?
- if (handle_id < 0 || (unsigned int) handle_id+1 > m_sound_data.size())
- {
- delete [] data;
- return -1;
- }
- sound_data* sounddata = m_sound_data[handle_id];
-
- // If doing ADPCM, knowing the framesize is needed to decode!
- if (sounddata->soundinfo->getFormat() == AUDIO_CODEC_ADPCM) {
- sounddata->m_frames_size[sounddata->size()] = data_bytes;
- }
-
- // Handling of the sound data
- size_t start_size = sounddata->size();
- sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
-
- return start_size;
-}
-
-
-void SDL_sound_handler::play_sound(int sound_handle, int loop_count, int
offset, long start_position, const std::vector<sound_envelope>* envelopes)
-// Play the index'd sample.
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists, or if audio is muted
- if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >=
m_sound_data.size() || muted)
- {
- // Invalid handle or muted
- return;
- }
-
- sound_data* sounddata = m_sound_data[sound_handle];
-
- // If this is called from a streamsoundblocktag, we only start if this
- // sound isn't already playing.
- if (start_position > 0 && sounddata->m_active_sounds.size() > 0) {
- return;
- }
-
- // Make sure sound actually got some data
- if (sounddata->size() < 1) {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Trying to play sound with size 0"));
- );
- return;
- }
-
- // Make a "active_sound" for this sound which is later placed on the
vector of instances of this sound being played
- std::auto_ptr<active_sound> sound ( new active_sound() );
-
- // Set source data to the active_sound
- sound->set_data(sounddata);
-
- // Set the given options of the sound
- if (start_position < 0) sound->position = 0;
- else sound->position = start_position;
-
- if (offset < 0) sound->offset = 0;
- else sound->offset = (sounddata->soundinfo->isStereo() ? offset :
offset*2); // offset is stored as stereo
-
- sound->envelopes = envelopes;
-
- // Set number of loop we should do. -1 is infinte loop, 0 plays it
once, 1 twice etc.
- sound->loop_count = loop_count;
-
- sound->decoder = NULL;
-
- switch (sounddata->soundinfo->getFormat()) {
- case AUDIO_CODEC_NELLYMOSER:
- case AUDIO_CODEC_NELLYMOSER_8HZ_MONO:
- sound->decoder = new AudioDecoderNellymoser();
-
- if (!sound->decoder->setup(sounddata->soundinfo.get())) {
- log_error("The audio decoder can't decode the audio");
- delete sound->decoder;
- sound->decoder = NULL;
- }
-
- break;
- case AUDIO_CODEC_MP3:
-#ifdef USE_MAD
- sound->decoder = new AudioDecoderMad();
-
- if (!sound->decoder->setup(sounddata->soundinfo.get())) {
- log_error("The audio decoder can't decode the audio");
- delete sound->decoder;
- sound->decoder = NULL;
- }
-
- break;
-#endif
-#ifdef USE_FFMPEG
- sound->decoder = new AudioDecoderFfmpeg();
-
- if (!sound->decoder->setup(sounddata->soundinfo.get())) {
- log_error("The audio decoder can't decode the audio");
- delete sound->decoder;
- sound->decoder = NULL;
- }
-
- break;
-#endif
- case AUDIO_CODEC_ADPCM:
- default:
-
- sound->decoder = new AudioDecoderSimple();
-
- if (!sound->decoder->setup(sounddata->soundinfo.get())) {
- log_error("The audio decoder can't decode the audio");
- delete sound->decoder;
- sound->decoder = NULL;
- }
-
- }
-
- if (!soundOpened) {
- if (SDL_OpenAudio(&audioSpec, NULL) < 0 ) {
- log_error(_("Unable to start SDL sound: %s"),
SDL_GetError());
- return;
- }
- soundOpened = true;
-
- }
-
- ++soundsPlaying;
- ++_soundsStarted;
- sounddata->m_active_sounds.push_back(sound.release());
-
- if (soundsPlaying == 1) {
- SDL_PauseAudio(0);
- }
-
-}
-
-
-void SDL_sound_handler::stop_sound(int sound_handle)
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists.
- if (sound_handle < 0 || (unsigned int) sound_handle >=
m_sound_data.size())
- {
- // Invalid handle.
- } else {
-
- sound_data* sounddata = m_sound_data[sound_handle];
-
- for (boost::int32_t i = (boost::int32_t)
sounddata->m_active_sounds.size()-1; i >-1; i--) {
-
- //active_sound* sound = sounddata->m_active_sounds[i];
-
- // Stop sound, remove it from the active list
- //sound->delete_raw_data();
- //delete sound->decoder;
-
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + i);
-
- --soundsPlaying;
- ++_soundsStopped;
- }
- }
-
-}
-
-
-// this gets called when it's done with a sample.
-void SDL_sound_handler::delete_sound(int sound_handle)
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) <
m_sound_data.size())
- {
- delete m_sound_data[sound_handle];
- m_sound_data[sound_handle] = NULL;
- }
-
-}
-
-// This will stop all sounds playing. Will cause problems if the soundhandler
is made static
-// and supplys sound_handling for many SWF's, since it will stop all sounds
with no regard
-// for what sounds is associated with what SWF.
-void SDL_sound_handler::stop_all_sounds()
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- boost::int32_t num_sounds = (boost::int32_t) m_sound_data.size()-1;
- for (boost::int32_t j = num_sounds; j > -1; j--) {//Optimized
- sound_data* sounddata = m_sound_data[j];
- boost::int32_t num_active_sounds = (boost::int32_t)
sounddata->m_active_sounds.size()-1;
- for (boost::int32_t i = num_active_sounds; i > -1; i--) {
-
- //active_sound* sound = sounddata->m_active_sounds[i];
-
- // Stop sound, remove it from the active list
- //delete sound->decoder;
-
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + i);
-
- --soundsPlaying;
- ++_soundsStopped;
- }
- }
-}
-
-
-// returns the sound volume level as an integer from 0 to 100,
-// where 0 is off and 100 is full volume. The default setting is 100.
-int SDL_sound_handler::get_volume(int sound_handle) {
-
- boost::mutex::scoped_lock lock(_mutex);
-
- int ret;
- // Check if the sound exists.
- if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) <
m_sound_data.size())
- {
- ret = m_sound_data[sound_handle]->volume;
- } else {
- ret = 0; // Invalid handle
- }
- return ret;
-}
-
-
-// A number from 0 to 100 representing a volume level.
-// 100 is full volume and 0 is no volume. The default setting is 100.
-void SDL_sound_handler::set_volume(int sound_handle, int volume) {
-
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists.
- if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >=
m_sound_data.size())
- {
- // Invalid handle.
- } else {
-
- // Set volume for this sound. Should this only apply to the
active sounds?
- m_sound_data[sound_handle]->volume = volume;
- }
-
-
-}
-
-SoundInfo* SDL_sound_handler::get_sound_info(int sound_handle) {
-
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists.
- if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) <
m_sound_data.size())
- {
- return m_sound_data[sound_handle]->soundinfo.get();
- } else {
- return NULL;
- }
-
-}
-
-// gnash calls this to mute audio
-void SDL_sound_handler::mute() {
- stop_all_sounds();
- muted = true;
-}
-
-// gnash calls this to unmute audio
-void SDL_sound_handler::unmute() {
- muted = false;
-}
-
-bool SDL_sound_handler::is_muted()
-{
- return muted;
-}
-
-void SDL_sound_handler::attach_aux_streamer(aux_streamer_ptr ptr, void*
owner)
-{
- boost::mutex::scoped_lock lock(_mutex);
- assert(owner);
- assert(ptr);
-
- if ( ! m_aux_streamer.insert(std::make_pair(owner, ptr)).second )
- {
- // Already in the hash.
- return;
- }
-
- ++soundsPlaying;
-
- if (!soundOpened) {
- if (SDL_OpenAudio(&audioSpec, NULL) < 0 ) {
- log_error(_("Unable to start aux SDL sound: %s"),
SDL_GetError());
- return;
- }
- soundOpened = true;
- }
- SDL_PauseAudio(0);
-
-}
-
-void SDL_sound_handler::detach_aux_streamer(void* owner)
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- CallbacksMap::iterator it2=m_aux_streamer.find(owner);
- if ( it2 != m_aux_streamer.end() )
- {
- // WARNING: erasing would break any iteration in the map
- --soundsPlaying;
- m_aux_streamer.erase(it2);
- }
-}
-
-unsigned int SDL_sound_handler::get_duration(int sound_handle)
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists.
- if (sound_handle < 0 || (unsigned int) sound_handle >=
m_sound_data.size())
- {
- // Invalid handle.
- return 0;
- }
-
- sound_data* sounddata = m_sound_data[sound_handle];
-
- boost::uint32_t sampleCount = sounddata->soundinfo->getSampleCount();
- boost::uint32_t sampleRate = sounddata->soundinfo->getSampleRate();
-
- // Return the sound duration in milliseconds
- if (sampleCount > 0 && sampleRate > 0) {
- unsigned int ret = sampleCount / sampleRate * 1000;
- ret += ((sampleCount % sampleRate) * 1000) / sampleRate;
- if (sounddata->soundinfo->isStereo()) ret = ret / 2;
- return ret;
- } else {
- return 0;
- }
-}
-
-unsigned int SDL_sound_handler::get_position(int sound_handle)
-{
- boost::mutex::scoped_lock lock(_mutex);
-
- // Check if the sound exists.
- if (sound_handle < 0 || (unsigned int) sound_handle >=
m_sound_data.size())
- {
- // Invalid handle.
- return 0;
- }
-
- sound_data* sounddata = m_sound_data[sound_handle];
-
- // If there is no active sounds, return 0
- if (sounddata->m_active_sounds.size() == 0) return 0;
-
- // We use the first active sound of this.
- active_sound* asound = sounddata->m_active_sounds[0];
-
- // Return the playhead position in milliseconds
- unsigned int ret = asound->samples_played / audioSpec.freq * 1000;
- ret += ((asound->samples_played % audioSpec.freq) * 1000) /
audioSpec.freq;
- if (audioSpec.channels > 1) ret = ret / audioSpec.channels;
- return ret;
-}
-
-sound_handler*
-create_sound_handler_sdl()
-// Factory.
-{
- return new SDL_sound_handler;
-}
-
-// Pointer handling and checking functions
-boost::uint8_t*
-active_sound::get_raw_data_ptr(unsigned long int pos)
-{
- if ( _decodedData.get() )
- {
- return _decodedData->data(pos);
- }
- else return 0;
-}
-
-boost::uint8_t*
-active_sound::get_data_ptr(unsigned long int pos)
-{
- assert(_undecodedData);
- return _undecodedData->data(pos);
-}
-
-void active_sound::set_data(sound_data* idata)
-{
- _undecodedData = idata;
-}
-
-void active_sound::deleteDecodedData()
-{
- _decodedData.reset();
-}
-
-// AS-volume adjustment
-void adjust_volume(boost::int16_t* data, int size, int volume)
-{
- for (int i=0; i < size*0.5; i++) {
- data[i] = data[i] * volume/100;
- }
-}
-
-// envelope-volume adjustment
-static void
-use_envelopes(active_sound* sound, unsigned int length)
-{
- // Check if this is the time to use envelopes yet
- if (sound->current_env == 0 && (*sound->envelopes)[0].m_mark44 >
sound->samples_played+length/2)
- {
- return;
-
- }
- // switch to the next envelope if needed and possible
- else if (sound->current_env < sound->envelopes->size()-1 &&
(*sound->envelopes)[sound->current_env+1].m_mark44 >= sound->samples_played)
- {
- sound->current_env++;
- }
-
- // Current envelope position
- boost::int32_t cur_env_pos =
sound->envelopes->operator[](sound->current_env).m_mark44;
-
- // Next envelope position
- boost::uint32_t next_env_pos = 0;
- if (sound->current_env == (sound->envelopes->size()-1)) {
- // If there is no "next envelope" then set the next envelope
start point to be unreachable
- next_env_pos = cur_env_pos + length;
- } else {
- next_env_pos =
(*sound->envelopes)[sound->current_env+1].m_mark44;
- }
-
- unsigned int startpos = 0;
- // Make sure we start adjusting at the right sample
- if (sound->current_env == 0 &&
(*sound->envelopes)[sound->current_env].m_mark44 > sound->samples_played) {
- startpos = sound->raw_position +
((*sound->envelopes)[sound->current_env].m_mark44 - sound->samples_played)*2;
- } else {
- startpos = sound->raw_position;
- }
-
- boost::int16_t* data =
reinterpret_cast<boost::int16_t*>(sound->get_raw_data_ptr(startpos));
-
- for (unsigned int i=0; i < length/2; i+=2) {
- float left =
static_cast<float>((*sound->envelopes)[sound->current_env].m_level0 / 32768.0);
- float right =
static_cast<float>((*sound->envelopes)[sound->current_env].m_level1 / 32768.0);
-
- data[i] = static_cast<boost::int16_t>(data[i] * left); // Left
- data[i+1] = static_cast<boost::int16_t>(data[i+1] * right); //
Right
-
- if ((sound->samples_played+(length/2-i)) >= next_env_pos &&
sound->current_env != (sound->envelopes->size()-1)) {
- sound->current_env++;
- // Next envelope position
- if (sound->current_env == (sound->envelopes->size()-1))
{
- // If there is no "next envelope" then set the
next envelope start point to be unreachable
- next_env_pos = cur_env_pos + length;
- } else {
- next_env_pos =
(*sound->envelopes)[sound->current_env+1].m_mark44;
- }
- }
- }
-}
-
-
-// Prepare for mixing/adding (volume adjustments) and mix/add.
-static void
-do_mixing(Uint8* stream, active_sound* sound, Uint8* data, unsigned int
mix_length, unsigned int volume) {
- // If the volume needs adjustments we call a function to do that
- if (volume != 100) {
- adjust_volume(reinterpret_cast<boost::int16_t*>(data),
mix_length, volume);
- } else if (sound->envelopes != NULL) {
- use_envelopes(sound, mix_length);
- }
-
- // Mix the raw data
- SDL_MixAudio(static_cast<Uint8*>(stream),static_cast<const
Uint8*>(data), mix_length, SDL_MIX_MAXVOLUME);
-
- // Update sound info
- sound->raw_position += mix_length;
-
- // Sample size is always 2
- sound->samples_played += mix_length / 2;
-}
-
-
-// Callback invoked by the SDL audio thread.
-void SDL_sound_handler::sdl_audio_callback (void *udata, Uint8 *stream, int
buffer_length_in)
-{
- if ( buffer_length_in < 0 )
- {
- log_error(_("Negative buffer length in sdl_audio_callback
(%d)"), buffer_length_in);
- return;
- }
-
- if ( buffer_length_in == 0 )
- {
- log_error(_("Zero buffer length in sdl_audio_callback"));
- return;
- }
-
- unsigned int buffer_length = static_cast<unsigned
int>(buffer_length_in);
-
- // Get the soundhandler
- SDL_sound_handler* handler = static_cast<SDL_sound_handler*>(udata);
-
- // If nothing to play there is no reason to play
- // Is this a potential deadlock problem?
- if (handler->soundsPlaying == 0 && handler->m_aux_streamer.size() == 0)
{
- SDL_PauseAudio(1);
- return;
- }
-
- boost::mutex::scoped_lock lock(handler->_mutex);
-
- // Mixed sounddata buffer
- Uint8* buffer = stream;
- memset(buffer, 0, buffer_length);
-
- // call NetStream or Sound audio callbacks
- if ( !handler->m_aux_streamer.empty() )
- {
- boost::scoped_array<boost::uint8_t> buf ( new
boost::uint8_t[buffer_length] );
-
- // Loop through the attached sounds
- CallbacksMap::iterator it = handler->m_aux_streamer.begin();
- CallbacksMap::iterator end = handler->m_aux_streamer.end();
- while (it != end) {
- memset(buf.get(), 0, buffer_length);
-
- SDL_sound_handler::aux_streamer_ptr aux_streamer =
it->second;
- void* owner = it->first;
-
- // If false is returned the sound doesn't want to be
attached anymore
- bool ret = (aux_streamer)(owner, buf.get(),
buffer_length);
- if (!ret) {
- CallbacksMap::iterator it2=it;
- ++it2; // before we erase it
- handler->m_aux_streamer.erase(it); // FIXME:
isn't this terribly wrong ?
- it = it2;
- handler->soundsPlaying--;
- } else {
- ++it;
- }
- SDL_MixAudio(stream, buf.get(), buffer_length,
SDL_MIX_MAXVOLUME);
-
- }
- }
-
- // Run through all the sounds. TODO: don't call .size() at every
iteration !
- for(boost::uint32_t i=0; i < handler->m_sound_data.size(); i++) {
- sound_data* sounddata = handler->m_sound_data[i];
- for(boost::uint32_t j = 0; j <
sounddata->m_active_sounds.size(); j++) {
-
- // Temp variables to make the code simpler and easier
to read
- active_sound* sound = sounddata->m_active_sounds[j];
-
- // If there exist no decoder, then we can't decode!
- if (sound->decoder == NULL) continue;
-
- // When the current sound dont have enough decoded data
to fill the buffer,
- // we first mix what is already decoded, then decode
some more data, and
- // mix some more until the buffer is full. If a sound
loops the magic
- // happens here ;)
- if (sound->rawDataSize() - sound->raw_position <
buffer_length
- && (sound->position < sound->dataSize() ||
sound->loop_count != 0)) {
- // First we mix what is decoded
- unsigned int index = 0;
- if (sound->rawDataSize() - sound->raw_position
> 0)
- {
- index = sound->rawDataSize() -
sound->raw_position;
-
- do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
- index, sounddata->volume);
-
- }
-
- // Then we decode some data
- // We loop until the size of the decoded sound
is greater than the buffer size,
- // or there is no more to decode.
- unsigned int decoded_size = 0;
-
- // Delete any previous raw_data
- sound->deleteDecodedData();
-
- while(decoded_size < buffer_length)
- {
-
- // If we need to loop, we reset the
data pointer
- if (sound->dataSize() ==
sound->position && sound->loop_count != 0) {
- sound->loop_count--;
- sound->position = 0;
- sound->samples_played = 0;
- }
-
- // Test if we will get problems...
Should not happen...
- assert(sound->dataSize() >
sound->position);
-
- // temp raw buffer
- Uint8* tmp_raw_buffer;
- boost::uint32_t tmp_raw_buffer_size = 0;
- boost::uint32_t decodedBytes = 0;
-
- boost::uint32_t inputSize = 0;
- bool parse = true;
- if (sounddata->soundinfo->getFormat()
== AUDIO_CODEC_ADPCM) {
- parse = false;
- if
(sounddata->m_frames_size.size() > 0) inputSize =
sounddata->m_frames_size[sound->position];
- else inputSize =
sound->dataSize() - sound->position;
- } else {
- inputSize = sound->dataSize() -
sound->position;
- }
-
- tmp_raw_buffer =
sound->decoder->decode(sound->get_data_ptr(sound->position),
-
inputSize, tmp_raw_buffer_size, decodedBytes, parse);
-
- sound->position += decodedBytes;
-
-
sound->appendDecodedData(tmp_raw_buffer, tmp_raw_buffer_size);
-
- decoded_size += tmp_raw_buffer_size;
-
- // no more to decode from this sound,
so we break the loop
- if (sound->dataSize() <=
sound->position && sound->loop_count == 0 || tmp_raw_buffer_size == 0 &&
decodedBytes == 0) {
- sound->position =
sound->dataSize();
- break;
- }
-
- } // end of "decode min. bufferlength data"
while loop
-
- sound->raw_position = 0;
-
- // Determine how much should be mixed
- unsigned int mix_length = 0;
- if (decoded_size >= buffer_length - index) {
- mix_length = buffer_length - index;
- } else {
- mix_length = decoded_size;
- }
- if (sound->rawDataSize() < 2) continue; //
something went terrible wrong
- do_mixing(stream+index, sound,
sound->get_raw_data_ptr(0), mix_length, sounddata->volume);
-
- // When the current sound has enough decoded data to
fill
- // the buffer, we do just that.
- } else if (sound->rawDataSize() > sound->raw_position
&& sound->rawDataSize() - sound->raw_position > buffer_length ) {
-
- do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
- buffer_length, sounddata->volume);
-
- // When the current sound doesn't have anymore data to
decode,
- // and doesn't loop (anymore), but still got unplayed
data,
- // we put the last data on the stream
- } else if (sound->rawDataSize() - sound->raw_position
<= buffer_length && sound->rawDataSize() > sound->raw_position+1) {
-
-
- do_mixing(stream, sound,
sound->get_raw_data_ptr(sound->raw_position),
- sound->rawDataSize() -
sound->raw_position, sounddata->volume);
-
- sound->raw_position = sound->rawDataSize();
- }
-
- // Sound is done, remove it from the active list
- if (sound->position == sound->dataSize() &&
sound->raw_position == sound->rawDataSize() && sound->loop_count == 0) {
-
sounddata->m_active_sounds.erase(sounddata->m_active_sounds.begin() + j);
- handler->soundsPlaying--;
- handler->_soundsStopped++;
-
- }
- } // active sounds loop
- } // existing sounds loop
-
-}
-
-} // gnash.media namespace
-} // namespace gnash
-
-// Local Variables:
-// mode: C++
-// End:
-
Index: libmedia/sdl/sound_handler_sdl.h
===================================================================
RCS file: libmedia/sdl/sound_handler_sdl.h
diff -N libmedia/sdl/sound_handler_sdl.h
--- libmedia/sdl/sound_handler_sdl.h 21 Jan 2008 23:10:16 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,401 +0,0 @@
-// sound_handler_sdl.h: Sound handling using standard SDL
-//
-// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-// $Id: sound_handler_sdl.h,v 1.10 2008/01/21 23:10:16 rsavoye Exp $
-
-#ifndef SOUND_HANDLER_SDL_H
-#define SOUND_HANDLER_SDL_H
-
-
-#include "sound_handler.h" // for inheritance
-#include "AudioDecoder.h"
-
-#include "log.h"
-
-#ifdef USE_FFMPEG
-extern "C" {
-#include <ffmpeg/avcodec.h>
-}
-#elif defined(USE_MAD)
-#include <mad.h>
-#endif
-
-#include <vector>
-#include <map> // for composition
-
-#include <SDL_audio.h>
-#include <boost/thread/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/thread/mutex.hpp>
-
-namespace gnash {
-namespace media {
-
-class active_sound;
-
-/// Used to hold the sounddata when doing on-demand-decoding
-class sound_data
-{
- /// The undecoded data
- Buffer _buf;
-
-public:
-
- sound_data()
- {}
-
- ~sound_data();
-
- /// Object holding information about the sound
- std::auto_ptr<SoundInfo> soundinfo;
-
- std::map<boost::uint32_t,boost::uint32_t> m_frames_size;
-
- /// Append size bytes to this sound
- //
- /// @param data
- /// Data bytes, allocated with new[]. Ownership transferred.
- ///
- /// @param size
- /// Size of the 'data' buffer.
- ///
- void append(boost::uint8_t* data, unsigned int size)
- {
- _buf.append(data, size);
- }
-
- /// Return size of the data buffer
- size_t size() const
- {
- return _buf.size();
- }
-
- /// Return a pointer to the underlying buffer
- const boost::uint8_t* data() const {
- return _buf.data();
- }
-
- /// Return a pointer to the underlying buffer
- boost::uint8_t* data() {
- return _buf.data();
- }
-
- /// Return a pointer to an offset in the underlying buffer
- //
- /// @param pos The offset value.
- /// An assertion will fail if pos > size()
- ///
- const boost::uint8_t* data(size_t pos) const {
- return _buf.data(pos);
- }
-
- /// Return a pointer to an offset in the underlying buffer
- //
- /// @param pos The offset value.
- /// An assertion will fail if pos > size()
- ///
- boost::uint8_t* data(size_t pos) {
- return _buf.data(pos);
- }
-
- /// Volume for AS-sounds, range: 0-100.
- /// It's the SWF range that is represented here.
- int volume;
-
- /// Vector containing the active instances of this sounds being played
- //
- /// NOTE: This class *owns* all active sounds
- ///
- typedef std::vector<active_sound*> ActiveSounds;
-
- ActiveSounds m_active_sounds;
-
-};
-
-/// Used to hold the info about active sounds
-//
-/// This class contains a pointer to the sound_data used for playing
-/// and an optional Buffer to use when decoding is needed.
-///
-/// When the Buffer is NULL we'll play the sound_data bytes directly
-/// (we assume they are decoded already)
-///
-class active_sound
-{
-public:
- active_sound()
- :
- position(0),
- raw_position(0),
- loop_count(0),
- offset(0),
- current_env(0),
- samples_played(0),
- _undecodedData(0)
- {}
-
- ~active_sound()
- {
- deleteDecodedData();
- if (decoder) delete decoder;
- }
-
- /// The decoder object used to convert the data into the playable format
- AudioDecoder* decoder;
-
- /// Current decoding position in the stream
- unsigned long position;
-
- /// Current playing position in the decoded stream
- unsigned long raw_position;
-
- /// Numbers of loops: -1 means loop forever, 0 means play once.
- /// For every loop completed, it is decremented.
- long loop_count;
-
- /// Offset to make playback start in-sync, only used with mp3 streams.
- unsigned int offset;
-
- /// Sound envelopes for the current sound, which determine the volume
level
- /// from a given position. Only used with sound events.
- const std::vector<sound_handler::sound_envelope>* envelopes;
-
- /// Index of current envelope.
- boost::uint32_t current_env;
-
- /// Number of samples played so far.
- unsigned long samples_played;
-
- /// Set the undecoded data pointer
- //
- /// @param newUndecodedData
- /// Pointer to a sound_data being the undecoded data
- /// Ownership will NOT be transferred.
- ///
- void set_data(sound_data* newUndecodedData);
-
- /// Returns the data pointer in the undecoded datastream
- /// for the given position. Boundaries are checked.
- boost::uint8_t* get_data_ptr(unsigned long int pos);
-
- /// Returns the data pointer in the decoded datastream
- /// for the given position. Boundaries are checked.
- boost::uint8_t* get_raw_data_ptr(unsigned long int pos);
-
- /// Release resources associated with decoded data, if any.
- //
- /// After this call, the active_sound will have no decoded data
- /// buffer, thus any pointer to the decoded data will be fetched
- /// from the undecoded one.
- ///
- void deleteDecodedData();
-
- /// Append size bytes to this raw data
- //
- /// @param data
- /// Data bytes, allocated with new[]. Ownership transferred.
- ///
- /// @param size
- /// Size of the 'data' buffer.
- ///
- void appendDecodedData(boost::uint8_t* data, unsigned int size)
- {
- if ( ! _decodedData.get() )
- {
- _decodedData.reset( new Buffer );
- }
-
- _decodedData->append(data, size);
- }
-
- /// Set decoded data
- //
- /// @param data
- /// Data bytes, allocated with new[]. Ownership transferred.
- ///
- /// @param size
- /// Size of the 'data' buffer.
- ///
- void setDecodedData(boost::uint8_t* data, unsigned int size)
- {
- if ( ! _decodedData.get() )
- {
- _decodedData.reset( new Buffer(data, size) );
- }
- else
- {
- _decodedData->assign(data, size);
- }
- }
-
- size_t rawDataSize() const
- {
- if ( _decodedData.get() )
- {
- return _decodedData->size();
- }
- else return 0;
- }
-
- size_t dataSize() const
- {
- return _undecodedData ? _undecodedData->size() : 0;
- }
-
-private:
-
- /// The undecoded data
- sound_data* _undecodedData;
-
- /// The decoded buffer
- //
- /// If NULL, the _undecodedData will be considered
- /// decoded instead
- ///
- std::auto_ptr<Buffer> _decodedData;
-
-};
-
-// This is here as it needs definition of active_sound
-sound_data::~sound_data()
-{
- for (ActiveSounds::iterator i=m_active_sounds.begin(),
e=m_active_sounds.end(); i!=e; ++i)
- {
- delete *i;
- }
-}
-
-// Use SDL and ffmpeg/mad/nothing to handle sounds.
-class SDL_sound_handler : public sound_handler
-{
-private:
- /// AS classes (NetStream, Sound) audio callbacks
- typedef std::map< void* /* owner */, aux_streamer_ptr /* callback */>
CallbacksMap;
- CallbacksMap m_aux_streamer;
-
- /// Vector containing all sounds.
- //
- /// Elemenst of the vector are owned by this class
- ///
- std::vector<sound_data*> m_sound_data;
-
- /// Is sound device opened?
- bool soundOpened;
-
- /// The SDL_audio specs
- SDL_AudioSpec audioSpec;
-
- /// Keeps track of numbers of playing sounds
- int soundsPlaying;
-
- /// Is the audio muted?
- bool muted;
-
- /// Mutex for making sure threads doesn't mess things up
- boost::mutex _mutex;
-
- // stop and delete all sounds
- void delete_all_sounds();
-
-public:
- SDL_sound_handler();
- virtual ~SDL_sound_handler();
-
- /// Called to create a sound.
- virtual int create_sound(void* data, unsigned int data_bytes,
std::auto_ptr<SoundInfo> sinfo);
-
- /// this gets called when a stream gets more data
- virtual long fill_stream_data(unsigned char* data, unsigned int
data_bytes,
- unsigned int sample_count, int
handle_id);
-
- /// Play the index'd sample.
- virtual void play_sound(int sound_handle, int loop_count, int offset,
- long start_position, const
std::vector<sound_envelope>* envelopes);
-
- /// Stop the index'd sample.
- virtual void stop_sound(int sound_handle);
-
- /// This gets called when it's done with a sample.
- virtual void delete_sound(int sound_handle);
-
- // See dox in sound_handler.h
- virtual void reset();
-
- /// This will stop all sounds playing.
- virtual void stop_all_sounds();
-
- /// Returns the sound volume level as an integer from 0 to 100.
AS-script only.
- virtual int get_volume(int sound_handle);
-
- /// Sets the sound volume level as an integer from 0 to 100. AS-script
only.
- virtual void set_volume(int sound_handle, int volume);
-
- /// Gnash uses this to get info about a sound. Used when a stream needs
more data.
- virtual SoundInfo* get_sound_info(int sound_handle);
-
- /// Gnash calls this to mute audio.
- virtual void mute();
-
- /// Gnash calls this to unmute audio.
- virtual void unmute();
-
- /// Gnash calls this to get the mute state.
- virtual bool is_muted();
-
- /// Gets the duration in milliseconds of an event sound connected to an
AS Sound obejct.
- virtual unsigned int get_duration(int sound_handle);
-
- /// Gets the playhead position in milliseconds of an event sound
connected to an AS Soound obejct.
- virtual unsigned int get_position(int sound_handle);
-
- virtual void attach_aux_streamer(aux_streamer_ptr ptr, void* owner);
//vv
- virtual void detach_aux_streamer(void* owner); //vv
-
- /// Callback invoked by the SDL audio thread.
- //
- /// Refills the output stream/buffer with data.
- ///
- /// We run trough all the attached auxiliary streamers fetching decoded
- /// audio blocks and mixing them into the given output stream.
- ///
- /// If sound is compresssed (mp3) a mp3-frame is decoded into a buffer,
- /// and resampled if needed. When the buffer has been sampled, another
- /// frame is decoded until all frames has been decoded.
- /// If a sound is looping it will be decoded from the beginning again.
- ///
- /// TODO: make a static method of the SDL_sound_handler class
- ///
- /// @param udata
- /// User data pointer (SDL_sound_handler instance in our case).
- /// We'll lock the SDL_sound_handler::_mutex during operations.
- ///
- /// @param stream
- /// The output stream/buffer to fill
- ///
- /// @param buffer_length_in
- /// Length of the buffer.
- /// If zero or negative we log an error and return
- /// (negative is probably an SDL bug, zero dunno yet).
- ///
- static void sdl_audio_callback (void *udata, Uint8 *stream, int
buffer_length_in);
-};
-
-} // gnash.media namespace
-} // namespace gnash
-
-#endif // SOUND_HANDLER_SDL_H
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libmedia/sdl/AudioDecoderFfmpeg...,
Sandro Santilli <=