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, guac_rdp_audio_buffer_ack(audio_buffer,
"OK", GUAC_PROTOCOL_STATUS_SUCCESS); "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)); pthread_mutex_unlock(&(audio_buffer->lock));
} }
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer, void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps, int packet_size, int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
guac_rdp_audio_buffer_flush_handler* flush_handler, void* data) { void* data) {
pthread_mutex_lock(&(audio_buffer->lock)); pthread_mutex_lock(&(audio_buffer->lock));
/* Reset buffer state to provided values */ /* Reset buffer state to provided values */
audio_buffer->bytes_written = 0; 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->flush_handler = flush_handler;
audio_buffer->data = data; 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 */ /* Allocate new buffer */
free(audio_buffer->packet); 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) */ /* Acknowledge stream creation (if stream is ready to receive) */
guac_rdp_audio_buffer_ack(audio_buffer, 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, 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); 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 * Begins handling of audio data received via guac_rdp_audio_buffer_write() and
* allocates the necessary underlying packet buffer. Audio packets of exactly * allocates the necessary underlying packet buffer. Audio packets having
* packet_size bytes will be flushed as available using the provided * exactly packet_frames frames will be flushed as available using the provided
* flush_handler. * 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 * @param audio_buffer
* The audio buffer to begin. * The audio buffer to begin.
* *
* @param rate * @param packet_frames
* The rate of the audio stream expected by RDP, if any, in samples per * The exact number of frames (a set of samples, one for each channel)
* second. * which MUST be included in all audio packets provided to the
*
* @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
* given flush_handler. * given flush_handler.
* *
* @param 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. * needs to be flushed.
*/ */
void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer, void guac_rdp_audio_buffer_begin(guac_rdp_audio_buffer* audio_buffer,
int rate, int channels, int bps, int packet_size, int packet_frames, guac_rdp_audio_buffer_flush_handler* flush_handler,
guac_rdp_audio_buffer_flush_handler* flush_handler, void* data); void* data);
/** /**
* Writes the given buffer of audio data to the given audio buffer. A new * 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, void guac_rdp_ai_process_formats(guac_client* client,
IWTSVirtualChannel* channel, wStream* stream) { 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; UINT32 num_formats;
Stream_Read_UINT32(stream, num_formats); /* NumFormats */ Stream_Read_UINT32(stream, num_formats); /* NumFormats */
Stream_Seek_UINT32(stream); /* cbSizeFormatsPacket (MUST BE IGNORED) */ 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) if (format.tag != GUAC_RDP_WAVE_FORMAT_PCM)
continue; 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 */ /* Accept single format */
guac_rdp_ai_send_incoming_data(channel); guac_rdp_ai_send_incoming_data(channel);
guac_rdp_ai_send_formats(channel, &format, 1); 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, packet_frames); /* FramesPerPacket */
Stream_Read_UINT32(stream, initial_format); /* InitialFormat */ Stream_Read_UINT32(stream, initial_format); /* InitialFormat */
/* STUB */ guac_client_log(client, GUAC_LOG_DEBUG, "RDP server is accepting audio "
guac_client_log(client, GUAC_LOG_DEBUG, "AUDIO_INPUT: open: " "input as %i-channel, %i Hz PCM audio at %i bytes/sample.",
"packet_frames=%i, initial_format=%i", audio_buffer->out_format.channels,
packet_frames, initial_format); audio_buffer->out_format.rate,
audio_buffer->out_format.bps);
/* Success */ /* Success */
guac_rdp_ai_send_formatchange(channel, initial_format); guac_rdp_ai_send_formatchange(channel, initial_format);
guac_rdp_ai_send_open_reply(channel, 0); guac_rdp_ai_send_open_reply(channel, 0);
/* FIXME: Assuming mimetype of 16-bit 44100 Hz stereo PCM */ /* Begin receiving audio data */
guac_rdp_audio_buffer_begin(audio_buffer, packet_frames * 2 * 2, guac_rdp_audio_buffer_begin(audio_buffer, packet_frames,
44100, 2, 2, guac_rdp_ai_flush_packet, channel); guac_rdp_ai_flush_packet, channel);
} }