Files
OpenSceneGraph/src/osgPlugins/ffmpeg/FFmpegDecoderAudio.hpp
Robert Osfield d409ffcb91 From Javier Taibo, "I have found that since version 1.1, FFMPEG changed the way audio streams are retrieved, from packed to planar format. SDL interprets packed audio, as is used in the osgmovie example. To make the audio work when the OSGffmpeg plug-in is compiled against recent FFMPEG versions, FFmpegDecoderAudio must check for planar formats and in these cases request the samples as packed. This way all works as before. It can be checked with osgmovie example application.
$ osgmovie --audio movie.avi.ffmpeg
  FFmpegImageStream::open audio failed, audio stream will be disabled: unknown audio format

  With the attached FFmpegDecoderAudio.cpp, audio sounds correctly.

  I am also attaching a modified version of FindFFmpeg.cmake that allows to set as FFMPEG_DIR the ffmpeg compiled in the source directory structure. It should not break anything as it only adds some additional search paths.
"


git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14654 16af8721-9629-0410-8352-f15c8da7e697
2015-01-07 14:14:55 +00:00

115 lines
2.9 KiB
C++

#ifndef HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_AUDIO_H
#define HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_AUDIO_H
#include <OpenThreads/Thread>
#include <osg/Timer>
#include "FFmpegClocks.hpp"
#include "FFmpegPacket.hpp"
#include "FFmpegParameters.hpp"
#include <osg/AudioStream>
#include "BoundedMessageQueue.hpp"
namespace osgFFmpeg {
class FFmpegDecoderAudio : public OpenThreads::Thread
{
public:
typedef BoundedMessageQueue<FFmpegPacket> PacketQueue;
typedef void (* PublishFunc) (const FFmpegDecoderAudio & decoder, void * user_data);
FFmpegDecoderAudio(PacketQueue & packets, FFmpegClocks & clocks);
~FFmpegDecoderAudio();
void open(AVStream * stream, FFmpegParameters* parameters);
void pause(bool pause);
void close(bool waitForThreadToExit);
void setVolume(float volume);
float getVolume() const;
virtual void run();
void setAudioSink(osg::ref_ptr<osg::AudioSink> audio_sink);
void fillBuffer(void * buffer, size_t size);
bool validContext() const;
int frequency() const;
int nbChannels() const;
osg::AudioStream::SampleFormat sampleFormat() const;
private:
typedef osg::ref_ptr<osg::AudioSink> SinkPtr;
typedef std::vector<uint8_t> Buffer;
void decodeLoop();
void adjustBufferEndPts(size_t buffer_size);
size_t decodeFrame(void * buffer, size_t size);
PacketQueue & m_packets;
FFmpegClocks & m_clocks;
AVStream * m_stream;
AVCodecContext * m_context;
FFmpegPacket m_packet;
const uint8_t * m_packet_data;
int m_bytes_remaining;
Buffer m_audio_buffer;
size_t m_audio_buf_size;
size_t m_audio_buf_index;
int m_in_sample_rate;
int m_in_nb_channels;
AVSampleFormat m_in_sample_format;
int m_out_sample_rate;
int m_out_nb_channels;
AVSampleFormat m_out_sample_format;
SinkPtr m_audio_sink;
osg::Timer m_pause_timer;
bool m_end_of_stream;
bool m_paused;
volatile bool m_exit;
SwrContext * m_swr_context; // Sw resampling context
};
inline bool FFmpegDecoderAudio::validContext() const
{
return m_context != 0;
}
inline int FFmpegDecoderAudio::frequency() const
{
return m_out_sample_rate;
}
inline int FFmpegDecoderAudio::nbChannels() const
{
return m_out_nb_channels;
}
} // namespace osgFFmpeg
#endif // HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_AUDIO_H