#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iokit/IOKitLib.h>
#include <iokit/avc/IOFireWireAVCConsts.h>
#include <DVComponentGlue/IsochronousDataHandler.h>
#include <DVComponentGlue/DeviceControl.h>
static QTAtomSpec videoConfig;
static IDHDeviceID deviceID;
static IDHNotificationID notificationID;
static void printP(const char *s)
{
int len = *s++;
while(len--)
printf("%c", *s++);
}
static void print4(const char *s, UInt32 val)
{
printf("%s'%c%c%c%c'(0x%x)", s, val>>24, val>>16, val>>8, val, val);
}
static OSStatus notificationProc(IDHGenericEvent* event, void* userData)
{
ComponentInstance theInst = userData;
printf("Got notification for device 0x%x, notification 0x%x, event 0x%x, userdata 0x%x\n",
event->eventHeader.deviceID, event->eventHeader.notificationID, event->eventHeader.event,
userData);
IDHNotifyMeWhen(theInst, event->eventHeader.notificationID, kIDHEventEveryEvent);
return noErr;
}
static void doControlTest(ComponentInstance theInst, QTAtomSpec *currentIsochConfig, UInt8 op1, UInt8 op2)
{
ComponentInstance controlInst;
ComponentResult result;
IDHDeviceStatus devStatus;
DVCTransactionParams pParams;
char in[4], out[16];
int i;
result = IDHGetDeviceControl(theInst, &controlInst);
if(result)
goto Exit;
result = IDHGetDeviceStatus( theInst, currentIsochConfig, &devStatus);
if(result)
goto Exit;
if(!controlInst)
goto Exit;
#if 1
in[0] = kAVCStatusInquiryCommand; in[1] = 0x20; in[2] = op1;
in[3] = op2;
#else
in[0] = 0x00;
in[1] = 0x58; in[2] = 0x50;
in[3] = 0x00;
in[4] = 0xff;
in[5] = 0x00; in[6] = 0x00;
in[7] = 0x00;
in[8] = 0xff;
in[9] = 0xff;
in[10] = 0xff;
in[11] = 0xff;
in[12] = 0x00;
in[13] = 0x00;
in[14] = 0x00;
in[15] = 0x1b;
in[16] = 0x5c;
in[17] = 0x44;
in[18] = 0x43;
in[19] = 0x49;
in[20] = 0x4d;
in[21] = 0x5c;
in[22] = 0x31;
in[23] = 0x30;
in[24] = 0x31;
in[25] = 0x43;
in[26] = 0x41;
in[27] = 0x4e;
in[28] = 0x4f;
in[29] = 0x4e;
in[30] = 0x5c;
in[31] = 0x41;
in[32] = 0x55;
in[33] = 0x54;
in[34] = 0x5f;
in[35] = 0x30;
in[36] = 0x31;
in[37] = 0x30;
in[38] = 0x33;
in[39] = 0x2e;
in[40] = 0x4a;
in[41] = 0x50;
in[42] = 0x47;
in[43] = 0x00;
#endif
pParams.commandBufferPtr = in;
pParams.commandLength = sizeof(in);
pParams.responseBufferPtr = out;
pParams.responseBufferSize = sizeof(out);
pParams.responseHandler = NULL;
do {
for(i=0; i<sizeof(out); i++)
out[i] = 0;
result = DeviceControlDoAVCTransaction( controlInst, &pParams);
if(result == kIOReturnOffline) {
printf("offline!!\n");
sleep(1);
continue;
}
if(result)
goto Exit;
printf("Received %d bytes:", pParams.responseBufferSize);
for(i=0; i<sizeof(out); i++)
printf("%d(0x%x) ", out[i], out[i]);
printf("\n");
} while (1);
Exit:
if(result != noErr)
printf("Control error %d(%x)\n", result, result);
}
static void OpenDV()
{
ComponentInstance theInst;
ComponentResult version;
QTAtomContainer deviceList = NULL;
short nDVDevices, i, j;
QTAtom deviceAtom;
UInt32 cmpFlag;
UInt32 isoversion;
long size;
OSStatus err;
theInst = OpenDefaultComponent('ihlr', 'dv ');
printf("Instance is 0x%x\n", theInst);
if(theInst == NULL)
return;
version = CallComponentVersion(theInst);
printf("Version is 0x%x\n", version);
err = IDHNewNotification(theInst, kIDHDeviceIDEveryDevice, notificationProc, theInst, ¬ificationID);
if( err != noErr)
goto error;
err = IDHNotifyMeWhen(theInst, notificationID, kIDHEventEveryEvent);
if( err != noErr)
goto error;
do {
err = IDHGetDeviceList( theInst, &deviceList);
if( err != noErr)
goto error;
nDVDevices = QTCountChildrenOfType( deviceList, kParentAtomIsContainer, kIDHDeviceAtomType);
if(nDVDevices > 0)
break;
printf("Waiting for a camera...\n");
sleep(1);
} while(true);
QTLockContainer( deviceList);
deviceAtom = QTFindChildByIndex( deviceList, kParentAtomIsContainer, kIDHUseCMPAtomType, 1, nil);
if( deviceAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, deviceAtom, true, sizeof( cmpFlag), &cmpFlag, &size);
deviceAtom = QTFindChildByIndex( deviceList, kParentAtomIsContainer, kIDHIsochVersionAtomType, 1, nil);
if( deviceAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, deviceAtom, true, sizeof( isoversion), &isoversion, &size);
printf("Version 0x%x. %d DV devices, use CMP flag is %d\n", isoversion, nDVDevices, cmpFlag);
for( i=0; i<nDVDevices; ++i)
{
QTAtom isochAtom, dataAtom;
UInt32 test[2];
int nConfigs;
char cameraName[256];
IDHDeviceStatus deviceStatus;
deviceAtom = QTFindChildByIndex( deviceList, kParentAtomIsContainer, kIDHDeviceAtomType, i + 1, nil);
if( deviceAtom == nil)
goto error;
printf("device %d ", i);
dataAtom = QTFindChildByIndex( deviceList, deviceAtom, kIDHUniqueIDType, 1, nil);
if( dataAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, dataAtom, true, sizeof( test), test, &size);
printf("guid 0x%x%08x ", test[0], test[1]);
dataAtom = QTFindChildByIndex( deviceList, deviceAtom, kIDHNameAtomType, 1, nil);
if( dataAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, dataAtom, true, 255, cameraName, &size);
cameraName[size] = 0;
printf("%s ", cameraName+1);
dataAtom = QTFindChildByIndex( deviceList, deviceAtom, kIDHDeviceIDType, 1, nil);
if( dataAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, dataAtom, true, sizeof( deviceID), &deviceID, &size);
printf("deviceID 0x%x ", deviceID);
dataAtom = QTFindChildByIndex( deviceList, deviceAtom, 'ddin', 1, nil);
if( dataAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, dataAtom, true, sizeof( deviceStatus), &deviceStatus, &size);
printf("\ndevice status:\n");
printf("version %d\n", deviceStatus.version);
printf("physicallyConnected %d\n", deviceStatus.physicallyConnected);
printf("readEnabled %d ", deviceStatus.readEnabled);
printf("writeEnabled %d ", deviceStatus.writeEnabled);
printf("exclusiveAccess %d\n", deviceStatus.exclusiveAccess);
printf("currentBandwidth %d ", deviceStatus.currentBandwidth);
printf("currentChannel %d ", deviceStatus.currentChannel);
printf("inputStandard %d ", deviceStatus.inputStandard);
printf("deviceActive %d\n", deviceStatus.deviceActive);
isochAtom = QTFindChildByIndex( deviceList, deviceAtom, kIDHIsochServiceAtomType, 1, nil);
if( isochAtom == nil)
goto error;
nConfigs = QTCountChildrenOfType( deviceList, isochAtom, kIDHIsochModeAtomType);
printf("\n%d configs:\n", nConfigs);
videoConfig.atom = nil;
for( j=0; j<nConfigs; ++j)
{
OSType mediaType;
QTAtom configAtom, mediaAtom;
configAtom = QTFindChildByIndex( deviceList, isochAtom, kIDHIsochModeAtomType, j + 1, nil);
if( configAtom == nil)
goto error;
printf("Config %d",j);
mediaAtom = QTFindChildByIndex( deviceList, configAtom, kIDHIsochMediaType, 1, nil);
if( mediaAtom == nil)
goto error;
QTCopyAtomDataToPtr( deviceList, mediaAtom, true, sizeof( mediaType), &mediaType, &size);
print4(" Media type:", mediaType);
if( mediaType == kIDHVideoMediaAtomType) {
videoConfig.container = deviceList; videoConfig.atom = configAtom;
break;
}
printf("\n");
}
printf("-----\n");
}
if( videoConfig.atom == nil) goto error;
printf("setting config\n");
err = IDHSetDeviceConfiguration( theInst, &videoConfig);
if( err != noErr)
goto error;
#if 1
doControlTest(theInst, &videoConfig,
0xd0, 0x7f
);
#else
{
TimeRecord time1, time2;
do {
err = IDHGetDeviceTime(theInst, &time1);
err = IDHGetDeviceTime(theInst, &time2);
if(time2.value.lo > time1.value.lo+1) {
printf("Diff is %d\n", time2.value.lo-time1.value.lo);
}
} while (1);
}
#endif
error:
if( err != noErr)
printf("error %d(0x%x)\n", err, err);
if(deviceList) {
QTUnlockContainer( deviceList);
QTDisposeAtomContainer(deviceList);
}
CloseComponent(theInst);
}
int main(int argc, char **argv)
{
UInt32 seed = GetComponentListModSeed();
UInt32 num;
Handle aName;
ComponentDescription desc, aDesc;
Component aComponent;
int pos = 1;
printf("Component seed is %d\n", seed);
desc.componentType = 'ihlr';
desc.componentSubType = 0;
desc.componentManufacturer = 0;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
num = CountComponents(&desc);
printf("%d components match\n", num);
aComponent = 0;
aName = NewHandleClear(200);
while (aComponent = FindNextComponent(aComponent, &desc)) {
OSStatus oops;
printf("Found component 0x%x:", aComponent);
oops = GetComponentInfo(aComponent, &aDesc, aName,
NULL, NULL);
if(oops)
printf("GetComponentInfo() returned error %d\n", oops);
else {
if(GetHandleSize(aName))
printP(*aName);
else
printf("Unnamed");
print4(", Type ", aDesc.componentType);
print4(", SubType ", aDesc.componentSubType);
print4(", Manufacturer ", aDesc.componentManufacturer);
printf("\n");
}
}
num = 0;
do {
ComponentInstance theInst;
theInst = OpenDefaultComponent('ihlr', 'dv ');
if(theInst == NULL)
return;
num++;
usleep(50000);
CloseComponent(theInst);
} while (0);
OpenDV();
return 0;
}