virtualx-engine/drivers/theoraplayer/include/theoraplayer/TheoraVideoClip.h
Juan Linietsky 6dd8768811 3D Import Import & UDP
-=-=-=-=-=-=-=-=-=-=-

-Animation Import filter support
-Animation Clip import support
-Animation Optimizer Fixes, Improvements and Visibile Options
-Extremely Experimental UDP support.
2014-11-12 11:23:23 -03:00

282 lines
8.8 KiB
C++

/************************************************************************************
This source file is part of the Theora Video Playback Library
For latest info, see http://libtheoraplayer.googlecode.com
*************************************************************************************
Copyright (c) 2008-2014 Kresimir Spes (kspes@cateia.com)
This program is free software; you can redistribute it and/or modify it under
the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause
*************************************************************************************/
#ifndef _TheoraVideoClip_h
#define _TheoraVideoClip_h
#include <string>
#include "TheoraExport.h"
// forward class declarations
class TheoraMutex;
class TheoraFrameQueue;
class TheoraTimer;
class TheoraAudioInterface;
class TheoraWorkerThread;
class TheoraDataSource;
class TheoraVideoFrame;
/**
format of the TheoraVideoFrame pixels. Affects decoding time
*/
enum TheoraOutputMode
{
// A = full alpha (255), order of letters represents the byte order for a pixel
// A means the image is treated as if it contains an alpha channel, while X formats
// just mean that RGB frame is transformed to a 4 byte format
TH_UNDEFINED = 0,
TH_RGB = 1,
TH_RGBA = 2,
TH_RGBX = 3,
TH_ARGB = 4,
TH_XRGB = 5,
TH_BGR = 6,
TH_BGRA = 7,
TH_BGRX = 8,
TH_ABGR = 9,
TH_XBGR = 10,
TH_GREY = 11,
TH_GREY3 = 12,
TH_GREY3A = 13,
TH_GREY3X = 14,
TH_AGREY3 = 15,
TH_XGREY3 = 16,
TH_YUV = 17,
TH_YUVA = 18,
TH_YUVX = 19,
TH_AYUV = 20,
TH_XYUV = 21
};
/**
This object contains all data related to video playback, eg. the open source file,
the frame queue etc.
*/
class TheoraPlayerExport TheoraVideoClip
{
friend class TheoraWorkerThread;
friend class TheoraVideoFrame;
friend class TheoraVideoManager;
protected:
TheoraFrameQueue* mFrameQueue;
TheoraAudioInterface* mAudioInterface;
TheoraDataSource* mStream;
TheoraTimer *mTimer, *mDefaultTimer;
TheoraWorkerThread* mAssignedWorkerThread;
bool mUseAlpha;
bool mWaitingForCache;
// benchmark vars
int mNumDroppedFrames, mNumDisplayedFrames, mNumPrecachedFrames;
int mThreadAccessCount; //! counter used by TheoraVideoManager to schedule workload
int mSeekFrame; //! stores desired seek position as a frame number. next worker thread will do the seeking and reset this var to -1
float mDuration, mFrameDuration, mFPS;
float mPriority; //! User assigned priority. Default value is 1
std::string mName;
int mWidth, mHeight, mStride;
int mNumFrames;
int audio_track;
int mSubFrameWidth, mSubFrameHeight, mSubFrameOffsetX, mSubFrameOffsetY;
float mAudioGain; //! multiplier for audio samples. between 0 and 1
TheoraOutputMode mOutputMode, mRequestedOutputMode;
bool mFirstFrameDisplayed;
bool mAutoRestart;
bool mEndOfFile, mRestarted;
int mIteration, mPlaybackIteration; //! used to ensure smooth playback of looping videos
TheoraMutex* mAudioMutex; //! syncs audio decoding and extraction
TheoraMutex* mThreadAccessMutex;
/**
* Get the priority of a video clip. based on a forumula that includes user
* priority factor, whether the video is paused or not, how many precached
* frames it has etc.
* This function is used in TheoraVideoManager to efficiently distribute job
* assignments among worker threads
* @return priority number of this video clip
*/
int calculatePriority();
void readTheoraVorbisHeaders();
virtual void doSeek() = 0; //! called by WorkerThread to seek to mSeekFrame
virtual bool _readData() = 0;
bool isBusy();
/**
* decodes audio from the vorbis stream and stores it in audio packets
* This is an internal function of TheoraVideoClip, called regularly if playing an
* audio enabled video clip.
* @return last decoded timestamp (if found in decoded packet's granule position)
*/
virtual float decodeAudio() = 0;
int _getNumReadyFrames();
void resetFrameQueue();
int discardOutdatedFrames(float absTime);
float getAbsPlaybackTime();
virtual void load(TheoraDataSource* source) = 0;
virtual void _restart() = 0; // resets the decoder and stream but leaves the frame queue intact
public:
TheoraVideoClip(TheoraDataSource* data_source,
TheoraOutputMode output_mode,
int nPrecachedFrames,
bool usePower2Stride);
virtual ~TheoraVideoClip();
std::string getName();
//! Returns the string name of the decoder backend (eg. Theora, AVFoundation)
virtual std::string getDecoderName() = 0;
//! benchmark function
int getNumDisplayedFrames() { return mNumDisplayedFrames; }
//! benchmark function
int getNumDroppedFrames() { return mNumDroppedFrames; }
//! return width in pixels of the video clip
int getWidth();
//! return height in pixels of the video clip
int getHeight();
//! Width of the actual picture inside a video frame (depending on implementation, this may be equal to mWidth or differ within a codec block size (usually 16))
int getSubFrameWidth();
//! Height of the actual picture inside a video frame (depending on implementation, this may be equal to mHeight or differ within a codec block size (usually 16))
int getSubFrameHeight();
//! X Offset of the actual picture inside a video frame (depending on implementation, this may be 0 or within a codec block size (usually 16))
int getSubFrameOffsetX();
//! Y Offset of the actual picture inside a video frame (depending on implementation, this may be 0 or differ within a codec block size (usually 16))
int getSubFrameOffsetY();
/**
\brief return stride in pixels
If you've specified usePower2Stride when creating the TheoraVideoClip object
then this value will be the next power of two size compared to width,
eg: w=376, stride=512.
Otherwise, stride will be equal to width
*/
int getStride() { return mStride; }
//! retur the timer objet associated with this object
TheoraTimer* getTimer();
//! replace the timer object with a new one
void setTimer(TheoraTimer* timer);
//! used by TheoraWorkerThread, do not call directly
virtual bool decodeNextFrame() = 0;
//! advance time. TheoraVideoManager calls this
void update(float timeDelta);
/**
\brief update timer to the display time of the next frame
useful if you want to grab frames instead of regular display
\return time advanced. 0 if no frames are ready
*/
float updateToNextFrame();
TheoraFrameQueue* getFrameQueue();
/**
\brief pop the frame from the front of the FrameQueue
see TheoraFrameQueue::pop() for more details
*/
void popFrame();
/**
\brief Returns the first available frame in the queue or NULL if no frames are available.
see TheoraFrameQueue::getFirstAvailableFrame() for more details
*/
TheoraVideoFrame* getNextFrame();
/**
check if there is enough audio data decoded to submit to the audio interface
TheoraWorkerThread calls this
*/
virtual void decodedAudioCheck() = 0;
void setAudioInterface(TheoraAudioInterface* iface);
TheoraAudioInterface* getAudioInterface();
/**
\brief resize the frame queues
Warning: this call discards ready frames in the frame queue
*/
void setNumPrecachedFrames(int n);
//! returns the size of the frame queue
int getNumPrecachedFrames();
//! returns the number of ready frames in the frame queue
int getNumReadyFrames();
//! if you want to adjust the audio gain. range [0,1]
void setAudioGain(float gain);
float getAudioGain();
//! if you want the video to automatically and smoothly restart when the last frame is reached
void setAutoRestart(bool value);
bool getAutoRestart() { return mAutoRestart; }
void set_audio_track(int p_track) { audio_track=p_track; }
/**
TODO: user priority. Useful only when more than one video is being decoded
*/
void setPriority(float priority);
float getPriority();
//! Used by TheoraVideoManager to schedule work
float getPriorityIndex();
//! get the current time index from the timer object
float getTimePosition();
//! get the duration of the movie in seconds
float getDuration();
//! return the clips' frame rate, warning, fps can be a non integer number!
float getFPS();
//! get the number of frames in this movie
int getNumFrames() { return mNumFrames; }
//! return the current output mode for this video object
TheoraOutputMode getOutputMode();
/**
set a new output mode
Warning: this discards the frame queue. ready frames will be lost.
*/
void setOutputMode(TheoraOutputMode mode);
bool isDone();
void play();
void pause();
void restart();
bool isPaused();
void stop();
void setPlaybackSpeed(float speed);
float getPlaybackSpeed();
//! seek to a given time position
void seek(float time);
//! seek to a given frame number
void seekToFrame(int frame);
//! wait max_time for the clip to cache a given percentage of frames, factor in range [0,1]
void waitForCache(float desired_cache_factor = 0.5f, float max_wait_time = 1.0f);
};
#endif