clQueryFree(3dm)
clQueryFree, clUpdateHead, clQueryValid, clUpdateTail, clDoneUpdatingHead - Reading and writing data with implicit buffers
As shipped in IRIX 6.5.15. Unchanged since IRIX 6.5.
NAME clQueryFree, clUpdateHead, clQueryValid, clUpdateTail, clDoneUpdatingHead - Reading and writing data with implicit buffers SYNOPSIS #include <dmedia/cl.h> int clQueryFree(CLbufferHdl bufferHdl, int freeAmount, void **freeData, int *freeWrap) int clUpdateHead(CLbufferHdl bufferHdl, int amountToAdd) int clQueryValid(CLbufferHdl bufferHdl, int validAmount, void **validData, int *validWrap) int clUpdateTail(CLbufferHdl bufferHdl, int amountToRelease) int clDoneUpdatingHead(CLbufferHdl bufferHdl) ARGUMENTS bufferHdl A handle to a CL buffer. freeAmount The number of blocks of free space to wait for. If it is zero, then the current number of blocks of free space is returned without waiting. freeData A pointer to the returned pointer to the location of free space. freeWrap The number of blocks of free space that have wrapped to the beginning of the ring buffer. If it is greater than zero, then the total free space is in two segments. amountToAdd The number of blocks of free space that were written by the caller and are ready to be consumed by the library. validAmount The number of blocks of valid data to wait for. If it is zero, then the current number of blocks of valid data is returned without waiting. validData A pointer to the returned pointer to the location of valid data. validWrap The number of blocks of valid data that have wrapped to the beginning of the ring buffer. If it is greater than zero, then the total valid data is in two segments. amountToRelease The number of blocks of valid data that were read by the caller and can be reused by the library. DESCRIPTION These calls are part of the Compression Library's interface for managing implicit buffers. Implicit buffering is invoked by clCompress and clDecompress by giving NULL arguments for the input and output buffers. For an overview of the Compression Library and its buffering strategy, see CLintro(3dm). Implicit buffers in the CL are ring buffers with the newest data filled in at the head and the oldest data removed at the tail. The calls to read and write data operate on block counts. The size of a block is the frame size in bytes for buffer type CL_BUF_FRAME, and is 1 byte for buffer type CL_BUF_COMPRESSED. clQueryFree is used to find out how much free space is available and where it is. clUpdateHead is used to notify the library that data has been placed in the ring buffer. clQueryValid is used to find out how much valid data is available and where it is. clUpdateTail is used to notify the library that valid data has been consumed from the ring buffer and is no longer needed. clDoneUpdatingHead is used to notify the library that no more data will be written to the ring buffer, in which case readers of the buffer will not block waiting for data to arrive. RETURN VALUES Each routine returns a negative error code on failure. On success, clQueryFree and clQueryValid return the number of free or valid blocks that are available before wrapping, clUpdateHead and clUpdateTail return the number of blocks updated, and clDoneUpdatingHead returns SUCCESS. NOTE In the case of valid data which is wrapped and is in two segments, the first segment can be accessed through validData and the pointer to the second segment is the beginning of the ring buffer. This pointer to the beginning of the ring buffer can be accessed by calling clQueryBufferHdl. EXAMPLES 1. Record /* Create the frame (input) and compressed (output) buffers */ frameBufferHdl = clCreateBuf(compressorHdl, CL_BUF_FRAME, numberOfFrames, bytesPerFrame, NULL); compressedBufferHdl = clCreateBuf(compressorHdl, CL_BUF_COMPRESSED, compressedBufferSize, 1, NULL); /* Write a frame from screen to buffer */ clQueryFree(frameBufferHdl, 1, &frameBuffer, &wrap); lrectread(0, 0, width - 1, height - 1, frameBuffer); clUpdateHead(frameBufferHdl, 1); /* Compress the frame */ clCompress(compressorHdl, 1, NULL, &compressedBufferSize, NULL); /* Copy compressed bytes to file */ while ((size=clQueryValid(compressedBufferHdl, 0, &buf, &wrap)) > 0) { write(fd, buf, size); clUpdateTail(compressedBufferHdl, size); } 2. Playback /* Fill the compressed buffer */ while ((size=clQueryFree(compressedBufferHdl, 0, &buf, &wrap)) > 0) { read(fd, buf, size); clUpdateHead(compressedBufferHdl, size); } /* Decompress a frame */ clDecompress(decompressorHdl, 1, 0, NULL, NULL); /* Read and display the frame */ clQueryValid(frameBufferHdl, 1, &frameBuffer, &wrap); lrectwrite(0, 0, width-1, height-1, frameBuffer); clUpdateTail(frameBufferHdl, 1); 3. Multiprocess Record ProduceFrameProcess() : while (1) { clQueryFree(frameBufferHdl, 1, &frameBuffer, &wrap); lrectread(0, 0, width - 1, height - 1, frameBuffer); clUpdateHead(frameBufferHdl, 1); } CompressProcess() : while (1) clCompress(compressorHdl, 1, NULL, &compressedBufferSize, NULL); ConsumeCompressedDataProcess() : while (1) { size = clQueryValid(compressedBufferHdl, 0, &buf, &wrap); write(fd, buf, size); clUpdateTail(compressedBufferHdl, size); } 4. Multiprocess Playback ProduceCompressedDataProcess() : while (1) { size = clQueryFree(compressedBufferHdl, 0, &buf, &wrap); read(fd, buf, size); clUpdateHead(compressedBufferHdl, size); } DecompressProcess() : while (1) clDecompress(decompressorHdl, 1, 0, NULL, NULL); ConsumeFrameProcess() : while (1) { clQueryValid(frameBufferHdl, 1, &frameBuffer, &wrap); lrectwrite(0, 0, width - 1, height - 1, frameBuffer); clUpdateTail(frameBufferHdl, 1); } SEE ALSO CLintro(3dm), clCreateBuf(3dm), clDestroyBuf(3dm), clCompress(3dm), clDecompress(3dm)