From Riccardo Corsi, "this should be the final version of the qt-plugin ported to windows and cleaned up to avoid crashes on exit.

Stephan and I tested it on Mac and Win.
Just a couple of notes:

    * the plugin is able to load both regular 2D images and movie stream. There is a #define QT_HANDLE_IMAGES_ALSO mechanism to indicate whether to use it for images or not. This is defined by default on Mac only, to avoid conflicts with the standard windows plugins. See comments on QTUtils.h

    * de-initialization of quicktime before exit is now left to an observer, which calls exitQuicktime() when last media loaded with the plugin is released. This prevent a crash on exit without need of any extra call external to the plugin."
This commit is contained in:
Robert Osfield
2007-01-12 22:07:33 +00:00
parent b992451586
commit 35ec6cee40
5 changed files with 105 additions and 61 deletions

View File

@@ -27,7 +27,7 @@ using namespace std;
#endif
OSErr err = EnterMovies();
if (err!=0)
osg::notify(osg::FATAL) << "Error while initializing quicktime: " << err << endl;
osg::notify(osg::FATAL) << "Error while initializing quicktime: " << err << endl;
else
osg::notify(osg::DEBUG_INFO) << "Quicktime initialized successfully" << endl;
registerQTReader();
@@ -45,6 +45,9 @@ using namespace std;
protected:
void registerQTReader() {
osgDB::Registry* r = osgDB::Registry::instance();
r->addFileExtensionAlias("mov", "qt");
#ifdef QT_HANDLE_IMAGES_ALSO
r->addFileExtensionAlias("jpg", "qt");
r->addFileExtensionAlias("jpe", "qt");
r->addFileExtensionAlias("jpeg", "qt");
@@ -59,8 +62,9 @@ using namespace std;
r->addFileExtensionAlias("mpg", "qt");
r->addFileExtensionAlias("mpv", "qt");
r->addFileExtensionAlias("dv", "qt");
r->addFileExtensionAlias("mp4", "qt");
r->addFileExtensionAlias("m4v", "qt");
r->addFileExtensionAlias("mp4", "qt");
r->addFileExtensionAlias("m4v", "qt");
#endif
}
};

View File

@@ -10,9 +10,17 @@
#ifndef QTUTILS_HEADER_
#define QTUTILS_HEADER_
// Quicktime plugin is able to load regular 2D images
// besides movie streams.
// It is used as default image loader on __APPLE__
// Uncomment this define to use it as image loader
// on other platforms.
// #define QT_HANDLE_IMAGES_ALSO
#ifdef __APPLE__
#include <Quicktime/Quicktime.h>
#include <Carbon/Carbon.h>
#define QT_HANDLE_IMAGES_ALSO
#else
#include <QTML.h>
#include <Movies.h>

View File

@@ -38,22 +38,21 @@
#define IDLE_TIMEOUT 150000L
#define ERR_MSG(no,msg) osg::notify(osg::WARN) << "QT-ImageStream: " << msg << " failed with error " << no << std::endl;
static OpenThreads::Mutex* s_qtMutex = new OpenThreads::Mutex;
int QuicktimeImageStream::_qtInstanceCount = 0;
// Constructor: setup and start thread
QuicktimeImageStream::QuicktimeImageStream(std::string fileName) : ImageStream()
{
// ricky
/*
// ricky
if(_qtInstanceCount == 0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
{
osg::notify(osg::NOTICE) << "quicktime Init" << std::endl;
initQuicktime();
}
++ _qtInstanceCount;
++ _qtInstanceCount;
// end ricky
*/
_len = 0;
@@ -81,21 +80,20 @@ QuicktimeImageStream::~QuicktimeImageStream()
quit(true);
}
// ricky
/*
// ricky
-- _qtInstanceCount;
if(_qtInstanceCount == 0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
osg::notify(osg::NOTICE) << "quicktime Exit" << std::endl;
exitQuicktime();
}
}
// end ricky
*/
// clean up quicktime movies.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
delete _data;
}
delete _data;
}
@@ -131,14 +129,10 @@ void QuicktimeImageStream::load(std::string fileName)
{
osg::notify(osg::DEBUG_INFO) << "QT-ImageStream: loading quicktime movie from " << fileName << std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
_data->load(this, fileName);
_len = _data->getMovieDuration();
_current = 0;
}
void QuicktimeImageStream::quit(bool wiatForThreadToExit)
@@ -177,8 +171,6 @@ void QuicktimeImageStream::run()
osg::notify(osg::DEBUG_INFO) << "movietime: " << _data->getMovieTime() << " rate: " << _data->getMovieRate() << " state " << cmd << " playing: " << playing << " done " << done << " " << _wrIndex << "/" << _rdIndex << std::endl;
// Handle commands
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*s_qtMutex);
if (cmd != THREAD_IDLE) {
osg::notify(osg::DEBUG_INFO) << "new cmd: " << cmd << std::endl;
switch (cmd) {
@@ -265,8 +257,9 @@ void QuicktimeImageStream::run()
rewind();
}
// orig
//pause();
//pause();
//end ricky
}
}

