From e035decd95e78507a56a5785734805f048188c7a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 3 Mar 2009 16:51:01 +0000 Subject: [PATCH] Introduce FFmpegAudioStream implementation --- CMakeLists.txt | 1 + examples/osgmovie/CMakeLists.txt | 6 +- examples/osgmovie/osgmovie.cpp | 41 +++++++++- include/osg/AudioStream | 12 +-- src/osg/AudioStream.cpp | 2 +- src/osgPlugins/CMakeLists.txt | 4 + src/osgPlugins/ffmpeg/CMakeLists.txt | 3 + src/osgPlugins/ffmpeg/FFmpegAudioStream.cpp | 79 ++++++++++++++++++++ src/osgPlugins/ffmpeg/FFmpegAudioStream.hpp | 43 +++++++++++ src/osgPlugins/ffmpeg/FFmpegDecoder.hpp | 2 +- src/osgPlugins/ffmpeg/FFmpegDecoderAudio.cpp | 3 +- src/osgPlugins/ffmpeg/FFmpegDecoderAudio.hpp | 4 +- src/osgPlugins/ffmpeg/FFmpegImageStream.cpp | 55 ++------------ src/osgPlugins/ffmpeg/FFmpegImageStream.hpp | 19 +---- 14 files changed, 198 insertions(+), 76 deletions(-) create mode 100644 src/osgPlugins/ffmpeg/FFmpegAudioStream.cpp create mode 100644 src/osgPlugins/ffmpeg/FFmpegAudioStream.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb3f643c7..fe4b00fb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,6 +310,7 @@ FIND_PACKAGE(CURL) FIND_PACKAGE(ITK) FIND_PACKAGE(LibVNCServer) FIND_PACKAGE(OurDCMTK) +FIND_PACKAGE(OpenAL) FIND_PACKAGE(XUL) FIND_PACKAGE(FFmpeg) diff --git a/examples/osgmovie/CMakeLists.txt b/examples/osgmovie/CMakeLists.txt index 3b10e7253..c0cdafbef 100644 --- a/examples/osgmovie/CMakeLists.txt +++ b/examples/osgmovie/CMakeLists.txt @@ -1,7 +1,9 @@ -#this file is automatically generated - +# INCLUDE_DIRECTORIES( ${OPENAL_INCLUDE_DIR} ) SET(TARGET_SRC osgmovie.cpp ) SET(TARGET_ADDED_LIBRARIES osgGA ) + +# SET(TARGET_EXTERNAL_LIBRARIES ${OPENAL_LIBRARY} alut) + #### end var setup ### SETUP_EXAMPLE(osgmovie) diff --git a/examples/osgmovie/osgmovie.cpp b/examples/osgmovie/osgmovie.cpp index 336529d7a..1a5336d88 100644 --- a/examples/osgmovie/osgmovie.cpp +++ b/examples/osgmovie/osgmovie.cpp @@ -320,6 +320,30 @@ osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,flo } } +class CustomAudioSink : public osg::AudioSink +{ + public: + + CustomAudioSink(osg::AudioStream* audioStream): + _playing(false), + _audioStream(audioStream) {} + + virtual void startPlaying() + { + _playing = true; + osg::notify(osg::NOTICE)<<"CustomAudioSink()::startPlaying()"<(image); - if (imagestream) imagestream->play(); + if (imagestream) + { + osg::ImageStream::AudioStreams& audioStreams = imagestream->getAudioStreams(); + if (useOpenALAudio && !audioStreams.empty()) + { + osg::AudioStream* audioStream = audioStreams[0].get(); + osg::notify(osg::NOTICE)<<"AudioStream read ["<getName()<<"]"<setAudioSink(new CustomAudioSink(audioStream)); + } + + + imagestream->play(); + } if (image) { diff --git a/include/osg/AudioStream b/include/osg/AudioStream index 35b1daf12..b1b105039 100644 --- a/include/osg/AudioStream +++ b/include/osg/AudioStream @@ -18,12 +18,12 @@ namespace osg { -/** Pure virtual AudioSinkInterface bass class that is used to connect the audio system with AudioStreams. */ -class OSG_EXPORT AudioSinkInterface : public osg::Object +/** Pure virtual AudioSink bass class that is used to connect the audio system with AudioStreams. */ +class OSG_EXPORT AudioSink : public osg::Object { public: - AudioSinkInterface(); + AudioSink(); virtual void startPlaying() = 0; virtual bool playing() const = 0; @@ -36,8 +36,8 @@ public: private: - virtual AudioSinkInterface * cloneType() const { return 0; } - virtual AudioSinkInterface * clone(const osg::CopyOp &) const { return 0; } + virtual AudioSink * cloneType() const { return 0; } + virtual AudioSink * clone(const osg::CopyOp &) const { return 0; } double _delay; }; @@ -55,7 +55,7 @@ class OSG_EXPORT AudioStream : public osg::Object virtual const char* libraryName() const { return "osg"; } virtual const char* className() const { return "AudioStream"; } - virtual void setAudioSink(osg::AudioSinkInterface* audio_sink) = 0; + virtual void setAudioSink(osg::AudioSink* audio_sink) = 0; virtual void consumeAudioBuffer(void * const buffer, const size_t size) = 0; diff --git a/src/osg/AudioStream.cpp b/src/osg/AudioStream.cpp index 635ab0290..bdf69a142 100644 --- a/src/osg/AudioStream.cpp +++ b/src/osg/AudioStream.cpp @@ -15,7 +15,7 @@ using namespace osg; -AudioSinkInterface::AudioSinkInterface() : +AudioSink::AudioSink() : _delay(0.0) { } diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 1580d6f07..8ec7b25a9 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -200,6 +200,10 @@ IF(FFMPEG_FOUND) ADD_SUBDIRECTORY(ffmpeg) ENDIF(FFMPEG_FOUND) +IF(OPENAL_FOUND) + ADD_SUBDIRECTORY(OpenAL) +ENDIF(OPENAL_FOUND) + IF(QUICKTIME_FOUND) ADD_SUBDIRECTORY(quicktime) ENDIF(QUICKTIME_FOUND) diff --git a/src/osgPlugins/ffmpeg/CMakeLists.txt b/src/osgPlugins/ffmpeg/CMakeLists.txt index cb51f7f5e..9d6fedd9a 100644 --- a/src/osgPlugins/ffmpeg/CMakeLists.txt +++ b/src/osgPlugins/ffmpeg/CMakeLists.txt @@ -19,6 +19,7 @@ SET(TARGET_SRC FFmpegDecoder.cpp FFmpegDecoderVideo.cpp FFmpegImageStream.cpp + FFmpegAudioStream.cpp ReaderWriterFFmpeg.cpp ) @@ -30,6 +31,8 @@ SET(TARGET_H FFmpegDecoderVideo.hpp FFmpegHeaders.hpp FFmpegPacket.hpp + FFmpegImageStream.hpp + FFmpegAudioStream.hpp MessageQueue.hpp ) diff --git a/src/osgPlugins/ffmpeg/FFmpegAudioStream.cpp b/src/osgPlugins/ffmpeg/FFmpegAudioStream.cpp new file mode 100644 index 000000000..df9a4716b --- /dev/null +++ b/src/osgPlugins/ffmpeg/FFmpegAudioStream.cpp @@ -0,0 +1,79 @@ + +#include "FFmpegAudioStream.hpp" + +#include +#include + +#include "FFmpegDecoder.hpp" +#include "MessageQueue.hpp" + +#include + + + +namespace osgFFmpeg { + + + +FFmpegAudioStream::FFmpegAudioStream(FFmpegDecoder* decoder): + m_decoder(decoder) +{ +} + + + +FFmpegAudioStream::FFmpegAudioStream(const FFmpegAudioStream & audio, const osg::CopyOp & copyop) : + osg::AudioStream(audio, copyop) +{ +} + +FFmpegAudioStream::~FFmpegAudioStream() +{ +} + +void FFmpegAudioStream::setAudioSink(osg::AudioSink* audio_sink) +{ + osg::notify(osg::NOTICE)<<"FFmpegAudioStream::setAudioSink( "<audio_decoder().setAudioSink(audio_sink); +} + + +void FFmpegAudioStream::consumeAudioBuffer(void * const buffer, const size_t size) +{ + m_decoder->audio_decoder().fillBuffer(buffer, size); +} + +double FFmpegAudioStream::duration() const +{ + return m_decoder->duration(); +} + + +bool FFmpegAudioStream::audioStream() const +{ + return m_decoder->audio_decoder().validContext(); +} + + + +int FFmpegAudioStream::audioFrequency() const +{ + return m_decoder->audio_decoder().frequency(); +} + + + +int FFmpegAudioStream::audioNbChannels() const +{ + return m_decoder->audio_decoder().nbChannels(); +} + + + +osg::AudioStream::SampleFormat FFmpegAudioStream::audioSampleFormat() const +{ + return m_decoder->audio_decoder().sampleFormat(); +} + + +} // namespace osgFFmpeg diff --git a/src/osgPlugins/ffmpeg/FFmpegAudioStream.hpp b/src/osgPlugins/ffmpeg/FFmpegAudioStream.hpp new file mode 100644 index 000000000..2d6c741f8 --- /dev/null +++ b/src/osgPlugins/ffmpeg/FFmpegAudioStream.hpp @@ -0,0 +1,43 @@ + +#ifndef HEADER_GUARD_OSGFFMPEG_FFMPEG_AUDIO_STREAM_H +#define HEADER_GUARD_OSGFFMPEG_FFMPEG_AUDIO_STREAM_H + +#include +#include "FFmpegDecoder.hpp" + +namespace osgFFmpeg +{ + + class FFmpegAudioStream : public osg::AudioStream + { + public: + + FFmpegAudioStream(FFmpegDecoder* decoder=0); + FFmpegAudioStream(const FFmpegAudioStream & audio, const osg::CopyOp & copyop = osg::CopyOp::SHALLOW_COPY); + + META_Object(osgFFmpeg, FFmpegAudioStream); + + virtual void setAudioSink(osg::AudioSink* audio_sink); + + void consumeAudioBuffer(void * const buffer, const size_t size); + + bool audioStream() const; + int audioFrequency() const; + int audioNbChannels() const; + osg::AudioStream::SampleFormat audioSampleFormat() const; + + double duration() const; + + private: + + virtual ~FFmpegAudioStream(); + + osg::ref_ptr m_decoder; + + }; + +} + + + +#endif // HEADER_GUARD_OSGFFMPEG_FFMPEG_IMAGE_STREAM_H diff --git a/src/osgPlugins/ffmpeg/FFmpegDecoder.hpp b/src/osgPlugins/ffmpeg/FFmpegDecoder.hpp index 917db6de8..bd625e45d 100644 --- a/src/osgPlugins/ffmpeg/FFmpegDecoder.hpp +++ b/src/osgPlugins/ffmpeg/FFmpegDecoder.hpp @@ -56,7 +56,7 @@ class FormatContextPtr }; -class FFmpegDecoder +class FFmpegDecoder : public osg::Referenced { public: diff --git a/src/osgPlugins/ffmpeg/FFmpegDecoderAudio.cpp b/src/osgPlugins/ffmpeg/FFmpegDecoderAudio.cpp index 5fb92bf48..8890fad7d 100644 --- a/src/osgPlugins/ffmpeg/FFmpegDecoderAudio.cpp +++ b/src/osgPlugins/ffmpeg/FFmpegDecoderAudio.cpp @@ -106,9 +106,10 @@ void FFmpegDecoderAudio::run() -void FFmpegDecoderAudio::setAudioSink(osg::ref_ptr audio_sink) +void FFmpegDecoderAudio::setAudioSink(osg::ref_ptr audio_sink) { // The FFmpegDecoderAudio object takes the responsability of destroying the audio_sink. + osg::notify(osg::NOTICE)<<"Assigning "< audio_sink); + void setAudioSink(osg::ref_ptr audio_sink); void fillBuffer(void * buffer, size_t size); bool validContext() const; @@ -42,7 +42,7 @@ public: private: //typedef boost::shared_ptr FramePtr; - typedef osg::ref_ptr SinkPtr; + typedef osg::ref_ptr SinkPtr; typedef std::vector Buffer; void decodeLoop(); diff --git a/src/osgPlugins/ffmpeg/FFmpegImageStream.cpp b/src/osgPlugins/ffmpeg/FFmpegImageStream.cpp index e9b3ac03f..24989c655 100644 --- a/src/osgPlugins/ffmpeg/FFmpegImageStream.cpp +++ b/src/osgPlugins/ffmpeg/FFmpegImageStream.cpp @@ -1,12 +1,10 @@ #include "FFmpegImageStream.hpp" +#include "FFmpegAudioStream.hpp" #include #include -#include "FFmpegDecoder.hpp" -#include "MessageQueue.hpp" - #include @@ -44,7 +42,6 @@ FFmpegImageStream::~FFmpegImageStream() quit(true); delete m_commands; - delete m_decoder; } @@ -63,6 +60,13 @@ bool FFmpegImageStream::open(const std::string & filename) m_decoder->video_decoder().setUserData(this); m_decoder->video_decoder().setPublishCallback(publishNewFrame); + + if (m_decoder->audio_decoder().validContext()) + { + osg::notify(osg::NOTICE)<<"Attaching FFmpegAudioStream"<audio_decoder().setAudioSink(audio_sink); -} - - -void FFmpegImageStream::consumeAudioBuffer(void * const buffer, const size_t size) -{ - m_decoder->audio_decoder().fillBuffer(buffer, size); -} - - - double FFmpegImageStream::duration() const { return m_decoder->duration(); @@ -161,35 +151,6 @@ double FFmpegImageStream::videoFrameRate() const } - -bool FFmpegImageStream::audioStream() const -{ - return m_decoder->audio_decoder().validContext(); -} - - - -int FFmpegImageStream::audioFrequency() const -{ - return m_decoder->audio_decoder().frequency(); -} - - - -int FFmpegImageStream::audioNbChannels() const -{ - return m_decoder->audio_decoder().nbChannels(); -} - - - -osg::AudioStream::SampleFormat FFmpegImageStream::audioSampleFormat() const -{ - return m_decoder->audio_decoder().sampleFormat(); -} - - - void FFmpegImageStream::run() { try diff --git a/src/osgPlugins/ffmpeg/FFmpegImageStream.hpp b/src/osgPlugins/ffmpeg/FFmpegImageStream.hpp index a4fbf3683..8658c62da 100644 --- a/src/osgPlugins/ffmpeg/FFmpegImageStream.hpp +++ b/src/osgPlugins/ffmpeg/FFmpegImageStream.hpp @@ -7,17 +7,15 @@ #include #include +#include "FFmpegDecoder.hpp" +#include "MessageQueue.hpp" + namespace osgFFmpeg { - class FFmpegDecoder; - class FFmpegDecoderAudio; - class FFmpegDecoderVideo; - template class MessageQueue; - class FFmpegImageStream : public osg::ImageStream, public OpenThreads::Thread { public: @@ -34,15 +32,6 @@ namespace osgFFmpeg virtual void rewind(); virtual void quit(bool waitForThreadToExit = true); - virtual void setAudioSink(osg::AudioSinkInterface* audio_sink); - - void consumeAudioBuffer(void * const buffer, const size_t size); - - bool audioStream() const; - int audioFrequency() const; - int audioNbChannels() const; - osg::AudioStream::SampleFormat audioSampleFormat() const; - double duration() const; bool videoAlphaChannel() const; @@ -76,7 +65,7 @@ namespace osgFFmpeg static void publishNewFrame(const FFmpegDecoderVideo &, void * user_data); - FFmpegDecoder * m_decoder; + osg::ref_ptr m_decoder; CommandQueue * m_commands; Mutex m_mutex;