// 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);
}
Пример #2
0
/* 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");
                        }
                }
Пример #3
0
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;
}