static gboolean device_select (GstOSXVideoSrc * src) { Str63 pstr; ComponentResult err; gchar *sgname; int inputIndex; /* if there's no device id set, attempt to select default device */ if (!src->device_id && !device_set_default (src)) return FALSE; if (!parse_device_id (src->device_id, &sgname, &inputIndex)) { GST_ERROR_OBJECT (src, "unable to parse device id: [%s]", src->device_id); return FALSE; } c2pstrcpy (pstr, sgname); g_free (sgname); err = SGSetChannelDevice (src->video_chan, (StringPtr) & pstr); if (err != noErr) { GST_ERROR_OBJECT (src, "SGSetChannelDevice returned %d", (int) err); return FALSE; } err = SGSetChannelDeviceInput (src->video_chan, inputIndex); if (err != noErr) { GST_ERROR_OBJECT (src, "SGSetChannelDeviceInput returned %d", (int) err); return FALSE; } return TRUE; }
// Create the Sequence Grabber Audio Channel void QuicktimeLiveImageStream::createSequenceGrabberAudioChannel() { // Check capability and setting of Sequence Grabber GDHandle origDevice; CGrafPtr origPort; // Create GWorld GetGWorld (&origPort, &origDevice); SetGWorld (m_gw, NULL); // set current graphics port to offscreen // Setup // Get a video channel ComponentResult result = SGNewChannel (m_gSeqGrabber, SoundMediaType, &m_gSoundChannel); if ((m_gSoundChannel != nil) && (result == noErr)) { result = SGInitChannel(m_gSoundChannel, m_gSeqGrabber); // result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview ); // Usage if (g_s_use_sg_record) result = SGSetChannelUsage (m_gSoundChannel, seqGrabRecord | seqGrabLowLatencyCapture); else { result = SGSetChannelUsage (m_gSoundChannel, seqGrabPreview | seqGrabRecord | seqGrabLowLatencyCapture); } // Get Str255 deviceName; Str255 inputName; short inputNumber; result = SGGetChannelDeviceAndInputNames(m_gSoundChannel, deviceName, inputName, &inputNumber); // Set // OSG_DEBUG << "Setting up audio component from input prefs" << std::endl; result = SGSetChannelDevice (m_gSoundChannel, m_soundDeviceIDStr); result = SGSetChannelDeviceInput(m_gSoundChannel, m_soundDeviceInputID); // Set the volume low to prevent feedback when we start the preview, // in case the mic is anywhere near the speaker. short volume = 0; result = SGGetChannelVolume (m_gSoundChannel, &volume); // result = SGSetChannelVolume (m_gSoundChannel, 255); // Inform result = SGChangedSource (m_gSeqGrabber, m_gSoundChannel); } else { OSG_FATAL << "Could not create SGNewChannel for Sound Channel" << std::endl; } // Set GWorld back SetGWorld(origPort, origDevice); }
// Create the Sequence Grabber Video Channel void QuicktimeLiveImageStream::createSequenceGrabberVideoChannel() { // Check capability and setting of Sequence Grabber GDHandle origDevice; CGrafPtr origPort; // Create GWorld GetGWorld (&origPort, &origDevice); SetGWorld (m_gw, NULL); // set current graphics port to offscreen // Setup // Get a video channel ComponentResult result = SGNewChannel (m_gSeqGrabber, VideoMediaType, &m_gVideoChannel); if ((m_gVideoChannel != nil) && (result == noErr)) { result = SGInitChannel(m_gVideoChannel, m_gSeqGrabber); Rect gActiveVideoRect; // Usage if (g_s_use_sg_record) result = SGSetChannelUsage (m_gVideoChannel, seqGrabRecord | seqGrabLowLatencyCapture); else { result = SGSetChannelUsage (m_gVideoChannel, seqGrabPreview); } // result = SGSetUseScreenBuffer(m_gVideoChannel, FALSE); // Set OSG_DEBUG << "Setting up vdig from input prefs" << std::endl; result = SGSetChannelDevice ( m_gVideoChannel, m_videoDeviceIDStr); result = SGSetChannelDeviceInput( m_gVideoChannel, m_videoDeviceInputID); // result = SGSetChannelPlayFlags ( m_gVideoChannel, channelPlayFast | channelPlayHighQuality | channelPlayAllData); result = SGSetChannelPlayFlags ( m_gVideoChannel, channelPlayFast ); VideoDigitizerComponent vdig = SGGetVideoDigitizerComponent(m_gVideoChannel); VideoDigitizerError vid_err; vid_err = VDSetInputStandard (vdig, palIn); OSG_DEBUG << "Setup vdig from input prefs:" << std::endl; print_video_component_capability(vdig); result = SGVideoDigitizerChanged( m_gVideoChannel); result = SGGetSrcVideoBounds ( m_gVideoChannel, &gActiveVideoRect); result = SGSetChannelBounds ( m_gVideoChannel, &gActiveVideoRect); result = SGChangedSource (m_gSeqGrabber, m_gVideoChannel); Fixed frame_rate; result = SGGetFrameRate (m_gVideoChannel, &frame_rate); result = SGSetFrameRate (m_gVideoChannel, 100); // // Sound /* long sound_id; Str255 sound_driver_name; char* sound_driver_name_cstr; vid_err = VDGetSoundInputSource(vdig, (long)m_videoDeviceInputID, &sound_id); vid_err = VDGetSoundInputDriver(vdig, sound_driver_name); sound_driver_name_cstr = pstr_printable(sound_driver_name); OSG_DEBUG << "vdig sound driver name :" << sound_driver_name_cstr << std::endl; OSG_DEBUG << "vdig sound driver id :" << sound_id << std::endl; */ } else { OSG_FATAL << "Could not create SGNewChannel for Video Channel" << std::endl; } // Set GWorld back SetGWorld(origPort, origDevice); }
//-------------------------------------------------------------------- bool ofVideoGrabber::qtSelectDevice(int deviceNumber, bool didWeChooseADevice){ //note - check for memory freeing possibly needed for the all SGGetChannelDeviceList mac stuff // also see notes in listDevices() regarding new enunemeration method. //Generate a device list and enumerate //all devices availble to the channel SGDeviceList deviceList; SGGetChannelDeviceList(gVideoChannel, sgDeviceListIncludeInputs, &deviceList); unsigned char pascalName[256]; unsigned char pascalNameInput[256]; int numDevices = (*deviceList)->count; if(numDevices == 0){ ofLog(OF_LOG_ERROR, "error: No catpure devices found"); return false; } int deviceCount = 0; for(int i = 0 ; i < numDevices; ++i) { SGDeviceName nameRec; nameRec = (*deviceList)->entry[i]; SGDeviceInputList deviceInputList = nameRec.inputs; int numInputs = 0; if( deviceInputList ) numInputs = ((*deviceInputList)->count); memcpy(pascalName, (*deviceList)->entry[i].name, sizeof(char) * 256); memset(pascalNameInput, 0, sizeof(char)*256); //this means we can use the capture method if(nameRec.flags != sgDeviceNameFlagDeviceUnavailable){ //if we have a capture 'device' (qt's word not mine - I would prefer 'system' ) that is ready to be used //we go through its inputs to list all physical devices - as there could be more than one! for(int j = 0; j < numInputs; j++){ //if our 'device' has inputs we get their names here if( deviceInputList ){ SGDeviceInputName inputNameRec = (*deviceInputList)->entry[j]; memcpy(pascalNameInput, inputNameRec.name, sizeof(char) * 256); } //if the device number matches we try and setup the device //if we didn't specifiy a device then we will try all devices till one works! if( deviceCount == deviceNumber || !didWeChooseADevice ){ ofLog(OF_LOG_NOTICE, "attempting to open device[%i] %s - %s", deviceCount, p2cstr(pascalName), p2cstr(pascalNameInput) ); OSErr err1 = SGSetChannelDevice(gVideoChannel, pascalName); OSErr err2 = SGSetChannelDeviceInput(gVideoChannel, j); int successLevel = 0; //if there were no errors then we have opened the device without issue if ( err1 == noErr && err2 == noErr){ successLevel = 2; } //parameter errors are not fatal so we will try and open but will caution the user else if ( (err1 == paramErr || err1 == noErr) && (err2 == noErr || err2 == paramErr) ){ successLevel = 1; } //the device is opened! if ( successLevel > 0 ){ deviceName = (char *)p2cstr(pascalName); deviceName += "-"; deviceName += (char *)p2cstr(pascalNameInput); if(successLevel == 2)ofLog(OF_LOG_NOTICE, "device opened successfully"); else ofLog(OF_LOG_WARNING, "device opened with some paramater errors - should be fine though!"); //no need to keep searching - return that we have opened a device! return true; }else{ //if we selected a device in particular but failed we want to go through the whole list again - starting from 0 and try any device. //so we return false - and try one more time without a preference if( didWeChooseADevice ){ ofLog(OF_LOG_WARNING, "problems setting device[%i] %s - %s *****", deviceNumber, p2cstr(pascalName), p2cstr(pascalNameInput)); return false; }else{ ofLog(OF_LOG_WARNING, "unable to open device, trying next device"); } } } //we count this way as we need to be able to distinguish multiple inputs as devices deviceCount++; } }else{ //ofLog(OF_LOG_ERROR, "(unavailable) device[%i] %s", deviceCount, p2cstr(pascalName) ); deviceCount++; } } return false; }
void pix_videoDarwin :: InitSeqGrabber() { OSErr anErr; Rect m_srcRect = {0,0, m_vidYSize, m_vidXSize}; SGDeviceList devices; short deviceIndex,inputIndex; short deviceCount = 0; SGDeviceInputList theSGInputList = NULL; bool showInputsAsDevices; // UserData *uD; /* int num_components = 0; Component c = 0; ComponentDescription cd; cd.componentType = SeqGrabComponentType; cd.componentSubType = 0; cd.componentManufacturer = 0; cd.componentFlags = 0; cd.componentFlagsMask = 0; while((c = FindNextComponent(c, &cd)) != 0) { num_components++; } // add component c to the list. // post("number of SGcomponents: %d",num_components); */ m_sg = OpenDefaultComponent(SeqGrabComponentType, 0); if(m_sg==NULL){ error("could not open default component"); return; } anErr = SGInitialize(m_sg); if(anErr!=noErr){ error("could not initialize SG error %d",anErr); return; } anErr = SGSetDataRef(m_sg, 0, 0, seqGrabDontMakeMovie); if (anErr != noErr){ error("dataref failed with error %d",anErr); } anErr = SGNewChannel(m_sg, VideoMediaType, &m_vc); if(anErr!=noErr){ error("could not make new SG channnel error %d",anErr); return; } anErr = SGGetChannelDeviceList(m_vc, sgDeviceListIncludeInputs, &devices); if(anErr!=noErr){ error("could not get SG channnel Device List"); }else{ deviceCount = (*devices)->count; deviceIndex = (*devices)->selectedIndex; logpost(NULL, 3, "SG channnel Device List count %d index %d",deviceCount,deviceIndex); int i; for (i = 0; i < deviceCount; i++){ logpost(NULL, 3, "SG channnel Device List %.*s", (*devices)->entry[i].name[0], (*devices)->entry[i].name+1); } SGGetChannelDeviceAndInputNames(m_vc, NULL, NULL, &inputIndex); showInputsAsDevices = ((*devices)->entry[deviceIndex].flags) & sgDeviceNameFlagShowInputsAsDevices; theSGInputList = ((SGDeviceName *)(&((*devices)->entry[deviceIndex])))->inputs; //fugly //we should have device names in big ass undocumented structs //walk through the list //for (i = 0; i < deviceCount; i++){ for (i = 0; i < inputIndex; i++){ logpost(NULL, 3, "SG channnel Input Device List %d %.*s", i, (*theSGInputList)->entry[i].name[0], (*theSGInputList)->entry[i].name+1); } } //this call sets the input device if (m_inputDevice > 0 && m_inputDevice < deviceCount) //check that the device is not out of bounds //anErr = SGSetChannelDeviceInput(m_vc,m_inputDevice); logpost(NULL, 3, "SGSetChannelDevice trying %s", (*devices)->entry[m_inputDevice].name[0], (*devices)->entry[m_inputDevice].name+1); anErr = SGSetChannelDevice(m_vc, (*devices)->entry[m_inputDevice].name); if(anErr!=noErr) error("SGSetChannelDevice returned error %d",anErr); anErr = SGSetChannelDeviceInput(m_vc,m_inputDeviceChannel); if(anErr!=noErr) error("SGSetChannelDeviceInput returned error %d",anErr); /* //attempt to save SG settings to disk NewUserData(uD); SGGetSettings(m_sg,uD,0); short uDCount; uDCount = CountUserDataType(*uD,sgClipType); post("UserDataType count %d",uDCount); Handle myHandle; PutUserDataIntoHandle(*uD,myHandle); int myFile; myFile = open("/Users/lincoln/Documents/temp",O_CREAT | O_RDWR, 0600); write(myFile,myHandle,4096); close(myFile); */ //grab the VDIG info from the SGChannel m_vdig = SGGetVideoDigitizerComponent(m_vc); vdigErr = VDGetDigitizerInfo(m_vdig,&m_vdigInfo); //not sure if this is useful Str255 vdigName; memset(vdigName,0,255); vdigErr = VDGetInputName(m_vdig,m_inputDevice,vdigName); logpost(NULL, 3, "vdigName is %s",vdigName); // pascal string? Rect vdRect; vdigErr = VDGetDigitizerRect(m_vdig,&vdRect); logpost(NULL, 3, "digitizer rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right); vdigErr = VDGetActiveSrcRect(m_vdig,0,&vdRect); logpost(NULL, 3, "active src rect is top %d bottom %d left %d right %d",vdRect.top,vdRect.bottom,vdRect.left,vdRect.right); anErr = SGSetChannelBounds(m_vc, &m_srcRect); if(anErr!=noErr){ error("could not set SG ChannelBounds "); } anErr = SGSetVideoRect(m_vc, &m_srcRect); if(anErr!=noErr){ error("could not set SG Rect "); } anErr = SGSetChannelUsage(m_vc, seqGrabPreview); if(anErr!=noErr){ error("could not set SG ChannelUsage "); } switch (m_quality){ case 0: anErr = SGSetChannelPlayFlags(m_vc, channelPlayNormal); post("set SG NormalQuality"); break; case 1: anErr = SGSetChannelPlayFlags(m_vc, channelPlayHighQuality); post("set SG HighQuality"); break; case 2: anErr = SGSetChannelPlayFlags(m_vc, channelPlayFast); post("set SG FastQuality"); break; case 3: anErr = SGSetChannelPlayFlags(m_vc, channelPlayAllData); post("set SG PlayAlldata"); break; } if (m_colorspace==GL_BGRA_EXT){ m_pixBlock.image.xsize = m_vidXSize; m_pixBlock.image.ysize = m_vidYSize; m_pixBlock.image.setCsizeByFormat(GL_RGBA_GEM); m_pixBlock.image.reallocate(); m_rowBytes = m_vidXSize*4; anErr = QTNewGWorldFromPtr (&m_srcGWorld, k32ARGBPixelFormat, &m_srcRect, NULL, NULL, 0, m_pixBlock.image.data, m_rowBytes); post ("using RGB"); }else{ m_pixBlock.image.xsize = m_vidXSize; m_pixBlock.image.ysize = m_vidYSize; m_pixBlock.image.csize = 2; m_pixBlock.image.format = GL_YCBCR_422_APPLE; #ifdef __VEC__ m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_REV_APPLE; #else m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_APPLE; #endif m_pixBlock.image.reallocate(); m_rowBytes = m_vidXSize*2; anErr = QTNewGWorldFromPtr (&m_srcGWorld, // k422YpCbCr8CodecType, k422YpCbCr8PixelFormat, // '2vuy', // kComponentVideoUnsigned, &m_srcRect, NULL, NULL, 0, m_pixBlock.image.data, m_rowBytes); post ("using YUV"); } if (anErr!= noErr) { error("%d error at QTNewGWorldFromPtr", anErr); return; } if (NULL == m_srcGWorld) { error("could not allocate off screen"); return; } SGSetGWorld(m_sg,(CGrafPtr)m_srcGWorld, NULL); SGStartPreview(m_sg); //moved to starttransfer? m_haveVideo = 1; }