topical media & game development
lib-of-vs-libs-openFrameworks-video-ofQtUtils.cpp / cpp
include <ofQtUtils.h>
include <ofUtils.h>
ifndef TARGET_LINUX
static bool bQuicktimeInitialized = false;
//----------------------------------------
void initializeQuicktime(){
if (bQuicktimeInitialized == false){
//----------------------------------
// do we have quicktime installed at all?
// http://www.apple.com/quicktime/download/win.html
// can gestalt help with versions, or is that only after init?
OSErr myErr = noErr;
#ifdef TARGET_WIN32
myErr = InitializeQTML(0);
if (myErr != noErr){
ofLog(OF_LOG_ERROR, "-----------------------------------------------------");
ofLog(OF_LOG_ERROR, "sorry, there is a problem with quicktime starting up... please check!");
OF_EXIT_APP(0);
}
#endif
myErr = EnterMovies ();
if (myErr != noErr){
ofLog(OF_LOG_ERROR, "-----------------------------------------------------");
ofLog(OF_LOG_ERROR, "sorry, there is a problem with quicktime starting up... please check!");
OF_EXIT_APP(0);
}
bQuicktimeInitialized = true;
}
}
//----------------------------------------
void closeQuicktime(){
if (bQuicktimeInitialized == true){
ExitMovies();
#ifdef TARGET_WIN32
TerminateQTML();
#endif
bQuicktimeInitialized = false;
}
}
//----------------------------------------
void convertPixels(unsigned char * gWorldPixels, unsigned char * rgbPixels, int w, int h){
// ok for macs?
// ok for intel macs?
int * rgbaPtr = (int *) gWorldPixels;
pix24 * rgbPtr = (pix24 *) rgbPixels;
unsigned char * rgbaStart;
// putting in the boolean, so we can work on
// 0,0 in top right...
// bool bFlipVertically = true;
bool bFlipVertically = false;
// -------------------------------------------
// we flip vertically because the 0,0 position in OF
// is the bottom left (not top left, like processing)
// since the 0,0 of a picture is top left
// if we upload and drawf the data as is
// it will be upside-down....
// -------------------------------------------
if (!bFlipVertically){
//----- argb->rgb
for (int i = 0; i < h; i++){
pix24 * rgbPtr = (pix24 *) rgbPixels + ((i) * w);
for (int j = 0; j < w; j++){
rgbaStart = (unsigned char *)rgbaPtr;
memcpy (rgbPtr, rgbaStart+1, sizeof(pix24));
rgbPtr++;
rgbaPtr++;
}
}
} else {
//----- flip while argb->rgb
for (int i = 0; i < h; i++){
pix24 * rgbPtr = (pix24 *) rgbPixels + ((h-i-1) * w);
for (int j = 0; j < w; j++){
rgbaStart = (unsigned char *)rgbaPtr;
memcpy (rgbPtr, rgbaStart+1, sizeof(pix24));
rgbPtr++;
rgbaPtr++;
}
}
}
}
//----------------------------------------
// osx needs this for modal dialogs.
Boolean SeqGrabberModalFilterUPP (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){
#pragma unused(theDialog, itemHit)
Boolean handled = false;
if ((theEvent->what == updateEvt) &&
((WindowPtr) theEvent->message == (WindowPtr) refCon))
{
BeginUpdate ((WindowPtr) refCon);
EndUpdate ((WindowPtr) refCon);
handled = true;
}
return (handled);
}
define kCharacteristicHasVideoFrameRate FOUR_CHAR_CODE('vfrr')
define kCharacteristicIsAnMpegTrack FOUR_CHAR_CODE('mpeg')
/*
Calculate the static frame rate for a given movie.
*/
void MovieGetStaticFrameRate(Movie inMovie, double *outStaticFrameRate)
{
*outStaticFrameRate = 0;
Media movieMedia;
MediaHandler movieMediaHandler;
/* get the media identifier for the media that contains the first
video track's sample data, and also get the media handler for
this media. */
MovieGetVideoMediaAndMediaHandler(inMovie, &movieMedia, &movieMediaHandler);
if (movieMedia && movieMediaHandler)
{
Boolean isMPEG = false;
/* is this the MPEG-1/MPEG-2 media handler? */
OSErr err = IsMPEGMediaHandler(movieMediaHandler, &isMPEG);
if (err == noErr)
{
if (isMPEG) /* working with MPEG-1/MPEG-2 media */
{
Fixed staticFrameRate;
ComponentResult err = MPEGMediaGetStaticFrameRate(movieMediaHandler, &staticFrameRate);
if (err == noErr)
{
/* convert Fixed data result to type double */
*outStaticFrameRate = Fix2X(staticFrameRate);
}
}
else /* working with non-MPEG-1/MPEG-2 media */
{
OSErr err = MediaGetStaticFrameRate(movieMedia, outStaticFrameRate);
if (err != noErr) ofLog(OF_LOG_ERROR, "error in MediaGetStaticFrameRate, ofQtUtils");
//assert(err == noErr);
}
}
}
}
/*
Get the media identifier for the media that contains the first
video track's sample data, and also get the media handler for
this media.
*/
void MovieGetVideoMediaAndMediaHandler(Movie inMovie, Media *outMedia, MediaHandler *outMediaHandler)
{
*outMedia = NULL;
*outMediaHandler = NULL;
/* get first video track */
Track videoTrack = GetMovieIndTrackType(inMovie, 1, kCharacteristicHasVideoFrameRate,
movieTrackCharacteristic | movieTrackEnabledOnly);
if (videoTrack != NULL)
{
/* get media ref. for track's sample data */
*outMedia = GetTrackMedia(videoTrack);
if (*outMedia)
{
/* get a reference to the media handler component */
*outMediaHandler = GetMediaHandler(*outMedia);
}
}
}
/*
Return true if media handler reference is from the MPEG-1/MPEG-2 media handler.
Return false otherwise.
*/
OSErr IsMPEGMediaHandler(MediaHandler inMediaHandler, Boolean *outIsMPEG)
{
/* is this the MPEG-1/MPEG-2 media handler? */
return((OSErr) MediaHasCharacteristic(inMediaHandler,
kCharacteristicIsAnMpegTrack,
outIsMPEG));
}
/*
Given a reference to the media handler used for media in a MPEG-1/MPEG-2
track, return the static frame rate.
*/
ComponentResult MPEGMediaGetStaticFrameRate(MediaHandler inMPEGMediaHandler, Fixed *outStaticFrameRate)
{
*outStaticFrameRate = 0;
MHInfoEncodedFrameRateRecord encodedFrameRate;
Size encodedFrameRateSize = sizeof(encodedFrameRate);
/* get the static frame rate */
ComponentResult err = MediaGetPublicInfo(inMPEGMediaHandler,
kMHInfoEncodedFrameRate,
&encodedFrameRate,
&encodedFrameRateSize);
if (err == noErr)
{
/* return frame rate at which the track was encoded */
*outStaticFrameRate = encodedFrameRate.encodedFrameRate;
}
return err;
}
/*
Given a reference to the media that contains the sample data for a track,
calculate the static frame rate.
*/
OSErr MediaGetStaticFrameRate(Media inMovieMedia, double *outFPS)
{
*outFPS = 0;
/* get the number of samples in the media */
long sampleCount = GetMediaSampleCount(inMovieMedia);
OSErr err = GetMoviesError();
if (sampleCount && err == noErr)
{
/* find the media duration */
//Quicktime 7.0 code
//TimeValue64 duration = GetMediaDisplayDuration(inMovieMedia);
TimeValue64 duration = GetMediaDuration(inMovieMedia);
err = GetMoviesError();
if (err == noErr)
{
/* get the media time scale */
TimeValue64 timeScale = GetMediaTimeScale(inMovieMedia);
err = GetMoviesError();
if (err == noErr)
{
/* calculate the frame rate:
frame rate = (sample count * media time scale) / media duration
*/
*outFPS = (double)sampleCount * (double)timeScale / (double)duration;
}
}
}
return err;
}
//----------------------------------------
ifdef TARGET_OSX
// GetSettingsPreference
// Returns a preference for a specified key as QuickTime UserData
// It is your responsibility to dispose of the returned UserData
OSErr GetSettingsPreference(CFStringRef inKey, UserData *outUserData)
{
CFPropertyListRef theCFSettings;
Handle theHandle = NULL;
UserData theUserData = NULL;
OSErr err = paramErr;
// read the new setttings from our preferences
theCFSettings = CFPreferencesCopyAppValue(inKey,
kCFPreferencesCurrentApplication);
if (theCFSettings) {
err = PtrToHand(CFDataGetBytePtr((CFDataRef)theCFSettings), &theHandle,
CFDataGetLength((CFDataRef)theCFSettings));
CFRelease(theCFSettings);
if (theHandle) {
err = NewUserDataFromHandle(theHandle, &theUserData);
if (theUserData) {
*outUserData = theUserData;
}
DisposeHandle(theHandle);
}
}
return err;
}
//----------------------------------------
// SaveSettingsPreference
// Saves a preference for a specified key from QuickTime UserData
OSErr SaveSettingsPreference(CFStringRef inKey, UserData inUserData)
{
CFDataRef theCFSettings;
Handle hSettings;
OSErr err;
if (NULL == inUserData) return paramErr;
hSettings = NewHandle(0);
err = MemError();
if (noErr == err) {
err = PutUserDataIntoHandle(inUserData, hSettings);
if (noErr == err) {
HLock(hSettings);
theCFSettings = CFDataCreate(kCFAllocatorDefault,
(UInt8 *)*hSettings,
GetHandleSize(hSettings));
if (theCFSettings) {
CFPreferencesSetAppValue(inKey, theCFSettings,
kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
CFRelease(theCFSettings);
}
}
DisposeHandle(hSettings);
}
return err;
}
//end mac specific stuff
endif
endif
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.