The libraries we may mention in the Lurker's Guide are:
vlGetTransferSize(VLServer, VLPath) vlCreateBuffer(VLServer, VLPath, VLNode, numFrames) vlDestroyBuffer(VLServer, VLBuffer) vlRegisterBuffer(VLServer, VLPath, VLNode, VLBuffer) vlDeregisterBuffer(VLServer, VLPath, VLNode, VLBuffer) vlBufferAdvise(VLBuffer, usageInfo) vlBufferGetFd(VLBuffer) vlBufferDone(VLBuffer) vlBufferReset(VLServer, VLBuffer) vlGetNextFree(VLServer, VLBuffer, size) vlPutValid(VLServer svr, VLBuffer buffer) vlGetNextValid(VLServer, VLBuffer) vlGetLatestValid(VLServer, VLBuffer) vlPutFree(VLServer, VLBuffer) vlGetActiveRegion(VLServer, VLBuffer, VLInfoPtr) vlGetDMediaInfo(VLServer svr, VLBuffer buffer, VLInfoPtr info) vlGetImageInfo(VLServer svr, VLBuffer buffer, VLInfoPtr info) vlGetFilled(VLServer server, VLPath path, VLBuffer buffer)are collectively known as the "classic buffering API." Even the latest batch of VL devices support this API.
In the classic buffering API, video data is transferred between the device and the application using a VLBuffer data structure, which is essentially a ringbuffer. An application can pull items arriving from video input off of an input ringbuffer by calling vlGetNextValid(3dm). The application can get a pointer to the memory corresponding to that item. The application can only free items in the order in which it received the items. Video output works similarly. The application allocates one item in the output ringbuffer per field or frame, gets a pointer to the space, fills the data in, and sends the item on with vlPutValid(3dm). The application cannot send the same video data multiple times without imposing additional copies. The VLBuffer items are allocated by the VL and cannot be passed to any other image processing libraries without copying all of the image data.
The most recent VL devices also support DMbuffer-based buffering APIs, which solve all of the shortcomings above. An application creates a DMbufferpool instead of a VLBuffer. The DMbufferpool is a collection of DMbuffers (in the DM terminology, each field or frame is containined in a DMbuffer). DMbuffers are understood by more than just the VL. For example, when doing JPEG compression and decompression, you pass DMbuffers directly between the VL and dmIC. No mapping (vlGetActiveRegion) or copy operation is required.
A video input application using DMbuffers tells the VL to allocate DMbuffers for input data from a supplied DMbufferpool. The application then uses VL calls to wait for and dequeue filled-in DMbuffers. The application can then pass each DMbuffer directly to another library (such as dmIC), or map and manipulate each buffer if it wishes. The application can free received DMbuffers in any order, and their memory will immediately be returned to the DMbufferpool.
A video output application using DMbuffers allocates its own DMbuffers from the DMbufferpool it has created, or uses DMbuffers received from another library (such as dmIC). The application uses VL calls to enqueue DMbuffers for output. The application can send its DMbuffers to the VL as many times and in whatever order it wants.
And now, the catch. Due to icky historical reasons, the DMbuffer API originally released for O2 (mvp) on IRIX 6.3 consists of a different set of calls from that released for ev3, cosmo2, and divo on IRIX 6.4. These two DMbuffer APIs are called the O2 buffering API and the cross-platform buffering API, respectively. As its name suggests, the cross-platform buffering API is the one which will be available on all modern platforms (mvp, ev3, cosmo2, and divo) under IRIX 6.5. This table summarizes the combinations:
buffering API | buffering mechanism | VL platforms | OS releases |
---|---|---|---|
classic | VLInfoPtrs and VLBuffers | all | all |
O2 | DMbuffers and DMbufferpools | O2 (mvp) | IRIX 6.3 and later |
cross-platform | DMbuffers and DMbufferpools | ev3, cosmo2, divo | IRIX 6.4 and later |
all | IRIX 6.5 and later |
Check out Multi-Threaded Apps and the VL to see how the three buffering APIs can and cannot coexist in the same program.
The O2 buffering API consists of these calls:
vlDMPoolRegister(VLServer, VLPath, VLNode, DMbufferpool) vlDMPoolDeregister(VLServer, VLPath, VLNode, DMbufferpool) vlDMPoolGetParams(VLServer, VLPath, VLNode, DMparams *) vlDMBufferSend(VLServer, VLPath, DMbuffer) vlPathGetFD(VLServer, VLPath, int *ret_fd) vlEventRecv(VLServer, VLPath, VLEvent *) vlEventToDMBuffer(VLEvent *, DMbuffer *) vlGetFilledByNode(VLServer server, VLPath path, VLNode node)The cross-platform buffering API consists of these calls:
vlDMPoolRegister(VLServer, VLPath, VLNode, DMbufferpool) vlDMPoolDeregister(VLServer, VLPath, VLNode, DMbufferpool) vlDMGetParams(VLServer, VLPath, VLNode, DMparams*) vlDMBufferPutValid(VLServer, VLPath, VLNode, DMbuffer) vlDMBufferGetValid(VLServer, VLPath, VLNode, DMbuffer*) vlNodeGetFd(VLServer, VLPath, VLNode) vlDMBufferGetFilledByNode(VLServer, VLPath, VLNode) vlDMBufferResetNode(VLServer, VLPath, VLNode) vlDMBufferGetVideoInfo(DMbuffer, DMBufferVideoInfo* ) vlDMBufferSetVideoInfo(DMbuffer, DMBufferVideoInfo* ) vlNextEvent (VLServer, VLEvent *) vlCheckEvent(VLServer, VLEventMask, VLEvent *)