Professional Web Applications Themes

How are iMovie's Camera Controls implemented? - Mac Programming

How are iMovie's Camera Controls implemented? I've previously written application programs in C++ that use Canopus og video -> DV over firewire converters, and they worked just fine using Apple's standard Quicktime Sequence Grabber examples like HackTV. Now, Canopus appears to have dropped its old PCI card and replaced it with a new one (ACEDVio) that iMovie can work with just fine, but my Quicktime Sequence Grabber cannot. (I can't use an external converter box, because our product must comply with strict RFI standards.) With the old card, I got video in iMovie as soon as I pressed the "camera" ...

  1. #1

    Default How are iMovie's Camera Controls implemented?

    How are iMovie's Camera Controls implemented?

    I've previously written application programs in C++ that use Canopus
    og video -> DV over firewire converters, and they worked just fine
    using Apple's standard Quicktime Sequence Grabber examples like HackTV.

    Now, Canopus appears to have dropped its old PCI card and replaced it
    with a new one (ACEDVio) that iMovie can work with just fine, but my
    Quicktime Sequence Grabber cannot.

    (I can't use an external converter box, because our product must comply
    with strict RFI standards.)

    With the old card, I got video in iMovie as soon as I pressed the
    "camera" button. With the new card, I need to first press the "camera"
    button, then press iMovie's "Play" button to get video.

    My guess is that iMovie is sending an IIDC "play" control command, but
    when I tried to do that from one of the sample projects in the Firewire
    SDK, the card returned an error code.

    Anyone have any pointers to doentation or sample source for
    controlling a firewire video digitizer that appears to need camera
    controls IIDC? OHCI? to function?

    David Phillip Oster
    David Guest

  2. #2

    Default Re: How are iMovie's Camera Controls implemented?

    In article <sf.sbcglobal.net>,
    David Phillip Oster <org> wrote:
     

    Answering my own question:

    You get a handle to the device, then use the system call
    DeviceControlDoAVCTransaction()
    to send it a "Play" command.

    This has been tested with the Canopus aceDVio board, which requires a
    Play command to send DV video over Firewire (1394).

    Here is the source code:

    This uses the PowerPlant class library, but it gives you the idea:

    // Open a DV isoch component instance
    // When done, close it.
    /// SendPlayCommand - returns an open component that caller must delete when done with it (or NULL)
    ///
    /// The system calls used in this routine are doented in IsoComponentsRef.txt .
    /// the Firewire camera control commands like "play" are doented in
    /// "Developing a Java API for digital video control using the Firewire SDK" by
    /// Bing-Chang Lai, Phillip John McKerrow and Damon Woolley
    /// (I found that with a google search in May 2004.)
    /// who in turn got it from: "AV/C Digital Interface Command Set" from
    /// <http://www.1394ta.org/> which also doents the return codes returned in outBuffer.
    ///
    /// The file IsochronousDataHandler.h states that for Classic, you need IDHLib.
    /// that isn't correct. The actual library is IsochronousDataHandlerLib
    /// Note that these calls came in with Quicktime 5, so if you might run on
    /// earlier systems, weak link and check.
    ///
    ///\todo: What if there are two or more digitizers attached?
    /// This function sends a play command to the first DV component it finds. It should be
    /// modified to return the number of acceptable components, and if it is more than one, we should
    /// present a user interface, asking the user to choose. (with persistence.) If the current configuration
    /// matches the saved configuration, then we should send the play command to the selected device.

    #include <IsochronousDataHandler.h> // for SendPlayCommand
    #include <DeviceControl.h> // for SendPlayCommand

    ComponentInstance SendPlayCommand(){
    // check that the weak link succeeded
    if(static_cast<void*>(kUnresolvedCFragSymbolAddres s) == DeviceControlDoAVCTransaction){
    return NULL;
    }
    ComponentDescription desc;
    desc.componentType = kIDHComponentType;
    desc.componentSubType = kIDHSubtypeDV;
    desc.componentManufacturer = NULL;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    Component dvComponent = FindNextComponent(NULL, &desc);
    if(NULL == dvComponent){ Throw_(cantFindHandler); }
    ComponentInstance dvInstance = NULL;
    ThrowIfOSStatus_(OpenAComponent(dvComponent, &dvInstance));
    try{
    QTAtomContainer deviceList;
    ThrowIfOSStatus_(IDHGetDeviceList(dvInstance, &deviceList));
    long numberDVDevices = QTCountChildrenOfType(deviceList, kParentAtomIsContainer, kIDHDeviceAtomType);
    if(0 == numberDVDevices){ Throw_(resNotFound); }

    for(long i=1; i <= numberDVDevices; ++i){
    QTAtom deviceAtom; // get the atom to each device
    if(NULL == (deviceAtom = QTFindChildByIndex(deviceList, kParentAtomIsContainer, kIDHDeviceAtomType, i, NULL))){ continue; }

    QTAtom isochAtom; // find the isoch characteristics for this device
    if(NULL == (isochAtom = QTFindChildByIndex(deviceList, deviceAtom, kIDHIsochServiceAtomType, 1, NULL))){ continue; }

    long nConfigs = QTCountChildrenOfType( deviceList, isochAtom, kIDHIsochModeAtomType);
    for(long j = 1; j <= nConfigs; ++j){

    QTAtom configAtom; // get this configs atom
    if(NULL == (configAtom = QTFindChildByIndex( deviceList, isochAtom, kIDHIsochModeAtomType, j, NULL))){ continue; }

    QTAtom mediaAtom; // find the media type atom
    if(NULL == (mediaAtom = QTFindChildByIndex(deviceList, configAtom, kIDHIsochMediaType, 1, NULL))){ continue; }

    QTLockContainer(deviceList);

    OSType mediaType = 0; // get the value of the mediaType atom
    Size siz;
    QTCopyAtomDataToPtr(deviceList, mediaAtom, true, sizeof mediaType, &mediaType, &siz);
    QTUnlockContainer(deviceList);

    if(kIDHVideoMediaAtomType == mediaType){ // found first appropriate media type.
    QTAtomSpec videoConfig;
    // found video device
    videoConfig.container = deviceList;
    videoConfig.atom = configAtom;
    ThrowIfOSStatus_(IDHSetDeviceConfiguration(dvInsta nce, &videoConfig));
    ComponentInstance deviceControlInstance;
    ThrowIfOSStatus_(IDHGetDeviceControl(dvInstance, &deviceControlInstance));

    char inBuffer[4];
    char outBuffer[16];
    DVCTransactionParams pParams;

    // fill up the avc frame
    inBuffer[0] = 0x00; //kAVCControlCommand;
    inBuffer[1] = 0x20;
    inBuffer[2] = 0xC3; // Play command is 0xc3 0x75
    inBuffer[3] = 0x75;

    // fill up the transaction parameter block
    pParams.commandBufferPtr = inBuffer;
    pParams.commandLength = sizeof inBuffer;
    pParams.responseBufferPtr = outBuffer;
    pParams.responseBufferSize = sizeof outBuffer;
    pParams.responseHandler = NULL;
    std::memset(outBuffer, 0, sizeof outBuffer);
    ThrowIfOSStatus_(DeviceControlDoAVCTransaction(dev iceControlInstance, &pParams));

    return dvInstance;
    }
    }
    }
    // nothing acceptable found.
    CloseComponent(dvInstance);
    return NULL;
    }catch(...){
    CloseComponent(dvInstance);
    throw;
    }
    }
    David Guest

  3. #3

    Default Re: How are iMovie's Camera Controls implemented?

    In article <sf.sbcglobal.net>,
    David Phillip Oster <org> wrote:
     

    Answering my own question:

    You get a handle to the device, then use the system call
    DeviceControlDoAVCTransaction()
    to send it a "Play" command.

    This has been tested with the Canopus aceDVio board, which requires a
    Play command to send DV video over Firewire (1394).

    I still have some unsolved issues:

    Why doesn't quicktime already take care of this for me?
    There are a bunch of digitizer control functions defined, but they all seem to no-op.

    What if there are two or more digitizers attached?

    This function sends a play command to the first DV component it finds. It should be
    modified to return the number of acceptable components, and if it is more than one, we should
    present a user interface, asking the user to choose. (with persistence.) If the current configuration
    matches the saved configuration, then we should send the play command to the selected device.


    Here is the source code:

    This uses the PowerPlant class library, but it gives you the idea:

    // Open a DV isoch component instance
    // When done, close it.
    /// SendPlayCommand - returns an open component that caller must delete when done with it (or NULL)
    ///
    /// The system calls used in this routine are doented in IsoComponentsRef.txt .
    /// the Firewire camera control commands like "play" are doented in
    /// "Developing a Java API for digital video control using the Firewire SDK" by
    /// Bing-Chang Lai, Phillip John McKerrow and Damon Woolley
    /// (I found that with a google search in May 2004.)
    /// who in turn got it from: "AV/C Digital Interface Command Set" from
    /// <http://www.1394ta.org/> which also doents the return codes returned in outBuffer.
    ///
    /// The file IsochronousDataHandler.h states that for Classic, you need IDHLib.
    /// that isn't correct. The actual library is IsochronousDataHandlerLib
    /// Note that these calls came in with Quicktime 5, so if you might run on
    /// earlier systems, weak link and check.
    ///

    #include <IsochronousDataHandler.h> // for SendPlayCommand
    #include <DeviceControl.h> // for SendPlayCommand

    ComponentInstance SendPlayCommand(){
    // check that the weak link succeeded
    if(static_cast<void*>(kUnresolvedCFragSymbolAddres s) == DeviceControlDoAVCTransaction){
    return NULL;
    }
    ComponentDescription desc;
    desc.componentType = kIDHComponentType;
    desc.componentSubType = kIDHSubtypeDV;
    desc.componentManufacturer = NULL;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    Component dvComponent = FindNextComponent(NULL, &desc);
    if(NULL == dvComponent){ Throw_(cantFindHandler); }
    ComponentInstance dvInstance = NULL;
    ThrowIfOSStatus_(OpenAComponent(dvComponent, &dvInstance));
    try{
    QTAtomContainer deviceList;
    ThrowIfOSStatus_(IDHGetDeviceList(dvInstance, &deviceList));
    long numberDVDevices = QTCountChildrenOfType(deviceList, kParentAtomIsContainer, kIDHDeviceAtomType);
    if(0 == numberDVDevices){ Throw_(resNotFound); }

    for(long i=1; i <= numberDVDevices; ++i){
    QTAtom deviceAtom; // get the atom to each device
    if(NULL == (deviceAtom = QTFindChildByIndex(deviceList, kParentAtomIsContainer, kIDHDeviceAtomType, i, NULL))){ continue; }

    QTAtom isochAtom; // find the isoch characteristics for this device
    if(NULL == (isochAtom = QTFindChildByIndex(deviceList, deviceAtom, kIDHIsochServiceAtomType, 1, NULL))){ continue; }

    long nConfigs = QTCountChildrenOfType( deviceList, isochAtom, kIDHIsochModeAtomType);
    for(long j = 1; j <= nConfigs; ++j){

    QTAtom configAtom; // get this configs atom
    if(NULL == (configAtom = QTFindChildByIndex( deviceList, isochAtom, kIDHIsochModeAtomType, j, NULL))){ continue; }

    QTAtom mediaAtom; // find the media type atom
    if(NULL == (mediaAtom = QTFindChildByIndex(deviceList, configAtom, kIDHIsochMediaType, 1, NULL))){ continue; }

    QTLockContainer(deviceList);

    OSType mediaType = 0; // get the value of the mediaType atom
    Size siz;
    QTCopyAtomDataToPtr(deviceList, mediaAtom, true, sizeof mediaType, &mediaType, &siz);
    QTUnlockContainer(deviceList);

    if(kIDHVideoMediaAtomType == mediaType){ // found first appropriate media type.
    QTAtomSpec videoConfig;
    // found video device
    videoConfig.container = deviceList;
    videoConfig.atom = configAtom;
    ThrowIfOSStatus_(IDHSetDeviceConfiguration(dvInsta nce, &videoConfig));
    ComponentInstance deviceControlInstance;
    ThrowIfOSStatus_(IDHGetDeviceControl(dvInstance, &deviceControlInstance));

    char inBuffer[4];
    char outBuffer[16];
    DVCTransactionParams pParams;

    // fill up the avc frame
    inBuffer[0] = 0x00; //kAVCControlCommand;
    inBuffer[1] = 0x20;
    inBuffer[2] = 0xC3; // Play command is 0xc3 0x75
    inBuffer[3] = 0x75;

    // fill up the transaction parameter block
    pParams.commandBufferPtr = inBuffer;
    pParams.commandLength = sizeof inBuffer;
    pParams.responseBufferPtr = outBuffer;
    pParams.responseBufferSize = sizeof outBuffer;
    pParams.responseHandler = NULL;
    std::memset(outBuffer, 0, sizeof outBuffer);
    ThrowIfOSStatus_(DeviceControlDoAVCTransaction(dev iceControlInstance, &pParams));

    return dvInstance;
    }
    }
    }
    // nothing acceptable found.
    CloseComponent(dvInstance);
    return NULL;
    }catch(...){
    CloseComponent(dvInstance);
    throw;
    }
    }
    David Guest

Similar Threads

  1. Replies: 1
    Last Post: November 11th, 12:00 AM
  2. -999 Not implemented yet.
    By LUQUE in forum Informix
    Replies: 9
    Last Post: February 17th, 03:41 PM
  3. SITE command not implemented
    By Michael in forum Sun Solaris
    Replies: 2
    Last Post: August 27th, 03:16 AM
  4. how to uninstall iMovie 3 and restore iMovie 2
    By 0bserblur in forum Mac Applications & Software
    Replies: 5
    Last Post: July 18th, 01:08 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139