GUACAMOLE-179: Use non-owner users of connection to determine audio encoding if necessary.
This commit is contained in:
parent
48ebbe95ea
commit
440668a78a
@ -30,16 +30,38 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Sets the encoder associated with the given guac_audio_stream, automatically
|
||||
* invoking its begin_handler. The guac_audio_stream MUST NOT already be
|
||||
* associated with an encoder.
|
||||
*
|
||||
* @param audio
|
||||
* The guac_audio_stream whose encoder is being set.
|
||||
*
|
||||
* @param encoder
|
||||
* The encoder to associate with the given guac_audio_stream.
|
||||
*/
|
||||
static void guac_audio_stream_set_encoder(guac_audio_stream* audio,
|
||||
guac_audio_encoder* encoder) {
|
||||
|
||||
/* Call handler, if defined */
|
||||
if (encoder != NULL && encoder->begin_handler)
|
||||
encoder->begin_handler(audio);
|
||||
|
||||
/* Assign encoder, which may be NULL */
|
||||
audio->encoder = encoder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a new audio encoder to the given guac_audio_stream based on the
|
||||
* audio mimetypes declared as supported by the given user. If no audio encoder
|
||||
* can be found, no new audio encoder is assigned, and the existing encoder is
|
||||
* left untouched (if any).
|
||||
*
|
||||
* @param owner
|
||||
* @param user
|
||||
* The user whose supported audio mimetypes should determine the audio
|
||||
* encoder selected. It is expected that this user will be the owner of
|
||||
* the connection.
|
||||
* encoder selected.
|
||||
*
|
||||
* @param data
|
||||
* The guac_audio_stream to which the new encoder should be assigned.
|
||||
@ -50,31 +72,32 @@
|
||||
* The assigned audio encoder. If no new audio encoder can be assigned,
|
||||
* this will be the currently-assigned audio encoder (which may be NULL).
|
||||
*/
|
||||
static void* guac_audio_assign_encoder(guac_user* owner, void* data) {
|
||||
static void* guac_audio_assign_encoder(guac_user* user, void* data) {
|
||||
|
||||
int i;
|
||||
|
||||
guac_audio_stream* audio = (guac_audio_stream*) data;
|
||||
int bps = audio->bps;
|
||||
|
||||
/* If there is no owner, do not attempt to assign a new encoder */
|
||||
if (owner == NULL)
|
||||
/* If no user is provided, or an encoder has already been assigned,
|
||||
* do not attempt to assign a new encoder */
|
||||
if (user == NULL || audio->encoder != NULL)
|
||||
return audio->encoder;
|
||||
|
||||
/* For each supported mimetype, check for an associated encoder */
|
||||
for (i=0; owner->info.audio_mimetypes[i] != NULL; i++) {
|
||||
for (i=0; user->info.audio_mimetypes[i] != NULL; i++) {
|
||||
|
||||
const char* mimetype = owner->info.audio_mimetypes[i];
|
||||
const char* mimetype = user->info.audio_mimetypes[i];
|
||||
|
||||
/* If 16-bit raw audio is supported, done. */
|
||||
if (bps == 16 && strcmp(mimetype, raw16_encoder->mimetype) == 0) {
|
||||
audio->encoder = raw16_encoder;
|
||||
guac_audio_stream_set_encoder(audio, raw16_encoder);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If 8-bit raw audio is supported, done. */
|
||||
if (bps == 8 && strcmp(mimetype, raw8_encoder->mimetype) == 0) {
|
||||
audio->encoder = raw8_encoder;
|
||||
guac_audio_stream_set_encoder(audio, raw8_encoder);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -100,16 +123,17 @@ guac_audio_stream* guac_audio_stream_alloc(guac_client* client,
|
||||
audio->channels = channels;
|
||||
audio->bps = bps;
|
||||
|
||||
/* Assign encoder for owner, abort if no encoder can be found */
|
||||
if (!guac_client_for_owner(client, guac_audio_assign_encoder, audio)) {
|
||||
guac_client_free_stream(client, audio->stream);
|
||||
free(audio);
|
||||
return NULL;
|
||||
}
|
||||
/* Assign encoder if explicitly provided */
|
||||
if (encoder != NULL)
|
||||
guac_audio_stream_set_encoder(audio, encoder);
|
||||
|
||||
/* Call handler, if defined */
|
||||
if (audio->encoder->begin_handler)
|
||||
audio->encoder->begin_handler(audio);
|
||||
/* Otherwise, attempt to automatically assign encoder for owner */
|
||||
if (audio->encoder == NULL)
|
||||
guac_client_for_owner(client, guac_audio_assign_encoder, audio);
|
||||
|
||||
/* Failing that, attempt to assign encoder for ANY connected user */
|
||||
if (audio->encoder == NULL)
|
||||
guac_client_foreach_user(client, guac_audio_assign_encoder, audio);
|
||||
|
||||
return audio;
|
||||
|
||||
@ -118,8 +142,12 @@ guac_audio_stream* guac_audio_stream_alloc(guac_client* client,
|
||||
void guac_audio_stream_reset(guac_audio_stream* audio,
|
||||
guac_audio_encoder* encoder, int rate, int channels, int bps) {
|
||||
|
||||
/* Pull assigned encoder if no other encoder is requested */
|
||||
if (encoder == NULL)
|
||||
encoder = audio->encoder;
|
||||
|
||||
/* Do nothing if nothing is changing */
|
||||
if ((encoder == NULL || encoder == audio->encoder)
|
||||
if (encoder == audio->encoder
|
||||
&& rate == audio->rate
|
||||
&& channels == audio->channels
|
||||
&& bps == audio->bps) {
|
||||
@ -127,31 +155,28 @@ void guac_audio_stream_reset(guac_audio_stream* audio,
|
||||
}
|
||||
|
||||
/* Free old encoder data */
|
||||
if (audio->encoder->end_handler)
|
||||
if (audio->encoder != NULL && audio->encoder->end_handler)
|
||||
audio->encoder->end_handler(audio);
|
||||
|
||||
/* Assign new encoder, if changed */
|
||||
if (encoder != NULL)
|
||||
audio->encoder = encoder;
|
||||
|
||||
/* Set PCM properties */
|
||||
audio->rate = rate;
|
||||
audio->channels = channels;
|
||||
audio->bps = bps;
|
||||
|
||||
/* Init encoder with new data */
|
||||
if (audio->encoder->begin_handler)
|
||||
audio->encoder->begin_handler(audio);
|
||||
/* Re-init encoder */
|
||||
guac_audio_stream_set_encoder(audio, encoder);
|
||||
|
||||
}
|
||||
|
||||
void guac_audio_stream_add_user(guac_audio_stream* audio, guac_user* user) {
|
||||
|
||||
guac_audio_encoder* encoder = audio->encoder;
|
||||
/* Attempt to assign encoder if no encoder has yet been assigned */
|
||||
if (audio->encoder == NULL)
|
||||
guac_audio_assign_encoder(user, audio);
|
||||
|
||||
/* Notify encoder that a new user is present */
|
||||
if (encoder->join_handler)
|
||||
encoder->join_handler(audio, user);
|
||||
if (audio->encoder != NULL && audio->encoder->join_handler)
|
||||
audio->encoder->join_handler(audio, user);
|
||||
|
||||
}
|
||||
|
||||
@ -161,7 +186,7 @@ void guac_audio_stream_free(guac_audio_stream* audio) {
|
||||
guac_audio_stream_flush(audio);
|
||||
|
||||
/* Clean up encoder */
|
||||
if (audio->encoder->end_handler)
|
||||
if (audio->encoder != NULL && audio->encoder->end_handler)
|
||||
audio->encoder->end_handler(audio);
|
||||
|
||||
/* Free associated data */
|
||||
@ -173,7 +198,7 @@ void guac_audio_stream_write_pcm(guac_audio_stream* audio,
|
||||
const unsigned char* data, int length) {
|
||||
|
||||
/* Write data */
|
||||
if (audio->encoder->write_handler)
|
||||
if (audio->encoder != NULL && audio->encoder->write_handler)
|
||||
audio->encoder->write_handler(audio, data, length);
|
||||
|
||||
}
|
||||
@ -181,7 +206,7 @@ void guac_audio_stream_write_pcm(guac_audio_stream* audio,
|
||||
void guac_audio_stream_flush(guac_audio_stream* audio) {
|
||||
|
||||
/* Flush any buffered data */
|
||||
if (audio->encoder->flush_handler)
|
||||
if (audio->encoder != NULL && audio->encoder->flush_handler)
|
||||
audio->encoder->flush_handler(audio);
|
||||
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ struct guac_audio_stream {
|
||||
* Allocates a new audio stream at the client level which encodes audio data
|
||||
* using the given encoder. If NULL is specified for the encoder, an
|
||||
* appropriate encoder will be selected based on the encoders built into
|
||||
* libguac and the level of support declared by the owner associated with the
|
||||
* libguac and the level of support declared by users associated with the
|
||||
* given guac_client. The PCM format specified here (via rate, channels, and
|
||||
* bps) must be the format used for all PCM data provided to the audio stream.
|
||||
* The format may only be changed using guac_audio_stream_reset().
|
||||
@ -125,10 +125,10 @@ struct guac_audio_stream {
|
||||
* for the new user.
|
||||
*
|
||||
* @param client
|
||||
* The guac_client for which this audio stream is being allocated. Only the
|
||||
* connection owner is used to determine the level of audio support, and it
|
||||
* is currently assumed that all other joining users on the connection will
|
||||
* have the same level of audio support.
|
||||
* The guac_client for which this audio stream is being allocated. The
|
||||
* connection owner is given priority when determining the level of audio
|
||||
* support. It is currently assumed that all other joining users on the
|
||||
* connection will have the same level of audio support.
|
||||
*
|
||||
* @param encoder
|
||||
* The guac_audio_encoder to use when encoding audio, or NULL if libguac
|
||||
|
@ -236,9 +236,6 @@ guac_pa_stream* guac_pa_stream_alloc(guac_client* client,
|
||||
if (audio == NULL)
|
||||
return NULL;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_INFO, "Audio will be encoded as %s",
|
||||
audio->encoder->mimetype);
|
||||
|
||||
/* Init main loop */
|
||||
guac_pa_stream* stream = malloc(sizeof(guac_pa_stream));
|
||||
stream->client = client;
|
||||
|
Loading…
Reference in New Issue
Block a user