Files
OpenSceneGraph/src/osgPlugins/ffmpeg/FFmpegDecoderVideo.hpp

141 lines
3.0 KiB
C++

#ifndef HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_VIDEO_H
#define HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_VIDEO_H
#include "BoundedMessageQueue.hpp"
#include "FFmpegClocks.hpp"
#include "FFmpegPacket.hpp"
#include <boost/shared_ptr.hpp>
#include <OpenThreads/Thread>
#include <vector>
namespace osgFFmpeg {
class FFmpegDecoderVideo : public OpenThreads::Thread
{
public:
typedef BoundedMessageQueue<FFmpegPacket> PacketQueue;
typedef void (* PublishFunc) (const FFmpegDecoderVideo & decoder, void * user_data);
FFmpegDecoderVideo(PacketQueue & packets, FFmpegClocks & clocks);
~FFmpegDecoderVideo();
void open(AVStream * stream);
virtual void run();
void setUserData(void * user_data);
void setPublishCallback(PublishFunc function);
int width() const;
int height() const;
double aspectRatio() const;
bool alphaChannel() const;
double frameRate() const;
const uint8_t * image() const;
private:
typedef boost::shared_ptr<AVFrame> FramePtr;
typedef std::vector<uint8_t> Buffer;
void decodeLoop();
void findAspectRatio();
void publishFrame(double delay);
void swapBuffers();
double synchronizeVideo(double pts);
void yuva420pToRgba(AVPicture *dst, const AVPicture *src, int width, int height);
static int getBuffer(AVCodecContext * context, AVFrame * picture);
static void releaseBuffer(AVCodecContext * context, AVFrame * picture);
PacketQueue & m_packets;
FFmpegClocks & m_clocks;
AVStream * m_stream;
AVCodecContext * m_context;
AVCodec * m_codec;
const uint8_t * m_packet_data;
int m_bytes_remaining;
int64_t m_packet_pts;
FramePtr m_frame;
FramePtr m_frame_rgba;
Buffer m_buffer_rgba;
Buffer m_buffer_rgba_public;
void * m_user_data;
PublishFunc m_publish_func;
double m_frame_rate;
double m_aspect_ratio;
int m_width;
int m_height;
size_t m_next_frame_index;
bool m_alpha_channel;
volatile bool m_exit;
};
inline void FFmpegDecoderVideo::setUserData(void * const user_data)
{
m_user_data = user_data;
}
inline void FFmpegDecoderVideo::setPublishCallback(const PublishFunc function)
{
m_publish_func = function;
}
inline int FFmpegDecoderVideo::width() const
{
return m_width;
}
inline int FFmpegDecoderVideo::height() const
{
return m_height;
}
inline double FFmpegDecoderVideo::aspectRatio() const
{
return m_aspect_ratio;
}
inline bool FFmpegDecoderVideo::alphaChannel() const
{
return m_alpha_channel;
}
inline double FFmpegDecoderVideo::frameRate() const
{
return m_frame_rate;
}
inline const uint8_t * FFmpegDecoderVideo::image() const
{
return &m_buffer_rgba_public[0];
}
} // namespace osgFFmpeg
#endif // HEADER_GUARD_OSGFFMPEG_FFMPEG_DECODER_VIDEO_H