Files
OpenSceneGraph/src/osgPlugins/ffmpeg/FFmpegDecoder.hpp
2009-03-08 16:48:48 +00:00

176 lines
3.3 KiB
C++

#ifndef HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_H
#define HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_H
#include "FFmpegDecoderAudio.hpp"
#include "FFmpegDecoderVideo.hpp"
#include <osg/Notify>
namespace osgFFmpeg {
class FormatContextPtr
{
public:
typedef AVFormatContext T;
explicit FormatContextPtr() : _ptr(0) {}
explicit FormatContextPtr(T* ptr) : _ptr(ptr) {}
~FormatContextPtr()
{
cleanup();
}
T* get() { return _ptr; }
T * operator-> () const // never throws
{
return _ptr;
}
void reset(T* ptr)
{
if (ptr==_ptr) return;
cleanup();
_ptr = ptr;
}
void cleanup()
{
if (_ptr)
{
osg::notify(osg::NOTICE)<<"Calling av_close_input_file("<<_ptr<<")"<<std::endl;
av_close_input_file(_ptr);
}
_ptr = 0;
}
protected:
T* _ptr;
};
class FFmpegDecoder : public osg::Referenced
{
public:
FFmpegDecoder();
~FFmpegDecoder();
bool open(const std::string & filename);
void close(bool waitForThreadToExit);
bool readNextPacket();
void rewind();
void loop(bool loop);
bool loop() const;
double duration() const;
FFmpegDecoderAudio & audio_decoder();
FFmpegDecoderVideo & video_decoder();
FFmpegDecoderAudio const & audio_decoder() const;
FFmpegDecoderVideo const & video_decoder() const;
protected:
enum State
{
NORMAL,
END_OF_STREAM,
REWINDING
};
typedef BoundedMessageQueue<FFmpegPacket> PacketQueue;
void findAudioStream();
void findVideoStream();
void flushAudioQueue();
void flushVideoQueue();
bool readNextPacketNormal();
bool readNextPacketEndOfStream();
bool readNextPacketRewinding();
void rewindButDontFlushQueues();
FormatContextPtr m_format_context;
AVStream * m_audio_stream;
AVStream * m_video_stream;
unsigned int m_audio_index;
unsigned int m_video_index;
FFmpegClocks m_clocks;
FFmpegPacket m_pending_packet;
PacketQueue m_audio_queue;
PacketQueue m_video_queue;
FFmpegDecoderAudio m_audio_decoder;
FFmpegDecoderVideo m_video_decoder;
double m_duration;
double m_start;
State m_state;
bool m_loop;
};
inline void FFmpegDecoder::loop(const bool loop)
{
m_loop = loop;
}
inline bool FFmpegDecoder::loop() const
{
return m_loop;
}
inline double FFmpegDecoder::duration() const
{
return double(m_format_context->duration) / AV_TIME_BASE;
}
inline FFmpegDecoderAudio & FFmpegDecoder::audio_decoder()
{
return m_audio_decoder;
}
inline FFmpegDecoderVideo & FFmpegDecoder::video_decoder()
{
return m_video_decoder;
}
inline FFmpegDecoderAudio const & FFmpegDecoder::audio_decoder() const
{
return m_audio_decoder;
}
inline FFmpegDecoderVideo const & FFmpegDecoder::video_decoder() const
{
return m_video_decoder;
}
} // namespace osgFFmpeg
#endif // HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_H