View File

@@ -1,26 +1,26 @@
// -*-c++-*-
/*
* Copyright (C) 2004 Stephan Huber http://digitalmind.de
*
* The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
* real-time rendering of large 3D photo-realistic models.
* The OSG homepage is http://www.openscenegraph.org/
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
* Copyright (C) 2004 Stephan Huber http://digitalmind.de
*
* The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
* real-time rendering of large 3D photo-realistic models.
* The OSG homepage is http://www.openscenegraph.org/
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _QUICKTIMEIMAGESTREAM_H_
#define _QUICKTIMEIMAGESTREAM_H_

View File

@@ -3,6 +3,8 @@
#include <osg/Geode>
#include <osg/observer_ptr>
#include "osg/GL"
#include "osgDB/FileNameUtils"
@@ -23,6 +25,35 @@
using namespace osg;
// This class is used as a helper to de-initialize
// properly quicktime, when the last media loaded
// with the quicktime plugin is released.
// All loaded media must be added to the observer
// (see ReaderWriterQT::readImage() function)
class QuicktimeExitObserver : public osg::Observer
{
public:
QuicktimeExitObserver () : _instanceCount(0){}
virtual ~QuicktimeExitObserver(){};
void addMedia(Image* ptr)
{
ptr->addObserver(this);
++ _instanceCount;
}
virtual void objectDeleted(void*)
{
-- _instanceCount;
if(_instanceCount== 0)
exitQuicktime();
}
private:
unsigned int _instanceCount;
};
class ReaderWriterQT : public osgDB::ReaderWriter
@@ -46,7 +77,9 @@ public:
{
// this should be the only image importer required on the Mac
// dont know what else it supports, but these will do
return
return
#ifdef QT_HANDLE_IMAGES_ALSO
osgDB::equalCaseInsensitive(extension,"rgb") ||
osgDB::equalCaseInsensitive(extension,"rgba") ||
osgDB::equalCaseInsensitive(extension,"jpg") ||
@@ -58,28 +91,27 @@ public:
osgDB::equalCaseInsensitive(extension,"pict") ||
osgDB::equalCaseInsensitive(extension,"pct") ||
osgDB::equalCaseInsensitive(extension,"tga") ||
osgDB::equalCaseInsensitive(extension,"psd") ||
osgDB::equalCaseInsensitive(extension,"psd") ||
#endif
acceptsMovieExtension(extension);
}
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options*) const
{
// ricky
// If using only the QuicktimeImageStream class for the movies, you can comment
// out this line, as the init function is called inside the QTImageStream
// ctor.
// It is left here for compatibility with the original plugin, to handle
// regular 2D images as well.
initQuicktime();
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file );
std::string fileName = osgDB::findDataFile( file, options);
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
// Note from Riccardo Corsi
// Quicktime initialization is done here, when a media is found
// and before any image or movie is loaded.
// After the first call the function does nothing.
// The cleaning up is left to the QuicktimeExitObserver (see below)
initQuicktime();
// if the file is a movie file then load as an ImageStream.
if (acceptsMovieExtension(ext))
{
@@ -90,9 +122,13 @@ public:
// to get things off the ground.
QuicktimeImageStream* moov = new QuicktimeImageStream(fileName);
// moov->play();
// add the media to the observer for proper clean up on exit
_qtExitObserver.addMedia(moov);
return moov;
}
long origWidth, origHeight,buffWidth,buffHeight,buffDepth,origDepth;
// NOTE - implememntation means that this will always return 32 bits, so it is hard to work out if
@@ -211,6 +247,10 @@ public:
osg::Image::USE_NEW_DELETE );
notify(DEBUG_INFO) << "image read ok "<<buffWidth<<" "<<buffHeight<<std::endl;
// add the media to the observer for proper clean up on exit
_qtExitObserver.addMedia(image);
return image;
}
@@ -411,11 +451,10 @@ public:
return WriteResult::ERROR_IN_WRITING_FILE;
}
}
mutable QuicktimeExitObserver _qtExitObserver;
};
// now register with Registry to instantiate the above