|
|
API Documentation
Our public API is in VDigProperty.h
and VDigProperty.cp
The intent of the extended property API is to provide more video parameters
than the seven defined by the original 'vdig' API. To this end we've defined
calls with exactly the same semantics as VDGet/SetBrightness, etc. and
VDGetDefaults(), but using a four-character code to select the parameter:
| VideoDigitizerError |
VDGetVideoParamValue( |
|
VideoDigitizerComponent
OSType
unsigned short * |
|
ci,
property,
value); |
| VideoDigitizerError |
VDSetVideoParamValue( |
|
VideoDigitizerComponent
OSType
unsigned short * |
|
ci,
property,
value); |
| VideoDigitizerError |
VDGetVideoParamDefault( |
|
VideoDigitizerComponent
OSType
unsigned short * |
|
ci,
property,
value); |
These have exactly the semantics as the corresponding vdig calls in that,
for continuous properties, the values are mapped [0..65535].
VDSetVideoParamValue both takes a requested value and returns the actual
value used -- for instance if manual gain only has 64 steps, any value
will be accepted, but the actual value used by the hardware, mapped to
[0..65535] will be returned.
This means that if an application wants to programmatically increment
a value to the next logical step, it needs to loop over VDSetVideoParamValue()
with increasing values until the returned value changes -- we could definitely
use a better API for this, but it's that VDSetBrightness, et. al. do and
something may applications get wrong, so I thought it was worth mentioning.
There is also a call to return properties which are a list of 32-bit values:
| VideoDigitizerError |
VDGetVideoParamList( |
|
VideoDigitizerComponent
OSType
UInt32 *
long *
|
|
ci,
property,
list,
size) |
This is used to return the list of hardware-supported video sizes (as
a list of Point) and the list of hardware-supported frame rates (as a
list of Fixed).
Also, there are calls to save/restore all of a video digitizer's settings
to/from a UserData (note that the caller is responsible for allocating
the UserData). Normally these are used by our SGPanels, but it might be
useful for applications to access:
| VideoDigitizerError |
VDSaveSettingsToUserData( |
|
VideoDigitizerComponent
UserData
long |
|
ci,
ud,
flags) |
| VideoDigitizerError |
VDRestoreSettingsFromUserData( |
|
VideoDigitizerComponent
UserData
long |
|
ci,
ud,
flags) |
---- Public selectors ----
Our publicly documented selectors are available in the IOXVideoParams.h
header:
We have a bunch more (manual exposure, etc.) that I'd like to make public,
but would like to clean up the definitions/semantics to support the widest
possible range of devices (we have to support something like 13 different
chip sets) before applications start depending on them.
Following are selectors that are supported by most of our drivers and
are not going to change....
For VDGetVideoParamList:
kVDFrameRateList = 'FPS#',
// List of supported frame rates as Fixed[]
kVDVideoSizeList = 'VSZ#', // List of supported video sizes as Point[]
For VDGetVideoParamValue/VDSetVideoParamValue/VDGetVideoParamDefault:
Control horizontal and vertical mirroring:
kVDParamFlipHorizontal
= 'FHor', // boolean 0=off 1=on
kVDParamFlipVertical = 'FVrt', // boolean 0=off 1=on
Access to camera buttons:
kVDParamLatchedButtons
= 'BtnL', // Latched button state -- clears on read
kVDParamSnapshotEnable = 'Snap', // enable=1/disable=0 snapshot function
For cameras which have a button or buttons, these allow an application
to determine if any buttons have been pressed -- the "Latched Buttons"
property returns a "1" bit for each button which has been pressed
since the last time the property was read (and resets the internal latch).
Applications should read this once when starting up and toss the result
to clear the latches of any presses that may have accumulated -- whether
the buttons are polled when video is not running is camera-dependent.
By default our drivers implement a "snapshot" feature that will
save a snapshot out of the video stream into the users "Pictures"
directory whenever the first button on the camera is pressed (video must
be running). If an application want to disable this feature and take over
the buttons itself, it should set the snapshot parameter to 0 and restore
it to 1 on exit.
Performance tuning:
kVDMaxGrabBuffers = 'Buf+',
// max grab buffers to allocate [default=6]
kVDMinGrabBuffers = 'Buf-', // start allocating when less than this many
[default=3]
kVDMaxQueuedFrames = 'Frm+', // max frames to queue [default=6]
We've also exported properties to allow the application to tune how the
driver manages buffers so that that, for instance, a video conferencing
application can tell us not to buffer video and always return a fresh
frame and a recording app can tell us to bend over backward to not lose
frames if some other app is hogging the machine.
We now support the low-latency and preview flags of VDGrabStateChanging(),
introduced in QT 6 -- if either of these flags is set, we behave as it
kVDMaxQueuedFrames==1 and queue at most one complete frame on order to
always return a fresh frame.
If you're using the SG in Preview mode, this will happen automatically,
but if you're doing Mung-grab-style grabbing of live video with an SGDataProc
and want to have low latency, you'll want to make sure to set the low-latency
flag because in this case, the VDIG thinks you're recording.
In any case, the buffer pipeline inside our drivers looks like this, where
the grab code is running at interrupt time (Mac OS 9) or a very high priority
thread (Mac OS X):
(free buffer pool) -> (grab code) -> (done frame queue) -> (application)
The parameters above control the number of buffers allowed in each pool.
kVDMaxGrabBuffers is the maximum number of buffers to keep in the free
pool -- it is topped off when grabbing starts and re-filled when the count
drops below kVDMinGrabBuffers. You probably don't need to mess with these
unless you want to save memory.
kVDMaxQueuedFrames controls the maximum number of completed frames to
buffer in case the application is busy or interrupted -- this is parameter
you may want to play with.
Values are defined as follows:
0: Don't buffer any frames and don't start grabbing until VDCompressOneFrameAsync
is called
1: Keep one fresh frame around for minimum latency, but don't save any
old frames
2..n: Keep this many frames around
Using a value of 0 will minimize the CPU used by the grabbing subsystem
but will result in a delay of up to 1 frame from the time VDCompressOneFrameAsync
is called and when VDCompressDone() returns a frame. You might want to
use this if you are a CPU-intensive video conferencing application where
you can use the gaps in the input video to compress/send data.
Using a value of 1 will result in the lowest latency at the expense of
keeping the grab code running all the time -- it probably the best for
preview.
Use higher values for recording -- in the case where the maximum count
is exceeded, the buffer pool will automatically revert to low latency
mode until the app catches up -- if you see jerky video, this is what's
happening.
The default values above are guesses, I'd like to know if anyone comes
up with better values.
Also, we'd be glad to improve this API to better service application developers
-- we've tried to have a working group to extend the 'vdig' API for several
years now, and nothing's come of it, so it seems like time the toss something
out and see what sticks.
If you have any ideas, please contact us.
|