1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 ISOCHRONOUS COMPONENTS REFERENCE v1.0 3/16/2001 25 (INITIAL DOCUMENTATION - SUBJECT TO CHANGE) 26 27 28Header Files: IsochronousDataHandler.h, DeviceControl.h 29Framework: DVComponentGlue 30 31 32 33 34 35Component Types for Isoch Components 36------------------------------------ 37 38 #define kIDHComponentType 'ihlr' /* Component type*/ 39 #define kIDHSubtypeDV 'dv ' /* Subtype for DV (over FireWire)*/ 40 41 42 43Data Types for Isoch Components 44------------------------------- 45 46The callback function prototype: 47 48 typedef OSStatus (*IDHNotificationProc)(IDHGenericEvent *event, void *userData); 49 50 FieldDecriptions: 51 52 event - a IDHGenericEvent that is returned from the Isoch component. If this is an IDHRead() or 53 IDHWrite() notification function, then 'event' is the address of the IDHParameterBlock 54 that was passed to the IDHRead()/IDHWrite() call. 55 56 userData - If this is an IDHRead() or IDHWrite() notification function, the userData returned will 57 be the 'refCon' field of the IDHParameterBlock. Otherwise, it will be the value specified 58 in the IDHNewNotification() function. 59 60 61 62The parameter block passed to IDHRead() and IDHWrite(): 63 64 struct IDHParameterBlock { 65 UInt32 reserved1; /* reserved by Apple */ 66 UInt16 reserved2; /* reserved by Apple */ 67 void * buffer; /* buffer used in read/write operation */ 68 ByteCount requestedCount; /* bytes required to read/write */ 69 ByteCount actualCount; /* actual bytes read/written */ 70 IDHNotificationProc completionProc; /* called after read/write complete */ 71 void * refCon; /* user specified data */ 72 OSErr result; /* result of read/write */ 73 }; 74 75 Field Descriptions 76 77 reserved1, reserved2 - reserved by Apple 78 79 buffer - can contain an address of a user supplied buffer or 'nil'. 80 In reads: if 'buffer' is supplied, the data is read into the buffer 81 82 if 'buffer' is 'nil', a buffer address is returned in the completion proc 83 and the client has control of the buffer until it is released by 84 the IDHReleaseBuffer() function. NOTE: The buffer will remain valid for 85 an indeterminate amount of time. The client should USE the buffer ASAP to 86 guarantee data integrity 87 88 In writes: If 'buffer' is supplied, the data from the buffer is written to the 89 isoch device. 90 91 If 'buffer' is 'nil', a buffer address is supplied to the client on 92 callback. The client then writes his data into the buffer and returns 93 control to the IDH component. The data is then written to the device. 94 95 requestedCount - contains the number of bytes requested to read or write. 96 97 actualCount - the actual number of bytes read or written from/to the device. 98 99 completionProc - the routine that is called after read or write completion. If the completionProc 100 parameter is set to 'nil', the function becomes synchronous and does not return 101 until the read/write is complete. It is NOT possible to have a synchronous write/ 'nil' 102 buffer operation. 103 104 refCon - user data that is returned to the completion proc. 105 106 result - result of IDHRead()/IDHWrite() operation. 107 108 109Error Codes (see functions for actual meanings) 110----------------------------------------------- 111 112 #define kIDHErrDeviceDisconnected -14101 113 #define kIDHErrInvalidDeviceID -14102 114 #define kIDHErrDeviceInUse -14104 115 #define kIDHErrDeviceNotOpened -14105 116 #define kIDHErrDeviceReadError -14107 117 #define kIDHErrDeviceWriteError -14108 118 #define kIDHErrDeviceNotConfigured -14109 119 #define kIDHErrDeviceList -14110 120 #define kIDHErrCompletionPending -14111 121 #define kIDHErrDeviceTimeout -14112 122 #define kIDHErrInvalidIndex -14113 123 #define kIDHErrDeviceCantRead -14114 124 #define kIDHErrDeviceCantWrite -14115 125 126 127Isochronous Component Atoms 128--------------------------- 129 130 #define kIDHDeviceAtomType 'devc' /* QTAtom - contains the description for a device */ 131 #define kIDHDeviceIDType 'dvid' /* UInt32 - contains the device ID referenced in notification events */ 132 #define kIDHIsochServiceAtomType 'isoc' /* QTAtom - contains the isoch configs for a device */ 133 #define kIDHIsochModeAtomType 'mode' /* QTAtom - contains isoch configuration atoms */ 134 #define kIDHIsochVersionAtomType 'iver' /* UInt32 - contains the version of the isoch component */ 135 #define kIDHUseCMPAtomType 'ucmp' /* UInt32 - true when using CMP */ 136 #define kIDHUniqueIDType 'unid' /* variable size - contains a unique ID associated with device */ 137 #define kIDHNameAtomType 'name' /* Str255 - contains the name of the device */ 138 #define kIDHIsochMediaType 'av ' /* OSType - kIDHSoundMediaAtomType or kIDHVideoMediaAtomType */ 139 #define kIDHDataTypeAtomType 'dtyp' /* OSType - a configuration identifier */ 140 #define kIDHDefaultIOType 'dfio' /* UInt32 - set for default read or write config */ 141 #define kIDHDataSizeAtomType 'dsiz' /* UInt32 - the size of a frame of data */ 142 #define kIDHDataBufferSizeAtomType 'dbuf' /* UInt32 - the size of a packet of data*/ 143 #define kIDHDataIntervalAtomType 'intv' /* float - frame rate i.e. 29.97fps */ 144 #define kIDHDataIODirectionAtomType 'ddir' /* long - I/O direction associated with the device 145 kIDHDataTypeIsInput is 1 146 kIDHDataTypeIsOutput is 2 147 kIDHDataTypeIsInputAndOutput is 4 */ 148 #define kIDHSoundChannelCountAtomType 'ccnt' /* long - number of audio channels */ 149 #define kIDHSoundSampleSizeAtomType 'ssiz' /* long - number of bytes per sample of audio */ 150 #define kIDHSoundSampleRateAtomType 'srat' /* Fixed - audio sample rate */ 151 #define kIDHVideoDimensionsAtomType 'dimn' /* IDHDimension - pixel dimension of video */ 152 #define kIDHVideoResolutionAtomType 'resl' /* IDHResolution - DPI resolution */ 153 #define kIDHVideoRefreshRateAtomType 'refr' /* Fixed - video refresh rate */ 154 #define kIDHVideoPixelTypeAtomType 'pixl' /* OSType - Quicktime pixel type */ 155 #define kIDHVideoDecompressorTypeAtomType 'dety' /* OSType - Quicktime decompressor type */ 156 #define kIDHVideoDecompressorComponentAtomType 'cmpt' /* Component - Quicktime decompressor */ 157 158 Atom Layout 159 ----------- 160 deviceList - QTAtomContainer 161 kIDHIsochVersionAtomType (r) 162 kIDHUseCMPAtomType (r/w) 163 kIDHDeviceAtomType (r) 164 kIDHDeviceIDType (r) 165 kIDHUniqueIDType (r) 166 kIDHNameAtomType (r/w) 167 kIDHDefaultIOType (r/w) 168 kIDHIsochServiceAtomType (r) 169 kIDHIsochModeAtomType (r) 170 kIDHDataTypeAtomType (r) 171 kIDHDataSizeAtomType (r) 172 kIDHDataBufferSizeAtomType (r) 173 kIDHDataBufferSizeAtomType (r) 174 kIDHDataIntervalAtomType (r) 175 kIDHDataIODirectionAtomType (r) 176 kIDHSoundChannelCountAtomType (r) 177 kIDHSoundSampleSizeAtomType (r) 178 kIDHSoundSampleRateAtomType (r) 179 kIDHIsochModeAtomType (r) 180 kIDHDataTypeAtomType (r) 181 kIDHDataSizeAtomType (r) 182 kIDHDataBufferSizeAtomType (r) 183 kIDHDataBufferSizeAtomType (r) 184 kIDHDataIntervalAtomType (r) 185 kIDHDataIODirectionAtomType (r) 186 kIDHVideoDimensionsAtomType (r) 187 kIDHVideoResolutionAtomType (r) 188 kIDHVideoRefreshRateAtomType (r) 189 kIDHVideoPixelTypeAtomType (r) 190 kIDHVideoDecompressorTypeAtomType (r) 191 kIDHVideoDecompressorComponentAtomType (r) 192 kIDHDeviceAtomType 193 ... 194 195 Note: (r) - read only, (r/w) - read/write 196 197 198Device Status Structure 199 200 struct IDHDeviceStatus { 201 UInt32 version; /* version of structure */ 202 Boolean physicallyConnected; /* device is connected and active */ 203 Boolean readEnabled; /* device has been enabled for read */ 204 Boolean writeEnabled; /* device has been enabled for writing */ 205 Boolean exclusiveAccess; /* a client has opened device for exclusive access */ 206 UInt32 currentBandwidth; /* ??? */ 207 UInt32 currentChannel; /* ??? */ 208 PsuedoID localNodeID; /* the ID associated with this device */ 209 SInt16 inputStandard; /* ntscIn is 0 or palIn is 1 */ 210 Boolean deviceActive; /* device is being used by another client */ 211 }; 212 213 214 215Notification Structures 216 217 218 struct IDHEventHeader { 219 IDHDeviceID deviceID; /* a unique device ID */ 220 IDHNotificationID notificationID; /* notification ID associated this callback */ 221 IDHEvent event; /* The event */ 222 }; 223 224 struct IDHGenericEvent { 225 IDHEventHeader eventHeader; /* as described above */ 226 UInt32 pad[4]; 227 }; 228 229 struct IDHDeviceConnectionEvent { 230 IDHEventHeader eventHeader; 231 }; 232 233 struct IDHDeviceIOEnableEvent { 234 IDHEventHeader eventHeader; 235 }; 236 237 238Notification Events 239 240 #define kIDHEventInvalid 0, 241 #define kIDHEventDeviceAdded 1L << 0 /* Uses IDHDeviceConnectionEvent*/ 242 #define kIDHEventDeviceRemoved 1L << 1 /* Uses IDHDeviceConnectionEvent*/ 243 #define kIDHEventDeviceChanged 1L << 2 /* Uses ????*/ 244 #define kIDHEventReadEnabled 1L << 3 /* Uses IDHDeviceIOEnableEvent*/ 245 #define kIDHEventReserved1 1L << 4 /* Reserved for future use*/ 246 #define kIDHEventReadDisabled 1L << 5 /* Uses IDHDeviceIOEnableEvent*/ 247 #define kIDHEventWriteEnabled 1L << 6 /* Uses IDHDeviceIOEnableEvent*/ 248 #define kIDHEventReserved2 1L << 7 /* Reserved for future use*/ 249 #define kIDHEventWriteDisabled 1L << 8 /* Uses IDHDeviceIOEnableEvent*/ 250 #define kIDHEventEveryEvent (long)0xFFFFFFFF 251 252 253 254 255 Isochronous Component Functions 256 =============================== 257 258Getting device information and choosing a device 259 260IDHGetDeviceList 261---------------- 262 263 The IDHGetDeviceList function returns an atom list of the devices that are currently active. 264 265 pascal ComponentResult IDHGetDeviceList( ComponentInstance idh, QTAtomContainer *deviceList) 266 267 idh - Specifies the IDH component for operation. You can obtain this identifier from the 268 ComponentManager's OpenComponent() function. 269 270 deviceList - An atom container that describes each of the devices that support this isoch component. 271 The atom structure is defined above. The user must free this atom container using 272 QTRemoveChildren() and QTDisposeAtomContainer() when finished. 273 274 Result Codes: 275 Quicktime error codes 276 277IDHUpdateDeviceList 278------------------- 279 280 The IDHUpdateDeviceList function allows the client to change certain atoms within the internal atom list. 281 282 pascal ComponentResult IDHUpdateDeviceList( ComponentInstance idh, QTAtomContainer *deviceList) 283 284 idh - Specifies the IDH component for operation. You can obtain this identifier from the 285 ComponentManager's OpenComponent() function. 286 287 deviceList - An atom container that was returned from IDHGetDeviceList(). The client has modified one 288 or more atoms identified as (r/w). 289 290 Result Codes: 291 kIDHErrDeviceList The device list is either stale or corrupt. Please IDHGetDeviceList(). 292 Quicktime error codes 293 294IDHSetDeviceConfiguration 295------------------------- 296 297 The IDHSetDeviceConfiguration function allows the user to choose a specific configuration of a device 298 for reads or writes. The configuration structure is defined in the atom description above. 299 300 pascal ComponentResult IDHSetDeviceConfiguration( ComponentInstance idh, const QTAtomSpec *configurationID) 301 302 idh - Specifies the IDH component for operation. You can obtain this identifier from the 303 ComponentManager's OpenComponent() function. 304 305 configurationID - Specifies the requested configuration. The user passes an QTAtomSpec which is 306 an atom container/ kIDHIsochModeAtomType atom pair. NOTE: The user must NOT dispose 307 of the device list (requested by IDHGetDeviceList()) until he is through with this 308 configuration. 309 310 Result Codes: 311 kIDHErrDeviceInUse Another device has already been opened. Please IDHCloseDevice(). 312 kIDHErrDeviceList The device list is either stale or corrupt. Please IDHGetDeviceList(). 313 kIDHErrInvalidDeviceID Internal Error 314 kAlreadyEnabledErr Device control has already been enabled on this device 315 kNotEnabledErr Device control is not enabled 316 317IDHGetDeviceConfiguration 318------------------------- 319 320 The IDHGetDeviceConfiguration function returns the configuration that the client set using the 321 IDHSetDeviceConfiguration() call. 322 323 pascal ComponentResult IDHGetDeviceConfiguration( ComponentInstance idh, QTAtomSpec *configurationID) 324 325 idh - Specifies the IDH component for operation. You can obtain this identifier from the 326 ComponentManager's OpenComponent() function. 327 328 configurationID - Contains the previously specified configuration. The function returns an QTAtomSpec 329 which is an atom container/ kIDHIsochModeAtomType atom pair. NOTE: The user must NOT 330 dispose the device list (requested by IDHGetDeviceList()) until he is through with this 331 configuration. 332 333 Result Codes: 334 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 335 336 337Opening and closing a device 338 339IDHOpenDevice 340------------- 341 342 The IDHOpenDevice function opens the currently configured device. 343 344 pascal ComponentResult IDHOpenDevice( ComponentInstance idh, UInt32 permissions) 345 346 idh - Specifies the IDH component for operation. You can obtain this identifier from the 347 ComponentManager's OpenComponent() function. 348 349 permissions - The user specifies a combination of the following flags when opening a device. 350 351 kIDHOpenForReadTransactions - Indicates that the device will be opened for reads. The value of 352 this flag is 1. One or more clients can open a device for reads unless a client specifies 353 the kIDHOpenWithExclusiveAccess flag. 354 355 kIDHOpenForWriteTransactions - Indicates that the device will be opened for writes. The value of 356 this flag is 0x2. Note: Only one client can open a device for writes. 357 358 kIDHOpenWithExclusiveAccess - Indicates that the device cannot be opened by another client. The 359 value of this flag is 0x4. 360 361 Result Codes: 362 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 363 kIDHErrInvalidDeviceID Internal Error 364 kIDHErrDeviceInUse Device has been exclusively opened by another client. Or it has already been 365 in another state. 366 kIDHErrInvalidIndex Internal Error 367 368IDHCloseDevice 369-------------- 370 371 The IDHCloseDevice function closes the previously opened IDH device. 372 373 pascal ComponentResult IDHCloseDevice( ComponentInstance idh) 374 375 idh - Specifies the IDH component for operation. You can obtain this identifier from the 376 ComponentManager's OpenComponent() function. 377 378 Result Codes: 379 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 380 kIDHErrInvalidDeviceID Internal Error 381 kIDHErrDeviceNotOpened A device has not been opened 382 383 384Device I/O 385 386IDHRead 387------- 388 389 The IDHRead function reads data from the currently opened device configuration. 390 391 pascal ComponentResult IDHRead( ComponentInstance idh, IDHParameterBlock *pb) 392 393 idh - Specifies the IDH component for operation. You can obtain this identifier from the 394 ComponentManager's OpenComponent() function. 395 396 pb - Specifies the address of a IDHParameterBlock structure. Each of the fields are described in detail 397 in a previous section. The user should keep the IDHParameterBlock around until the completion routine 398 is called. NOTE: On a 'nil' buffer read, the buffer will remain valid for an indeterminate 399 amount of time. The client should USE the buffer ASAP to guarantee data integrity. 400 401 Result Codes: 402 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 403 kIDHErrInvalidDeviceID Internal Error 404 kIDHErrDeviceTimeout Timeout on synchronous read 405 406 407IDHWrite 408-------- 409 410 The IDHWrite function writes data to the currently opened device configuration. 411 412 pascal ComponentResult IDHWrite( ComponentInstance idh, IDHParameterBlock *pb) 413 414 idh - Specifies the IDH component for operation. You can obtain this identifier from the 415 ComponentManager's OpenComponent() function. 416 417 pb - Specifies the address of a IDHParameterBlock structure. Each of the fields are described in detail 418 in a previous section. The user should keep the IDHParameterBlock around until the completion routine 419 is called. 420 421 Result Codes: 422 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 423 kIDHErrInvalidDeviceID Internal Error 424 kIDHErrDeviceTimeout Timeout on synchronous read 425 426IDHReleaseBuffer 427---------------- 428 429 The IDHReleaseBuffer function releases a buffer returned from an IDHRead() request where 430 the client specified a 'nil' buffer. 431 432 pascal ComponentResult IDHReleaseBuffer( ComponentInstance idh, IDHParameterBlock *pb) 433 434 idh - Specifies the IDH component for operation. You can obtain this identifier from the 435 ComponentManager's OpenComponent() function. 436 437 pb - Specifies the address of the IDHParameterBlock structure that was originally passed into 438 IDHRead() function. NOTE: The buffer will remain valid for an indeterminate amount of time. 439 The client should USE the buffer ASAP to guarantee data integrity. 440 441 Result Codes: 442 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 443 kIDHErrInvalidDeviceID Internal Error 444 445IDHCancelPendingIO 446------------------ 447 448 The IDHCancelPendingIO function cancels any outstanding IDHRead() or IDHWrite() requests. This 449 should be called prior to closing a device. 450 451 pascal ComponentResult IDHCancelPendingIO( ComponentInstance idh, IDHParameterBlock *pb) 452 453 idh - Specifies the IDH component for operation. You can obtain this identifier from the 454 ComponentManager's OpenComponent() function. 455 456 pb - Specifies the address of the IDHParameterBlock structure that was originally passed into 457 IDHRead() or IDHWrite() function. 458 459 Result Codes: 460 Macintosh errors 461 462 463Getting device status 464 465IDHGetDeviceStatus 466------------------ 467 468 The IDHGetDeviceStatus function gets the device status from the specified device configuration. 469 470 pascal ComponentResult IDHGetDeviceStatus( ComponentInstance idh, const QTAtomSpec *configurationID, 471 IDHDeviceStatus *status) 472 473 idh - Specifies the IDH component for operation. You can obtain this identifier from the 474 ComponentManager's OpenComponent() function. 475 476 configurationID - The user passes an QTAtomSpec which is an atom container/ kIDHIsochModeAtomType atom 477 pair. NOTE: The user must NOT dispose of the device list (requested by IDHGetDeviceList()) 478 until he is through with this configuration. 479 480 status - The address of a IDHDeviceStatus structure. The specified device status will be returned. Each 481 of the status fields are described in detail above. 482 483 Result Codes: 484 kIDHErrDeviceList The device list is either stale or corrupt. Please IDHGetDeviceList(). 485 kIDHErrInvalidDeviceID Internal Error 486 487 488 489Device Notification 490 491IDHNewNotification 492------------------ 493 494 The IDHNewNotification function creates a notification ID which is used to initiate client notification 495 based on device events. 496 497 pascal ComponentResult IDHNewNotification( ComponentInstance idh, IDHDeviceID deviceID, 498 IDHNotificationProc notificationProc, void *userData, 499 IDHNotificationID *notificationID) 500 501 idh - Specifies the IDH component for operation. You can obtain this identifier from the 502 ComponentManager's OpenComponent() function. 503 504 deviceID - the value of a devices kIDHDeviceIDType atom or kIDHDeviceIDEveryDevice. 505 506 notificationProc - the client function that is called when a particular event has taken place 507 508 userData - the client specified data returned to the client notificationProc. 509 510 notificationID - this parameter is returned to the client and used in other IDH functions. 511 512 Result Codes: 513 Macintosh errors 514 515IDHNotifyMeWhen 516--------------- 517 518 The IDHNotifyMeWhen function actually enables the notification process. When one of the client specified 519 events occur, the client will be notified through his notification function. NOTE: This function is 520 a one shot. The function must be called again after the event(s) have occured to re-enable the 521 notification. 522 523 pascal ComponentResult IDHNotifyMeWhen( ComponentInstance idh, IDHNotificationID notificationID, 524 IDHEvent events) 525 526 527 idh - Specifies the IDH component for operation. You can obtain this identifier from the 528 ComponentManager's OpenComponent() function. 529 530 notificationID - this parameter is obtained by calling IDHNewNotification. 531 532 events - one or more flags that the client uses to specify the device events of interest 533 kIDHEventDeviceAdded - Indicates that a new device has been added to the computer. The value of this 534 flag is 1. 535 536 kIDHEventDeviceRemoved - Indicates that a device has been removed from the computer. The value of this 537 flag is 2. 538 539 kIDHEventDeviceChanged - Indicates that a device is ???. The value of this flag is 4. 540 541 kIDHEventReadEnabled - Indicates that a device has been enabled for read. The value of this flag 542 is 8. 543 544 kIDHEventReadDisabled - Indicates that a device has been disabled for read. The value of this flag 545 is 32. 546 547 kIDHEventWriteEnabled - Indicates that a device has been enabled for write. The value of this flag 548 is 64. 549 550 kIDHEventWriteDisabled - Indicates that a device has been disabled for write. The value of this flag 551 is 256. 552 553 Result Codes: 554 Macintosh Errors 555 556 557IDHCancelNotification 558--------------------- 559 560 The IDHCancelNotification function cancels an outstanding IDHNotifyMeWhen() request. This function 561 should be called prior to exiting to avoid spurious calls to the client callback. 562 563 pascal ComponentResult IDHCancelNotification( ComponentInstance idh, IDHNotificationID notificationID) 564 565 idh - Specifies the IDH component for operation. You can obtain this identifier from the 566 ComponentManager's OpenComponent() function. 567 568 notificationID - this parameter is obtained by calling IDHNewNotification() and used in IDHNotifyMeWhen(). 569 570 Result Codes: 571 Macintosh Errors 572 573IDHDisposeNotification 574---------------------- 575 576 The IDHDisposeNotification function releases the resources associated with the IDHNotificationID. This 577 function should be called before closing the isoch component. 578 579 pascal ComponentResult IDHDisposeNotification( ComponentInstance idh, IDHNotificationID notificationID) 580 581 idh - Specifies the IDH component for operation. You can obtain this identifier from the 582 ComponentManager's OpenComponent() function. 583 584 notificationID - this parameter is obtained by calling IDHNewNotification(). 585 586 Result Codes: 587 Macintosh Errors 588 589 590 591Other functions 592 593IDHGetDeviceClock 594----------------- 595 596 The IDHGetDeviceClock function returns a bus specific clock component used in audio/video 597 synchronization. The client should read the Quicktime documentation for information about 598 a Clock Component. The Clock component is used in other Quicktime functions such as video out. 599 600 pascal ComponentResult IDHGetDeviceClock( ComponentInstance idh, Component *clock) 601 602 idh - Specifies the IDH component for operation. You can obtain this identifier from the 603 ComponentManager's OpenComponent() function. 604 605 clock - returns the Clock component associated with this IDH component. 606 607 Result Codes: 608 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 609 610IDHGetDeviceControl 611------------------- 612 613 The IDHGetDeviceControl function returns an instance to a device control component associated with 614 the device that was most recently set with IDHSetDeviceConfiguration. See the device control component 615 documentation for more details. 616 617 pascal ComponentResult IDHGetDeviceControl( ComponentInstance idh, ComponentInstance *deviceControl) 618 619 idh - Specifies the IDH component for operation. You can obtain this identifier from the 620 ComponentManager's OpenComponent() function. 621 622 deviceControl - returns an instance of a device control component. 623 624 Result Codes: 625 kIDHErrDeviceNotConfigured A device has not already been selected using IDHSetDeviceConfiguration() 626 kIDHErrInvalidDeviceID Internal Error 627 628 629 Device Control Component Reference 630 ================================== 631 632Component Types for Device Control Components 633------------------------------------ 634 635 #define kDVCComponentType 'devc' /* Component type*/ 636 #define kDVCSubtypeDV 'fwdv' /* Subtype for DV (over FireWire)*/ 637 638 639 640Data Types for Device Control Components 641------------------------------- 642 643The parameter block passed to DeviceControlDoAVCTransaction(): 644 645typedef UInt32 DCResponseHandler(UInt32 fwCommandObjectID, Ptr responseBuffer, UInt32 responseLength); 646struct DVCTransactionParams { 647 Ptr commandBufferPtr; /* pointer to AVC command bytes */ 648 UInt32 commandLength; /* command length in bytes */ 649 Ptr responseBufferPtr; /* pointer to buffer to store AVC response */ 650 UInt32 responseBufferSize; /* response buffer size in bytes */ 651 DCResponseHandler * responseHandler; /* Function to call when device sends response - IGNORED in X 1.0 */ 652}; 653typedef struct DVCTransactionParams DVCTransactionParams; 654 655 656 Device Control Component Functions 657 =============================== 658DeviceControlDoAVCTransaction 659----------------------------- 660 661 The DeviceControlDoAVCTransaction transaction sends an AV/C command to the device and returns the response sent by the device. Documentation on AV/C command and response formats is available from the 1394 Trade Association (www.1394TA.org) 662 663 ComponentResult DeviceControlDoAVCTransaction(ComponentInstance instance, DVCTransactionParams * params) 664 665 instance - specifies the device control component for operation. Obtained from IDHGetDeviceControl(). 666 params - parameter block for call. 667 668 SAMPLE CODE 669 =========== 670 671 672 NOTE - The isoch component requires QT 4.0 headers and libraries. 673 674 Opening a DV isoch component 675 ---------------------------- 676 677 ComponentDescription compDesc; 678 Component isochComponent; 679 ComponentInstance isochInstance; 680 681 compDesc.componentType = kIDHComponentType; 682 compDesc.componentSubType = kIDHSubtypeDV; 683 compDesc.componentManufacturer = 0; 684 compDesc.componentFlags = 0; 685 compDesc.componentFlagsMask = kAnyComponentFlagsMask; 686 687 isochComponent = FindNextComponent( nil, &compDesc); 688 if( isochComponent == nil) 689 goto error; 690 691 isochInstance = OpenComponent( isochComponent); 692 if( isochInstance == nil) 693 goto error; 694 695 696 Finding the first video device in the list 697 ------------------------------------------ 698 699 QTAtomContainer deviceList; 700 short nDVDevices, i, j, nConfigs; 701 QTAtom deviceAtom, isochAtom; 702 QTAtomSpec currentIsochConfig; 703 704 err = IDHGetDeviceList( isochInstance, &deviceList); 705 if( err != noErr) 706 goto err; 707 708 nDVDevices = QTCountChildrenOfType( deviceList, kParentAtomIsContainer, kIDHDeviceAtomType); 709 710 for( i=0; i<nDVDevices; ++i) 711 { 712 QTAtom deviceAtom, isochAtom; 713 int nConfigs; 714 715 // get the atom to this device 716 deviceAtom = QTFindChildByIndex( deviceList, kParentAtomIsContainer, kIDHDeviceAtomType, i + 1, nil); 717 if( deviceAtom == nil) 718 goto error; 719 720 // find the isoch characteristics for this device 721 isochAtom = QTFindChildByIndex( deviceList, deviceAtom, kIDHIsochServiceAtomType, 1, nil); 722 if( isochAtom == nil) 723 goto error; 724 725 // how many configs exist for this device 726 nConfigs = QTCountChildrenOfType( deviceList, isochAtom, kIDHIsochModeAtomType); 727 728 currentIsochConfig.atom = nil; // start with no selected config 729 730 // process each config 731 for( j=0; j<nConfigs; ++j) 732 { 733 OSType mediaType; 734 long size; 735 QTAtom configAtom, mediaAtom; 736 737 // get this configs atom 738 configAtom = QTFindChildByIndex( deviceList, isochAtom, kIDHIsochModeAtomType, j + 1, nil); 739 if( configAtom == nil) 740 goto error; 741 742 // find the media type atom 743 mediaAtom = QTFindChildByIndex( deviceList, configAtom, kIDHIsochMediaType, 1, nil); 744 if( mediaAtom == nil) 745 goto error; 746 747 QTLockContainer( deviceList); 748 749 // get the value of the mediaType atom 750 QTCopyAtomDataToPtr( deviceList, mediaAtom, true, sizeof( mediaType), &mediaType, &size); 751 752 QTUnlockContainer( deviceList); 753 754 // is this config an video config? 755 if( mediaType == kIDHVideoMediaAtomType) // found video device 756 { 757 currentIsochConfig.container = deviceList; // save this config 758 currentIsochConfig.atom = configAtom; 759 break; 760 } 761 } 762 763 if( currentIsochConfig.atom != nil) // did we find a video config? 764 break; 765 } 766 767 if( currentIsochConfig.atom == nil) // no good configs found 768 goto error; 769 770 Setting a configuration and opening a device for reading 771 -------------------------------------------------------- 772 773 // set isoch to use this config 774 err = IDHSetDeviceConfiguration( isochInstance, ¤tIsochConfig); 775 if( err != noErr) 776 goto error; 777 778 // open the DV device 779 err = IDHOpenDevice( isochInstance, kIDHOpenForReadTransactions); 780 if( err != noErr) 781 goto Exit); 782 783 Reading from a device (client supplies buffer) 784 ---------------------------------------------- 785 786 // we are doing isoch reads with only one buffer at a time 787 isochParamBlock.buffer = myBuffer; 788 isochParamBlock.requestedCount = 120000; // NTSC buffer size 789 isochParamBlock.actualCount = 0; 790 isochParamBlock.completionProc = DVIsochComponentReadCallback; 791 isochParamBlock.refCon = iGlobals; 792 793 err = IDHRead( isochInstance, &isochParamBlock); 794 if( err != noErr) 795 goto error; 796 797 Callback from read request (client supplies buffer) 798 --------------------------------------------------- 799 800 // called when a new isoch read is received 801 OSStatus DVIsochComponentReadCallback( IDHGenericEvent *eventRecord, void *userData) 802 { 803 OSErr result = noErr; 804 ComponentInstancePtr iGlobals = userData; 805 IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord; 806 807 // fill out structure 808 pb->buffer = myBuffer; 809 pb->requestedCount = 120000; 810 pb->actualCount = 0; 811 pb->completionProc = DVIsochComponentReadCallback; 812 pb->refCon = iGlobals; 813 814 // do another read 815 result = IDHRead( isochInstance, pb); 816 if( result != noErr) 817 goto error; 818 819 error: 820 return result; 821 } 822 823 Reading from a device (isoch component supplies buffer) 824 ------------------------------------------------------- 825 826 // we are doing isoch reads with only one buffer at a time 827 isochParamBlock.buffer = nil; 828 isochParamBlock.requestedCount = 120000; // NTSC buffer size 829 isochParamBlock.actualCount = 0; 830 isochParamBlock.completionProc = DVIsochComponentReadCallback; 831 isochParamBlock.refCon = iGlobals; 832 833 err = IDHRead( isochInstance, &isochParamBlock); 834 if( err != noErr) 835 goto error; 836 837 Callback from read request (isoch component supplies buffer) 838 ------------------------------------------------------------ 839 840 // called when a new isoch read is received 841 OSStatus DVIsochComponentReadCallback( IDHGenericEvent *eventRecord, void *userData) 842 { 843 OSErr result = noErr; 844 ComponentInstancePtr iGlobals = userData; 845 IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord; 846 847 WorkOnData( pb->buffer, pb->actualCount); 848 849 result = IDHReleaseBuffer( isochInstance, pb); 850 if( result != noErr) 851 goto error; 852 853 // fill out structure 854 pb->buffer = nil; 855 pb->requestedCount = 120000; 856 pb->actualCount = 0; 857 pb->completionProc = DVIsochComponentReadCallback; 858 pb->refCon = iGlobals; 859 860 // do another read 861 result = IDHRead( isochInstance, pb); 862 if( result != noErr) 863 goto error; 864 865 error: 866 return result; 867 } 868 869 Writing to device (client supplies the buffer) 870 ---------------------------------------------- 871 872 // we are doing isoch reads with only one buffer at a time 873 isochParamBlock.buffer = myBuffer; 874 isochParamBlock.requestedCount = 120000; // NTSC buffer size 875 isochParamBlock.actualCount = 0; 876 isochParamBlock.completionProc = DVIsochComponentWriteCallback; 877 isochParamBlock.refCon = iGlobals; 878 879 err = IDHWrite( isochInstance, &isochParamBlock); 880 if( err != noErr) 881 goto error; 882 883 Callback from write request (client supplies the buffer) 884 -------------------------------------------------------- 885 886 // called when a new isoch read is received 887 OSStatus DVIsochComponentWriteCallback( IDHGenericEvent *eventRecord, void *userData) 888 { 889 OSErr result = noErr; 890 ComponentInstancePtr iGlobals = userData; 891 IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord; 892 893 // fill out structure 894 isochParamBlock.buffer = myBuffer; 895 isochParamBlock.requestedCount = 120000; // NTSC buffer size 896 isochParamBlock.actualCount = 0; 897 isochParamBlock.completionProc = DVIsochComponentWriteCallback; 898 isochParamBlock.refCon = iGlobals; 899 900 // do another read 901 result = IDHWrite( isochInstance, pb); 902 if( result != noErr) 903 goto error; 904 905 error: 906 return result; 907 } 908 909 Writing to device (isoch component supplies the buffer) 910 ------------------------------------------------------- 911 912 // we are doing isoch reads with only one buffer at a time 913 isochParamBlock.buffer = nil; 914 isochParamBlock.requestedCount = 120000; // NTSC buffer size 915 isochParamBlock.actualCount = 0; 916 isochParamBlock.completionProc = DVIsochComponentWriteCallback; 917 isochParamBlock.refCon = iGlobals; 918 919 err = IDHWrite( isochInstance, &isochParamBlock); 920 if( err != noErr) 921 goto error; 922 923 Callback from write request (isoch component supplies the buffer) 924 ----------------------------------------------------------------- 925 926 // called when a new isoch read is received 927 OSStatus DVIsochComponentWriteCallback( IDHGenericEvent *eventRecord, void *userData) 928 { 929 OSErr result = noErr; 930 ComponentInstancePtr iGlobals = userData; 931 IDHParameterBlock *pb = (IDHParameterBlock *) eventRecord; 932 933 BlockMove( myBuffer, pb->buffer, 120000); 934 935 // fill out structure 936 isochParamBlock.buffer = nil; 937 isochParamBlock.requestedCount = 120000; // NTSC buffer size 938 isochParamBlock.actualCount = 0; 939 isochParamBlock.completionProc = DVIsochComponentWriteCallback; 940 isochParamBlock.refCon = iGlobals; 941 942 // do another read 943 result = IDHWrite( isochInstance, pb); 944 if( result != noErr) 945 goto error; 946 947 error: 948 return result; 949 } 950 951 Closing down the isoch device 952 ----------------------------- 953 954 result = IDHCancelPendingIO( isochInstance, &isochParamBlock); 955 956 result = IDHCloseDevice( isochInstance); 957 958 CloseComponent( isochInstance); // close isoch component 959 960 961 Writing a device control command to a device 962 -------------------------------------------- 963 964 ComponentInstance deviceControlInstance; 965 966 result = IDHGetDeviceControl( isochInstance, &deviceControlInstance); 967 if( result != noErr) 968 goto error; 969 970 result = DeviceControlDoAVCTransaction( deviceControlInstance, (DVCTransactionParams *) pParams); 971 if( result != noErr) 972 goto error; 973 974 975 Setting up notification for a device being enabled for reads 976 ------------------------------------------------------------ 977 deviceNotificationID = 0; 978 result = IDHNewNotification( isochInstance, kIDHDeviceIDEveryDevice, DVDeviceCallback, 979 (void *) iGlobals, &deviceNotificationID); 980 if( result != noErr) 981 goto error; 982 983 result = IDHNotifyMeWhen( isochInstance, deviceNotificationID, kIDHEventReadEnabled); 984 if( result != noErr) 985 goto error; 986 987 988 Getting called on a notification event 989 -------------------------------------- 990 OSStatus DVDeviceCallback( IDHGenericEvent *event, void *userData) 991 { 992 switch( event->eventHeader.event) 993 { 994 case kIDHEventReadEnabled: 995 deviceHasBeenReadEnabled( event); 996 break; 997 } 998 } 999