static gboolean gst_osx_video_src_set_caps (GstBaseSrc * src, GstCaps * caps) { GstOSXVideoSrc *self = GST_OSX_VIDEO_SRC (src); GstStructure *structure = gst_caps_get_structure (caps, 0); gint width, height, framerate_num, framerate_denom; float fps; ComponentResult err; GST_DEBUG_OBJECT (src, "%s", G_STRFUNC); if (!self->seq_grab) return FALSE; gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); gst_structure_get_fraction (structure, "framerate", &framerate_num, &framerate_denom); fps = (float) framerate_num / framerate_denom; GST_DEBUG_OBJECT (src, "changing caps to %dx%d@%f", width, height, fps); SetRect (&self->rect, 0, 0, width, height); err = QTNewGWorld (&self->world, k422YpCbCr8PixelFormat, &self->rect, 0, NULL, 0); if (err != noErr) { GST_ERROR_OBJECT (self, "QTNewGWorld returned %d", (int) err); goto fail; } if (!LockPixels (GetPortPixMap (self->world))) { GST_ERROR_OBJECT (self, "LockPixels failed"); goto fail; } err = SGSetGWorld (self->seq_grab, self->world, NULL); if (err != noErr) { GST_ERROR_OBJECT (self, "SGSetGWorld returned %d", (int) err); goto fail; } err = SGSetChannelBounds (self->video_chan, &self->rect); if (err != noErr) { GST_ERROR_OBJECT (self, "SGSetChannelBounds returned %d", (int) err); goto fail; } // ###: if we ever support choosing framerates, do something with this /*err = SGSetFrameRate (self->video_chan, FloatToFixed(fps)); if (err != noErr) { GST_ERROR_OBJECT (self, "SGSetFrameRate returned %d", (int) err); goto fail; } */ return TRUE; fail: if (self->world) { SGSetGWorld (self->seq_grab, NULL, NULL); DisposeGWorld (self->world); self->world = NULL; } return FALSE; }
/* * PsychQTCreateMovie() -- Create a movie object. * * This function tries to open a Quicktime-Moviefile and create an * associated movie object for it. * * win = Pointer to window record of associated onscreen window. * moviename = char* with the name of the moviefile. * preloadSecs = How many seconds of the movie should be preloaded/prefetched into RAM at movie open time? * moviehandle = handle to the new movie. */ void PsychQTCreateMovie(PsychWindowRecordType *win, const char* moviename, double preloadSecs, int* moviehandle) { Movie theMovie = NULL; QTVisualContextRef QTMovieContext = NULL; QTAudioContextRef QTAudioContext = NULL; int i, slotid; OSErr error; CFStringRef movieLocation; CFURLRef movieURLLocation; CFStringRef coreAudioDeviceUID; psych_bool trueValue = TRUE; QTNewMoviePropertyElement newMovieProperties[4] = {0}; int propcount = 0; char msgerr[10000]; char errdesc[1000]; Rect movierect; psych_bool printErrors; // Suppress output of error-messages if moviehandle == 1000. That means we // run in our own Posix-Thread, not in the Matlab-Thread. Printing via Matlabs // printing facilities would likely cause a terrible crash. printErrors = (*moviehandle == -1000) ? FALSE : TRUE; // Set movie handle to "failed" initially: *moviehandle = -1; // We startup the Quicktime subsystem only on first invocation. if (firsttime) { #if PSYCH_SYSTEM == PSYCH_WINDOWS // Initialize Quicktime for Windows compatibility layer: This will fail if // QT isn't installed on the Windows machine... error = InitializeQTML(0); if (error!=noErr) { if (printErrors) { PsychErrorExitMsg(PsychError_internal, "Quicktime Media Layer initialization failed: Quicktime not properly installed?!?"); } else return; } #endif // Initialize Quicktime-Subsystem: error = EnterMovies(); if (error!=noErr) { if (printErrors) PsychErrorExitMsg(PsychError_internal, "Quicktime EnterMovies() failed!!!"); else return; } firsttime = FALSE; } if (!PsychIsOnscreenWindow(win)) { if (printErrors) PsychErrorExitMsg(PsychError_user, "Provided windowPtr is not an onscreen window."); else return; } if (NULL==moviename) { if (printErrors) PsychErrorExitMsg(PsychError_internal, "NULL-Ptr instead of moviename passed!"); else return; } if (numMovieRecords >= PSYCH_MAX_MOVIES) { *moviehandle = -2; if (printErrors) PsychErrorExitMsg(PsychError_user, "Allowed maximum number of simultaneously open movies exceeded!"); else return; } // Search first free slot in movieRecordBANK: for (i=0; (i < PSYCH_MAX_MOVIES) && (movieRecordBANK[i].theMovie); i++); if (i>=PSYCH_MAX_MOVIES) { *moviehandle = -2; if (printErrors) PsychErrorExitMsg(PsychError_user, "Allowed maximum number of simultaneously open movies exceeded!"); else return; } // Slot slotid will contain the movie record for our new movie object: slotid=i; // Create name-string for moviename: movieLocation = CFStringCreateWithCString (kCFAllocatorDefault, moviename, kCFStringEncodingASCII); // Zero-out new record in moviebank: movieRecordBANK[slotid].theMovie=NULL; movieRecordBANK[slotid].QTMovieContext=NULL; movieRecordBANK[slotid].QTAudioContext=NULL; movieRecordBANK[slotid].QTMovieGWorld=NULL; if (!PSYCH_USE_QT_GWORLDS) { // Create QTGLTextureContext: #if PSYCH_SYSTEM != PSYCH_WINDOWS error = QTOpenGLTextureContextCreate (kCFAllocatorDefault, win->targetSpecific.contextObject, win->targetSpecific.pixelFormatObject, NULL, &QTMovieContext); #endif if (error!=noErr) { if (printErrors) PsychErrorExitMsg(PsychError_internal, "OpenGL Quicktime visual context creation failed!!!"); else return; } } // The Movie location newMovieProperties[propcount].propClass = kQTPropertyClass_DataLocation; if (strstr(moviename, "http:") || strstr(moviename, "ftp:")) { // Open movie from URL, e.g., http- or ftp- server: movieURLLocation = CFURLCreateWithString(kCFAllocatorDefault, movieLocation, NULL); newMovieProperties[propcount].propID = kQTDataLocationPropertyID_CFURL; newMovieProperties[propcount].propValueSize = sizeof(movieURLLocation); newMovieProperties[propcount++].propValueAddress = (void*) &movieURLLocation; } else { // Open movie file from filesystem: newMovieProperties[propcount].propID = kQTDataLocationPropertyID_CFStringPosixPath; newMovieProperties[propcount].propValueSize = sizeof(CFStringRef); newMovieProperties[propcount++].propValueAddress = &movieLocation; } if (!PSYCH_USE_QT_GWORLDS) { // The Movie visual context newMovieProperties[propcount].propClass = kQTPropertyClass_Context; newMovieProperties[propcount].propID = kQTContextPropertyID_VisualContext; newMovieProperties[propcount].propValueSize = sizeof(QTVisualContextRef); newMovieProperties[propcount++].propValueAddress = &QTMovieContext; } if (TRUE) { // Create QTAudioContext for default CoreAudio device: coreAudioDeviceUID = NULL; // Use default audio-output device. error =QTAudioContextCreateForAudioDevice (kCFAllocatorDefault, coreAudioDeviceUID, NULL, &QTAudioContext); if (error!=noErr) { if (printErrors) PsychErrorExitMsg(PsychError_internal, "Quicktime audio context creation failed!!!"); else return; } // The Movie audio context newMovieProperties[propcount].propClass = kQTPropertyClass_Context; newMovieProperties[propcount].propID = kQTContextPropertyID_AudioContext; newMovieProperties[propcount].propValueSize = sizeof(QTAudioContextRef); newMovieProperties[propcount++].propValueAddress = &QTAudioContext; } // The Movie active newMovieProperties[propcount].propClass = kQTPropertyClass_NewMovieProperty; newMovieProperties[propcount].propID = kQTNewMoviePropertyID_Active; newMovieProperties[propcount].propValueSize = sizeof(trueValue); newMovieProperties[propcount++].propValueAddress = &trueValue; // Instantiate the Movie error = NewMovieFromProperties(propcount, newMovieProperties, 0, NULL, &theMovie); if (error!=noErr) { QTVisualContextRelease(QTMovieContext); QTAudioContextRelease(QTAudioContext); switch(error) { case -2000: case -50: case -43: sprintf(errdesc, "File not found."); break; case -2048: sprintf(errdesc, "This is not a file that Quicktime understands."); break; case -2003: sprintf(errdesc, "Can't find media handler (codec) for this movie."); break; default: sprintf(errdesc, "Unknown: Check http://developer.apple.com/documentation/QuickTime/APIREF/ErrorCodes.htm#//apple_ref/doc/constant_group/Error_Codes"); } sprintf(msgerr, "Couldn't load movie %s! Quicktime error code %i [%s]", moviename, (int) error, errdesc); *moviehandle = (int) error; if (printErrors) PsychErrorExitMsg(PsychError_user, msgerr); else return; } CFRelease(movieLocation); if (PSYCH_USE_QT_GWORLDS) { // Determine size of images in movie: GetMovieBox(theMovie, &movierect); // Only create a GWorld if movie frames contain at least 1 pixel. This way we skip GWorld // setup on "movies" which only consist of sound tracks. if ((movierect.right - movierect.left != 0) && (movierect.bottom - movierect.top != 0)) { // Create GWorld for this movie object: // error = QTNewGWorld(&movieRecordBANK[slotid].QTMovieGWorld, k32ABGRPixelFormat, &movierect, NULL, NULL, 0); error = QTNewGWorld(&movieRecordBANK[slotid].QTMovieGWorld, 0, &movierect, NULL, NULL, 0); if (error!=noErr) { QTAudioContextRelease(QTAudioContext); DisposeMovie(movieRecordBANK[slotid].theMovie); movieRecordBANK[slotid].theMovie=NULL; if (printErrors) PsychErrorExitMsg(PsychError_internal, "Quicktime GWorld creation failed!!!"); else return; } // Attach this GWorld as rendering target for Quicktime: SetMovieGWorld(theMovie, movieRecordBANK[slotid].QTMovieGWorld, NULL); } } // Preload preloadSecs seconds of movie into system RAM for faster playback: if (preloadSecs > 0) LoadMovieIntoRam(theMovie, 0, ((long) preloadSecs + 0.5) * GetMovieTimeScale(theMovie), keepInRam); // Special setting - 1 means: Load whole movie into RAM: if (preloadSecs == -1) LoadMovieIntoRam(theMovie, 0, GetMovieDuration(theMovie), keepInRam); // We don't preroll: Didn't help for async playback, but leads to failure in // manual playback mode: PrerollMovie(theMovie, 0, FloatToFixed(1)); // MoviesTask() it to make sure start of plaback will be as stutter-free as possible: MoviesTask(theMovie, 10000); // Assign new record in moviebank: movieRecordBANK[slotid].theMovie=theMovie; movieRecordBANK[slotid].QTMovieContext=QTMovieContext; movieRecordBANK[slotid].QTAudioContext=QTAudioContext; movieRecordBANK[slotid].loopflag = 0; *moviehandle = slotid; // Increase counter: numMovieRecords++; // Compute basic movie properties - Duration and fps as well as image size: // Compute duration in seconds: movieRecordBANK[slotid].movieduration = (double) GetMovieDuration(theMovie) / (double) GetMovieTimeScale(theMovie); // Compute expected framerate, assuming a linear spacing between frames: It is derived as // reciprocal of the duration of the first video frame in the movie: movieRecordBANK[slotid].fps = PsychDetermineMovieFramecountAndFps(theMovie, NULL); // Determine size of images in movie: GetMovieBox(theMovie, &movierect); movieRecordBANK[slotid].width = movierect.right - movierect.left; movieRecordBANK[slotid].height = movierect.bottom - movierect.top; // We set nrframes == -1 to indicate that this value is not yet available. // Will do counting on first query for this parameter as it is very time-consuming: movieRecordBANK[slotid].nrframes = -1; return; }
void TLevelWriter3gp::save(const TImageP &img, int frameIndex) { if (m_cancelled) return; TRasterImageP image(img); int lx = image->getRaster()->getLx(); int ly = image->getRaster()->getLy(); //void *buffer = image->getRaster()->getRawData(); int pixSize = image->getRaster()->getPixelSize(); if (pixSize != 4) throw TImageException(getFilePath(), "Unsupported pixel type"); QMutexLocker sl(&m_mutex); if (!m_properties) m_properties = new Tiio::MovWriterProperties(); Tiio::MovWriterProperties *prop = (Tiio::MovWriterProperties *)(m_properties); //CodecType compression = StandardCompressionType; prop->getCurrentCodec(); //CodecQ quality = StandardQualityType; prop->getCurrentQuality(); if (!m_initDone) { //FSSpec fspec; Rect frame; long max_compressed_size; QDErr err; m_videoTrack = NewMovieTrack(m_movie, FixRatio((short)lx, 1), FixRatio((short)ly, 1), kNoVolume); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create video track"); m_dataRef = nil; m_hMovieData = NewHandle(0); // Construct the Handle data reference err = PtrToHand(&m_hMovieData, &m_dataRef, sizeof(Handle)); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create Data Ref"); m_videoMedia = NewTrackMedia(m_videoTrack, VideoMediaType, (TINT32)m_frameRate, m_dataRef, HandleDataHandlerSubType); OpenADefaultComponent(MovieExportType, '3gpp', &m_myExporter); // err = (short)MovieExportDoUserDialog(m_myExporter, m_movie, 0, 0, 0, &m_cancelled); // if (m_cancelled) // throw TImageException(getFilePath(), "User abort of 3GP render"); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create video media"); if ((err = BeginMediaEdits(m_videoMedia)) != noErr) throw TImageException(getFilePath(), "can't begin edit video media"); frame.left = 0; frame.top = 0; frame.right = lx; frame.bottom = ly; #if 0 if ((err = NewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0))!=noErr) #else /* Mac OSX 10.7 later */ if ((err = QTNewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr) #endif throw TImageException(getFilePath(), "can't create movie buffer"); #ifdef WIN32 LockPixels(m_gworld->portPixMap); if ((err = GetMaxCompressionSize(m_gworld->portPixMap, &frame, 0, quality, compression, anyCodec, &max_compressed_size)) != noErr) throw TImageException(getFilePath(), "can't get max compression size"); #else #if 0 PixMapHandle pixmapH = GetPortPixMap (m_gworld); LockPixels(pixmapH); #else PixMapHandle pixmapH = NULL; #endif max_compressed_size = lx * ly * 4 * 20; /*if ((err = GetMaxCompressionSize(pixmapH, &frame, 0, quality, compression,anyCodec, &max_compressed_size))!=noErr) throw TImageException(getFilePath(), "can't get max compression size");*/ #endif m_compressedData = NewHandle(max_compressed_size); if ((err = MemError()) != noErr) throw TImageException(getFilePath(), "can't allocate compressed data for movie"); MoveHHi(m_compressedData); HLock(m_compressedData); if ((err = MemError()) != noErr) throw TImageException(getFilePath(), "can't allocate img handle"); #if 0 m_pixmap = GetGWorldPixMap(m_gworld); if (!LockPixels(m_pixmap)) throw TImageException(getFilePath(), "can't lock pixels"); buf = (PixelXRGB*) GetPixBaseAddr(m_pixmap); #else m_pixmap = NULL; buf = NULL; #endif buf_lx = lx; buf_ly = ly; m_initDone = true; } unsigned short rowBytes = (unsigned short)(((short)(*(m_pixmap))->rowBytes & ~(3 << 14))); Rect frame; ImageDescriptionHandle img_descr; Ptr compressed_data_ptr; QDErr err; frame.left = 0; frame.top = 0; frame.right = lx; frame.bottom = ly; TRasterP ras = image->getRaster(); #ifdef WIN32 compressed_data_ptr = StripAddress(*(m_compressedData)); copy(ras, buf, buf_lx, buf_ly); #else compressed_data_ptr = *m_compressedData; copy(ras, buf, buf_lx, buf_ly, rowBytes); #endif img_descr = (ImageDescriptionHandle)NewHandle(4); #ifdef WIN32 if ((err = CompressImage(m_gworld->portPixMap, &frame, quality, compression, img_descr, compressed_data_ptr)) != noErr) throw TImageException(getFilePath(), "can't compress image"); #else #if 0 PixMapHandle pixmapH = GetPortPixMap (m_gworld); if ((err = CompressImage(pixmapH, &frame, codecNormalQuality, kJPEGCodecType, img_descr, compressed_data_ptr))!=noErr) { throw TImageException(getFilePath(), "can't compress image"); } #endif #endif if ((err = AddMediaSample(m_videoMedia, m_compressedData, 0, (*img_descr)->dataSize, 1, (SampleDescriptionHandle)img_descr, 1, 0, 0)) != noErr) throw TImageException(getFilePath(), "can't add image to movie media"); DisposeHandle((Handle)img_descr); }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { if (nlhs < 0) { mexErrMsgTxt("Too few output arguments."); return; } if (nlhs > 1) { mexErrMsgTxt("Too many output arguments."); return; } if (nrhs < 1) { mexErrMsgTxt("Too few input arguments."); return; } if (nrhs > 3) { mexErrMsgTxt("Too many input arguments."); return; } TimeValue duration; TimeRecord myTimeRecord; Rect bounds; OSErr result = 0; short resRefNum = -1; short actualResId = DoTheRightThing; FSSpec theFSSpec; GWorldPtr offWorld; Movie theMovie = nil; MovieController thePlayer = nil; MovieDrawingCompleteUPP myDrawCompleteProc; long frame_end; long myStep = 1; char location[PATH_BUFFER_SIZE]; long frame_count; mwSize cdims[2]; mxGetString(prhs[0], location, PATH_BUFFER_SIZE); if (nrhs > 2) { frame_start = rint(mxGetScalar(prhs[1])); frame_end = rint(mxGetScalar(prhs[2])); } else if (nrhs > 1) { frame_start = 1; frame_end = rint(mxGetScalar(prhs[1])); } else { frame_start = 1; frame_end = 0; } if (frame_start < 1) { mexErrMsgTxt("Error: the starting frame must be positive\n"); return; } if (frame_end < 0) { mexErrMsgTxt("Error: the ending frame must be positive\n"); return; } if (frame_end != 0 && frame_end < frame_start) { mexErrMsgTxt("Error: the ending frame must not be less than the starting frame\n"); return; } myDrawCompleteProc = NewMovieDrawingCompleteUPP(DrawCompleteProc); EnterMovies(); if (NativePathNameToFSSpec(location, &theFSSpec, 0) || OpenMovieFile(&theFSSpec, &resRefNum, 0) || NewMovieFromFile(&theMovie, resRefNum, &actualResId, 0, 0, 0)) { mexErrMsgTxt("Error: failed to open movie\n"); return; } if (resRefNum != -1) CloseMovieFile(resRefNum); GetMovieBox(theMovie, &bounds); QTNewGWorld(&offWorld, k32ARGBPixelFormat, &bounds, NULL, NULL, 0); LockPixels(GetGWorldPixMap(offWorld)); SetGWorld(offWorld, NULL); thePlayer = NewMovieController(theMovie, &bounds, mcTopLeftMovie | mcNotVisible); SetMovieGWorld(theMovie, offWorld, NULL); SetMovieActive(theMovie, true); SetMovieDrawingCompleteProc(theMovie, movieDrawingCallWhenChanged, myDrawCompleteProc, (long) offWorld); GetMovieTime(theMovie, &myTimeRecord); duration = GetMovieDuration(theMovie); // Compute the number of frames for allocation of output structure frame_count = 0; while ((frame_end == 0 || frame_count < frame_end) && GetMovieTime(theMovie, NULL) < duration) { frame_count++; MCDoAction(thePlayer, mcActionStep, (Ptr) myStep); } SetMovieTime(theMovie, &myTimeRecord); // Ignore frames greater than those in the file if (frame_end == 0 || frame_count < frame_end) frame_end = frame_count; cdims[0] = frame_end - frame_start + 1; // Indices are one-based cdims[1] = 1; plhs[0] = mxCreateCellArray(2, cdims); // Step through the movie and save the frame when in the chosen interval // Note: the step size seems to be handled as a short internally. // Using anything greater than 32758 will seek to an incorrect frame frame_num = 1; while (frame_num <= frame_end) { MCDoAction(thePlayer, mcActionStep, (Ptr) myStep); if (frame_num >= frame_start) { MCIdle(thePlayer); mxSetCell(plhs[0], frame_num - frame_start, framedata); } frame_num++; } UnlockPixels(GetGWorldPixMap (offWorld)); DisposeGWorld(offWorld); DisposeMovieController (thePlayer); DisposeMovie(theMovie); DisposeMovieDrawingCompleteUPP(myDrawCompleteProc); ExitMovies(); return; }
// ###################################################################### QuickTimeGrabber::Impl::Impl(const Dims& dims) : itsSeqGrab(0, &CloseComponent), itsSGChanVideo(&itsSeqGrab.it), itsDrawSeq(0), itsTimeScale(0), itsTimeBase(0), itsQueuedFrameCount(0), itsSkipFrameCount(0), itsSkipFrameCountTotal(0), itsPrevTime(0), itsFrameCount(0), itsGWorld(0), itsGotFrame(false), itsCurrentImage(), itsErrorMsg(), itsStreamStarted(false) { OSErr err; EnterMovies(); // open the default sequence grabber itsSeqGrab.it = OpenDefaultComponent(SeqGrabComponentType, 0); if (itsSeqGrab.it == NULL) LFATAL("OpenDefaultComponent() failed"); // initialize the default sequence grabber component if (noErr != (err = SGInitialize(itsSeqGrab.it))) LFATAL("SGInitialize() failed (err=%ld)", (long) err); Rect scaleRect; MacSetRect(&scaleRect, 0, 0, dims.w(), dims.h()); ASSERT(itsGWorld == 0); QTNewGWorld(&itsGWorld, k32ARGBPixelFormat, &scaleRect, NULL, NULL, kNativeEndianPixMap); // set its graphics world if (noErr != (err = SGSetGWorld(itsSeqGrab.it, itsGWorld, NULL))) LFATAL("SGSetGWorld() failed (err=%ld)", (long) err); // specify the destination data reference for a record operation // tell it we're not making a movie if the flag seqGrabDontMakeMovie // is used, the sequence grabber still calls your data function, but // does not write any data to the movie file writeType will always // be set to seqGrabWriteAppend if (noErr != (err = SGSetDataRef(itsSeqGrab.it, 0, 0, seqGrabDontMakeMovie | seqGrabDataProcIsInterruptSafe))) LFATAL("SGSetDataRef() failed (err=%ld)", (long) err); Impl::SGChannelHolder sgchanSound(&itsSeqGrab.it); if (noErr != (err = SGNewChannel(itsSeqGrab.it, VideoMediaType, &itsSGChanVideo.it))) LFATAL("SGNewChannel(video) failed (err=%ld)", (long) err); if (noErr != (err = SGNewChannel(itsSeqGrab.it, SoundMediaType, &sgchanSound.it))) { // don't care if we couldn't get a sound channel sgchanSound.it = NULL; LERROR("SGNewChannel(audio) failed (err=%ld)", (long) err); } // get the active rectangle Rect srcBounds; if (noErr != (err = SGGetSrcVideoBounds(itsSGChanVideo.it, &srcBounds))) LFATAL("SGGetSrcVideoBounds() failed (err=%ld)", (long) err); // we always want all the source setVideoChannelBounds(itsSGChanVideo.it, &srcBounds, &srcBounds); // set usage for new video channel to avoid playthrough // note we don't set seqGrabPlayDuringRecord if (noErr != (err = SGSetChannelUsage(itsSGChanVideo.it, seqGrabRecord | seqGrabLowLatencyCapture | seqGrabAlwaysUseTimeBase))) LFATAL("SGSetChannelUsage(video) failed (err=%ld)", (long) err); if (noErr != (err = SGSetChannelUsage(sgchanSound.it, seqGrabRecord | //seqGrabPlayDuringRecord | seqGrabLowLatencyCapture | seqGrabAlwaysUseTimeBase))) LERROR("SGSetChannelUsage(audio) failed (err=%ld)", (long) err); // specify a sequence grabber data function if (noErr != (err = SGSetDataProc(itsSeqGrab.it, NewSGDataUPP(Impl::grabDataProc), (long)(this)))) LFATAL("SGSetDataProc() failed (err=%ld)", (long) err); SGSetChannelRefCon(itsSGChanVideo.it, (long)(this)); // set up the video bottlenecks so we can get our queued frame count VideoBottles vb = { 0 }; if (noErr != (err = SGGetVideoBottlenecks(itsSGChanVideo.it, &vb))) LFATAL("SGGetVideoBottlenecks() failed (err=%ld)", (long) err); vb.procCount = 9; // there are 9 bottleneck procs; this must be filled in vb.grabCompressCompleteProc = NewSGGrabCompressCompleteBottleUPP (Impl::grabCompressCompleteBottle); if (noErr != (err = SGSetVideoBottlenecks(itsSGChanVideo.it, &vb))) LFATAL("SGSetVideoBottlenecks() failed (err=%ld)", (long) err); SGSetFrameRate(itsSGChanVideo.it, FixRatio(30, 1)); }
static int sequence_grabber_start(V4lState *s) { int err; Rect theRect = {0, 0, s->vsize.height, s->vsize.width}; err = QTNewGWorld(&(s->pgworld), // returned GWorld k24BGRPixelFormat, &theRect, // bounding rectangle 0, // color table NULL, // graphic device handle 0); // flags if (err!=noErr) { return -1; } if(!LockPixels(GetPortPixMap(s->pgworld))) { v4m_close(s); return -1; } s->seqgrab = OpenDefaultComponent(SeqGrabComponentType, 0); err = SGInitialize(s->seqgrab); if (err!=noErr) { v4m_close(s); return -1; } err = SGSetDataRef(s->seqgrab, 0, 0, seqGrabDontMakeMovie); if (err!=noErr) { v4m_close(s); return -1; } err = SGSetGWorld(s->seqgrab, s->pgworld, GetMainDevice()); if (err!=noErr) { v4m_close(s); return -1; } err = SGNewChannel(s->seqgrab, VideoMediaType, &s->sgchanvideo); if (err!=noErr) { v4m_close(s); return -1; } err = SGSetChannelBounds(s->sgchanvideo, &theRect); if (err!=noErr) { v4m_close(s); return -1; } err = SGSetChannelUsage(s->sgchanvideo, seqGrabRecord); if (err!=noErr) { v4m_close(s); return -1; } err = SGSetDataProc(s->seqgrab,NewSGDataUPP(sgdata_callback),(long)s); if (err!=noErr) { v4m_close(s); return -1; } err = SGStartRecord(s->seqgrab); if (err!=noErr) { v4m_close(s); return -1; } return 0; }
void QTCmpr_CompressImage (WindowObject theWindowObject) { Rect myRect; GraphicsImportComponent myImporter = NULL; ComponentInstance myComponent = NULL; GWorldPtr myImageWorld = NULL; // the graphics world we draw the image in PixMapHandle myPixMap = NULL; ImageDescriptionHandle myDesc = NULL; Handle myHandle = NULL; OSErr myErr = noErr; if (theWindowObject == NULL) return; ////////// // // get a graphics importer for the image file and determine the natural size of the image; // note that the image file *already* has a graphics importer associated with it (namely // (**theWindowObject).fGraphicsImporter), but we create a new one so that the existing one // can be used to redraw the image in the callback procedure QTCmpr_FilterProc // ////////// myErr = GetGraphicsImporterForFile(&(**theWindowObject).fFileFSSpec, &myImporter); if (myErr != noErr) goto bail; myErr = GraphicsImportGetNaturalBounds(myImporter, &myRect); if (myErr != noErr) goto bail; ////////// // // create an offscreen graphics world and draw the image into it // ////////// myErr = QTNewGWorld(&myImageWorld, 0, &myRect, NULL, NULL, kICMTempThenAppMemory); 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; // set the current port and draw the image GraphicsImportSetGWorld(myImporter, (CGrafPtr)myImageWorld, NULL); GraphicsImportDraw(myImporter); ////////// // // configure and display the standard image compression dialog box // ////////// // open the standard compression dialog component myComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); if (myComponent == NULL) goto bail; // 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); // request image compression settings from the user; in other words, put up the dialog box myErr = SCRequestImageSettings(myComponent); if (myErr == scUserCancelled) goto bail; ////////// // // compress the image // ////////// myErr = SCCompressImage(myComponent, myPixMap, NULL, &myDesc, &myHandle); if (myErr != noErr) goto bail; ////////// // // save the compressed image in a new file // ////////// QTCmpr_PromptUserForDiskFileAndSaveCompressed(myHandle, myDesc); bail: if (gUseExtendedProcs) QTCmpr_RemoveExtendedProcs(); if (myPixMap != NULL) if (GetPixelsState(myPixMap) & pixelsLocked) UnlockPixels(myPixMap); if (myImporter != NULL) CloseComponent(myImporter); if (myComponent != NULL) CloseComponent(myComponent); if (myDesc != NULL) DisposeHandle((Handle)myDesc); if (myHandle != NULL) DisposeHandle(myHandle); if (myImageWorld != NULL) DisposeGWorld(myImageWorld); }