From f963397726f28f75b22129c8bf86c83bd2d02070 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 11 Feb 2009 17:42:17 +0000 Subject: [PATCH] From Riccardo Corsi, "in attach you'll find a patch to cleanup a little bit the (de)initialization code of QuickTime? environment from the quickTime pluging. It basically removes the static init() and exit() functions,and move them inside the observer class (the one that cleans everything up when the last media is unloaded). It also add an extra check to clean up on exit if the QuickTime? env is initialized, but no media is succesfully loaded / written (it might happens with streaming resources). I tested it under WinXP with zero, one and multiple videos. " Merged from svn/trunk using: svn merge -r 9768:9769 http://www.openscenegraph.org/svn/osg/OpenSceneGraph/trunk --- src/osgPlugins/quicktime/QTImportExport.cpp | 1 - src/osgPlugins/quicktime/QTUtils.cpp | 75 --------- src/osgPlugins/quicktime/QTUtils.h | 10 -- src/osgPlugins/quicktime/ReaderWriterQT.cpp | 160 +++++++++++++++----- 4 files changed, 120 insertions(+), 126 deletions(-) diff --git a/src/osgPlugins/quicktime/QTImportExport.cpp b/src/osgPlugins/quicktime/QTImportExport.cpp index a26ec4f0c..24b67ebfb 100644 --- a/src/osgPlugins/quicktime/QTImportExport.cpp +++ b/src/osgPlugins/quicktime/QTImportExport.cpp @@ -34,7 +34,6 @@ QuicktimeImportExport::QuicktimeImportExport() : _error(0), _lastError("") { - initQuicktime(); } diff --git a/src/osgPlugins/quicktime/QTUtils.cpp b/src/osgPlugins/quicktime/QTUtils.cpp index 306c55fcf..3701bb012 100644 --- a/src/osgPlugins/quicktime/QTUtils.cpp +++ b/src/osgPlugins/quicktime/QTUtils.cpp @@ -16,81 +16,6 @@ using namespace std; - - class QuicktimeInitializer : public osg::Referenced { - public: - QuicktimeInitializer() :osg::Referenced() { - - #ifndef __APPLE__ - InitializeQTML(0); - #endif - OSErr err = EnterMovies(); - if (err!=0) - osg::notify(osg::FATAL) << "Error while initializing quicktime: " << err << endl; - else - osg::notify(osg::DEBUG_INFO) << "Quicktime initialized successfully" << endl; - - static bool registered = false; - - if (!registered){ - registerQTReader(); - registered = true; - } - } - - ~QuicktimeInitializer() { - #ifndef __APPLE__ - ExitMovies(); - #endif - //osg::notify(osg::DEBUG_INFO) << "Quicktime deinitialized successfully" << endl; - } - - 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"); - r->addFileExtensionAlias("tif", "qt"); - r->addFileExtensionAlias("tiff", "qt"); - r->addFileExtensionAlias("gif", "qt"); - r->addFileExtensionAlias("png", "qt"); - r->addFileExtensionAlias("psd", "qt"); - r->addFileExtensionAlias("tga", "qt"); - r->addFileExtensionAlias("mov", "qt"); - r->addFileExtensionAlias("avi", "qt"); - r->addFileExtensionAlias("mpg", "qt"); - r->addFileExtensionAlias("mpv", "qt"); - r->addFileExtensionAlias("dv", "qt"); - r->addFileExtensionAlias("mp4", "qt"); - r->addFileExtensionAlias("m4v", "qt"); - #endif - } - - }; - - void initQuicktime(bool erase) { - - static osg::ref_ptr s_qt_init = new QuicktimeInitializer(); - if (erase) { - s_qt_init = NULL; - } else if (!s_qt_init.valid()) - { - s_qt_init = new QuicktimeInitializer(); - } - } - - - void exitQuicktime() { - initQuicktime(true); - } - - - - // --------------------------------------------------------------------------- // MakeFSSPecFromPath // wandelt einen Posix-Pfad in ein FSSpec um. diff --git a/src/osgPlugins/quicktime/QTUtils.h b/src/osgPlugins/quicktime/QTUtils.h index a70c71358..38e7f7dbd 100644 --- a/src/osgPlugins/quicktime/QTUtils.h +++ b/src/osgPlugins/quicktime/QTUtils.h @@ -49,16 +49,6 @@ #define OffsetRect MacOffsetRect #endif - - - /** - * inits Quicktime, if erase = true, the Quicktime-stuff gets cleaned, call it before your app exits - * @param erase true, if you want to cleanup quicktime-related stuff - */ - void initQuicktime(bool erase = false); - - /** cleans up all quicktime-related stuff */ - void exitQuicktime(); /** constructs an FSSpec out of an path */ OSStatus MakeFSSpecFromPath(const char* path, FSSpec* spec); diff --git a/src/osgPlugins/quicktime/ReaderWriterQT.cpp b/src/osgPlugins/quicktime/ReaderWriterQT.cpp index 20c78d477..04baabeb1 100644 --- a/src/osgPlugins/quicktime/ReaderWriterQT.cpp +++ b/src/osgPlugins/quicktime/ReaderWriterQT.cpp @@ -36,46 +36,94 @@ 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 { public: + + + // 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 QuicktimeInitializer : public osg::Observer + { + public: + + QuicktimeInitializer (): + _instanceCount(0), + _setup(false) + {} + + virtual ~QuicktimeInitializer() + { + // When we get here, the exit() function + // should have been called, when last media was released. + // In case no media has been added after initialization, + // let's perform an extra check + if (_setup && _instanceCount == 0) + { + exit(); + } + }; + + void addMedia(Image* ptr) + { + ptr->addObserver(this); + ++ _instanceCount; + } + + virtual void objectDeleted(void*) + { + -- _instanceCount; + if(_instanceCount== 0) + exit(); + } + + void init() + { + if (!_setup) + { + #ifndef __APPLE__ + InitializeQTML(0); + #endif + + OSErr err = EnterMovies(); + if (err!=0) + osg::notify(osg::FATAL) << "Error while initializing quicktime: " << err << std::endl; + else + osg::notify(osg::DEBUG_INFO) << "Quicktime initialized successfully" << std::endl; + + _setup = true; + } + } + + void exit() + { + #ifndef __APPLE__ + ExitMovies(); + #endif + + _setup = false; + } + + private: + unsigned int _instanceCount; + bool _setup; + + }; + + + + + ReaderWriterQT::ReaderWriterQT() { + + registerQtReader(); + + supportsExtension("mov","Movie format"); supportsExtension("mpg","Movie format"); supportsExtension("mpv","Movie format"); @@ -228,8 +276,9 @@ public: // 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(); + // The cleaning up is left to the QuicktimeInitializer (see below) + _qtExitObserver.init(); + // QuicktimeLiveImageStream* p_qt_image_stream = new QuicktimeLiveImageStream(osgDB::getNameLessExtension(file)); // add the media to the observer for proper clean up on exit @@ -252,8 +301,8 @@ public: // 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(); + // The cleaning up is left to the QuicktimeInitializer (see below) + _qtExitObserver.init(); // if the file is a movie file then load as an ImageStream. @@ -316,6 +365,8 @@ public: } } } + + _qtExitObserver.init(); QuicktimeImportExport importer; osg::ref_ptr image = importer.readFromStream(is, filename, sizeHint); @@ -334,7 +385,7 @@ public: std::string ext = osgDB::getFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; - initQuicktime(); + _qtExitObserver.init(); //Buidl map of extension <-> osFileTypes std::map extmap; @@ -386,6 +437,8 @@ public: } } + _qtExitObserver.init(); + QuicktimeImportExport exporter; exporter.writeToStream(os, const_cast(&img), filename); @@ -395,8 +448,35 @@ public: return WriteResult::ERROR_IN_WRITING_FILE; } +protected: - mutable QuicktimeExitObserver _qtExitObserver; + //internal utils + void registerQtReader() const + { + 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"); + r->addFileExtensionAlias("tif", "qt"); + r->addFileExtensionAlias("tiff", "qt"); + r->addFileExtensionAlias("gif", "qt"); + r->addFileExtensionAlias("png", "qt"); + r->addFileExtensionAlias("psd", "qt"); + r->addFileExtensionAlias("tga", "qt"); + r->addFileExtensionAlias("mov", "qt"); + r->addFileExtensionAlias("avi", "qt"); + r->addFileExtensionAlias("mpg", "qt"); + r->addFileExtensionAlias("mpv", "qt"); + r->addFileExtensionAlias("dv", "qt"); + r->addFileExtensionAlias("mp4", "qt"); + r->addFileExtensionAlias("m4v", "qt"); + #endif + } + + mutable QuicktimeInitializer _qtExitObserver; }; // now register with Registry to instantiate the above