Added ImageStream::quit(bool) for exiting from video threads, and added
clean up to OsgCameGroup to quit movie threads automatically.
This commit is contained in:
@@ -50,6 +50,8 @@ class SG_EXPORT ImageStream : public Image
|
||||
virtual void pause() { _status=PAUSED; }
|
||||
|
||||
virtual void rewind() { _status=REWINDING; }
|
||||
|
||||
virtual void quit(bool /*wiatForThreadToExit*/ = true) {}
|
||||
|
||||
StreamStatus getStatus() { return _status; }
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup
|
||||
|
||||
OsgCameraGroup(osg::ArgumentParser& arguments);
|
||||
|
||||
virtual ~OsgCameraGroup() {}
|
||||
virtual ~OsgCameraGroup();
|
||||
|
||||
|
||||
void setApplicationUsage(osg::ApplicationUsage* au) { _applicationUsage = au; }
|
||||
|
||||
@@ -65,23 +65,10 @@ MpegImageStream::MpegImageStream(const char* fileName) : ImageStream()
|
||||
// Deconstructor: stop and terminate thread
|
||||
MpegImageStream::~MpegImageStream()
|
||||
{
|
||||
setCmd(THREAD_QUIT);
|
||||
|
||||
if( isRunning() )
|
||||
{
|
||||
|
||||
// cancel the thread..
|
||||
// cancel();
|
||||
|
||||
//join();
|
||||
|
||||
// then wait for the the thread to stop running.
|
||||
while(isRunning())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Waiting for MpegImageStream to cancel"<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
|
||||
quit(true);
|
||||
}
|
||||
|
||||
mpeg3_t* mpg = (mpeg3_t*)_mpg;
|
||||
@@ -96,7 +83,6 @@ MpegImageStream::~MpegImageStream()
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Set command
|
||||
void MpegImageStream::setCmd(ThreadCommand cmd)
|
||||
{
|
||||
@@ -204,6 +190,22 @@ void MpegImageStream::load(const char* fileName)
|
||||
}
|
||||
|
||||
|
||||
void MpegImageStream::quit(bool wiatForThreadToExit)
|
||||
{
|
||||
osg::notify(osg::DEBUG_INFO)<<"Sending quit"<<std::endl;
|
||||
setCmd(THREAD_QUIT);
|
||||
|
||||
if (wiatForThreadToExit)
|
||||
{
|
||||
while(isRunning())
|
||||
{
|
||||
osg::notify(osg::DEBUG_INFO)<<"Waiting for MpegImageStream to quit"<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MpegImageStream::run()
|
||||
{
|
||||
bool playing = false;
|
||||
@@ -287,6 +289,7 @@ void MpegImageStream::run()
|
||||
}
|
||||
else if (!done)
|
||||
{
|
||||
//OpenThreads::Thread::YieldCurrentThread();
|
||||
::usleep(IDLE_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ namespace osg {
|
||||
/// Rewind stream to beginning.
|
||||
virtual void rewind() { setCmd(THREAD_REWIND); }
|
||||
|
||||
virtual void quit(bool wiatForThreadToExit);
|
||||
|
||||
/// Enable/disable MMX.
|
||||
inline void enableMMX(bool b) { _useMMX = b; }
|
||||
|
||||
|
||||
@@ -42,8 +42,11 @@ static OpenThreads::Mutex s_qtMutex;
|
||||
// Constructor: setup and start thread
|
||||
QuicktimeImageStream::QuicktimeImageStream(std::string fileName) : ImageStream()
|
||||
{
|
||||
|
||||
osgQuicktime::initQuicktime();
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_qtMutex);
|
||||
osgQuicktime::initQuicktime();
|
||||
}
|
||||
|
||||
_len = 0;
|
||||
|
||||
@@ -66,22 +69,10 @@ QuicktimeImageStream::QuicktimeImageStream(std::string fileName) : ImageStream()
|
||||
// Deconstructor: stop and terminate thread
|
||||
QuicktimeImageStream::~QuicktimeImageStream()
|
||||
{
|
||||
setCmd(THREAD_QUIT);
|
||||
|
||||
if( isRunning() )
|
||||
{
|
||||
|
||||
// cancel the thread..
|
||||
// cancel();
|
||||
//join();
|
||||
|
||||
// then wait for the the thread to stop running.
|
||||
while(isRunning())
|
||||
{
|
||||
osg::notify(osg::DEBUG_INFO)<<"Waiting for QuicktimeImageStream to cancel"<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
|
||||
quit(true);
|
||||
}
|
||||
|
||||
// clean up quicktime movies.
|
||||
@@ -97,10 +88,10 @@ QuicktimeImageStream::~QuicktimeImageStream()
|
||||
// Set command
|
||||
void QuicktimeImageStream::setCmd(ThreadCommand cmd)
|
||||
{
|
||||
lock();
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
_cmd[_wrIndex] = cmd;
|
||||
_wrIndex = (_wrIndex + 1) % NUM_CMD_INDEX;
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -108,12 +99,14 @@ void QuicktimeImageStream::setCmd(ThreadCommand cmd)
|
||||
QuicktimeImageStream::ThreadCommand QuicktimeImageStream::getCmd()
|
||||
{
|
||||
ThreadCommand cmd = THREAD_IDLE;
|
||||
lock();
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
if (_rdIndex != _wrIndex) {
|
||||
cmd = _cmd[_rdIndex];
|
||||
_rdIndex = (_rdIndex + 1) % NUM_CMD_INDEX;
|
||||
}
|
||||
unlock();
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@@ -131,6 +124,21 @@ void QuicktimeImageStream::load(std::string fileName)
|
||||
|
||||
}
|
||||
|
||||
void QuicktimeImageStream::quit(bool wiatForThreadToExit)
|
||||
{
|
||||
osg::notify(osg::DEBUG_INFO)<<"Sending quit"<<std::endl;
|
||||
setCmd(THREAD_QUIT);
|
||||
|
||||
if (wiatForThreadToExit)
|
||||
{
|
||||
while(isRunning())
|
||||
{
|
||||
osg::notify(osg::DEBUG_INFO)<<"Waiting for QuicktimeImageStream to quit"<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QuicktimeImageStream::run()
|
||||
{
|
||||
@@ -149,13 +157,7 @@ void QuicktimeImageStream::run()
|
||||
|
||||
float currentTime=0.0f;
|
||||
|
||||
if (cmd == THREAD_QUIT)
|
||||
{
|
||||
osg::notify(NOTICE) << "QT-ImageStream: quick quit" << std::endl;
|
||||
playing = false;
|
||||
done = true;
|
||||
}
|
||||
else if (cmd != THREAD_IDLE)
|
||||
if (cmd != THREAD_IDLE)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_qtMutex);
|
||||
|
||||
@@ -184,7 +186,7 @@ void QuicktimeImageStream::run()
|
||||
case THREAD_QUIT: // TODO
|
||||
SetMovieRate(_data->getMovie(),0);
|
||||
osg::notify(NOTICE) << "QT-ImageStream: quit" << std::endl;
|
||||
playing = false;
|
||||
//playing = false;
|
||||
done = true;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -59,8 +59,8 @@ namespace osg {
|
||||
/// Rewind stream to beginning.
|
||||
virtual void rewind() { setCmd(THREAD_REWIND); }
|
||||
|
||||
|
||||
|
||||
virtual void quit(bool wiatForThreadToExit);
|
||||
|
||||
/// Get total length in seconds.
|
||||
inline float getLength() const { return _len; }
|
||||
|
||||
@@ -90,10 +90,6 @@ namespace osg {
|
||||
|
||||
OpenThreads::Mutex _mutex;
|
||||
|
||||
// Lock/unlock object.
|
||||
inline void lock() { _mutex.lock(); }
|
||||
inline void unlock() { _mutex.unlock(); }
|
||||
|
||||
/// Set command.
|
||||
void setCmd(ThreadCommand cmd);
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <osg/ApplicationUsage>
|
||||
#include <osg/Timer>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osg/ImageStream>
|
||||
|
||||
#include <osgUtil/DisplayRequirementsVisitor>
|
||||
#include <osgDB/FileUtils>
|
||||
@@ -122,6 +125,84 @@ OsgCameraGroup::OsgCameraGroup(osg::ArgumentParser& arguments):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class QuitImageStreamVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
QuitImageStreamVisitor():
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
|
||||
/** Simply traverse using standard NodeVisitor traverse method.*/
|
||||
virtual void apply(osg::Node& node)
|
||||
{
|
||||
if (node.getStateSet())
|
||||
apply(*(node.getStateSet()));
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
virtual void apply(osg::Geode& node)
|
||||
{
|
||||
if (node.getStateSet())
|
||||
apply(*(node.getStateSet()));
|
||||
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable* drawable = node.getDrawable(i);
|
||||
if (drawable && drawable->getStateSet())
|
||||
apply(*(drawable->getStateSet()));
|
||||
}
|
||||
}
|
||||
|
||||
void apply(osg::StateSet& stateset)
|
||||
{
|
||||
for(unsigned int i=0;i<stateset.getTextureAttributeList().size();++i)
|
||||
{
|
||||
osg::StateAttribute* texture = stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE);
|
||||
if (texture)
|
||||
{
|
||||
osg::TextureRectangle* textureRect = dynamic_cast<osg::TextureRectangle*>(texture);
|
||||
if (textureRect)
|
||||
{
|
||||
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(textureRect->getImage());
|
||||
if (imageStream)
|
||||
{
|
||||
imageStream->quit();
|
||||
}
|
||||
}
|
||||
|
||||
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(texture);
|
||||
if (texture2D)
|
||||
{
|
||||
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(texture2D->getImage());
|
||||
if (imageStream)
|
||||
{
|
||||
imageStream->quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
OsgCameraGroup::~OsgCameraGroup()
|
||||
{
|
||||
// kill the DatabasePager and associated thread if one exists.
|
||||
osgDB::Registry::instance()->setDatabasePager(0);
|
||||
|
||||
osg::Node* node = getTopMostSceneData();
|
||||
if (node)
|
||||
{
|
||||
// kill any ImageStream threads
|
||||
QuitImageStreamVisitor qisv;
|
||||
node->accept(qisv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OsgCameraGroup::_init()
|
||||
{
|
||||
_thread_model = ThreadPerCamera;
|
||||
|
||||
@@ -303,8 +303,6 @@ Viewer::Viewer(osg::ArgumentParser& arguments):
|
||||
|
||||
Viewer::~Viewer()
|
||||
{
|
||||
// kill the DatabasePager and associated thread if one exists.
|
||||
osgDB::Registry::instance()->setDatabasePager(0);
|
||||
}
|
||||
|
||||
void Viewer::setCoordindateSystemNodePath(const osg::NodePath& nodePath)
|
||||
|
||||
Reference in New Issue
Block a user