bool OpenGLApp::initAPI(){ initialMode = CGDisplayCurrentMode(kCGDirectMainDisplay); dmodes = CGDisplayAvailableModes(kCGDirectMainDisplay); int count = CFArrayGetCount(dmodes); Array <DispRes> modes; int foundMode = -1; for (int i = 0; i < count; i++){ CFDictionaryRef mode = (CFDictionaryRef) CFArrayGetValueAtIndex(dmodes, i); long bitsPerPixel = GetDictionaryLong(mode, kCGDisplayBitsPerPixel); Boolean safeForHardware = GetDictionaryBoolean(mode, kCGDisplayModeIsSafeForHardware); Boolean stretched = GetDictionaryBoolean(mode, kCGDisplayModeIsStretched); if (bitsPerPixel < colorBits || !safeForHardware || stretched) continue; long width = GetDictionaryLong(mode, kCGDisplayWidth); long height = GetDictionaryLong(mode, kCGDisplayHeight); long refreshRate = GetDictionaryLong(mode, kCGDisplayRefreshRate); // printf("Mode: %dx%dx%d @ %d\n", width, height, bitsPerPixel, refreshRate); if (width >= 640 && height >= 480){ modes.add(newRes(width, height, i)); if (width == fullscreenWidth && height == fullscreenHeight){ foundMode = i; } } } resolution->clear(); modes.sort(dComp); char str[64]; for (uint i = 0; i < modes.getCount(); i++){ sprintf(str, "%dx%d", modes[i].w, modes[i].h); int index = resolution->addItemUnique(str); if (modes[i].index == foundMode) resolution->selectItem(index); } if (fullscreen){ if (foundMode < 0 || CGDisplaySwitchToMode(kCGDirectMainDisplay, (CFDictionaryRef) CFArrayGetValueAtIndex(dmodes, foundMode)) != kCGErrorSuccess){ sprintf(str, "Couldn't set fullscreen to %dx%d.", fullscreenWidth, fullscreenHeight); ErrorMsg(str); fullscreen = false; } } Rect rect; if (fullscreen){ rect.left = 0; rect.top = 0; } else { long w = GetDictionaryLong(initialMode, kCGDisplayWidth); long h = GetDictionaryLong(initialMode, kCGDisplayHeight); rect.left = (w - width) / 2; rect.top = (h - height) / 2; } rect.right = rect.left + width; rect.bottom = rect.top + height; WindowAttributes attributes = fullscreen? (kWindowNoTitleBarAttribute | kWindowNoShadowAttribute) : (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute); OSStatus error = CreateNewWindow(kDocumentWindowClass, attributes, &rect, &window); if (error != noErr || window == NULL){ ErrorMsg("Couldn't create window"); return false; } GDHandle screen = GetGWorldDevice(GetWindowPort(window)); if (screen == NULL){ ErrorMsg("Couldn't get device"); ReleaseWindow(window); return false; } AGLPixelFormat pixelFormat; while (true){ GLint attributes[] = { fullscreen? AGL_FULLSCREEN : AGL_WINDOW, AGL_RGBA, AGL_DOUBLEBUFFER, AGL_RED_SIZE, 8, AGL_GREEN_SIZE, 8, AGL_BLUE_SIZE, 8, AGL_ALPHA_SIZE, (colorBits > 24)? 8 : 0, AGL_DEPTH_SIZE, depthBits, AGL_STENCIL_SIZE, stencilBits, AGL_SAMPLE_BUFFERS_ARB, (antiAliasSamples > 0), AGL_SAMPLES_ARB, antiAliasSamples, AGL_NONE }; pixelFormat = aglChoosePixelFormat(&screen, 1, attributes); if (pixelFormat != NULL) break; antiAliasSamples -= 2; if (antiAliasSamples < 0){ ErrorMsg("No suitable pixel format"); ReleaseWindow(window); return false; } } glContext = aglCreateContext(pixelFormat, NULL); aglDestroyPixelFormat(pixelFormat); if (glContext == NULL){ ErrorMsg("Couldn't create context"); ReleaseWindow(window); return false; } if (fullscreen){ CGCaptureAllDisplays(); aglSetFullScreen(glContext, 0, 0, 0, 0); } else { if (!aglSetDrawable(glContext, GetWindowPort(window))){ ErrorMsg("Couldn't set drawable"); aglDestroyContext(glContext); ReleaseWindow(window); return false; } } if (!aglSetCurrentContext(glContext)){ ErrorMsg("Couldn't make context current"); aglDestroyContext(glContext); ReleaseWindow(window); return false; } setWindowTitle(getTitle()); ShowWindow(window); initExtensions(); if (antiAliasSamples > 0){ glEnable(GL_MULTISAMPLE_ARB); } if (fullscreen) captureMouse(!configDialog->isVisible()); renderer = new OpenGLRenderer(glContext); renderer->setViewport(width, height); antiAlias->selectItem(antiAliasSamples / 2); linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP); defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp); blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); noDepthTest = renderer->addDepthState(false, false); noDepthWrite = renderer->addDepthState(true, false); cullNone = renderer->addRasterizerState(CULL_NONE); cullBack = renderer->addRasterizerState(CULL_BACK); cullFront = renderer->addRasterizerState(CULL_FRONT); return true; }
//////////////////////////////////////////////////////////////////////////////// // virtual bool LLMediaImplQuickTime::sizeChanged() { if ( ! mMovieHandle ) return false; // sanitize size of movie Rect movie_rect; setMovieBoxEnhanced( &movie_rect ); // we need this later int width = ( movie_rect.right - movie_rect.left ); int height = ( movie_rect.bottom - movie_rect.top ); std::cout << "LLMEDIA> size changed to " << width << " x " << height << std::endl; setMediaSize( width, height ); // media depth won't change int depth_bits = getMediaDepth() * 8; GWorldPtr old_gworld_handle = mGWorldHandle; if (old_gworld_handle) { GWorldFlags result = UpdateGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, 0 ); if ( gwFlagErr == result ) { // TODO: unrecoverable?? throw exception? return something? return false; } } else { OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, keepLocal | pixelsLocked ); if ( noErr != result ) { // ATODO: unrecoverable?? throw exception? return something? return false; } // clear memory in GWorld to avoid random screen visual fuzz from uninitialized texture data if ( mGWorldHandle ) { PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); unsigned char* ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); memset( ptr, 0x00, height * QTGetPixMapHandleRowBytes( pix_map_handle ) ); } } // point movie at GWorld if it's new if ( mMovieHandle && ! old_gworld_handle ) { SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice ( mGWorldHandle ) ); } // update movie controller if ( mMovieController ) { MCSetControllerPort( mMovieController, mGWorldHandle ); MCPositionController( mMovieController, &movie_rect, &movie_rect, mcTopLeftMovie | mcPositionDontInvalidate ); MCMovieChanged( mMovieController, mMovieHandle ); } // Emit event with size change so the calling app knows about it too LLMediaEvent event( this ); mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); return true; }
void TLevelReader3gp::load(const TRasterP &rasP, int frameIndex, const TPoint &pos, int shrinkX, int shrinkY) { TRaster32P ras = rasP; { QMutexLocker sl(&m_mutex); ras->lock(); if (m_IOError != QTNoError) goto error; Rect rect; rect.right = pos.x + ras->getLx(); rect.left = pos.x; rect.bottom = pos.y + ras->getLy(); rect.top = pos.y; GWorldPtr offscreenGWorld; OSErr err; #if defined TNZ_MACHINE_CHANNEL_ORDER_BGRM OSType pixelFormat = k32BGRAPixelFormat; #elif defined TNZ_MACHINE_CHANNEL_ORDER_MRGB OSType pixelFormat = k32ARGBPixelFormat; #endif err = QTNewGWorldFromPtr( &offscreenGWorld, pixelFormat, &rect, 0, 0, 0, ras->getRawData(), ras->getWrap() * 4); if (err != noErr) { m_IOError = QTUnableToCreateResource; goto error; } SetMovieBox(m_movie, &rect); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetMovieBox; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } #if 0 SetMovieGWorld(m_movie, offscreenGWorld, GetGWorldDevice(offscreenGWorld)); #endif err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetMovieGWorld; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } TimeValue currentTime = currentTimes[frameIndex]; SetMovieTimeValue(m_movie, currentTime); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToSetTimeValue; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } err = UpdateMovie(m_movie); if (err != noErr) { m_IOError = QTUnableToUpdateMovie; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } MoviesTask(m_movie, 0); err = GetMoviesError(); if (err != noErr) { m_IOError = QTUnableToDoMovieTask; #if 0 DisposeGWorld(offscreenGWorld); #endif goto error; } SetMovieGWorld(m_movie, 0, 0); #if 0 DisposeGWorld(offscreenGWorld); #endif ras->unlock(); } if (m_depth != 32) { setMatteAndYMirror(rasP); } else { rasP->yMirror(); } return; error: ras->unlock(); throw TImageException(m_path, buildQTErrorString(m_IOError)); }
void QTCode_SetMovieGWorld(Movie theMovie, GWorldPtr offscreen) { SetMovieGWorld(theMovie, offscreen, GetGWorldDevice(offscreen)); }
// ----------------------------------------------------------------------------- // CreateCGImageWithQTFromFile // ----------------------------------------------------------------------------- // OSStatus CreateCGImageWithQTFromFile( FSRef* inFSRef, CGImageRef* outImage ) { OSStatus err; GraphicsImportComponent importer; FSSpec fileSpec; GWorldPtr gWorld = NULL; Rect bounds; CGDataProviderRef provider; CGColorSpaceRef colorspace; long width; long height; long rowbytes; Ptr dataPtr; // Make an FSRef into an FSSpec err = FSGetCatalogInfo( inFSRef, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL ); require_noerr( err, CantMakeFSSpec ); err = GetGraphicsImporterForFile( &fileSpec, &importer ); require_noerr( err, CantGetImporter ); err = GraphicsImportGetNaturalBounds( importer, &bounds ); require_noerr( err, CantGetBounds ); // Allocate the buffer width = RECT_WIDTH( bounds ); height = RECT_HEIGHT( bounds ); rowbytes = width * 4; dataPtr = NewPtr( height * rowbytes ); require_action( dataPtr != NULL, CantAllocBuffer, err = memFullErr ); err = NewGWorldFromPtr( &gWorld, 32, &bounds, NULL, NULL, NULL, dataPtr, rowbytes ); require_noerr( err, CantCreateGWorld ); err = GraphicsImportSetGWorld( importer, gWorld, GetGWorldDevice( gWorld) ); require_noerr( err, CantSetGWorld ); err = GraphicsImportDraw( importer ); require_noerr( err, CantDraw ); provider = CGDataProviderCreateWithData( NULL, dataPtr, height * rowbytes, GWorldImageBufferRelease ); require_action( provider != NULL, CantCreateProvider, err = memFullErr ); colorspace = CGColorSpaceCreateDeviceRGB(); require_action( colorspace != NULL, CantCreateColorSpace, err = memFullErr ); *outImage = CGImageCreate( width, height, 8, 32, rowbytes, colorspace, kCGImageAlphaPremultipliedFirst, provider, NULL, false, kCGRenderingIntentDefault ); require_action( *outImage != NULL, CantCreateImage, err = memFullErr ); CantCreateImage: CGColorSpaceRelease( colorspace ); CantCreateColorSpace: CGDataProviderRelease( provider ); CantCreateProvider: CantDraw: CantSetGWorld: if ( gWorld != NULL ) DisposeGWorld( gWorld ); CantCreateGWorld: CantAllocBuffer: CantGetBounds: CantGetImporter: CantMakeFSSpec: return err; }
void QTCmpr_CompressSequence (WindowObject theWindowObject) { ComponentInstance myComponent = NULL; GWorldPtr myImageWorld = NULL; // the graphics world we draw the images in PixMapHandle myPixMap = NULL; Movie mySrcMovie = NULL; Track mySrcTrack = NULL; Movie myDstMovie = NULL; Track myDstTrack = NULL; Media myDstMedia = NULL; Rect myRect; PicHandle myPicture = NULL; CGrafPtr mySavedPort = NULL; GDHandle mySavedDevice = NULL; SCTemporalSettings myTimeSettings; SCDataRateSettings myRateSettings; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; short myRefNum = -1; StringPtr myMoviePrompt = QTUtils_ConvertCToPascalString(kQTCSaveMoviePrompt); StringPtr myMovieFileName = QTUtils_ConvertCToPascalString(kQTCSaveMovieFileName); MatrixRecord myMatrix; ImageDescriptionHandle myImageDesc = NULL; TimeValue myCurMovieTime = 0L; TimeValue myOrigMovieTime = 0L; // current movie time, when compression is begun short myFrameNum; long myFlags = 0L; long myNumFrames = 0L; long mySrcMovieDuration = 0L; // duration of source movie OSErr myErr = noErr; #if USE_ASYNC_COMPRESSION ICMCompletionProcRecord myICMComplProcRec; ICMCompletionProcRecordPtr myICMComplProcPtr = NULL; OSErr myICMComplProcErr = noErr; myICMComplProcRec.completionProc = NULL; myICMComplProcRec.completionRefCon = 0L; #endif if (theWindowObject == NULL) goto bail; ////////// // // get the movie and the first video track in the movie // ////////// mySrcMovie = (**theWindowObject).fMovie; if (mySrcMovie == NULL) goto bail; mySrcTrack = GetMovieIndTrackType(mySrcMovie, 1, VideoMediaType, movieTrackMediaType); if (mySrcTrack == NULL) goto bail; // stop the movie; we don't want it to be playing while we're (re)compressing it SetMovieRate(mySrcMovie, (Fixed)0L); // get the current movie time, when compression is begun; we'll restore this later myOrigMovieTime = GetMovieTime(mySrcMovie, NULL); ////////// // // configure and display the Standard Image Compression dialog box // ////////// // open an instance of the Standard Image Compression dialog component myComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); if (myComponent == NULL) goto bail; // turn off "best depth" option in the compression dialog, because all of our // buffering is done at 32-bits (regardless of the depth of the source data) // // a more ambitious approach would be to loop through each of the video sample // descriptions in each of the video tracks looking for the deepest depth, and // using that for the best depth; better yet, we could find out which compressors // were used and set one of those as the default in the compression dialog SCGetInfo(myComponent, scPreferenceFlagsType, &myFlags); myFlags &= ~scShowBestDepth; SCSetInfo(myComponent, scPreferenceFlagsType, &myFlags); // because we are recompressing a movie that may have a variable frame rate, // we want to allow the user to leave the frame rate text field blank (in which // case we can preserve the frame durations of the source movie); if the user // enters a number, we will resample the movie at a new frame rate; if we don't // clear this flag, the compression dialog will not allow zero in the frame rate field // // NOTE: we could have set this flag above when we cleared the scShowBestDepth flag; // it is done here for clarity. SCGetInfo(myComponent, scPreferenceFlagsType, &myFlags); myFlags |= scAllowZeroFrameRate; SCSetInfo(myComponent, scPreferenceFlagsType, &myFlags); // get the number of video frames in the movie myNumFrames = QTUtils_GetFrameCount(mySrcTrack); // get the bounding rectangle of the movie, create a 32-bit GWorld with those // dimensions, and draw the movie poster picture into it; this GWorld will be // used for the test image in the compression dialog box and for rendering movie // frames myPicture = GetMoviePosterPict(mySrcMovie); if (myPicture == NULL) goto bail; GetMovieBox(mySrcMovie, &myRect); myErr = NewGWorld(&myImageWorld, 32, &myRect, NULL, NULL, 0L); if (myErr != noErr) goto bail; // get the pixmap of the GWorld; we'll lock the pixmap, just to be safe myPixMap = GetGWorldPixMap(myImageWorld); if (!LockPixels(myPixMap)) goto bail; // draw the movie poster image into the GWorld GetGWorld(&mySavedPort, &mySavedDevice); SetGWorld(myImageWorld, NULL); EraseRect(&myRect); DrawPicture(myPicture, &myRect); KillPicture(myPicture); SetGWorld(mySavedPort, mySavedDevice); // set the picture to be displayed in the dialog box; passing NULL for the rect // means use the entire image; passing 0 for the flags means to use the default // system method of displaying the test image, which is currently a combination // of cropping and scaling; personally, I prefer scaling (your mileage may vary) SCSetTestImagePixMap(myComponent, myPixMap, NULL, scPreferScaling); // install the custom procs, if requested // we can install two kinds of custom procedures for use in connection with // the standard dialog box: (1) a modal-dialog filter function, and (2) a hook // function to handle the custom button in the dialog box if (gUseExtendedProcs) QTCmpr_InstallExtendedProcs(myComponent, (long)myPixMap); // set up some default settings for the compression dialog SCDefaultPixMapSettings(myComponent, myPixMap, true); // clear out the default frame rate chosen by Standard Compression (a frame rate // of 0 means to use the rate of the source movie) myErr = SCGetInfo(myComponent, scTemporalSettingsType, &myTimeSettings); if (myErr != noErr) goto bail; myTimeSettings.frameRate = 0; SCSetInfo(myComponent, scTemporalSettingsType, &myTimeSettings); // request image compression settings from the user; in other words, put up the dialog box myErr = SCRequestSequenceSettings(myComponent); if (myErr == scUserCancelled) goto bail; // get a copy of the temporal settings the user entered; we'll need them for some // of our calculations (in a simpler application, we'd never have to look at them) SCGetInfo(myComponent, scTemporalSettingsType, &myTimeSettings); ////////// // // adjust the data rate [to be supplied][relevant only for movies that have sound tracks] // ////////// ////////// // // adjust the sample count // // if the user wants to resample the frame rate of the movie (as indicated a non-zero // value in the frame rate field) calculate the number of frames and duration for the new movie // ////////// if (myTimeSettings.frameRate != 0) { long myDuration = GetMovieDuration(mySrcMovie); long myTimeScale = GetMovieTimeScale(mySrcMovie); float myFloat = (float)myDuration * myTimeSettings.frameRate; myNumFrames = myFloat / myTimeScale / 65536; if (myNumFrames == 0) myNumFrames = 1; } ////////// // // get the name and location of the new movie file // ////////// // prompt the user for a file to put the compressed image into; in theory, the name // should have a file extension appropriate to the type of compressed data selected by the user; // this is left as an exercise for the reader QTFrame_PutFile(myMoviePrompt, myMovieFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // delete any existing file of that name if (myIsReplacing) { myErr = DeleteMovieFile(&myFile); if (myErr != noErr) goto bail; } ////////// // // create the target movie // ////////// myErr = CreateMovieFile(&myFile, sigMoviePlayer, smSystemScript, createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &myRefNum, &myDstMovie); if (myErr != noErr) goto bail; // create a new video movie track with the same dimensions as the entire source movie myDstTrack = NewMovieTrack(myDstMovie, (long)(myRect.right - myRect.left) << 16, (long)(myRect.bottom - myRect.top) << 16, kNoVolume); if (myDstTrack == NULL) goto bail; // create a media for the new track with the same time scale as the source movie; // because the time scales are the same, we don't have to do any time scale conversions. myDstMedia = NewTrackMedia(myDstTrack, VIDEO_TYPE, GetMovieTimeScale(mySrcMovie), 0, 0); if (myDstMedia == NULL) goto bail; // copy the user data and settings from the source to the dest movie CopyMovieSettings(mySrcMovie, myDstMovie); // set movie matrix to identity and clear the movie clip region (because the conversion // process transforms and composites all video tracks into one untransformed video track) SetIdentityMatrix(&myMatrix); SetMovieMatrix(myDstMovie, &myMatrix); SetMovieClipRgn(myDstMovie, NULL); // set the movie to highest quality imaging SetMoviePlayHints(mySrcMovie, hintsHighQuality, hintsHighQuality); myImageDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); if (myImageDesc == NULL) goto bail; // prepare for adding frames to the movie myErr = BeginMediaEdits(myDstMedia); if (myErr != noErr) goto bail; ////////// // // compress the image sequence // // we are going to step through the source movie, compress each frame, and then add // the compressed frame to the destination movie // ////////// myErr = SCCompressSequenceBegin(myComponent, myPixMap, NULL, &myImageDesc); if (myErr != noErr) goto bail; #if USE_ASYNC_COMPRESSION myFlags = codecFlagUpdatePrevious + codecFlagUpdatePreviousComp + codecFlagLiveGrab; SCSetInfo(myComponent, scCodecFlagsType, &myFlags); #endif // clear out our image GWorld and set movie to draw into it SetGWorld(myImageWorld, NULL); EraseRect(&myRect); SetMovieGWorld(mySrcMovie, myImageWorld, GetGWorldDevice(myImageWorld)); // set current time value to beginning of the source movie myCurMovieTime = 0; // get a value we'll need inside the loop mySrcMovieDuration = GetMovieDuration(mySrcMovie); // loop through all of the interesting times we counted above for (myFrameNum = 0; myFrameNum < myNumFrames; myFrameNum++) { short mySyncFlag; TimeValue myDuration; long myDataSize; Handle myCompressedData; ////////// // // get the next frame of the source movie // ////////// // if we are resampling the movie, step to the next frame if (myTimeSettings.frameRate) { myCurMovieTime = myFrameNum * mySrcMovieDuration / (myNumFrames - 1); myDuration = mySrcMovieDuration / myNumFrames; } else { OSType myMediaType = VIDEO_TYPE; myFlags = nextTimeMediaSample; // if this is the first frame, include the frame we are currently on if (myFrameNum == 0) myFlags |= nextTimeEdgeOK; // if we are maintaining the frame durations of the source movie, // skip to the next interesting time and get the duration for that frame GetMovieNextInterestingTime(mySrcMovie, myFlags, 1, &myMediaType, myCurMovieTime, 0, &myCurMovieTime, &myDuration); } SetMovieTimeValue(mySrcMovie, myCurMovieTime); MoviesTask(mySrcMovie, 0); MoviesTask(mySrcMovie, 0); MoviesTask(mySrcMovie, 0); // if data rate constraining is being done, tell Standard Compression the // duration of the current frame in milliseconds; we only need to do this // if the frames have variable durations if (!SCGetInfo(myComponent, scDataRateSettingsType, &myRateSettings)) { myRateSettings.frameDuration = myDuration * 1000 / GetMovieTimeScale(mySrcMovie); SCSetInfo(myComponent, scDataRateSettingsType, &myRateSettings); } ////////// // // compress the current frame of the source movie and add it to the destination movie // ////////// // if SCCompressSequenceFrame completes successfully, myCompressedData will hold // a handle to the newly-compressed image data and myDataSize will be the size of // the compressed data (which will usually be different from the size of the handle); // also mySyncFlag will be a value that that indicates whether or not the frame is a // key frame (and which we pass directly to AddMediaSample); note that we do not need // to dispose of myCompressedData, since SCCompressSequenceEnd will do that for us #if !USE_ASYNC_COMPRESSION myErr = SCCompressSequenceFrame(myComponent, myPixMap, &myRect, &myCompressedData, &myDataSize, &mySyncFlag); if (myErr != noErr) goto bail; #else if (myICMComplProcPtr == NULL) { myICMComplProcRec.completionProc = NewICMCompletionProc(QTCmpr_CompletionProc); myICMComplProcRec.completionRefCon = (long)&myICMComplProcErr; myICMComplProcPtr = &myICMComplProcRec; } myICMComplProcErr = kAsyncDefaultValue; myErr = SCCompressSequenceFrameAsync(myComponent, myPixMap, &myRect, &myCompressedData, &myDataSize, &mySyncFlag, myICMComplProcPtr); if (myErr != noErr) goto bail; // spin our wheels while we're waiting for the compress call to complete while (myICMComplProcErr == kAsyncDefaultValue) { EventRecord myEvent; WaitNextEvent(0, &myEvent, 60, NULL); SCAsyncIdle(myComponent); } myErr = myICMComplProcErr; #endif myErr = AddMediaSample(myDstMedia, myCompressedData, 0, myDataSize, myDuration, (SampleDescriptionHandle)myImageDesc, 1, mySyncFlag, NULL); if (myErr != noErr) goto bail; } // close the compression sequence; this will dispose of the image description // and compressed data handles allocated by SCCompressSequenceBegin SCCompressSequenceEnd(myComponent); ////////// // // add the media data to the destination movie // ////////// myErr = EndMediaEdits(myDstMedia); if (myErr != noErr) goto bail; InsertMediaIntoTrack(myDstTrack, 0, 0, GetMediaDuration(myDstMedia), fixed1); // add the movie resource to the dst movie file. myErr = AddMovieResource(myDstMovie, myRefNum, NULL, NULL); if (myErr != noErr) goto bail; // flatten the movie data [to be supplied] // close the movie file CloseMovieFile(myRefNum); bail: // close the Standard Compression component if (myComponent != NULL) CloseComponent(myComponent); if (mySrcMovie != NULL) { // restore the source movie's original graphics port and device SetMovieGWorld(mySrcMovie, mySavedPort, mySavedDevice); // restore the source movie's original movie time SetMovieTimeValue(mySrcMovie, myOrigMovieTime); } // restore the original graphics port and device SetGWorld(mySavedPort, mySavedDevice); // delete the GWorld we were drawing frames into if (myImageWorld != NULL) DisposeGWorld(myImageWorld); #if USE_ASYNC_COMPRESSION if (myICMComplProcRec.completionProc != NULL) DisposeICMCompletionUPP(myICMComplProcRec.completionProc); #endif free(myMoviePrompt); free(myMovieFileName); }