What Are the SGI Video-Related Libraries?

By Chris Pirazzi.

The libraries we may mention in the Lurker's Guide are:

The 3 VL Buffering APIs

Since the VL was born, all VL devices have supported a common set of VL function calls, including a set of VLBuffer calls which you can use to read incoming pixels or write outgoing pixels. The VLBuffer calls:
    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 APIbuffering mechanismVL platformsOS releases
classicVLInfoPtrs and VLBuffersallall
O2DMbuffers and DMbufferpoolsO2 (mvp)IRIX 6.3 and later
cross-platformDMbuffers and DMbufferpools ev3, cosmo2, divoIRIX 6.4 and later
allIRIX 6.5 and later

Micheal Minakami has written a most excellent document detailing the exact differences between the DMbuffer APIs and providing sample code to ease your transition to the cross-platform DMbuffer API. This document is in the Developer's Toolbox at https://toolbox.sgi.com under src/exampleCode/video/VLdmbuffer/video_library_buffering.html. As of 12/16/97, it is not available in the free "Taste of the Toolbox": you need to be registered as described at http://www.sgi.com/Technology/toolbox.html.

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 *)