#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iokit/IOKitLib.h>
#include <Carbon/Carbon.h>
#include "IsochronousDataHandler.h"
#include "DeviceControl.h"
static int done = 0;
static int file = 0;
static QTAtomSpec videoConfig;
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 DVIsochComponentReadCallback( IDHGenericEvent *eventRecord, void *userData)
{
OSErr result = noErr;
IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord;
#if 1
ComponentInstance theInst = userData;
if(file)
write(file, pb->buffer, pb->actualCount);
result = IDHReleaseBuffer( theInst, pb);
pb->buffer = NULL;
pb->requestedCount = 120000;
pb->actualCount = 0;
pb->completionProc = DVIsochComponentReadCallback;
result = IDHRead( theInst, pb);
if( result != noErr) {
printf("IDHRead error %d\n", result);
}
#else
printf("read complete for block 0x%x, refcon 0x%x\n", pb, userData);
#endif
done++;
return result;
}
static OSStatus DVIsochComponentWriteCallback( IDHGenericEvent *eventRecord, void *userData)
{
OSErr result = noErr;
IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord;
#if 1
ComponentInstance theInst = userData;
if(file) {
int len;
len = read(file, pb->buffer, 120000);
if(len < 120000)
return result;
}
#if WRITEBUFF
#else
pb->buffer = nil;
#endif
pb->requestedCount = 120000;
pb->actualCount = 0;
pb->completionProc = DVIsochComponentWriteCallback;
result = IDHWrite( theInst, pb);
if( result != noErr) {
printf("IDHWrite error %d\n", result);
}
#else
printf("write complete for block 0x%x, refcon 0x%x\n", pb, userData);
#endif
done++;
return result;
}
static void doControlTest(ComponentInstance theInst, QTAtomSpec *currentIsochConfig)
{
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;
in[0] = 0x00; in[1] = 0x20; in[2] = 0xc3; in[3] = 0x75;
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(result != kIOReturnSuccess);
CallComponentClose(controlInst, 0);
Exit:
if(result != noErr)
printf("Control error %d(%x)\n", result, result);
}
static OSErr doReadTest(ComponentInstance theInst)
{
Ptr myBuffer;
IDHParameterBlock isochParamBlock;
OSErr err;
err = IDHOpenDevice( theInst, kIDHOpenForReadTransactions);
if( err != noErr)
goto error;
printf("Opened device\n");
doControlTest(theInst, &videoConfig);
file = open("/tmp/dump.rawdv", O_CREAT | O_WRONLY | O_TRUNC, 0666);
#if 0
{
int i;
for(i=0; i<1000; i++) {
isochParamBlock.buffer = nil;
isochParamBlock.requestedCount = 120000; isochParamBlock.actualCount = 0;
isochParamBlock.refCon = (void *)0x12345678;
isochParamBlock.completionProc = 0;
err = IDHRead( theInst, &isochParamBlock);
if( err != noErr)
goto error;
write(file, isochParamBlock.buffer, 120000);
err = IDHReleaseBuffer( theInst, &isochParamBlock);
if( err != noErr)
goto error;
}
}
#else
isochParamBlock.buffer = nil;
isochParamBlock.requestedCount = 120000; isochParamBlock.actualCount = 0;
isochParamBlock.refCon = (void *)theInst;
isochParamBlock.completionProc = DVIsochComponentReadCallback;
err = IDHRead( theInst, &isochParamBlock);
if( err != noErr)
goto error;
printf("Issued read\n");
while(!done)
sleep(1);
sleep(10);
printf("Did %d frames\n", done);
#endif
err = IDHCloseDevice( theInst);
if( err != noErr)
goto error;
printf("Closed device\n");
printf("Read %d bytes\n", isochParamBlock.actualCount);
if(isochParamBlock.actualCount)
{
int i,j;
UInt8 *p = (UInt8 *)isochParamBlock.buffer;
for(i=0; i<100; i++) {
printf("%d: ", i*40);
for(j=0; j<40; j++)
printf("%2x ",*p++);
printf("\n");
}
}
error:
return err;
}
static OSErr doWriteTest(ComponentInstance theInst)
{
Ptr myBuffer;
IDHParameterBlock isochParamBlock;
OSErr err;
err = IDHOpenDevice( theInst, kIDHOpenForWriteTransactions);
if( err != noErr)
goto error;
printf("Opened device\n");
myBuffer = NewPtrClear(120000);
file = open("/work/dinosaur.rawdv", O_RDONLY, 0666);
printf("open file: %d\n", file);
#if 0
{
int i;
for(i=0; i<1000; i++) {
file = open("/work/dinosaur.rawdv", O_RDONLY, 0666);
printf("open file: %d\n", file);
while(true) {
int len;
len = read(file, myBuffer, 120000);
if(len < 120000)
break;
isochParamBlock.buffer = myBuffer;
isochParamBlock.requestedCount = 120000; isochParamBlock.actualCount = 0;
isochParamBlock.refCon = (void *)0x12345678;
isochParamBlock.completionProc = 0;
err = IDHWrite( theInst, &isochParamBlock);
if( err != noErr)
goto error;
}
close(file);
file = open("/work/dinosaur.rawdv", O_RDONLY, 0666);
printf("open file: %d\n", file);
}
}
#else
#if WRITEBUFF
read(file, myBuffer, 120000);
isochParamBlock.buffer = myBuffer;
#else
isochParamBlock.buffer = nil;
#endif
isochParamBlock.requestedCount = 120000; isochParamBlock.actualCount = 0;
isochParamBlock.refCon = (void *)theInst;
isochParamBlock.completionProc = DVIsochComponentWriteCallback;
err = IDHWrite( theInst, &isochParamBlock);
if( err != noErr)
goto error;
printf("Issued write\n");
while(!done)
sleep(1);
sleep(100);
printf("Did %d frames\n", done);
#endif
err = IDHCloseDevice( theInst);
if( err != noErr)
goto error;
printf("Closed device\n");
error:
return err;
}
static void OpenDV()
{
ComponentInstance theInst;
ComponentResult version;
QTAtomContainer deviceList = NULL;
short nDVDevices, i, j;
QTAtom deviceAtom;
UInt32 cmpFlag;
UInt32 isoversion;
long size;
OSErr 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);
do {
err = IDHGetDeviceList( theInst, &deviceList);
if( err != noErr)
goto error;
nDVDevices = QTCountChildrenOfType( deviceList, kParentAtomIsContainer, kIDHDeviceAtomType);
if(nDVDevices > 0)
break;
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];
IDHDeviceID deviceID;
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;
}
printf("\n");
}
printf("-----\n");
}
if( videoConfig.atom == nil) goto error;
QTUnlockContainer( deviceList);
deviceList = NULL;
printf("setting config\n");
err = IDHSetDeviceConfiguration( theInst, &videoConfig);
if( err != noErr)
goto error;
#if 1
err = doReadTest(theInst);
#else
err = doWriteTest(theInst);
#endif
if( err != noErr)
goto error;
error:
if( err != noErr)
printf("error %d(0x%x)\n", err, err);
if(deviceList) {
QTUnlockContainer( deviceList);
}
CallComponentClose(theInst, 0);
}
int main(void)
{
UInt32 seed = GetComponentListModSeed();
UInt32 num;
Handle aName;
ComponentDescription desc, aDesc;
Component aComponent;
ComponentInstance theInst;
ComponentResult version;
printf("Component seed is %d\n", seed);
desc.componentType = 0;
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)) {
OSErr 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");
}
}
OpenDV();
return 0;
}