// 1. // CreateAndRunWithSequenceGrabber void QuicktimeLiveImageStream::createAndRunWithSequenceGrabber(std::string fileName) { std::string::size_type idx = fileName.find(':'); if (idx == std::string::npos) { osg::notify(osg::FATAL) << "Error while parsing deviceID:deviceInputID.live path : " << fileName << std::endl; } // Better c++ code is to use istrstream std::string deviceIDStr = fileName.substr(0,idx); std::string deviceInputIDStr = fileName.substr(idx+1); m_videoDeviceID = static_cast<short>(atoi(deviceIDStr.c_str())); m_videoDeviceInputID = static_cast<short>(atoi(deviceInputIDStr.c_str())); // Get Video Digitizer Rectangle bounds from a Sequence Grabber proxy (using IDs) get_video_device_bounds_idstr(m_videoDeviceID, m_videoDeviceInputID, m_videoRectWidth, m_videoRectHeight, m_videoDeviceIDStr); // Sound m_soundDeviceID = 2; m_soundDeviceInputID = 0; //get_sound_device_idstr(m_soundDeviceID, m_soundDeviceInputID, m_soundDeviceIDStr); // Create the Image createImage(); // Create the offscreen GWorld (using Image as target memory) createGWorld(); // Create the Sequence Grabber (using GWorld as target memory) createSequenceGrabber(); // Create the Sequence Grabber Video Channel createSequenceGrabberVideoChannel(); if (g_s_use_sg_record) { // Create the Sequence Grabber DataProc setup for Record createSequenceGrabberDataProc(); } // Create the Sequence Grabber Audio Channel createSequenceGrabberAudioChannel(); // Start the engine Jack! // Callbacks createSequenceGrabberVideoBottlenecks(); ComponentResult result = noErr; result = SGPrepare( m_gSeqGrabber, TRUE, FALSE); if (result != noErr) osg::notify(osg::FATAL) << "SGPrepare : error" << std::endl; if (g_s_use_sg_record) { result = SGStartRecord(m_gSeqGrabber); if (result != noErr) osg::notify(osg::FATAL) << "SGStartRecord : error" << std::endl; } else { result = SGStartPreview(m_gSeqGrabber); if (result != noErr) osg::notify(osg::FATAL) << "SGStartPreview : error" << std::endl; } _status = ImageStream::PLAYING; // Ticker start(); }
// ###################################################################### void QuickTimeGrabber::Impl::startStream() { // lights...camera... if (noErr != SGPrepare(itsSeqGrab.it, false, true)) LFATAL("SGPrepare() failed"); // ...action if (noErr != SGStartRecord(itsSeqGrab.it)) LFATAL("SGStartRecord() failed"); itsStreamStarted = true; }
///////////////////////////////////////////////////////// // startTransfer // ///////////////////////////////////////////////////////// int pix_videoDarwin :: startTransfer() { OSErr err = noErr; if (m_record) { SGStartRecord(m_sg); if (err != noErr)error("SGStartRecord failed with error %d",err); } else SGStartPreview(m_sg); m_haveVideo = 1; m_pixBlock.newimage = 1; return 1; }
// ###################################################################### GenericFrame QuickTimeGrabber::Impl::readFrame() { if (!itsStreamStarted) this->startStream(); while (1) { itsGotFrame = false; itsErrorMsg = ""; if (noErr != SGIdle(itsSeqGrab.it)) LFATAL("SGIdle() failed"); if (itsErrorMsg.length() > 0) { // some error specific to SGIdle occurred - any errors // returned from the data proc will also show up here and we // don't want to write over them // in QT 4 you would always encounter a cDepthErr error // after a user drags the window, this failure condition has // been greatly relaxed in QT 5 it may still occur but // should only apply to vDigs that really control the screen // you don't always know where these errors originate from, // some may come from the VDig... LFATAL("QuickTimeGrabber error during SGIdle (%s)", itsErrorMsg.c_str()); // ...to fix this we simply call SGStop and SGStartRecord // again calling stop allows the SG to release and // re-prepare for grabbing hopefully fixing any problems, // this is obviously a very relaxed approach SGStop(itsSeqGrab.it); SGStartRecord(itsSeqGrab.it); } if (itsGotFrame) return GenericFrame(itsCurrentImage); usleep(20000); } }
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; }
static GstStateChangeReturn gst_osx_video_src_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn result; GstOSXVideoSrc *self; ComponentResult err; result = GST_STATE_CHANGE_SUCCESS; self = GST_OSX_VIDEO_SRC (element); // ###: prepare_capture in READY->PAUSED? switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_PLAYING: { ImageDescriptionHandle imageDesc; Rect sourceRect; MatrixRecord scaleMatrix; if (!prepare_capture (self)) return GST_STATE_CHANGE_FAILURE; // ###: should we start recording /after/ making the decompressionsequence? // CocoaSequenceGrabber does it beforehand, so we do too, but it feels // wrong. err = SGStartRecord (self->seq_grab); if (err != noErr) { /* since we prepare here, we should also unprepare */ SGRelease (self->seq_grab); GST_ERROR_OBJECT (self, "SGStartRecord returned %d", (int) err); return GST_STATE_CHANGE_FAILURE; } imageDesc = (ImageDescriptionHandle) NewHandle (0); err = SGGetChannelSampleDescription (self->video_chan, (Handle) imageDesc); if (err != noErr) { SGStop (self->seq_grab); SGRelease (self->seq_grab); DisposeHandle ((Handle) imageDesc); GST_ERROR_OBJECT (self, "SGGetChannelSampleDescription returned %d", (int) err); return GST_STATE_CHANGE_FAILURE; } GST_DEBUG_OBJECT (self, "actual capture resolution is %dx%d", (int) (**imageDesc).width, (int) (**imageDesc).height); SetRect (&sourceRect, 0, 0, (**imageDesc).width, (**imageDesc).height); RectMatrix (&scaleMatrix, &sourceRect, &self->rect); err = DecompressSequenceBegin (&self->dec_seq, imageDesc, self->world, NULL, NULL, &scaleMatrix, srcCopy, NULL, 0, codecNormalQuality, bestSpeedCodec); if (err != noErr) { SGStop (self->seq_grab); SGRelease (self->seq_grab); DisposeHandle ((Handle) imageDesc); GST_ERROR_OBJECT (self, "DecompressSequenceBegin returned %d", (int) err); return GST_STATE_CHANGE_FAILURE; } DisposeHandle ((Handle) imageDesc); break; } default: break; } result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); if (result == GST_STATE_CHANGE_FAILURE) return result; switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: SGStop (self->seq_grab); err = CDSequenceEnd (self->dec_seq); if (err != noErr) GST_WARNING_OBJECT (self, "CDSequenceEnd returned %d", (int) err); self->dec_seq = 0; SGRelease (self->seq_grab); break; default: break; } return result; }
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; }