summaryrefslogtreecommitdiff
path: root/drivers/theoraplayer/src/TheoraVideoClip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/theoraplayer/src/TheoraVideoClip.cpp')
-rw-r--r--drivers/theoraplayer/src/TheoraVideoClip.cpp496
1 files changed, 0 insertions, 496 deletions
diff --git a/drivers/theoraplayer/src/TheoraVideoClip.cpp b/drivers/theoraplayer/src/TheoraVideoClip.cpp
deleted file mode 100644
index 16897ee80e..0000000000
--- a/drivers/theoraplayer/src/TheoraVideoClip.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/************************************************************************************
-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
-*************************************************************************************/
-#include "TheoraVideoClip.h"
-#include "TheoraVideoManager.h"
-#include "TheoraVideoFrame.h"
-#include "TheoraFrameQueue.h"
-#include "TheoraAudioInterface.h"
-#include "TheoraTimer.h"
-#include "TheoraDataSource.h"
-#include "TheoraUtil.h"
-#include "TheoraException.h"
-
-#include "core/os/memory.h"
-
-TheoraVideoClip::TheoraVideoClip(TheoraDataSource* data_source,
- TheoraOutputMode output_mode,
- int nPrecachedFrames,
- bool usePower2Stride):
- mAudioInterface(NULL),
- mNumDroppedFrames(0),
- mNumDisplayedFrames(0),
- mSeekFrame(-1),
- mDuration(-1),
- mNumFrames(-1),
- mFPS(1),
- mUseAlpha(0),
- mFrameDuration(0),
- mName(data_source->repr()),
- mStride(usePower2Stride),
- mSubFrameWidth(0),
- mSubFrameHeight(0),
- mSubFrameOffsetX(0),
- mSubFrameOffsetY(0),
- mAudioGain(1),
- mRequestedOutputMode(output_mode),
- mAutoRestart(0),
- mEndOfFile(0),
- mRestarted(0),
- mIteration(0),
- mPlaybackIteration(0),
- mStream(0),
- mThreadAccessCount(0),
- mPriority(1),
- mFirstFrameDisplayed(0),
- mWaitingForCache(false),
- mOutputMode(TH_UNDEFINED)
-{
-
- audio_track=0;
- mAudioMutex = NULL;
- mThreadAccessMutex = new TheoraMutex();
- mTimer = mDefaultTimer = new TheoraTimer();
-
- mFrameQueue = NULL;
- mAssignedWorkerThread = NULL;
- mNumPrecachedFrames = nPrecachedFrames;
- setOutputMode(output_mode);
-}
-
-TheoraVideoClip::~TheoraVideoClip()
-{
- // wait untill a worker thread is done decoding the frame
- mThreadAccessMutex->lock();
-
- delete mDefaultTimer;
-
- if (mStream) memdelete(mStream);
-
- if (mFrameQueue) delete mFrameQueue;
-
- if (mAudioInterface)
- {
- mAudioMutex->lock(); // ensure a thread isn't using this mutex
- delete mAudioInterface; // notify audio interface it's time to call it a day
- mAudioMutex ->unlock();
- delete mAudioMutex;
- }
-
- mThreadAccessMutex->unlock();
-
- delete mThreadAccessMutex;
-}
-
-TheoraTimer* TheoraVideoClip::getTimer()
-{
- return mTimer;
-}
-
-void TheoraVideoClip::setTimer(TheoraTimer* timer)
-{
- if (!timer) mTimer = mDefaultTimer;
- else mTimer = timer;
-}
-
-void TheoraVideoClip::resetFrameQueue()
-{
- mFrameQueue->clear();
- mPlaybackIteration = mIteration = 0;
-}
-
-void TheoraVideoClip::restart()
-{
- mEndOfFile = true; //temp, to prevent threads to decode while restarting
- mThreadAccessMutex->lock();
- _restart();
- mTimer->seek(0);
- mFirstFrameDisplayed = false;
- resetFrameQueue();
- mEndOfFile = false;
- mRestarted = false;
- mSeekFrame = -1;
- mThreadAccessMutex->unlock();
-}
-
-void TheoraVideoClip::update(float timeDelta)
-{
- if (mTimer->isPaused())
- {
- mTimer->update(0); // update timer in case there is some code that needs to execute each frame
- return;
- }
- float time = mTimer->getTime(), speed = mTimer->getSpeed();
- if (time + timeDelta * speed >= mDuration)
- {
- if (mAutoRestart && mRestarted)
- {
- float seekTime = time + timeDelta * speed;
- for (;seekTime >= mDuration;)
- {
- seekTime -= mDuration;
- ++mPlaybackIteration;
- }
-
- mTimer->seek(seekTime);
- }
- else
- {
- if (time != mDuration)
- {
- mTimer->update((mDuration - time) / speed);
- }
- }
- }
- else
- {
- mTimer->update(timeDelta);
- }
-}
-
-float TheoraVideoClip::updateToNextFrame()
-{
- TheoraVideoFrame* f = mFrameQueue->getFirstAvailableFrame();
- if (!f) return 0;
-
- float time = f->mTimeToDisplay - mTimer->getTime();
- update(time);
- return time;
-}
-
-TheoraFrameQueue* TheoraVideoClip::getFrameQueue()
-{
- return mFrameQueue;
-}
-
-void TheoraVideoClip::popFrame()
-{
- ++mNumDisplayedFrames;
-
- // after transfering frame data to the texture, free the frame
- // so it can be used again
- if (!mFirstFrameDisplayed)
- {
- mFrameQueue->lock();
- mFrameQueue->_pop(1);
- mFirstFrameDisplayed = true;
- mFrameQueue->unlock();
- }
- else
- {
- mFrameQueue->pop();
- }
-}
-
-int TheoraVideoClip::getWidth()
-{
- return mUseAlpha ? mWidth / 2 : mWidth;
-}
-
-int TheoraVideoClip::getHeight()
-{
- return mHeight;
-}
-
-int TheoraVideoClip::getSubFrameWidth()
-{
- return mUseAlpha ? mWidth / 2 : mSubFrameWidth;
-}
-
-int TheoraVideoClip::getSubFrameHeight()
-{
- return mUseAlpha ? mHeight : mSubFrameHeight;
-}
-
-int TheoraVideoClip::getSubFrameOffsetX()
-{
- return mUseAlpha ? 0 : mSubFrameOffsetX;
-}
-
-int TheoraVideoClip::getSubFrameOffsetY()
-{
- return mUseAlpha ? 0 : mSubFrameOffsetY;
-}
-
-float TheoraVideoClip::getAbsPlaybackTime()
-{
- return mTimer->getTime() + mPlaybackIteration * mDuration;
-}
-
-int TheoraVideoClip::discardOutdatedFrames(float absTime)
-{
- int nReady = mFrameQueue->_getReadyCount();
- // only drop frames if you have more frames to show. otherwise even the late frame will do..
- if (nReady == 1) return 0;
- float time = absTime;
-
- int nPop = 0;
- TheoraVideoFrame* frame;
- float timeToDisplay;
-
- std::list<TheoraVideoFrame*>& queue = mFrameQueue->_getFrameQueue();
- foreach_l (TheoraVideoFrame*, queue)
- {
- frame = *it;
- if (!frame->mReady) break;
- timeToDisplay = frame->mTimeToDisplay + frame->mIteration * mDuration;
- if (time > timeToDisplay + mFrameDuration)
- {
- ++nPop;
- if (nReady - nPop == 1) break; // always leave at least one in the queue
- }
- else break;
- }
-
- if (nPop > 0)
- {
-#define _DEBUG
-#ifdef _DEBUG
- std::string log = getName() + ": dropped frame ";
-
- int i = nPop;
- foreach_l (TheoraVideoFrame*, queue)
- {
- log += str((int) (*it)->getFrameNumber());
- if (i-- > 1)
- {
- log += ", ";
- }
- else break;
- }
- th_writelog(log);
-#endif
- mNumDroppedFrames += nPop;
- mFrameQueue->_pop(nPop);
- }
-
- return nPop;
-}
-
-TheoraVideoFrame* TheoraVideoClip::getNextFrame()
-{
- TheoraVideoFrame* frame;
- // if we are about to seek, then the current frame queue is invalidated
- // (will be cleared when a worker thread does the actual seek)
- if (mSeekFrame != -1) return NULL;
-
- mFrameQueue->lock();
- float time = getAbsPlaybackTime();
- discardOutdatedFrames(time);
-
- frame = mFrameQueue->_getFirstAvailableFrame();
- if (frame != NULL)
- {
- if (frame->mTimeToDisplay + frame->mIteration * mDuration > time && mFirstFrameDisplayed)
- {
- frame = NULL; // frame is ready but it's not yet time to display it, except when we haven't displayed any frames yet
- }
- }
-
- mFrameQueue->unlock();
- return frame;
-}
-
-std::string TheoraVideoClip::getName()
-{
- return mName;
-}
-
-bool TheoraVideoClip::isBusy()
-{
- return mAssignedWorkerThread || mOutputMode != mRequestedOutputMode;
-}
-
-TheoraOutputMode TheoraVideoClip::getOutputMode()
-{
- return mOutputMode;
-}
-
-void TheoraVideoClip::setOutputMode(TheoraOutputMode mode)
-{
- if (mode == TH_UNDEFINED) throw TheoraGenericException("Invalid output mode: TH_UNDEFINED for video: " + mName);
- if (mOutputMode == mode) return;
- mRequestedOutputMode = mode;
- mUseAlpha = (mode == TH_RGBA ||
- mode == TH_ARGB ||
- mode == TH_BGRA ||
- mode == TH_ABGR ||
- mode == TH_GREY3A ||
- mode == TH_AGREY3 ||
- mode == TH_YUVA ||
- mode == TH_AYUV);
- if (mAssignedWorkerThread)
- {
- mThreadAccessMutex->lock();
- // discard current frames and recreate them
- mFrameQueue->setSize(mFrameQueue->getSize());
- mThreadAccessMutex->unlock();
-
- }
- mOutputMode = mRequestedOutputMode;
-}
-
-float TheoraVideoClip::getTimePosition()
-{
- return mTimer->getTime();
-}
-
-int TheoraVideoClip::getNumPrecachedFrames()
-{
- return mFrameQueue->getSize();
-}
-
-void TheoraVideoClip::setNumPrecachedFrames(int n)
-{
- if (mFrameQueue->getSize() != n)
- mFrameQueue->setSize(n);
-}
-
-int TheoraVideoClip::_getNumReadyFrames()
-{
- if (mSeekFrame != -1) return 0;
- return mFrameQueue->_getReadyCount();
-}
-
-int TheoraVideoClip::getNumReadyFrames()
-{
- if (mSeekFrame != -1) return 0; // we are about to seek, consider frame queue empty even though it will be emptied upon seek
- return mFrameQueue->getReadyCount();
-}
-
-float TheoraVideoClip::getDuration()
-{
- return mDuration;
-}
-
-float TheoraVideoClip::getFPS()
-{
- return mFPS;
-}
-
-void TheoraVideoClip::play()
-{
- mTimer->play();
-}
-
-void TheoraVideoClip::pause()
-{
- mTimer->pause();
-}
-
-bool TheoraVideoClip::isPaused()
-{
- return mTimer->isPaused();
-}
-
-bool TheoraVideoClip::isDone()
-{
- return mEndOfFile && !mFrameQueue->getFirstAvailableFrame();
-}
-
-void TheoraVideoClip::stop()
-{
- pause();
- resetFrameQueue();
- mFirstFrameDisplayed = false;
- seek(0);
-}
-
-void TheoraVideoClip::setPlaybackSpeed(float speed)
-{
- mTimer->setSpeed(speed);
-}
-
-float TheoraVideoClip::getPlaybackSpeed()
-{
- return mTimer->getSpeed();
-}
-
-void TheoraVideoClip::seek(float time)
-{
- seekToFrame((int) (time * getFPS()));
-}
-
-void TheoraVideoClip::seekToFrame(int frame)
-{
- if (frame < 0) mSeekFrame = 0;
- else if (frame > mNumFrames) mSeekFrame = mNumFrames;
- else mSeekFrame = frame;
-
- mFirstFrameDisplayed = false;
- mEndOfFile = false;
-}
-
-void TheoraVideoClip::waitForCache(float desired_cache_factor, float max_wait_time)
-{
- mWaitingForCache = true;
- bool paused = mTimer->isPaused();
- if (!paused) mTimer->pause();
- int elapsed = 0;
- int desired_num_precached_frames = (int) (desired_cache_factor * getNumPrecachedFrames());
- while (getNumReadyFrames() < desired_num_precached_frames)
- {
- _psleep(10);
- elapsed += 10;
- if (elapsed >= max_wait_time * 1000) break;
- }
- if (!paused) mTimer->play();
- mWaitingForCache = false;
-}
-
-float TheoraVideoClip::getPriority()
-{
- return mPriority;
-}
-
-void TheoraVideoClip::setPriority(float priority)
-{
- mPriority = priority;
-}
-
-float TheoraVideoClip::getPriorityIndex()
-{
- float priority = (float) getNumReadyFrames();
- if (mTimer->isPaused()) priority += getNumPrecachedFrames() / 2;
-
- return priority;
-}
-
-void TheoraVideoClip::setAudioInterface(TheoraAudioInterface* iface)
-{
- mAudioInterface = iface;
- if (iface && !mAudioMutex) mAudioMutex = new TheoraMutex;
- if (!iface && mAudioMutex)
- {
- delete mAudioMutex;
- mAudioMutex = NULL;
- }
-}
-
-TheoraAudioInterface* TheoraVideoClip::getAudioInterface()
-{
- return mAudioInterface;
-}
-
-void TheoraVideoClip::setAudioGain(float gain)
-{
- if (gain > 1) mAudioGain=1;
- if (gain < 0) mAudioGain=0;
- else mAudioGain=gain;
-}
-
-float TheoraVideoClip::getAudioGain()
-{
- return mAudioGain;
-}
-
-void TheoraVideoClip::setAutoRestart(bool value)
-{
- mAutoRestart = value;
- if (value) mEndOfFile = false;
-}