181 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
//-----------------------------------------------------------------------------
 | 
						|
// Torque Game Engine
 | 
						|
// Copyright (C) GarageGames.com, Inc.
 | 
						|
//-----------------------------------------------------------------------------
 | 
						|
 | 
						|
#ifndef _THEORATEXTURE_H_
 | 
						|
#define _THEORATEXTURE_H_
 | 
						|
 | 
						|
#ifndef _CONSOLE_H_
 | 
						|
#include "console/console.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _GTEXMANAGER_H_
 | 
						|
#include "dgl/gTexManager.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _GBITMAP_H_
 | 
						|
#include "dgl/gBitmap.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _O_THEORA_H_
 | 
						|
#include "theora/theora.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _vorbis_codec_h_
 | 
						|
#include "vorbis/codec.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _PLATFORMTHREAD_H_
 | 
						|
#include "platform/platformThread.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _OGGMIXEDSTREAMSOURCE_H_
 | 
						|
#include "audio/oggMixedStreamSource.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef _VORBISSTREAMSOURCE_H_
 | 
						|
#include "audio/vorbisStreamSource.h"
 | 
						|
#endif
 | 
						|
 | 
						|
/// TheoraTexture decodes Ogg Theora files, and their audio.
 | 
						|
///
 | 
						|
/// TheoraTexture objects can be used similarly to TextureObjects. Just
 | 
						|
/// set the video, call play(), and then refresh every frame to get the
 | 
						|
/// latest video. Audio happens automagically.
 | 
						|
///
 | 
						|
/// @note Uses Theora and ogg libraries which are Copyright (C) Xiph.org Foundation
 | 
						|
class TheoraTexture
 | 
						|
{
 | 
						|
private:
 | 
						|
	Thread*				mPlayThread;
 | 
						|
	
 | 
						|
	/// Ogg and codec state for demux/decode.
 | 
						|
	ogg_sync_state		mOggSyncState;
 | 
						|
	ogg_page			   mOggPage;
 | 
						|
	ogg_stream_state	mOggTheoraStream;
 | 
						|
	ogg_stream_state	mOggVorbisStream;
 | 
						|
 | 
						|
	theora_info			mTheoraInfo;
 | 
						|
	theora_comment		mTheoraComment;
 | 
						|
	theora_state		mTheoraState;
 | 
						|
		
 | 
						|
	vorbis_info			mVorbisInfo;
 | 
						|
	vorbis_comment		mVorbisComment;
 | 
						|
	vorbis_dsp_state	mVorbisDspState;
 | 
						|
	vorbis_block		mVorbisBlock;
 | 
						|
 | 
						|
	/// File handle for the theora file.
 | 
						|
	Stream*				mTheoraFile;
 | 
						|
 | 
						|
	volatile bool		mReady;
 | 
						|
	volatile bool		mPlaying;
 | 
						|
 | 
						|
	volatile bool		mHasVorbis;
 | 
						|
	OggMixedStreamSource* mVorbisBuffer;
 | 
						|
	AUDIOHANDLE			mVorbisHandle;
 | 
						|
 | 
						|
   volatile F32      mCurrentTime;
 | 
						|
   volatile U32      mStartTick;
 | 
						|
 | 
						|
	void init();
 | 
						|
 | 
						|
	bool parseHeaders();
 | 
						|
	bool createVideoBuffers();
 | 
						|
	bool createAudioBuffers(Audio::Description* desc);
 | 
						|
 | 
						|
   /// We precalculate adjusted YUV values for faster RGB conversion. This
 | 
						|
   /// function is responsible for making sure they're present and valid.
 | 
						|
	void generateLookupTables();
 | 
						|
	void destroyTexture(bool restartOgg = false);
 | 
						|
	
 | 
						|
	void drawFrame();
 | 
						|
 | 
						|
	bool readyVideo(const F64 lastFrame, F64 &vBuffTime);
 | 
						|
	bool readyAudio();
 | 
						|
	
 | 
						|
	bool demandOggPage();
 | 
						|
	S32  bufferOggPage();
 | 
						|
	S32  queueOggPage(ogg_page *page);
 | 
						|
 | 
						|
	F64 getTheoraTime();
 | 
						|
 | 
						|
	/// Background playback thread.
 | 
						|
	static void playThread( void *udata );
 | 
						|
	bool playLoop();
 | 
						|
 | 
						|
   /// Magical Trevor is responsible for tracking elapsed time based on
 | 
						|
   /// the currently playing buffer.
 | 
						|
   ///
 | 
						|
   /// @note He's ever so clear.
 | 
						|
   ///
 | 
						|
   /// Basically it takes periodic updates of the currently playing buffer
 | 
						|
   /// and figures the time between that buffer and the last tracked
 | 
						|
   /// buffer, and tells you how much time passed between those two events.
 | 
						|
   /// (time == duration of audio)
 | 
						|
   struct MagicalTrevor
 | 
						|
   {
 | 
						|
      struct BufInf
 | 
						|
      {
 | 
						|
         BufInf();
 | 
						|
 | 
						|
         ALuint id;
 | 
						|
         F64    time;
 | 
						|
         BufInf *next;
 | 
						|
      };
 | 
						|
 | 
						|
      FreeListChunker<BufInf> mBuffPool;
 | 
						|
      BufInf *mBufListHead;
 | 
						|
      ALint mLastBufferID;
 | 
						|
      void *mMutex;
 | 
						|
 | 
						|
      MagicalTrevor();
 | 
						|
      ~MagicalTrevor();
 | 
						|
 | 
						|
      /// Given current buffer, infer elapsed time since last call.
 | 
						|
      const F64 advanceTime(const ALuint buffId);
 | 
						|
 | 
						|
      /// Note a buffer, and how much time it contains.
 | 
						|
      void postBuffer(const ALuint buffId, const F64 duration);
 | 
						|
 | 
						|
      /// How many items in our list? Used for debugging.
 | 
						|
      const U32 getListSize() const;
 | 
						|
 | 
						|
      /// Clear everything out in preparation for the next playback.
 | 
						|
      void reset();
 | 
						|
   };
 | 
						|
 | 
						|
   MagicalTrevor mMagicalTrevor;
 | 
						|
 | 
						|
public:
 | 
						|
   TheoraTexture();
 | 
						|
   TheoraTexture(const char *filename, bool play = false, Audio::Description* desc = NULL);
 | 
						|
   ~TheoraTexture();
 | 
						|
 | 
						|
   operator TextureObject*()
 | 
						|
   {
 | 
						|
      return (TextureObject*)*mTextureHandle;
 | 
						|
   }
 | 
						|
 | 
						|
   bool setFile(const char*, bool play = false, bool restart = false, Audio::Description* desc = NULL);
 | 
						|
 | 
						|
   const bool isPlaying() const { return mPlaying; }
 | 
						|
   const bool isReady() const { return mReady; }
 | 
						|
   bool play();
 | 
						|
   void stop();
 | 
						|
   bool pause();
 | 
						|
 | 
						|
   /// Update the GL texture from the bitmap the background thread writes to.
 | 
						|
   void refresh();
 | 
						|
   U32  getGLName();
 | 
						|
 | 
						|
   const F64 getCurrentTime()
 | 
						|
   {
 | 
						|
      return getTheoraTime();
 | 
						|
   }
 | 
						|
 | 
						|
   TextureHandle*	mTextureHandle;
 | 
						|
};
 | 
						|
 | 
						|
#endif
 |