home *** CD-ROM | disk | FTP | other *** search
Wrap
#include "rb_plugin.h" #include <Movies.h> #include <QuicktimeComponents.h> #include "QTEffect.h" static double playerGetPosition(REALmoviePlayer instance, long param); static void playerSetPosition(REALmoviePlayer instance, long param, double value); static int movieTrackCount(REALobject instance, long param); static REALobject movieTrack(REALobject instance, int index); static REALobject newVideoTrack(REALobject movie, int width, int height, int frameRate); static double trackGetDuration(REALobject instance, long param); static unsigned long trackGetEnabled(REALobject instance, long param); static void trackSetEnabled(REALobject instance, long param, unsigned long value); static REALpicture effectSequenceImageGetter(REALobject instance, long param); static REALobject getQTSMPTEEffect(int wipeId); static REALobject getQTCrossFadeEffect(void); static void newQTEffectSequence(REALobject object, REALobject effect, REALpicture pic1, REALpicture pic2, int frames); static REALobject createMovie(REALfolderItem location); static REALobject openAsEditableMovie(REALfolderItem location); static void videoTrackAppendPicture(REALobject track, REALpicture pic); static int videoTrackSelectCompression(REALobject videoTrack); static void trackDestructor(REALobject track, void *garbage); static void videoTrackDestructor(REALobject track, void *garbage); static void qtEffectDestructor(REALobject object, void *crud); static void qtEffectSequenceDestructor(REALobject object, void *crud); static void editableMovieDestructor(REALobject instance, void *garbage); static double moviePositionGetter(REALobject instance, long param); static void moviePositionSetter(REALobject instance, long param, double value); static double movieDurationGetter(REALobject instance, long param); static int movieEOFGetter(REALobject instance, long param); static void trackFirstSample(REALobject track); static void trackNextSample(REALobject track); static void trackFirstSync(REALobject track); static void trackNextSync(REALobject track); static REALstring trackMediaType(REALobject track, long param); static Boolean gQuicktime21Installed, gQuicktime30Installed; REALproperty playerProperties[1] = { { nil, "Position", "Double", 0, (REALproc) playerGetPosition, (REALproc) playerSetPosition }, }; REALproperty movieProperties[] = { { nil, "TrackCount", "Integer", 0, (REALproc) movieTrackCount }, { nil, "Position", "Double", 0, (REALproc) moviePositionGetter, (REALproc) moviePositionSetter }, { nil, "Duration", "Double", 0, (REALproc) movieDurationGetter }, { nil, "EOF", "Boolean", 0, (REALproc) movieEOFGetter }, }; REALmethodDefinition movieMethods[] = { { (REALproc) movieTrack, REALnoImplementation, "Track(index as integer) As QTTrack"}, { (REALproc) newVideoTrack, REALnoImplementation, "NewVideoTrack(width as integer, height as integer, timeScale as integer) As QTVideoTrack" }, }; REALproperty trackProperties[] = { { nil, "Duration", "Double", 0, (REALproc) trackGetDuration }, { nil, "Enabled", "Boolean", 0, (REALproc) trackGetEnabled, (REALproc) trackSetEnabled }, { nil, "MediaType", "String", 0, (REALproc) trackMediaType }, }; REALproperty effectSequenceProperties[2] = { { nil, "Image", "Picture", 0, (REALproc) effectSequenceImageGetter }, { nil, "Frame", "Integer", 0, REALstandardGetter, REALstandardSetter, FieldOffset(EffectSequenceData, currentFrame) }, }; REALmethodDefinition GetQTSMPTEEffectMethod = { (REALproc) getQTSMPTEEffect, REALnoImplementation, "GetQTSMPTEEffect(Id as integer) As QTEffect" }; REALmethodDefinition GetQTCrossFadeEffectMethod = { (REALproc) getQTCrossFadeEffect, REALnoImplementation, "GetQTCrossFadeEffect As QTEffect" }; REALmethodDefinition effectSequenceMethods[1] = { { (REALproc) newQTEffectSequence, REALnoImplementation, "QTEffectSequence(effect as QTEffect, image1 as Picture, image2 as Picture, frames as integer)" }, }; REALmethodDefinition folderItemMethods[2] = { { (REALproc) createMovie, REALnoImplementation, "CreateMovie As EditableMovie" }, { (REALproc) openAsEditableMovie, REALnoImplementation, "OpenEditableMovie As EditableMovie" }, }; REALmethodDefinition trackMethods[] = { { (REALproc) trackFirstSample, REALnoImplementation, "FindFirstSample" }, { (REALproc) trackNextSample, REALnoImplementation, "FindNextSample" }, { (REALproc) trackFirstSync, REALnoImplementation, "FindFirstKeyFrame" }, { (REALproc) trackNextSync, REALnoImplementation, "FindNextKeyFrame" }, }; REALmethodDefinition videoTrackMethods[] = { { (REALproc) videoTrackAppendPicture, REALnoImplementation, "AppendPicture(pic As Picture)"}, { (REALproc) videoTrackSelectCompression, REALnoImplementation, "SelectCompressionSettings As Boolean" }, }; REALclassDefinition playerExtension = { kCurrentREALControlVersion, "MoviePlayer", nil, 0, 0, nil, nil, playerProperties, 1, nil, 0, nil, 0, }; struct EditableMovieData { Movie aMovie; short resRefNum, resId; Boolean bDirty, bNew; TimeValue currentTime; }; REALclassDefinition editableMovieClass = { kCurrentREALControlVersion, "EditableMovie", nil, sizeof(EditableMovieData), 0, nil, (REALproc) editableMovieDestructor, movieProperties, sizeof(movieProperties) / sizeof(REALproperty), movieMethods, sizeof(movieMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition folderItemExtension = { kCurrentREALControlVersion, "FolderItem", nil, 0, 0, nil, nil, nil, 0, folderItemMethods, sizeof(folderItemMethods) / sizeof(REALmethodDefinition), nil, 0, }; struct TrackData { Track theTrack; REALobject movie; }; struct VideoTrackData { Boolean bEdits; TimeValue oldDuration; Fixed frameRate; Boolean bCodecSelected; short codecDepth; CodecQ codecQuality; CodecQ temporalQuality; CodecType cType; CompressorComponent codec; int keyFrameRate; ComponentInstance standardCompressor; Boolean bCompressorPrepared; long maxSize; Handle bits; GWorldPtr compressionPage; ImageSequence seq; ImageDescription **imageDescriptionH; Boolean bFirstFrame; }; REALclassDefinition trackClass = { kCurrentREALControlVersion, "QTTrack", nil, sizeof(TrackData), 0, nil, (REALproc) trackDestructor, trackProperties, sizeof(trackProperties) / sizeof(REALproperty), nil, 0, nil, 0, }; REALclassDefinition videoTrackClass = { kCurrentREALControlVersion, "QTVideoTrack", "QTTrack", sizeof(VideoTrackData), 0, nil, (REALproc) videoTrackDestructor, nil, 0, videoTrackMethods, sizeof(videoTrackMethods) / sizeof(REALmethodDefinition), nil, 0, }; REALclassDefinition qteffectClass = { kCurrentREALControlVersion, "QTEffect", nil, sizeof(EffectData), 0, nil, (REALproc) qtEffectDestructor, nil, 0, nil, 0, nil, 0 }; REALclassDefinition qteffectSequenceClass = { kCurrentREALControlVersion, "QTEffectSequence", nil, sizeof(EffectSequenceData), 0, nil, (REALproc) qtEffectSequenceDestructor, effectSequenceProperties, sizeof(effectSequenceProperties) / sizeof(REALproperty), effectSequenceMethods, sizeof(effectSequenceMethods) / sizeof(REALmethodDefinition), nil, 0 }; static double playerGetPosition(REALmoviePlayer instance, long param) { TimeScale scale; float f; scale = 1000; f = MCGetCurrentTime(REALgetMoviePlayerController(instance), &scale); f = f / scale; return f; } static void playerSetPosition(REALmoviePlayer instance, long param, double value) { TimeRecord timeSpec; Movie movie; MovieController ctl = REALgetMoviePlayerController(instance); if (!ctl) return; movie = MCGetMovie(ctl); if (!movie) return; if (value < 0.0) value = 0.0; timeSpec.scale = GetMovieTimeScale(movie); value = value * timeSpec.scale; timeSpec.value.lo = value; timeSpec.value.hi = 0; timeSpec.base = GetMovieTimeBase(movie); MCDoAction(ctl, mcActionGoToTime, &timeSpec); } static int movieTrackCount(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); return GetMovieTrackCount(data->aMovie); } static REALobject movieTrack(REALobject instance, int index) { ClassData(editableMovieClass, instance, EditableMovieData, mdata); Track t = GetMovieIndTrack(mdata->aMovie, index); REALobject rv; if (!t) return nil; rv = REALnewInstance("QTTrack"); if (rv) { ClassData(trackClass, rv, TrackData, data); data->theTrack = t; data->movie = instance; REALLockObject(data->movie); } return rv; } static double trackGetDuration(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); double v = GetTrackDuration(data->theTrack); v = v / GetMovieTimeScale(GetTrackMovie(data->theTrack)); return v; } static unsigned long trackGetEnabled(REALobject instance, long param) { ClassData(trackClass, instance, TrackData, data); if (GetTrackEnabled(data->theTrack)) return 1; else return 0; } static void trackSetEnabled(REALobject instance, long param, unsigned long value) { ClassData(trackClass, instance, TrackData, data); SetTrackEnabled(data->theTrack, value != 0); } static REALpicture effectSequenceImageGetter(REALobject instance, long param) { ClassData(qteffectSequenceClass, instance, EffectSequenceData, data); if (data->lastFrame != data->currentFrame) { BuildEffectSequenceFrame(data, data->currentFrame); data->lastFrame = data->currentFrame; } REALLockObject((REALobject) data->destPicture); return data->destPicture; } static REALobject getQTSMPTEEffect(int wipeId) { REALobject rv; if (!gQuicktime30Installed) return nil; if (!REALenterMovies()) return nil; rv = REALnewInstance("QTEffect"); if (rv) { ClassData(qteffectClass, rv, EffectData, data); BuildSMPTEEffect(data, wipeId); } return rv; } static REALobject getQTCrossFadeEffect(void) { REALobject rv; if (!gQuicktime30Installed) return nil; if (!REALenterMovies()) return nil; rv = REALnewInstance("QTEffect"); if (rv) { ClassData(qteffectClass, rv, EffectData, data); BuildCrossFadeEffect(data); } return rv; } static void newQTEffectSequence(REALobject object, REALobject effect, REALpicture pic1, REALpicture pic2, int frames) { if (!gQuicktime30Installed) return; if (!REALenterMovies()) return; if (effect) { ClassData(qteffectSequenceClass, object, EffectSequenceData, data); ClassData(qteffectClass, effect, EffectData, effectData); if (effectData->theEffectType) BuildEffectSquence(data, effectData, pic1, pic2, frames); } } static void qtEffectDestructor(REALobject object, void *crud) { ClassData(qteffectClass, object, EffectData, effectData); if (effectData->fEffectDescription) QTDisposeAtomContainer(effectData->fEffectDescription); } static void qtEffectSequenceDestructor(REALobject object, void *crud) { ClassData(qteffectSequenceClass, object, EffectSequenceData, data); if (data->fEffectSequenceID != 0L) CDSequenceEnd(data->fEffectSequenceID); if (data->fEffectDescription) QTDisposeAtomContainer(data->fEffectDescription); if (data->pic1) { REALUnlockPictureDescription(data->pic1); REALUnlockObject((REALobject) data->pic1); } else if (data->fGW1) DisposeGWorld(data->fGW1); if (data->pic2) { REALUnlockPictureDescription(data->pic2); REALUnlockObject((REALobject) data->pic2); } else if (data->fGW2) DisposeGWorld(data->fGW2); if (data->destPicture) REALUnlockObject((REALobject) data->destPicture); if (data->fSampleDescription) DisposeHandle((Handle) data->fSampleDescription); } static REALobject createMovie(REALfolderItem location) { FSSpec spec; short resRefNum; Movie aMovie; REALobject newMovie; if (!REALenterMovies()) return nil; if (!REALFSSpecFromFolderItem(&spec, location)) return nil; if (noErr != CreateMovieFile(&spec, 'TVOD', 0, createMovieFileDeleteCurFile | newMovieActive, &resRefNum, &aMovie)) return nil; newMovie = REALnewInstance("editableMovie"); ClassData(editableMovieClass, newMovie, EditableMovieData, data); data->aMovie = aMovie; data->resRefNum = resRefNum; data->bDirty = true; data->bNew = true; return newMovie; } static REALobject openAsEditableMovie(REALfolderItem location) { FSSpec spec; short resRefNum, movieResID; Movie aMovie; REALobject newMovie; OSErr err; if (!REALenterMovies()) return nil; if (!REALFSSpecFromFolderItem(&spec, location)) return nil; if (noErr != OpenMovieFile(&spec, &resRefNum, fsRdPerm)) return nil; err = NewMovieFromFile(&aMovie, resRefNum, &movieResID, nil, newMovieActive, nil); if (noErr != err) return nil; newMovie = REALnewInstance("editableMovie"); ClassData(editableMovieClass, newMovie, EditableMovieData, data); data->aMovie = aMovie; data->resRefNum = resRefNum; data->resId = movieResID; data->bDirty = true; data->bNew = false; return newMovie; } static void editableMovieDestructor(REALobject instance, void *garbage) { ClassData(editableMovieClass, instance, EditableMovieData, data); short resId = 0; if (data->bNew) AddMovieResource(data->aMovie, data->resRefNum, &resId, nil); else if (data->bDirty) UpdateMovieResource(data->aMovie, data->resRefNum, data->resId, nil); DisposeMovie(data->aMovie); if (data->resRefNum) CloseMovieFile(data->resRefNum); } static double moviePositionGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); double v = data->currentTime / GetMovieTimeScale(data->aMovie); return v; } static double movieDurationGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); double v = GetMovieDuration(data->aMovie) / GetMovieTimeScale(data->aMovie); return v; } static int movieEOFGetter(REALobject instance, long param) { ClassData(editableMovieClass, instance, EditableMovieData, data); if (data->currentTime >= GetMovieDuration(data->aMovie)) return 1; return 0; } static void moviePositionSetter(REALobject instance, long param, double value) { ClassData(editableMovieClass, instance, EditableMovieData, data); long v = value * GetMovieTimeScale(data->aMovie); if (v < 0) v = 0; else if (v > GetMovieDuration(data->aMovie)) v = GetMovieDuration(data->aMovie); data->currentTime = v; } static void trackFirstSample(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeMediaSample + nextTimeEdgeOK, 0, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackNextSample(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); if (gQuicktime21Installed) GetTrackNextInterestingTime(trackData->theTrack, nextTimeStep, movieData->currentTime, fixed1, &theTime, nil); else GetTrackNextInterestingTime(trackData->theTrack, nextTimeMediaSample, movieData->currentTime, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackFirstSync(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeSyncSample + nextTimeEdgeOK, 0, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static void trackNextSync(REALobject track) { ClassData(trackClass, track, TrackData, trackData); ClassData(editableMovieClass, trackData->movie, EditableMovieData, movieData); TimeValue theTime = GetMovieDuration(movieData->aMovie); GetTrackNextInterestingTime(trackData->theTrack, nextTimeSyncSample, movieData->currentTime, fixed1, &theTime, nil); if (noErr != GetMoviesError()) movieData->currentTime = GetMovieDuration(movieData->aMovie); else movieData->currentTime = theTime; } static REALstring trackMediaType(REALobject track, long param) { ClassData(trackClass, track, TrackData, trackData); OSType mediaType; GetMediaHandlerDescription(GetTrackMedia(trackData->theTrack), &mediaType, nil, nil); return REALBuildString((Ptr) &mediaType, 4); } static REALobject newVideoTrack(REALobject instance, int width, int height, int frameRate) { ClassData(editableMovieClass, instance, EditableMovieData, data); Track aTrack = NewMovieTrack(data->aMovie, (long)width << 16, (long)height << 16, 0); REALobject rv; if (!aTrack) return nil; Media aMedia = NewTrackMedia(aTrack, VideoMediaType, frameRate, nil, (OSType)nil); if (!aMedia) return nil; BeginMediaEdits(aMedia); rv = REALnewInstance("QTVideoTrack"); if (rv) { ClassData(trackClass, rv, TrackData, trackData); ClassData(videoTrackClass, rv, VideoTrackData, data); trackData->theTrack = aTrack; trackData->movie = instance; REALLockObject(trackData->movie); data->bEdits = true; } return rv; } static void videoTrackAppendPicture(REALobject track, REALpicture pic) { ClassData(trackClass, track, TrackData, trackData); ClassData(videoTrackClass, track, VideoTrackData, data); Rect r; Fixed width, height; long compressedFrameSize; Media trackMedia = GetTrackMedia(trackData->theTrack); CGrafPtr oldPort; GDHandle oldDevice; if (!data->bEdits) { BeginMediaEdits(trackMedia); data->bEdits = true; data->oldDuration = GetMediaDuration(trackMedia); ClassData(editableMovieClass, trackData->movie, EditableMovieData, data); data->bDirty = true; } GetTrackDimensions(trackData->theTrack, &width, &height); SetRect(&r, 0, 0, width >> 16, height >> 16); if (data->standardCompressor) { if (data->bFirstFrame) { SCSpatialSettings ss; SCGetInfo(data->standardCompressor, scSpatialSettingsType, &ss); if (ss.depth == 0) ss.depth = 16; if (noErr != NewGWorld(&data->compressionPage, ss.depth, &r, nil, nil, 0)) NewGWorld(&data->compressionPage, ss.depth, &r, nil, nil, useTempMem); } } else { if (!data->bCodecSelected) { data->codecDepth = 16; data->codecQuality = codecNormalQuality; data->temporalQuality = 0; data->cType = 'raw '; data->codec = anyCodec; data->keyFrameRate = 16; data->bCodecSelected = true; } if (!data->bCompressorPrepared) { if (noErr != NewGWorld(&data->compressionPage, data->codecDepth, &r, nil, nil, 0)) NewGWorld(&data->compressionPage, data->codecDepth, &r, nil, nil, useTempMem); GetMaxCompressionSize(data->compressionPage->portPixMap, &r, data->codecDepth, data->codecQuality, data->cType, data->codec, &data->maxSize); data->bCompressorPrepared = true; data->bits = NewHandle(data->maxSize); data->imageDescriptionH = (ImageDescription **)NewHandle(sizeof(ImageDescription)); data->bFirstFrame = true; data->bCompressorPrepared = true; } } LockPixels(GetGWorldPixMap(data->compressionPage)); GetGWorld(&oldPort, &oldDevice); SetGWorld(data->compressionPage, nil); EraseRect(&r); if (pic) REALDrawPicturePrimitive(pic, &r, false); OSErr result; Handle bits; if (data->standardCompressor) { short notSyncFlag = 0; if (data->bFirstFrame) { SCCompressSequenceBegin(data->standardCompressor, data->compressionPage->portPixMap, &r, &data->imageDescriptionH); data->bFirstFrame = false; } SCCompressSequenceFrame(data->standardCompressor, data->compressionPage->portPixMap, &r, &bits, &compressedFrameSize, ¬SyncFlag); } else { if (data->bFirstFrame) { result = CompressSequenceBegin(&data->seq, data->compressionPage->portPixMap, nil, &r, nil, data->codecDepth, data->cType, data->codec, data->codecQuality, data->temporalQuality, data->keyFrameRate, nil, codecFlagUpdatePreviousComp, data->imageDescriptionH); data->bFirstFrame = false; } HLock(data->bits); Ptr compressBits = StripAddress(*data->bits); result = CompressSequenceFrame(data->seq, data->compressionPage->portPixMap, &r, codecFlagUpdatePreviousComp, compressBits, &compressedFrameSize, nil, nil); HUnlock(data->bits); bits = data->bits; } SetGWorld(oldPort, oldDevice); UnlockPixels(GetGWorldPixMap(data->compressionPage)); result = AddMediaSample(trackMedia, bits, 0L, compressedFrameSize, (TimeValue)1, (SampleDescriptionHandle)data->imageDescriptionH, 1L, 0, nil); } static void shutdownCurrentVideoCompressor(VideoTrackData *data) { if (data->standardCompressor) { if (!data->bFirstFrame) SCCompressSequenceEnd(data->standardCompressor); data->bFirstFrame = true; if (data->compressionPage) { DisposeGWorld(data->compressionPage); data->compressionPage = nil; } } else { if (data->seq) { CDSequenceEnd(data->seq); data->seq = 0; } if (data->bCompressorPrepared) { DisposeHandle((Handle) data->imageDescriptionH); DisposeHandle(data->bits); DisposeGWorld(data->compressionPage); data->bCompressorPrepared = false; } } } static void videoTrackDestructor(REALobject track, void *garbage) { ClassData(videoTrackClass, track, VideoTrackData, data); ClassData(trackClass, track, TrackData, trackData); Media trackMedia = GetTrackMedia(trackData->theTrack); shutdownCurrentVideoCompressor(data); if (data->standardCompressor) CloseComponent(data->standardCompressor); if (data->bEdits) { TimeValue newDuration = GetMediaDuration(trackMedia); if (newDuration > data->oldDuration) InsertMediaIntoTrack(trackData->theTrack, -1, data->oldDuration, newDuration - data->oldDuration, 0x10000); EndMediaEdits(trackMedia); } } static void trackDestructor(REALobject track, void *garbage) { ClassData(trackClass, track, TrackData, data); REALUnlockObject(data->movie); } static int videoTrackSelectCompression(REALobject videoTrack) { ClassData(videoTrackClass, videoTrack, VideoTrackData, data); shutdownCurrentVideoCompressor(data); if (!data->standardCompressor) data->standardCompressor = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); ComponentResult result; if (!data->standardCompressor) return false; result = SCRequestSequenceSettings(data->standardCompressor); if (result < 0 || result == scUserCancelled) { CloseComponent(data->standardCompressor); data->standardCompressor = nil; return false; } data->bFirstFrame = true; return true; } /* Boolean bCodecSelected; short codecDepth; CodecQ codecQuality; CodecQ temporalQuality; CodecType cType; CompressorComponent codec; int keyFrameRate; Boolean bCompressorPrepared; long maxSize; Handle bits; GWorldPtr compressionPage; ImageSequence seq; ImageDescription **imageDescriptionH; */ /* REALexport pluginExports[] = { { nil, movieGetPosition }, { nil, movieSetPosition }, { nil, trackGetDuration }, { nil, movieTrackCount }, { nil, movieTrack }, { nil, trackGetEnabled }, { nil, trackSetEnabled }, { nil, effectSequenceImageGetter }, { nil, getQTSMPTEEffect }, { nil, newQTEffectSequence }, { nil, qtEffectDestructor }, { nil, qtEffectSequenceDestructor }, { nil, getQTCrossFadeEffect }, { nil, createMovie }, { nil, newVideoTrack }, { nil, videoTrackAppendPicture }, { nil, videoTrackDestructor }, { nil, trackDestructor }, { nil, videoTrackSelectCompression }, }; short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport); */ void PluginEntry(void) { long result; OSErr error = Gestalt(gestaltQuickTime, &result); if (error == noErr) { if (result >= 0x2100000) gQuicktime21Installed = true; if (result >= 0x3000000) gQuicktime30Installed = true; } REALRegisterClass(&qteffectClass); REALRegisterClass(&qteffectSequenceClass); REALRegisterClass(&trackClass); REALRegisterClass(&videoTrackClass); REALRegisterClass(&editableMovieClass); REALRegisterClassExtension(&playerExtension); REALRegisterClassExtension(&folderItemExtension); REALRegisterMethod(&GetQTSMPTEEffectMethod); REALRegisterMethod(&GetQTCrossFadeEffectMethod); }