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:
@@ -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
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user