GUACAMOLE-25: Implement parsing of audio mimetypes.
This commit is contained in:
parent
8ccf61e6b1
commit
320f564daf
@ -30,16 +30,130 @@
|
||||
#include <guacamole/stream.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* Parses the given raw audio mimetype, producing the corresponding rate,
|
||||
* number of channels, and bytes per sample.
|
||||
*
|
||||
* @param mimetype
|
||||
* The raw auduio mimetype to parse.
|
||||
*
|
||||
* @param rate
|
||||
* A pointer to an int where the sample rate for the PCM format described
|
||||
* by the given mimetype should be stored.
|
||||
*
|
||||
* @param channels
|
||||
* A pointer to an int where the number of channels used by the PCM format
|
||||
* described by the given mimetype should be stored.
|
||||
*
|
||||
* @param bps
|
||||
* A pointer to an int where the number of bytes used the PCM format for
|
||||
* each sample (independent of number of channels) described by the given
|
||||
* mimetype should be stored.
|
||||
*
|
||||
* @return
|
||||
* Zero if the given mimetype is a raw audio mimetype and has been parsed
|
||||
* successfully, non-zero otherwise.
|
||||
*/
|
||||
static int guac_rdp_audio_parse_mimetype(const char* mimetype,
|
||||
int* rate, int* channels, int* bps) {
|
||||
|
||||
int parsed_rate = -1;
|
||||
int parsed_channels = 1;
|
||||
int parsed_bps;
|
||||
|
||||
/* PCM audio with one byte per sample */
|
||||
if (strncmp(mimetype, "audio/L8;", 9) == 0) {
|
||||
mimetype += 8; /* Advance to semicolon ONLY */
|
||||
parsed_bps = 1;
|
||||
}
|
||||
|
||||
/* PCM audio with two bytes per sample */
|
||||
else if (strncmp(mimetype, "audio/L16;", 10) == 0) {
|
||||
mimetype += 9; /* Advance to semicolon ONLY */
|
||||
parsed_bps = 2;
|
||||
}
|
||||
|
||||
/* Unsupported mimetype */
|
||||
else
|
||||
return 1;
|
||||
|
||||
/* Parse each parameter name/value pair within the mimetype */
|
||||
do {
|
||||
|
||||
/* Advance to first character of parameter (current is either a
|
||||
* semicolon or a comma) */
|
||||
mimetype++;
|
||||
|
||||
/* Parse number of channels */
|
||||
if (strncmp(mimetype, "channels=", 9) == 0) {
|
||||
|
||||
mimetype += 9;
|
||||
parsed_channels = strtol(mimetype, (char**) &mimetype, 10);
|
||||
|
||||
/* Fail if value invalid / out of range */
|
||||
if (errno == EINVAL || errno == ERANGE)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* Parse number of rate */
|
||||
else if (strncmp(mimetype, "rate=", 5) == 0) {
|
||||
|
||||
mimetype += 5;
|
||||
parsed_rate = strtol(mimetype, (char**) &mimetype, 10);
|
||||
|
||||
/* Fail if value invalid / out of range */
|
||||
if (errno == EINVAL || errno == ERANGE)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* Advance to next parameter */
|
||||
mimetype = strchr(mimetype, ',');
|
||||
|
||||
} while (mimetype != NULL);
|
||||
|
||||
/* Mimetype is invalid if rate was not specified */
|
||||
if (rate == -1)
|
||||
return 1;
|
||||
|
||||
/* Parse success */
|
||||
*rate = parsed_rate;
|
||||
*channels = parsed_channels;
|
||||
*bps = parsed_bps;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_audio_handler(guac_user* user, guac_stream* stream,
|
||||
char* mimetype) {
|
||||
|
||||
guac_client* client = user->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
|
||||
int rate;
|
||||
int channels;
|
||||
int bps;
|
||||
|
||||
/* Parse mimetype, abort on parse error */
|
||||
if (guac_rdp_audio_parse_mimetype(mimetype, &rate, &channels, &bps)) {
|
||||
guac_user_log(user, GUAC_LOG_WARN, "Denying user audio stream with "
|
||||
"unsupported mimetype: \"%s\"", mimetype);
|
||||
guac_protocol_send_ack(user->socket, stream, "Unsupported audio "
|
||||
"mimetype", GUAC_PROTOCOL_STATUS_CLIENT_BAD_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: Assuming mimetype of "audio/L16;rate=44100,channels=2" */
|
||||
else {
|
||||
guac_user_log(user, GUAC_LOG_DEBUG, "rate=%i, channels=%i, bps=%i",
|
||||
rate, channels, bps);
|
||||
}
|
||||
|
||||
/* Init stream data */
|
||||
stream->blob_handler = guac_rdp_audio_blob_handler;
|
||||
|
Loading…
Reference in New Issue
Block a user