From 28efbbc01f795eccf76e8d7e84b174fcb57457bd Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 25 Sep 2018 12:04:10 +0200 Subject: [PATCH] Refactored audio_format* functions. --- channels/audin/client/audin_main.c | 71 ++-------- channels/audin/client/mac/audin_mac.c | 3 +- .../audin/client/opensles/audin_opensl_es.c | 2 +- channels/audin/server/audin.c | 62 +++------ channels/rdpsnd/client/mac/rdpsnd_mac.c | 2 +- channels/rdpsnd/client/rdpsnd_main.c | 60 ++------- channels/rdpsnd/server/rdpsnd_main.c | 26 +--- include/freerdp/codec/audio.h | 16 ++- include/freerdp/server/audin.h | 8 +- libfreerdp/codec/audio.c | 121 ++++++++++++++++-- libfreerdp/codec/dsp_ffmpeg.c | 2 +- server/shadow/shadow_rdpsnd.c | 6 +- 12 files changed, 178 insertions(+), 201 deletions(-) diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 5a854b78a..15c0bc757 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -224,51 +224,23 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c { AUDIO_FORMAT format = { 0 }; - if (Stream_GetRemainingLength(s) < 18) + if (!audio_format_read(s, &format)) { error = ERROR_INVALID_DATA; goto out; } - Stream_Read_UINT16(s, format.wFormatTag); - Stream_Read_UINT16(s, format.nChannels); - Stream_Read_UINT32(s, format.nSamplesPerSec); - Stream_Read_UINT32(s, format.nAvgBytesPerSec); - Stream_Read_UINT16(s, format.nBlockAlign); - Stream_Read_UINT16(s, format.wBitsPerSample); - Stream_Read_UINT16(s, format.cbSize); - - if (Stream_GetRemainingLength(s) < format.cbSize) - { - error = ERROR_INVALID_DATA; - goto out; - } - - if (format.cbSize > 0) - { - format.data = malloc(format.cbSize); - - if (!format.data) - { - error = ERROR_OUTOFMEMORY; - goto out; - } - - memcpy(format.data, Stream_Pointer(s), format.cbSize); - Stream_Seek(s, format.cbSize); - } - WLog_Print(audin->log, WLOG_DEBUG, "wFormatTag=%s nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" " "nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"", - rdpsnd_get_audio_tag_string(format.wFormatTag), format.nChannels, format.nSamplesPerSec, + audio_format_get_tag_string(format.wFormatTag), format.nChannels, format.nSamplesPerSec, format.nBlockAlign, format.wBitsPerSample, format.cbSize); if ((audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag) || (audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels) || (audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec)) { - free(format.data); + rdpsnd_free_audio_format(&format); continue; } @@ -278,20 +250,16 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c /* Store the agreed format in the corresponding index */ callback->formats[callback->formats_count++] = format; - /* Put the format to output buffer */ - if (!Stream_EnsureRemainingCapacity(out, 18 + format.cbSize)) + if (!audio_format_write(out, &format)) { error = CHANNEL_RC_NO_MEMORY; WLog_Print(audin->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!"); goto out; } - - Stream_Write(out, &format, 18); - Stream_Write(out, format.data, format.cbSize); } else { - free(format.data); + rdpsnd_free_audio_format(&format); } } @@ -312,16 +280,8 @@ out: if (error != CHANNEL_RC_OK) { - size_t x; - - if (callback->formats) - { - for (x = 0; x < NumFormats; x++) - free(callback->formats[x].data); - - free(callback->formats); - callback->formats = NULL; - } + audio_formats_free(callback->formats, NumFormats); + callback->formats = NULL; } Stream_Free(out, TRUE); @@ -420,7 +380,7 @@ static UINT audin_receive_wave_data(const AUDIO_FORMAT* format, WLog_Print(audin->log, WLOG_TRACE, "%s: nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" " "nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16" [%"PRIdz"/%"PRIdz"]", - rdpsnd_get_audio_tag_string(audin->format->wFormatTag), + audio_format_get_tag_string(audin->format->wFormatTag), audin->format->nChannels, audin->format->nSamplesPerSec, audin->format->nAvgBytesPerSec, audin->format->nBlockAlign, audin->format->wBitsPerSample, audin->format->cbSize, size, Stream_GetPosition(audin->data) - 1); @@ -446,7 +406,7 @@ static BOOL audin_open_device(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callb format = *audin->format; supported = IFCALLRESULT(FALSE, audin->device->FormatSupported, audin->device, &format); WLog_Print(audin->log, WLOG_DEBUG, "microphone uses %s codec", - rdpsnd_get_audio_tag_string(format.wFormatTag)); + audio_format_get_tag_string(format.wFormatTag)); if (!supported) { @@ -646,18 +606,7 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback) } audin->format = NULL; - - if (callback->formats) - { - for (x = 0; x < callback->formats_count; x++) - { - AUDIO_FORMAT* format = &callback->formats[x]; - free(format->data); - } - - free(callback->formats); - } - + audio_formats_free(callback->formats, callback->formats_count); free(callback); return error; } diff --git a/channels/audin/client/mac/audin_mac.c b/channels/audin/client/mac/audin_mac.c index d60acb8a5..40ba05d47 100644 --- a/channels/audin/client/mac/audin_mac.c +++ b/channels/audin/client/mac/audin_mac.c @@ -133,7 +133,7 @@ static UINT audin_mac_set_format(IAudinDevice* device, const AUDIO_FORMAT* forma mac->FramesPerPacket = FramesPerPacket; mac->format = *format; WLog_INFO(TAG, "Audio Format %s [channels=%d, samples=%d, bits=%d]", - rdpsnd_get_audio_tag_string(format->wFormatTag), + audio_format_get_tag_string(format->wFormatTag), format->nChannels, format->nSamplesPerSec, format->wBitsPerSample); mac->audioFormat.mBitsPerChannel = format->wBitsPerSample; @@ -169,6 +169,7 @@ static void mac_audio_queue_input_cb(void* aqData, if (buffer_size > 0) error = mac->receive(&mac->format, buffer, buffer_size, mac->user_data); + AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL); if (error) diff --git a/channels/audin/client/opensles/audin_opensl_es.c b/channels/audin/client/opensles/audin_opensl_es.c index 5b89e7e7e..2e9309a27 100644 --- a/channels/audin/client/opensles/audin_opensl_es.c +++ b/channels/audin/client/opensles/audin_opensl_es.c @@ -189,7 +189,7 @@ static BOOL audin_opensles_format_supported(IAudinDevice* device, default: WLog_Print(opensles->log, WLOG_DEBUG, "Encoding '%s' [0x%04X"PRIX16"] not supported", - rdpsnd_get_audio_tag_string(format->wFormatTag), + audio_format_get_tag_string(format->wFormatTag), format->wFormatTag); break; } diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 0a4773e8c..c36a6aa57 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -154,8 +154,7 @@ static UINT audin_server_recv_version(audin_server* audin, wStream* s, */ static UINT audin_server_send_formats(audin_server* audin, wStream* s) { - int i; - UINT32 nAvgBytesPerSec; + size_t i; ULONG written; Stream_SetPosition(s, 0); Stream_Write_UINT8(s, MSG_SNDIN_FORMATS); @@ -166,35 +165,15 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s) for (i = 0; i < audin->context.num_server_formats; i++) { - nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec * - audin->context.server_formats[i].nChannels * - audin->context.server_formats[i].wBitsPerSample / 8; + AUDIO_FORMAT format = audin->context.server_formats[i]; + // TODO: Eliminate this + format.nAvgBytesPerSec = format.nSamplesPerSec * format.nChannels * format.wBitsPerSample / 8; - if (!Stream_EnsureRemainingCapacity(s, 18)) + if (!audio_format_write(s, &format)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } - - Stream_Write_UINT16(s, audin->context.server_formats[i].wFormatTag); - Stream_Write_UINT16(s, audin->context.server_formats[i].nChannels); - Stream_Write_UINT32(s, audin->context.server_formats[i].nSamplesPerSec); - Stream_Write_UINT32(s, nAvgBytesPerSec); - Stream_Write_UINT16(s, audin->context.server_formats[i].nBlockAlign); - Stream_Write_UINT16(s, audin->context.server_formats[i].wBitsPerSample); - Stream_Write_UINT16(s, audin->context.server_formats[i].cbSize); - - if (audin->context.server_formats[i].cbSize) - { - if (!Stream_EnsureRemainingCapacity(s, audin->context.server_formats[i].cbSize)) - { - WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - return CHANNEL_RC_NO_MEMORY; - } - - Stream_Write(s, audin->context.server_formats[i].data, - audin->context.server_formats[i].cbSize); - } } return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s), @@ -239,26 +218,15 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s, for (i = 0; i < audin->context.num_client_formats; i++) { - if (length < 18) + AUDIO_FORMAT* format = &audin->context.client_formats[i]; + + if (!audio_format_read(s, format)) { - free(audin->context.client_formats); + audio_formats_free(audin->context.client_formats, i); audin->context.client_formats = NULL; WLog_ERR(TAG, "expected length at least 18, but got %"PRIu32"", length); return ERROR_INVALID_DATA; } - - Stream_Read_UINT16(s, audin->context.client_formats[i].wFormatTag); - Stream_Read_UINT16(s, audin->context.client_formats[i].nChannels); - Stream_Read_UINT32(s, audin->context.client_formats[i].nSamplesPerSec); - Stream_Seek_UINT32(s); /* nAvgBytesPerSec */ - Stream_Read_UINT16(s, audin->context.client_formats[i].nBlockAlign); - Stream_Read_UINT16(s, audin->context.client_formats[i].wBitsPerSample); - Stream_Read_UINT16(s, audin->context.client_formats[i].cbSize); - - if (audin->context.client_formats[i].cbSize > 0) - { - Stream_Seek(s, audin->context.client_formats[i].cbSize); - } } IFCALLRET(audin->context.Opening, success, &audin->context); @@ -701,11 +669,13 @@ audin_server_context* audin_server_context_new(HANDLE vcm) void audin_server_context_free(audin_server_context* context) { audin_server* audin = (audin_server*) context; + + if (!audin) + return; + audin_server_close(context); - - if (audin->dsp_context) - freerdp_dsp_context_free(audin->dsp_context); - - free(audin->context.client_formats); + freerdp_dsp_context_free(audin->dsp_context); + audio_formats_free(audin->context.client_formats, audin->context.num_client_formats); + audio_formats_free(audin->context.server_formats, audin->context.num_server_formats); free(audin); } diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.c b/channels/rdpsnd/client/mac/rdpsnd_mac.c index 02a6da252..e696afaab 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.c +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.c @@ -109,7 +109,7 @@ static BOOL rdpsnd_mac_set_format(rdpsndDevicePlugin* device, const AUDIO_FORMAT return FALSE; } - rdpsnd_print_audio_format(format); + audio_format_print(format); return TRUE; } diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index da0fb673a..979c11b4a 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -139,7 +139,7 @@ static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd) static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) { UINT16 index; - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); + audio_formats_free(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; @@ -173,13 +173,7 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat)) { AUDIO_FORMAT* clientFormat = &rdpsnd->ClientFormats[rdpsnd->NumberOfClientFormats++]; - *clientFormat = *serverFormat; - - if (serverFormat->cbSize > 0) - { - clientFormat->data = (BYTE*) malloc(serverFormat->cbSize); - CopyMemory(clientFormat->data, serverFormat->data, serverFormat->cbSize); - } + audio_format_copy(serverFormat, clientFormat); } } } @@ -226,16 +220,12 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) for (index = 0; index < wNumberOfFormats; index++) { const AUDIO_FORMAT* clientFormat = &rdpsnd->ClientFormats[index]; - Stream_Write_UINT16(pdu, clientFormat->wFormatTag); - Stream_Write_UINT16(pdu, clientFormat->nChannels); - Stream_Write_UINT32(pdu, clientFormat->nSamplesPerSec); - Stream_Write_UINT32(pdu, clientFormat->nAvgBytesPerSec); - Stream_Write_UINT16(pdu, clientFormat->nBlockAlign); - Stream_Write_UINT16(pdu, clientFormat->wBitsPerSample); - Stream_Write_UINT16(pdu, clientFormat->cbSize); - if (clientFormat->cbSize > 0) - Stream_Write(pdu, clientFormat->data, clientFormat->cbSize); + if (!audio_format_write(pdu, clientFormat)) + { + Stream_Free(pdu, TRUE); + return ERROR_INTERNAL_ERROR; + } } WLog_Print(rdpsnd->log, WLOG_DEBUG, "Client Audio Formats"); @@ -254,7 +244,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, UINT16 wVersion; UINT16 wNumberOfFormats; UINT ret = ERROR_BAD_LENGTH; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); + audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; @@ -285,32 +275,8 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, { AUDIO_FORMAT* format = &rdpsnd->ServerFormats[index]; - if (Stream_GetRemainingLength(s) < 14) + if (!audio_format_read(s, format)) goto out_fail; - - Stream_Read_UINT16(s, format->wFormatTag); /* wFormatTag */ - Stream_Read_UINT16(s, format->nChannels); /* nChannels */ - Stream_Read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ - Stream_Read_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */ - Stream_Read_UINT16(s, format->nBlockAlign); /* nBlockAlign */ - Stream_Read_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */ - Stream_Read_UINT16(s, format->cbSize); /* cbSize */ - - if (format->cbSize > 0) - { - if (Stream_GetRemainingLength(s) < format->cbSize) - goto out_fail; - - format->data = (BYTE*) malloc(format->cbSize); - - if (!format->data) - { - ret = CHANNEL_RC_NO_MEMORY; - goto out_fail; - } - - Stream_Read(s, format->data, format->cbSize); - } } rdpsnd_select_supported_audio_formats(rdpsnd); @@ -325,7 +291,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, return ret; out_fail: - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); + audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->ServerFormats = NULL; rdpsnd->NumberOfServerFormats = 0; return ret; @@ -407,7 +373,7 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s, rdpsnd->waveDataSize = BodySize - 8; format = &rdpsnd->ClientFormats[wFormatNo]; WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveInfo: cBlockNo: %"PRIu8" wFormatNo: %"PRIu16" [%s]", - rdpsnd->cBlockNo, wFormatNo, rdpsnd_get_audio_tag_string(format->wFormatTag)); + rdpsnd->cBlockNo, wFormatNo, audio_format_get_tag_string(format->wFormatTag)); if (!rdpsnd->isOpen || (wFormatNo != rdpsnd->wCurrentFormatNo)) { @@ -1225,10 +1191,10 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd) StreamPool_Return(rdpsnd->pool, rdpsnd->data_in); StreamPool_Free(rdpsnd->pool); Queue_Free(rdpsnd->queue); - rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); + audio_formats_free(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); rdpsnd->NumberOfClientFormats = 0; rdpsnd->ClientFormats = NULL; - rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); + audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; rdpsnd->ServerFormats = NULL; diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index caebacab5..04d6fe7f1 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -45,7 +45,7 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) { size_t pos; UINT16 i; - BOOL status; + BOOL status = FALSE; ULONG written; Stream_Write_UINT8(s, SNDC_FORMATS); Stream_Write_UINT8(s, 0); @@ -61,25 +61,12 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) for (i = 0; i < context->num_server_formats; i++) { - Stream_Write_UINT16(s, - context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ - Stream_Write_UINT16(s, context->server_formats[i].nChannels); /* nChannels */ - Stream_Write_UINT32(s, - context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */ - Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec* - context->server_formats[i].nChannels* - context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */ - Stream_Write_UINT16(s, - context->server_formats[i].nBlockAlign); /* nBlockAlign */ - Stream_Write_UINT16(s, - context->server_formats[i].wBitsPerSample); /* wBitsPerSample */ - Stream_Write_UINT16(s, context->server_formats[i].cbSize); /* cbSize */ + AUDIO_FORMAT format = context->server_formats[i]; + // TODO: Eliminate this!!! + format.nAvgBytesPerSec = format.nSamplesPerSec * format.nChannels * format.wBitsPerSample / 8; - if (context->server_formats[i].cbSize > 0) - { - Stream_Write(s, context->server_formats[i].data, - context->server_formats[i].cbSize); - } + if (!audio_format_write(s, &format)) + goto fail; } pos = Stream_GetPosition(s); @@ -89,6 +76,7 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written); Stream_SetPosition(s, 0); +fail: return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR; } diff --git a/include/freerdp/codec/audio.h b/include/freerdp/codec/audio.h index 73ee571b2..a350efeb5 100644 --- a/include/freerdp/codec/audio.h +++ b/include/freerdp/codec/audio.h @@ -191,14 +191,20 @@ typedef struct AUDIO_FORMAT AUDIO_FORMAT; extern "C" { #endif -FREERDP_API UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size); +FREERDP_API UINT32 audio_format_compute_time_length(const AUDIO_FORMAT* format, size_t size); -FREERDP_API char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag); +FREERDP_API char* audio_format_get_tag_string(UINT16 wFormatTag); -FREERDP_API void rdpsnd_print_audio_format(const AUDIO_FORMAT* format); -FREERDP_API void rdpsnd_print_audio_formats(const AUDIO_FORMAT* formats, UINT16 count); +FREERDP_API void audio_format_print(const AUDIO_FORMAT* format); +FREERDP_API void audio_formats_print(const AUDIO_FORMAT* formats, UINT16 count); -FREERDP_API void rdpsnd_free_audio_formats(AUDIO_FORMAT* formats, UINT16 count); +FREERDP_API BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format); +FREERDP_API BOOL audio_format_write(wStream* s, const AUDIO_FORMAT* format); +FREERDP_API BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat); +FREERDP_API BOOL audio_format_compatible(const AUDIO_FORMAT* formatA, const AUDIO_FORMAT* formatB); + +FREERDP_API void audio_format_free(AUDIO_FORMAT* format); +FREERDP_API void audio_formats_free(AUDIO_FORMAT* formats, size_t count); #ifdef __cplusplus } diff --git a/include/freerdp/server/audin.h b/include/freerdp/server/audin.h index 10c7a88c6..a0a5ce97d 100644 --- a/include/freerdp/server/audin.h +++ b/include/freerdp/server/audin.h @@ -46,8 +46,8 @@ struct _audin_server_context void* data; /* Server supported formats. Set by server. */ - const AUDIO_FORMAT* server_formats; - int num_server_formats; + AUDIO_FORMAT* server_formats; + size_t num_server_formats; /* Server destination PCM audio format. Set by server. */ AUDIO_FORMAT dst_format; @@ -57,8 +57,8 @@ struct _audin_server_context /* Client supported formats. */ AUDIO_FORMAT* client_formats; - int num_client_formats; - int selected_client_format; + size_t num_client_formats; + size_t selected_client_format; /*** APIs called by the server. ***/ /** diff --git a/libfreerdp/codec/audio.c b/libfreerdp/codec/audio.c index d5e52d7c1..3f2ae38d8 100644 --- a/libfreerdp/codec/audio.c +++ b/libfreerdp/codec/audio.c @@ -28,7 +28,7 @@ #define TAG FREERDP_TAG("codec") -UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size) +UINT32 audio_format_compute_time_length(const AUDIO_FORMAT* format, size_t size) { UINT32 mstime; UINT32 wSamples; @@ -59,19 +59,19 @@ UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size) } else { - WLog_ERR(TAG, "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format"); + WLog_ERR(TAG, "audio_format_compute_time_length: invalid WAVE_FORMAT_GSM610 format"); } } else { - WLog_ERR(TAG, "rdpsnd_compute_audio_time_length: unknown format %"PRIu16"", format->wFormatTag); + WLog_ERR(TAG, "audio_format_compute_time_length: unknown format %"PRIu16"", format->wFormatTag); } } return mstime; } -char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag) +char* audio_format_get_tag_string(UINT16 wFormatTag) { switch (wFormatTag) { @@ -112,16 +112,16 @@ char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag) return "WAVE_FORMAT_UNKNOWN"; } -void rdpsnd_print_audio_format(const AUDIO_FORMAT* format) +void audio_format_print(const AUDIO_FORMAT* format) { WLog_INFO(TAG, "%s:\t wFormatTag: 0x%04"PRIX16" nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" " "nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16"", - rdpsnd_get_audio_tag_string(format->wFormatTag), format->wFormatTag, + audio_format_get_tag_string(format->wFormatTag), format->wFormatTag, format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec, format->nBlockAlign, format->wBitsPerSample, format->cbSize); } -void rdpsnd_print_audio_formats(const AUDIO_FORMAT* formats, UINT16 count) +void audio_format_prints(const AUDIO_FORMAT* formats, UINT16 count) { UINT16 index; const AUDIO_FORMAT* format; @@ -134,23 +134,122 @@ void rdpsnd_print_audio_formats(const AUDIO_FORMAT* formats, UINT16 count) { format = &formats[index]; WLog_ERR(TAG, "\t"); - rdpsnd_print_audio_format(format); + audio_format_print(format); } WLog_ERR(TAG, "}"); } } -void rdpsnd_free_audio_formats(AUDIO_FORMAT* formats, UINT16 count) +BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format) { - UINT16 index; + if (!s || !format) + return FALSE; + + if (Stream_GetRemainingLength(s) < 18) + return FALSE; + + Stream_Read_UINT16(s, format->wFormatTag); + Stream_Read_UINT16(s, format->nChannels); + Stream_Read_UINT32(s, format->nSamplesPerSec); + Stream_Read_UINT32(s, format->nAvgBytesPerSec); + Stream_Read_UINT16(s, format->nBlockAlign); + Stream_Read_UINT16(s, format->wBitsPerSample); + Stream_Read_UINT16(s, format->cbSize); + + if (Stream_GetRemainingLength(s) < format->cbSize) + return FALSE; + + format->data = NULL; + + if (format->cbSize > 0) + { + format->data = malloc(format->cbSize); + + if (!format->data) + return FALSE; + + Stream_Read(s, format->data, format->cbSize); + } + + return TRUE; +} + +BOOL audio_format_write(wStream* s, const AUDIO_FORMAT* format) +{ + if (!s || !format) + return FALSE; + + if (!Stream_EnsureRemainingCapacity(s, 18 + format->cbSize)) + return FALSE; + + Stream_Write_UINT16(s, format->wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */ + Stream_Write_UINT16(s, format->nChannels); /* nChannels */ + Stream_Write_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */ + Stream_Write_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */ + Stream_Write_UINT16(s, format->nBlockAlign); /* nBlockAlign */ + Stream_Write_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */ + Stream_Write_UINT16(s, format->cbSize); /* cbSize */ + + if (format->cbSize > 0) + Stream_Write(s, format->data, format->cbSize); + + return TRUE; +} + +BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat) +{ + if (!srcFormat || !dstFormat) + return FALSE; + + *dstFormat = *srcFormat; + + if (srcFormat->cbSize > 0) + { + dstFormat->data = malloc(srcFormat->cbSize); + + if (!dstFormat->data) + return FALSE; + + memcpy(dstFormat->data, srcFormat->data, dstFormat->cbSize); + } + + return TRUE; +} + +BOOL audio_format_compatible(const AUDIO_FORMAT* formatA, const AUDIO_FORMAT* formatB) +{ + if (!formatA || !formatB) + return FALSE; + + if (formatA->wFormatTag != formatB->wFormatTag) + return FALSE; + + if (formatA->nChannels != formatB->nChannels) + return FALSE; + + if (formatA->nSamplesPerSec != formatB->nSamplesPerSec) + return FALSE; + + return TRUE; +} + +void rdpsnd_free_audio_format(AUDIO_FORMAT* format) +{ + if (format) + free(format->data); +} + +void audio_formats_free(AUDIO_FORMAT* formats, size_t count) +{ + size_t index; if (formats) { for (index = 0; index < count; index++) { AUDIO_FORMAT* format = &formats[index]; - free(format->data); + rdpsnd_free_audio_format(format); } free(formats); diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c index 68bfd0691..d7fb54642 100644 --- a/libfreerdp/codec/dsp_ffmpeg.c +++ b/libfreerdp/codec/dsp_ffmpeg.c @@ -81,7 +81,7 @@ static enum AVCodecID ffmpeg_get_avcodec(const AUDIO_FORMAT* format) if (!format) return AV_CODEC_ID_NONE; - id = rdpsnd_get_audio_tag_string(format->wFormatTag); + id = audio_format_get_tag_string(format->wFormatTag); switch (format->wFormatTag) { diff --git a/server/shadow/shadow_rdpsnd.c b/server/shadow/shadow_rdpsnd.c index 21b693239..f285eff0d 100644 --- a/server/shadow/shadow_rdpsnd.c +++ b/server/shadow/shadow_rdpsnd.c @@ -50,11 +50,9 @@ static void rdpsnd_activated(RdpsndServerContext* context) { for (j = 0; j < context->num_server_formats; j++) { - if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) && - (context->client_formats[i].nChannels == context->server_formats[j].nChannels) && - (context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec)) + if (audio_format_compatible(&context->client_formats[i], &context->server_formats[j])) { - agreed_format = (AUDIO_FORMAT*) &context->server_formats[j]; + agreed_format = &context->server_formats[j]; break; } }