#ifndef __FFmpegPlayer_H__
#define __FFmpegPlayer_H__
#if _MSC_VER > 1000
#	pragma once
#endif	// #if _MSC_VER > 1000

#include <string>
#include <stdio.h>

extern "C" {

#ifndef UINT64_C
#	define UINT64_C(val) val##ui64
#endif // UINT64_C

#include "libavformat/avformat.h"
}

class FFmpegPlayer
{
	// iOrange - I/O funcs
	static int ReadPacket(void *opaque, uint8_t *buf, int buf_size);
	static int64_t Seek(void *opaque, int64_t offset, int whence);

public:
	FFmpegPlayer();
	~FFmpegPlayer();

	// iOrange - opens video from file using "fileName", return true if all is ok, false if not
	bool OpenVideoFile(const std::string& fileName);

	// iOrange - return video frame width
	int GetFrameWidth(void) const;

	// iOrange - return video frame height
	int GetFrameHeight(void) const;

	// iOrange - return video frequency in frames-per-second (FPS)
	float GetFramesPerSecond(void) const;

	// iOrange - advance video playing by "dt" milliseconds
	uint32 Advance(unsigned int dt);

	// iOrange - return true if video is not playing
	bool IsStopped(void) const;

	// iOrange - extract current frame to RGB color space using CPU for yuv-rgb conversion (integer optimization)
	void GetFrameRGB(char* outFrame, int pitch);

	// iOrange - extract current frame to planar YUV444 (de-interlaced yuv) to perform yuv-rgb conversion on GPU
	void GetFrameYUV444(char* outFrame, int pitch);

private:
	// iOrange - open file routine
	bool OpenFile(const std::string& fileName);

	// iOrange - open video stream routine
	bool OpenVideoStream(void);

	// iOrange - buffer some data from file into Ogg stream
	int BufferData(void);

	// iOrange - decodes current frame from Theora to YUV
	void DecodeVideoFrame(void);

private:
	bool				m_VideoOpened;
	FILE*				m_File;
	uint32				m_VideoTimer;
	uint32				m_LastVideoFrame;
	int					m_FrameWidth;
	int					m_FrameHeight;
	float				m_FramesPerSecond;
	bool				m_Stopped;

	// FFmpeg stuff
	uint8*				m_IOBuffer;
	AVFormatContext*	m_InputContext;
	AVFrame*			m_Frame;
	int					m_VideoStreamIdx;
	AVStream*			m_VideoStream;
	AVOutputFormat*		m_OutputFormat;
};

#endif // __FFmpegPlayer_H__
