Refactored audio_format* functions.

This commit is contained in:
Armin Novak 2018-09-25 12:04:10 +02:00
parent d0612151f9
commit 28efbbc01f
12 changed files with 178 additions and 201 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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
}

View File

@ -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. ***/
/**

View File

@ -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);

View File

@ -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)
{

View File

@ -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;
}
}