godot/drivers/theoraplayer/src/TheoraFrameQueue.cpp

175 lines
3.5 KiB
C++
Raw Normal View History

/************************************************************************************
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 "TheoraFrameQueue.h"
#include "TheoraVideoFrame.h"
#include "TheoraVideoManager.h"
#include "TheoraUtil.h"
TheoraFrameQueue::TheoraFrameQueue(TheoraVideoClip* parent)
{
mParent = parent;
}
TheoraFrameQueue::~TheoraFrameQueue()
{
foreach_l(TheoraVideoFrame*, mQueue)
{
delete (*it);
}
mQueue.clear();
}
TheoraVideoFrame* TheoraFrameQueue::createFrameInstance(TheoraVideoClip* clip)
{
TheoraVideoFrame* frame = new TheoraVideoFrame(clip);
if (frame->getBuffer() == NULL) // This can happen if you run out of memory
{
delete frame;
return NULL;
}
return frame;
}
void TheoraFrameQueue::setSize(int n)
{
mMutex.lock();
if (mQueue.size() > 0)
{
foreach_l (TheoraVideoFrame*, mQueue)
{
delete (*it);
}
mQueue.clear();
}
TheoraVideoFrame* frame;
for (int i = 0;i < n; ++i)
{
frame = createFrameInstance(mParent);
if (frame != NULL) mQueue.push_back(frame);
else
{
TheoraVideoManager::getSingleton().logMessage("TheoraFrameQueue: unable to create " + str(n) + " frames, out of memory. Created " + str((int) mQueue.size()) + " frames.");
break;
}
}
mMutex.unlock();
}
int TheoraFrameQueue::getSize()
{
return (int) mQueue.size();
}
TheoraVideoFrame* TheoraFrameQueue::_getFirstAvailableFrame()
{
TheoraVideoFrame* frame = mQueue.front();
if (frame->mReady) return frame;
else return NULL;
}
TheoraVideoFrame* TheoraFrameQueue::getFirstAvailableFrame()
{
mMutex.lock();
TheoraVideoFrame* frame = _getFirstAvailableFrame();
mMutex.unlock();
return frame;
}
void TheoraFrameQueue::clear()
{
mMutex.lock();
foreach_l (TheoraVideoFrame*, mQueue)
(*it)->clear();
mMutex.unlock();
}
void TheoraFrameQueue::_pop(int n)
{
for (int i = 0; i < n; ++i)
{
TheoraVideoFrame* first = mQueue.front();
first->clear();
mQueue.pop_front();
mQueue.push_back(first);
}
}
void TheoraFrameQueue::pop(int n)
{
mMutex.lock();
_pop(n);
mMutex.unlock();
}
TheoraVideoFrame* TheoraFrameQueue::requestEmptyFrame()
{
TheoraVideoFrame* frame = NULL;
mMutex.lock();
foreach_l (TheoraVideoFrame*, mQueue)
{
if (!(*it)->mInUse)
{
(*it)->mInUse = 1;
(*it)->mReady = 0;
frame = (*it);
break;
}
}
mMutex.unlock();
return frame;
}
int TheoraFrameQueue::getUsedCount()
{
mMutex.lock();
int n=0;
foreach_l(TheoraVideoFrame*,mQueue)
if ((*it)->mInUse) ++n;
mMutex.unlock();
return n;
}
int TheoraFrameQueue::_getReadyCount()
{
int n = 0;
foreach_l (TheoraVideoFrame*, mQueue)
if ((*it)->mReady) ++n;
return n;
}
int TheoraFrameQueue::getReadyCount()
{
mMutex.lock();
int n = _getReadyCount();
mMutex.unlock();
return n;
}
bool TheoraFrameQueue::isFull()
{
return getReadyCount() == mQueue.size();
}
void TheoraFrameQueue::lock()
{
mMutex.lock();
}
void TheoraFrameQueue::unlock()
{
mMutex.unlock();
}
std::list<TheoraVideoFrame*>& TheoraFrameQueue::_getFrameQueue()
{
return mQueue;
}