GUACAMOLE-25: Store PCM format expected by RDP server.
This commit is contained in:
parent
ad00cce0ad
commit
1c2890b47c
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user