#include <IOKit/IOKitLib.h>
#include <IOKit/firewire/IOFireWireLib.h>
#include <IOKit/avc/IOFireWireAVCLib.h>
#define kDVMaxDevicesActive 64 // max devices on firewire bus
#define kDVMaxStreamsActive 64 // max isoc channels on fw bus
#define kLogSize 20
typedef struct _Log {
UInt32 tag;
CFAbsoluteTime start;
CFAbsoluteTime end;
} Log;
typedef struct _syncStruct
{
pthread_mutex_t fMutex; pthread_cond_t fSyncCond; } ThreadSyncer;
typedef struct _DVThread DVThread;
struct DVGlobalOutStruct;
typedef struct DVGlobalOutStruct DVGlobalOut, *DVGlobalOutPtr;
struct DVGlobalInStruct;
typedef struct DVGlobalInStruct DVGlobalIn, *DVGlobalInPtr;
typedef struct _DVDevice
{
DVThread *fThread;
io_object_t fObject;
IOFireWireLibDeviceRef fDevInterface;
IOFireWireAVCLibUnitInterface **fAVCInterface;
IOFireWireAVCLibProtocolInterface **fAVCProtoInterface;
UInt64 fGUID;
char fName[256];
UInt32 fOutPlug;
UInt32 fDVFormats; UInt8 standard; UInt8 fWriteChan; UInt8 fReadChan; UInt8 fMaxSpeed; bool fSupportsFCP; UInt8 p2pConnected;
UInt32 p2pPlug;
UInt32 p2pChan;
UInt32 deviceIndex; } DVDevice;
typedef void (*DVDeviceArrivedFunc)(void *refcon, DVDevice *device, UInt32 index, UInt32 refound);
struct _DVThread
{
pthread_t fRTThread; pthread_t fRLThread; IONotificationPortRef fNotifyPort; CFRunLoopSourceRef fNotifySource; #if 0
CFRunLoopSourceRef fRequestSource; CFRunLoopTimerRef fTimerSource;
#else
mach_port_t fRequestMachPort; CFRunLoopTimerCallBack fTimerFunc; void * fTimerRefCon;
#endif
CFRunLoopRef fWorkLoop;
io_iterator_t fMatchEnumer; io_iterator_t fTermEnumer; DVDeviceArrivedFunc fAddedFunc;
void * fAddedRefCon;
IOServiceMatchingCallback fRemovedFunc;
void * fRemovedRefCon;
IOFWAVCMessageCallback fDeviceMessage;
pthread_mutex_t fRequestMutex;
ThreadSyncer fRequestSyncer;
UInt32 fSyncRequest; IOReturn (*fRequestFunc)(void *arg, UInt32 param);
void * fRequestArg;
UInt32 fRequestParam;
IOReturn fRequestResult;
UInt32 fNumDevices;
DVDevice fDevices[kDVMaxDevicesActive];
CFAbsoluteTime setTimeoutTime;
CFAbsoluteTime requestTimeoutTime;
DVGlobalOut * fOutStreams[kDVMaxStreamsActive];
DVGlobalIn * fInStreams[kDVMaxStreamsActive];
UInt32 fLogPos;
Log fLog[kLogSize];
io_object_t fPowerManagementNotifier;
IONotificationPortRef fPowerNotifyPort;
CFRunLoopSourceRef fPowerNotifySource;
io_connect_t fPowerNotifyConnect;
};
enum {
kNumPlayBufferGroups = 6, kDVMaxFrames = 20 };
enum {
kEmpty = 0,
kReading = 1,
kWriting = 2,
kReady = 3,
};
typedef struct _DVSharedVars {
UInt32 fNumGroups; UInt32 fGroupSize; UInt32 fAlignedPacketSize; UInt32 fPacketDataSize; UInt32 fDMAPos; volatile UInt32 * fTimeStampPtrs; UInt32 fDataOffset[kNumPlayBufferGroups]; } DVSharedVars;
typedef struct _DVFrameVars {
volatile UInt32 fReader;
volatile UInt32 fWriter;
volatile UInt32 fDroppedFrames;
volatile UInt32 fStatus;
volatile UInt32 fFrameSize[kDVMaxFrames];
volatile UInt8 fFrameStandard[kDVMaxFrames];
volatile UInt32 fFrameTime[kDVMaxFrames];
volatile UInt8 fFrameStatus[kDVMaxFrames];
UInt32 fNumFrames;
UInt8 * fFrames;
} DVFrameVars;
extern DVThread * DVCreateThread(DVDeviceArrivedFunc deviceAdded, void * addedRefCon,
CFRunLoopTimerCallBack timerTick, void *timerRefCon, IOFWAVCMessageCallback deviceMessage);
extern void DVRunThread(DVThread *thread);
extern void DVFreeThread(DVThread *thread);
extern void DVSetTimeoutTime(DVThread * dvThread, CFAbsoluteTime fireDate);
extern void DVSignalSync(ThreadSyncer *sync, UInt32 *var, UInt32 val);
extern void DVWaitSync(ThreadSyncer *sync, UInt32 *var);
extern void DVLock(ThreadSyncer *sync);
extern void DVUnlock(ThreadSyncer *sync);
extern IOReturn DVRequest(DVThread *thread, IOReturn (*func)(void *arg, UInt32 param), void *arg, UInt32 param);
extern IOReturn openFireWireUnit(IOFireWireAVCLibUnitInterface **avcInterface, IOFireWireSessionRef session, IOFireWireLibDeviceRef *retInterface, DVThread *thread);
extern IOReturn openAVCUnit(io_object_t obj, IOFireWireAVCLibUnitInterface ***retInterface, DVThread *thread);
extern IOReturn openAVCProto(IOFireWireAVCLibUnitInterface **avcInterface, IOFireWireAVCLibProtocolInterface ***retInterface, DVThread *thread);
extern IOReturn DVDeviceInit(DVThread *thread, DVDevice *device,
io_object_t obj, IOServiceInterestCallback deviceMessage, void * refCon);
extern void DVDeviceTerminate(DVDevice *device);
extern IOReturn DVDeviceOpen(DVThread *thread, DVDevice *device);
extern void DVDeviceClose(DVDevice *device);
extern DVGlobalOutPtr DVAllocWrite(DVDevice *device, DVThread *thread);
extern IOReturn DVWriteSetSignalMode(DVGlobalOutPtr globs, UInt8 mode);
extern IOReturn DVWriteAllocFrames(DVGlobalOutPtr globs, UInt32 numFrames,
DVFrameVars **frameVars, UInt8 **frames);
extern UInt8 * DVWriteGetDCLBuffer(DVGlobalOutPtr globs, DVSharedVars **varPtr);
extern IOReturn DVWriteStart(DVGlobalOutPtr globs);
extern void DVWriteStop(DVGlobalOutPtr globs);
extern void DVWriteFreeFrames(DVGlobalOutPtr globs);
extern void DVWriteFree(DVGlobalOutPtr globs);
extern DVGlobalInPtr DVAllocRead(DVDevice *device, DVThread *thread);
extern IOReturn DVReadSetSignalMode(DVGlobalInPtr globs, UInt8 mode);
extern IOReturn DVReadAllocFrames(DVGlobalInPtr globs, UInt32 numFrames,
DVFrameVars **frameVars, UInt8 **frames);
extern IOReturn DVReadStart(DVGlobalInPtr globs);
extern void DVReadStop(DVGlobalInPtr globs);
extern void DVReadFreeFrames(DVGlobalInPtr globs);
extern void DVReadFree(DVGlobalInPtr globs);
extern void DVSilenceFrame(UInt8 mode, UInt8* frame);
extern void DVLog(DVThread *thread, UInt32 tag, CFAbsoluteTime start, CFAbsoluteTime end);
extern void DVDumpLog(DVThread *thread);