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:
Robert Osfield
2004-07-23 09:15:22 +00:00
parent 215e65a42d
commit cf62f7097d
8 changed files with 135 additions and 51 deletions

View File

@@ -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; }

View File

@@ -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; }

View File

@@ -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);
}
}

View File

@@ -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; }

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)