GUACAMOLE-25: Store PCM format expected by RDP server.

This commit is contained in:
Michael Jumper 2016-05-26 10:39:33 -07:00
parent ad00cce0ad
commit 1c2890b47c
3 changed files with 76 additions and 33 deletions

View File

@ -250,28 +250,49 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
guac_rdp_audio_buffer_ack(audio_buffer,
"OK", GUAC_PROTOCOL_STATUS_SUCCESS);
guac_user_log(user, GUAC_LOG_DEBUG, "User is requesting to provide audio "
"input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
audio_buffer->in_format.channels,
audio_buffer->in_format.rate,
audio_buffer->in_format.bps);
pthread_mutex_unlock(&(audio_buffer->lock));
}
void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps) {
pthread_mutex_lock(&(audio_buffer->lock));
/* Set output format */
audio_buffer->out_format.rate = rate;
audio_buffer->out_format.channels = channels;
audio_buffer->out_format.bps = bps;
pthread_mutex_unlock(&(audio_buffer->lock));
}
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps, int packet_size,
guac_rdp_audio_buffer_flush_handler* flush_handler, void* data) {
int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
void* data) {
pthread_mutex_lock(&(audio_buffer->lock));
/* Reset buffer state to provided values */
audio_buffer->bytes_written = 0;
audio_buffer->out_format.rate = rate;
audio_buffer->out_format.channels = channels;
audio_buffer->out_format.bps = bps;
audio_buffer->packet_size = packet_size;
audio_buffer->flush_handler = flush_handler;
audio_buffer->data = data;
/* Calculate size of each packet in bytes */
audio_buffer->packet_size = packet_frames
* audio_buffer->out_format.channels
* audio_buffer->out_format.bps;
/* Allocate new buffer */
free(audio_buffer->packet);
audio_buffer->packet = malloc(packet_size);
audio_buffer->packet = malloc(audio_buffer->packet_size);
/* Acknowledge stream creation (if stream is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer,

View File

@ -180,29 +180,43 @@ guac_rdp_audio_buffer* guac_rdp_audio_buffer_alloc();
void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
guac_user* user, guac_stream* stream, int rate, int channels, int bps);
/**
* Defines the output format that should be used by the audio buffer when
* flushing packets of audio data received via guac_rdp_audio_buffer_write().
* As this format determines how the underlying packet buffer will be
* allocated, this function MUST be called prior to the call to
* guac_rdp_audio_buffer_begin().
*
* @param audio_buffer
* The audio buffer to set the output format of.
*
* @param rate
* The rate of the audio stream expected by RDP, in samples per second.
*
* @param channels
* The number of channels included in the audio stream expected by RDP.
*
* @param bps
* The size of each sample within the audio stream expected by RDP, in
* bytes.
*/
void guac_rdp_audio_buffer_set_output(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps);
/**
* Begins handling of audio data received via guac_rdp_audio_buffer_write() and
* allocates the necessary underlying packet buffer. Audio packets of exactly
* packet_size bytes will be flushed as available using the provided
* flush_handler.
* allocates the necessary underlying packet buffer. Audio packets having
* exactly packet_frames frames will be flushed as available using the provided
* flush_handler. An audio frame is a set of single samples, one sample per
* channel. The guac_rdp_audio_buffer_set_output() function MUST have
* been invoked first.
*
* @param audio_buffer
* The audio buffer to begin.
*
* @param rate
* The rate of the audio stream expected by RDP, if any, in samples per
* second.
*
* @param channels
* The number of channels included in the audio stream expected by RDP, if
* any.
*
* @param bps
* The size of each sample within the audio stream expected by RDP, if any,
* in bytes.
*
* @param packet_size
* The number of bytes to include in all audio packets provided to the
* @param packet_frames
* The exact number of frames (a set of samples, one for each channel)
* which MUST be included in all audio packets provided to the
* given flush_handler.
*
* @param flush_handler
@ -213,8 +227,8 @@ void guac_rdp_audio_buffer_set_stream(guac_rdp_audio_buffer* audio_buffer,
* needs to be flushed.
*/
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps, int packet_size,
guac_rdp_audio_buffer_flush_handler* flush_handler, void* data);
int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
void* data);
/**
* Writes the given buffer of audio data to the given audio buffer. A new

View File

@ -251,6 +251,9 @@ void guac_rdp_ai_process_version(guac_client* client,
void guac_rdp_ai_process_formats(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) {
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
guac_rdp_audio_buffer* audio_buffer = rdp_client->audio_input;
UINT32 num_formats;
Stream_Read_UINT32(stream, num_formats); /* NumFormats */
Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */
@ -265,6 +268,10 @@ void guac_rdp_ai_process_formats(guac_client* client,
if (format.tag != GUAC_RDP_WAVE_FORMAT_PCM)
continue;
/* Set output format of internal audio buffer to match RDP server */
guac_rdp_audio_buffer_set_output(audio_buffer, format.rate,
format.channels, format.bps / 8);
/* Accept single format */
guac_rdp_ai_send_incoming_data(channel);
guac_rdp_ai_send_formats(channel, &format, 1);
@ -301,18 +308,19 @@ void guac_rdp_ai_process_open(guac_client* client,
Stream_Read_UINT32(stream, packet_frames); /* FramesPerPacket */
Stream_Read_UINT32(stream, initial_format); /* InitialFormat */
/* STUB */
guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open: "
"packet_frames=%i, initial_format=%i",
packet_frames, initial_format);
guac_client_log(client, GUAC_LOG_DEBUG, "RDP server is accepting audio "
"input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
audio_buffer->out_format.channels,
audio_buffer->out_format.rate,
audio_buffer->out_format.bps);
/* Success */
guac_rdp_ai_send_formatchange(channel, initial_format);
guac_rdp_ai_send_open_reply(channel, 0);
/* FIXME: Assuming mimetype of 16-bit 44100 Hz stereo PCM */
guac_rdp_audio_buffer_begin(audio_buffer, packet_frames * 2 * 2,
44100, 2, 2, guac_rdp_ai_flush_packet, channel);
/* Begin receiving audio data */
guac_rdp_audio_buffer_begin(audio_buffer, packet_frames,
guac_rdp_ai_flush_packet, channel);
}