cl Read/Write Implicit Buffers(3dm) cl Read/Write Implicit Buffers(3dm)
clQueryFree, clUpdateHead, clQueryValid, clUpdateTail, clDoneUpdatingHead
- Reading and writing data with implicit buffers
#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)
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.
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.
Page 1
cl Read/Write Implicit Buffers(3dm) cl Read/Write Implicit Buffers(3dm)
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.
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.
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.
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);
Page 2
cl Read/Write Implicit Buffers(3dm) cl Read/Write Implicit Buffers(3dm)
/* 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);
}
Page 3
cl Read/Write Implicit Buffers(3dm) cl Read/Write Implicit Buffers(3dm)
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);
}
CLintro(3dm), clCreateBuf(3dm), clDestroyBuf(3dm), clCompress(3dm),
clDecompress(3dm)
PPPPaaaaggggeeee 4444 [ Back ]
|