GUAC-236: Add image stream allocation and management functions.

This commit is contained in:
Michael Jumper 2016-02-27 19:09:33 -08:00
parent 8ff8ccc92b
commit 578bedcd07
4 changed files with 231 additions and 5 deletions

View File

@ -170,6 +170,59 @@ guacenc_buffer* guacenc_display_get_related_buffer(guacenc_display* display,
} }
int guacenc_display_create_image_stream(guacenc_display* display, int index,
int mask, int layer_index, const char* mimetype, int x, int y) {
/* Do not lookup / allocate if index is invalid */
if (index < 0 || index > GUACENC_DISPLAY_MAX_STREAMS) {
guacenc_log(GUAC_LOG_WARNING, "Stream index out of bounds: %i", index);
return 1;
}
/* Free existing stream (if any) */
guacenc_image_stream_free(display->image_streams[index]);
/* Associate new stream */
guacenc_image_stream* stream = display->image_streams[index] =
guacenc_image_stream_alloc(mask, layer_index, mimetype, x, y);
/* Return zero only if stream is not NULL */
return stream == NULL;
}
guacenc_image_stream* guacenc_display_get_image_stream(
guacenc_display* display, int index) {
/* Do not lookup / allocate if index is invalid */
if (index < 0 || index > GUACENC_DISPLAY_MAX_STREAMS) {
guacenc_log(GUAC_LOG_WARNING, "Stream index out of bounds: %i", index);
return NULL;
}
/* Return existing stream (if any) */
return display->image_streams[index];
}
int guacenc_display_free_image_stream(guacenc_display* display, int index) {
/* Do not lookup / allocate if index is invalid */
if (index < 0 || index > GUACENC_DISPLAY_MAX_STREAMS) {
guacenc_log(GUAC_LOG_WARNING, "Stream index out of bounds: %i", index);
return 1;
}
/* Free stream (if allocated) */
guacenc_image_stream_free(display->image_streams[index]);
/* Mark stream as freed */
display->image_streams[index] = NULL;
return 0;
}
cairo_operator_t guacenc_display_cairo_operator(guac_composite_mode mask) { cairo_operator_t guacenc_display_cairo_operator(guac_composite_mode mask) {
/* Translate Guacamole channel mask into Cairo operator */ /* Translate Guacamole channel mask into Cairo operator */
@ -249,7 +302,7 @@ int guacenc_display_free(guacenc_display* display) {
/* Free all streams */ /* Free all streams */
for (i = 0; i < GUACENC_DISPLAY_MAX_STREAMS; i++) for (i = 0; i < GUACENC_DISPLAY_MAX_STREAMS; i++)
free(display->image_streams[i]); guacenc_image_stream_free(display->image_streams[i]);
free(display); free(display);
return 0; return 0;

View File

@ -131,6 +131,9 @@ int guacenc_display_free(guacenc_display* display);
* necessary. If the layer having the given index already exists, it will be * necessary. If the layer having the given index already exists, it will be
* returned. * returned.
* *
* @param display
* The Guacamole video encoder display to retrieve the layer from.
*
* @param index * @param index
* The index of the layer to retrieve. All valid layer indices are * The index of the layer to retrieve. All valid layer indices are
* non-negative. * non-negative.
@ -146,6 +149,10 @@ guacenc_layer* guacenc_display_get_layer(guacenc_display* display,
* Frees all resources associated with the layer having the given index. If * Frees all resources associated with the layer having the given index. If
* the layer has not been allocated, this function has no effect. * the layer has not been allocated, this function has no effect.
* *
* @param display
* The Guacamole video encoder display associated with the layer being
* freed.
*
* @param index * @param index
* The index of the layer to free. All valid layer indices are * The index of the layer to free. All valid layer indices are
* non-negative. * non-negative.
@ -154,14 +161,16 @@ guacenc_layer* guacenc_display_get_layer(guacenc_display* display,
* Zero if the layer was successfully freed or was not allocated, non-zero * Zero if the layer was successfully freed or was not allocated, non-zero
* if the layer could not be freed as the index was invalid. * if the layer could not be freed as the index was invalid.
*/ */
int guacenc_display_free_layer(guacenc_display* display, int guacenc_display_free_layer(guacenc_display* display, int index);
int index);
/** /**
* Returns the buffer having the given index. A new buffer will be allocated if * Returns the buffer having the given index. A new buffer will be allocated if
* necessary. If the buffer having the given index already exists, it will be * necessary. If the buffer having the given index already exists, it will be
* returned. * returned.
* *
* @param display
* The Guacamole video encoder display to retrieve the buffer from.
*
* @param index * @param index
* The index of the buffer to retrieve. All valid buffer indices are * The index of the buffer to retrieve. All valid buffer indices are
* negative. * negative.
@ -177,6 +186,10 @@ guacenc_buffer* guacenc_display_get_buffer(guacenc_display* display,
* Frees all resources associated with the buffer having the given index. If * Frees all resources associated with the buffer having the given index. If
* the buffer has not been allocated, this function has no effect. * the buffer has not been allocated, this function has no effect.
* *
* @param display
* The Guacamole video encoder display associated with the buffer being
* freed.
*
* @param index * @param index
* The index of the buffer to free. All valid buffer indices are negative. * The index of the buffer to free. All valid buffer indices are negative.
* *
@ -184,8 +197,7 @@ guacenc_buffer* guacenc_display_get_buffer(guacenc_display* display,
* Zero if the buffer was successfully freed or was not allocated, non-zero * Zero if the buffer was successfully freed or was not allocated, non-zero
* if the buffer could not be freed as the index was invalid. * if the buffer could not be freed as the index was invalid.
*/ */
int guacenc_display_free_buffer(guacenc_display* display, int guacenc_display_free_buffer(guacenc_display* display, int index);
int index);
/** /**
* Returns the buffer associated with the layer or buffer having the given * Returns the buffer associated with the layer or buffer having the given
@ -194,6 +206,9 @@ int guacenc_display_free_buffer(guacenc_display* display,
* will be returned. If the given index refers to a buffer (is negative), that * will be returned. If the given index refers to a buffer (is negative), that
* buffer will be returned directly. * buffer will be returned directly.
* *
* @param display
* The Guacamole video encoder display to retrieve the buffer from.
*
* @param index * @param index
* The index of the buffer or layer whose associated buffer should be * The index of the buffer or layer whose associated buffer should be
* retrieved. * retrieved.
@ -205,6 +220,81 @@ int guacenc_display_free_buffer(guacenc_display* display,
guacenc_buffer* guacenc_display_get_related_buffer(guacenc_display* display, guacenc_buffer* guacenc_display_get_related_buffer(guacenc_display* display,
int index); int index);
/**
* Creates a new image stream having the given index. If the stream having the
* given index already exists, it will be freed and replaced. If the mimetype
* specified is not supported, the image stream will still be allocated but
* will have no associated decoder (blobs send to that stream will have no
* effect).
*
* @param display
* The Guacamole video encoder display to associate with the
* newly-created image stream.
*
* @param index
* The index of the stream to create. All valid stream indices are
* non-negative.
*
* @param mask
* The Guacamole protocol compositing operation (channel mask) to apply
* when drawing the image.
*
* @param layer_index
* The index of the layer or bugger that the image should be drawn to.
*
* @param mimetype
* The mimetype of the image data that will be received along this stream.
*
* @param x
* The X coordinate of the upper-left corner of the rectangle within the
* destination layer or buffer that the image should be drawn to.
*
* @param y
* The Y coordinate of the upper-left corner of the rectangle within the
* destination layer or buffer that the image should be drawn to.
*
* @return
* Zero if the image stream was successfully created, non-zero otherwise.
*/
int guacenc_display_create_image_stream(guacenc_display* display, int index,
int mask, int layer_index, const char* mimetype, int x, int y);
/**
* Returns the stream having the given index. If no such stream exists, NULL
* will be returned.
*
* @param display
* The Guacamole video encoder display to retrieve the image stream from.
*
* @param index
* The index of the stream to retrieve. All valid stream indices are
* non-negative.
*
* @return
* The stream having the given index, or NULL if the index is invalid or
* a no such stream exists.
*/
guacenc_image_stream* guacenc_display_get_image_stream(
guacenc_display* display, int index);
/**
* Frees all resources associated with the stream having the given index. If
* the stream has not been allocated, this function has no effect.
*
* @param display
* The Guacamole video encoder display associated with the image stream
* being freed.
*
* @param index
* The index of the stream to free. All valid stream indices are
* non-negative.
*
* @return
* Zero if the stream was successfully freed or was not allocated, non-zero
* if the stream could not be freed as the index was invalid.
*/
int guacenc_display_free_image_stream(guacenc_display* display, int index);
/** /**
* Translates the given Guacamole protocol compositing mode (channel mask) to * Translates the given Guacamole protocol compositing mode (channel mask) to
* the corresponding Cairo composition operator. If no such operator exists, * the corresponding Cairo composition operator. If no such operator exists,

View File

@ -63,3 +63,40 @@ guacenc_decoder* guacenc_get_decoder(const char* mimetype) {
} }
guacenc_image_stream* guacenc_image_stream_alloc(int mask, int index,
const char* mimetype, int x, int y) {
/* Allocate stream */
guacenc_image_stream* stream = malloc(sizeof(guacenc_image_stream));
if (stream == NULL)
return NULL;
/* Init properties */
stream->index = index;
stream->mask = mask;
stream->x = x;
stream->y = y;
/* Associate with corresponding decoder */
stream->decoder = guacenc_get_decoder(mimetype);
return stream;
}
int guacenc_image_stream_free(guacenc_image_stream* stream) {
/* Ignore NULL streams */
if (stream == NULL)
return 0;
/* Invoke free handler for decoder (if associated) */
if (stream->decoder != NULL)
stream->decoder->free_handler(stream);
/* Free actual stream */
free(stream);
return 0;
}

View File

@ -206,5 +206,51 @@ extern guacenc_decoder_mapping guacenc_decoder_map[];
*/ */
guacenc_decoder* guacenc_get_decoder(const char* mimetype); guacenc_decoder* guacenc_get_decoder(const char* mimetype);
/**
* Allocates and initializes a new image stream. This allocation is independent
* of the Guacamole video encoder display; the allocated guacenc_image_stream
* will not automatically be associated with the active display, nor will the
* provided layer/buffer index be validated.
*
* @param mask
* The Guacamole protocol compositing operation (channel mask) to apply
* when drawing the image.
*
* @param index
* The index of the layer or bugger that the image should be drawn to.
*
* @param mimetype
* The mimetype of the image data that will be received along this stream.
*
* @param x
* The X coordinate of the upper-left corner of the rectangle within the
* destination layer or buffer that the image should be drawn to.
*
* @param y
* The Y coordinate of the upper-left corner of the rectangle within the
* destination layer or buffer that the image should be drawn to.
*
* @return
* A newly-allocated and initialized guacenc_image_stream, or NULL if
* allocation fails.
*/
guacenc_image_stream* guacenc_image_stream_alloc(int mask, int index,
const char* mimetype, int x, int y);
/**
* Frees the given image stream and all associated data. If the image stream
* has not yet ended (reached end-of-stream), no image will be drawn to the
* associated buffer or layer.
*
* @param stream
* The stream to free.
*
* @return
* Zero if freeing the stream succeeded, or non-zero if freeing the stream
* failed (for example, due to an error in the free handler of the
* decoder).
*/
int guacenc_image_stream_free(guacenc_image_stream* stream);
#endif #endif