OSErr DoPlayMovie(Boolean useOverlay) { Rect movieBounds; OSErr err; BailErr((err = GetAMovieFile(&mMovie))); GetMovieBox(mMovie, &movieBounds); mMovieController = NewMovieController(mMovie, &movieBounds, mcTopLeftMovie | mcNotVisible); NormalizeMovieRect(mMovie); GetMovieBox(mMovie, &movieBounds); BailErr((err = InitializeMungData(movieBounds, FrontWindow(), useOverlay, /* overlay */ true, /* clamp */ false /* draw with QT Effect */ ))); // This is key, as we need to draw all frames in our // offscreen gworld first. Once there, our custom // decompressor component can perform overlay drawing // or color clamping SetMovieGWorld(mMovie, GetMungDataOffscreen(), nil); // Our DrawCompleteProc calls BlitOneMungData which SetupMovieDrawCompleteProc(); // --------- SetMovieActive(mMovie, true); #ifndef __APPLE_CC__ // Due to a bug in Jaguar, some QT functions are missing from // /System/Library/CFMSupport/CarbonLib, so we must manually // grab the function pointers from the QuickTime.framework // for CFM Carbon applications. MachO Carbon applications do not // have the problem. GetMissingQTFunctionPointers(); #endif InstallMovieIdlingEventLoopTimer(&mMovieTimerState); // start the movie playing MCDoAction(mMovieController, mcActionPrerollAndPlay, (void*)Long2Fix(1)); bail: return err; }
OSErr CreateNewSGChannelForRecording(ComponentInstance seqGrab, SGDataUPP dataProc, CGrafPtr drawPort, Rect *theRect, SGChannel *sgChannel, long refCon) { OSErr err = noErr; BailErr((err = SGInitialize(seqGrab))); // tell it we're not making a movie BailErr((err = SGSetDataRef(seqGrab,0,0,seqGrabDontMakeMovie))); // It wants a port, even if its not drawing to it BailErr((err = SGSetGWorld(seqGrab, drawPort, GetMainDevice()))); BailErr((err = SGNewChannel(seqGrab, VideoMediaType, sgChannel))); // let the user configure the video channel BailErr((err = SGSettingsDialog(seqGrab, *sgChannel, 0, nil, 0, nil, 0))); BailErr((err = SGSetChannelBounds(*sgChannel, theRect))); // set usage for new video channel to avoid playthrough BailErr((err = SGSetChannelUsage(*sgChannel, seqGrabRecord ))); //note we don't set seqGrabPlayDuringRecord BailErr((err = SGSetDataProc(seqGrab, dataProc, refCon))); BailErr((err = SGStartRecord(seqGrab))); bail: return err; }
pascal OSErr sgdata_callback(SGChannel c, Ptr p, long len, long *offset, long chRefCon, TimeValue time, short writeType, long refCon) { #pragma unused(offset,chRefCon,time,writeType) CodecFlags ignore; V4lState *s=(V4lState *)refCon; ComponentResult err = noErr; if (!s) goto bail; Rect boundsRect = {0, 0, s->vsize.height, s->vsize.width}; /* 240 , 320*/ if (s->pgworld) { if (s->decomseq == 0) { Rect sourceRect = { 0, 0 }; MatrixRecord scaleMatrix; ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0); err = SGGetChannelSampleDescription(c,(Handle)imageDesc); BailErr(err); // make a scaling matrix for the sequence sourceRect.right = (**imageDesc).width; sourceRect.bottom = (**imageDesc).height; RectMatrix(&scaleMatrix, &sourceRect, &boundsRect); err = DecompressSequenceBegin(&s->decomseq, // pointer to field to receive unique ID for sequence imageDesc, // handle to image description structure s->pgworld, // port for the DESTINATION image NULL, // graphics device handle, if port is set, set to NULL NULL, // source rectangle defining the portion of the image to decompress &scaleMatrix, // transformation matrix srcCopy, // transfer mode specifier NULL, // clipping region in dest. coordinate system to use as a mask 0, // flags codecNormalQuality, // accuracy in decompression bestSpeedCodec); // compressor identifier or special identifiers ie. bestSpeedCodec BailErr(err); DisposeHandle((Handle)imageDesc); imageDesc = NULL; } // decompress a frame into the GWorld - can queue a frame for async decompression when passed in a completion proc // once the image is in the GWorld it can be manipulated at will err = DecompressSequenceFrameS(s->decomseq, // sequence ID returned by DecompressSequenceBegin p, // pointer to compressed image data len, // size of the buffer 0, // in flags &ignore, // out flags NULL); // async completion proc BailErr(err); { unsigned line; mblk_t *buf; int size = s->vsize.width * s->vsize.height * 3; buf=allocb(size,0); PixMap * pixmap = *GetGWorldPixMap(s->pgworld); uint8_t * data; unsigned rowBytes = pixmap->rowBytes & (((unsigned short) 0xFFFF) >> 2); unsigned pixelSize = pixmap->pixelSize / 8; // Pixel size in bytes unsigned lineOffset = rowBytes - s->vsize.width * pixelSize; data = (uint8_t *) GetPixBaseAddr(GetGWorldPixMap(s->pgworld)); for (line = 0 ; line < s->vsize.height ; line++) { unsigned offset = line * (s->vsize.width * pixelSize + lineOffset); memcpy(buf->b_wptr + ((line * s->vsize.width) * pixelSize), data + offset, (rowBytes - lineOffset)); } if (s->pix_fmt==MS_RGB24) { /* Conversion from top down bottom up (BGR to RGB and flip) */ unsigned long Index,nPixels; unsigned char *blue; unsigned char tmp; short iPixelSize; blue=buf->b_wptr; nPixels=s->vsize.width*s->vsize.height; iPixelSize=24/8; for(Index=0;Index!=nPixels;Index++) // For each pixel { tmp=*blue; *blue=*(blue+2); *(blue+2)=tmp; blue+=iPixelSize; } } buf->b_wptr+=size; ms_mutex_lock(&s->mutex); putq(&s->rq, buf); ms_mutex_unlock(&s->mutex); } } bail: return err; }