// 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); }
/* Initialize the QuickTime grabber */ static int qt_open_grabber(struct qt_grabber_state *s, char *fmt) { GrafPtr savedPort; WindowPtr gMonitor; //SGModalFilterUPP seqGrabModalFilterUPP; assert(s != NULL); assert(s->magic == MAGIC_QT_GRABBER); /****************************************************************************************/ /* Step 0: Initialise the QuickTime movie toolbox. */ InitCursor(); EnterMovies(); /****************************************************************************************/ /* Step 1: Create an off-screen graphics world object, into which we can capture video. */ /* Lock it into position, to prevent QuickTime from messing with it while capturing. */ OSType pixelFormat; pixelFormat = FOUR_CHAR_CODE('BGRA'); /****************************************************************************************/ /* Step 2: Open and initialise the default sequence grabber. */ s->grabber = OpenDefaultComponent(SeqGrabComponentType, 0); if (s->grabber == 0) { debug_msg("Unable to open grabber\n"); return 0; } gMonitor = GetDialogWindow(GetNewDialog(1000, NULL, (WindowPtr) - 1L)); GetPort(&savedPort); SetPort((GrafPtr)gMonitor); if (SGInitialize(s->grabber) != noErr) { debug_msg("Unable to init grabber\n"); return 0; } SGSetGWorld(s->grabber, GetDialogPort((DialogPtr)gMonitor), NULL); /****************************************************************************************/ /* 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 (SGSetDataRef(s->grabber, 0, 0, seqGrabDontMakeMovie) != noErr) { CloseComponent(s->grabber); debug_msg("Unable to set data ref\n"); return 0; } if (SGSetGWorld(s->grabber, NULL, NULL) != noErr) { debug_msg("Unable to get gworld from grabber\n"); return 0; } if (SGNewChannel(s->grabber, VideoMediaType, &s->video_channel) != noErr) { debug_msg("Unable to open video channel\n"); return 0; } /* do not check for grab audio in case that we will only display usage */ if (SGNewChannel(s->grabber, SoundMediaType, &s->audio_channel) != noErr) { fprintf(stderr, "Warning: Creating audio channel failed. " "Disabling sound output.\n"); s->grab_audio = FALSE; } /* Print available devices */ int i; int j; SGDeviceInputList inputList; SGDeviceList deviceList; if (strcmp(fmt, "help") == 0) { printf("\nUsage:\t-t quicktime:<device>:<mode>:<pixel_type>[:<audio_device>:<audio_mode>]\n\n"); if (SGGetChannelDeviceList (s->video_channel, sgDeviceListIncludeInputs, &deviceList) == noErr) { fprintf(stdout, "\nAvailable capture devices:\n"); for (i = 0; i < (*deviceList)->count; i++) { SGDeviceName *deviceEntry = &(*deviceList)->entry[i]; fprintf(stdout, " Device %d: ", i); nprintf((char *) deviceEntry->name); if (deviceEntry->flags & sgDeviceNameFlagDeviceUnavailable) { fprintf(stdout, " - ### NOT AVAILABLE ###"); } if (i == (*deviceList)->selectedIndex) { fprintf(stdout, " - ### ACTIVE ###"); } fprintf(stdout, "\n"); short activeInputIndex = 0; inputList = deviceEntry->inputs; if (inputList && (*inputList)->count >= 1) { SGGetChannelDeviceAndInputNames (s->video_channel, NULL, NULL, &activeInputIndex); for (j = 0; j < (*inputList)->count; j++) { fprintf(stdout, "\t"); fprintf(stdout, "- %d. ", j); nprintf((char *) &(*inputList)->entry [j].name); if ((i == (*deviceList)->selectedIndex) && (j == activeInputIndex)) fprintf(stdout, " - ### ACTIVE ###"); fprintf(stdout, "\n"); } } } SGDisposeDeviceList(s->grabber, deviceList); CodecNameSpecListPtr list; GetCodecNameList(&list, 1); printf("\nCompression types:\n"); for (i = 0; i < list->count; i++) { int fcc = list->list[i].cType; printf("\t%d) ", i); nprintf((char *) list->list[i].typeName); printf(" - FCC (%c%c%c%c)", fcc >> 24, (fcc >> 16) & 0xff, (fcc >> 8) & 0xff, (fcc) & 0xff); printf(" - codec id %x", (unsigned int)(list->list[i].codec)); printf(" - cType %x", (unsigned int)list->list[i].cType); printf("\n"); } }
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; }