Unified format support for rdpsnd.

This commit is contained in:
Armin Novak 2018-09-25 17:05:12 +02:00
parent 26ef8c9b3b
commit 2cf0662559
8 changed files with 80 additions and 100 deletions

View File

@ -309,17 +309,18 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context,
AUDIO_FORMAT* format; AUDIO_FORMAT* format;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
if (client_format_index < 0 if ((client_format_index < 0)
|| client_format_index >= context->num_client_formats) || (client_format_index >= context->num_client_formats)
|| (!context->src_format))
{ {
WLog_ERR(TAG, "index %d is not correct.", client_format_index); WLog_ERR(TAG, "index %d is not correct.", client_format_index);
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
} }
EnterCriticalSection(&context->priv->lock); EnterCriticalSection(&context->priv->lock);
context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8; context->priv->src_bytes_per_sample = context->src_format->wBitsPerSample / 8;
context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample * context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample *
context->src_format.nChannels; context->src_format->nChannels;
context->selected_client_format = client_format_index; context->selected_client_format = client_format_index;
format = &context->client_formats[client_format_index]; format = &context->client_formats[client_format_index];
@ -333,7 +334,7 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context,
if (context->latency <= 0) if (context->latency <= 0)
context->latency = 50; context->latency = 50;
context->priv->out_frames = context->src_format.nSamplesPerSec * context->priv->out_frames = context->src_format->nSamplesPerSec *
context->latency / 1000; context->latency / 1000;
if (context->priv->out_frames < 1) if (context->priv->out_frames < 1)

View File

@ -61,7 +61,7 @@ struct _rdpsnd_server_context
size_t num_server_formats; size_t num_server_formats;
/* Server source PCM audio format. Set by server. */ /* Server source PCM audio format. Set by server. */
AUDIO_FORMAT src_format; AUDIO_FORMAT* src_format;
/* Server audio latency, or buffer size, in milli-seconds. Set by server. */ /* Server audio latency, or buffer size, in milli-seconds. Set by server. */
int latency; int latency;

View File

@ -26,5 +26,6 @@
#include <freerdp/codec/audio.h> #include <freerdp/codec/audio.h>
FREERDP_API size_t server_audin_get_formats(AUDIO_FORMAT** dst_formats); FREERDP_API size_t server_audin_get_formats(AUDIO_FORMAT** dst_formats);
FREERDP_API size_t server_rdpsnd_get_formats(AUDIO_FORMAT** dst_formats);
#endif /* FREERDP_SERVER_COMMON_SERVER_H */ #endif /* FREERDP_SERVER_COMMON_SERVER_H */

View File

@ -29,17 +29,12 @@
#include "mf_rdpsnd.h" #include "mf_rdpsnd.h"
#include <winpr/sysinfo.h> #include <winpr/sysinfo.h>
#include <freerdp/server/server-common.h>
#include <freerdp/log.h> #include <freerdp/log.h>
#define TAG SERVER_TAG("mac") #define TAG SERVER_TAG("mac")
AQRecorderState recorderState; AQRecorderState recorderState;
static const AUDIO_FORMAT supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) static void mf_peer_rdpsnd_activated(RdpsndServerContext* context)
{ {
OSStatus status; OSStatus status;
@ -145,13 +140,11 @@ BOOL mf_peer_rdpsnd_init(mfPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm); context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p; context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context; context->rdpsnd->data = context;
context->rdpsnd->server_formats = supported_audio_formats; context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
context->rdpsnd->num_server_formats = sizeof(supported_audio_formats) / sizeof(
supported_audio_formats[0]); if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->src_format.wFormatTag = 1; context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
context->rdpsnd->Activated = mf_peer_rdpsnd_activated; context->rdpsnd->Activated = mf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd, TRUE); context->rdpsnd->Initialize(context->rdpsnd, TRUE);
return TRUE; return TRUE;

View File

@ -28,15 +28,10 @@
#include "sf_rdpsnd.h" #include "sf_rdpsnd.h"
#include <freerdp/server/server-common.h>
#include <freerdp/log.h> #include <freerdp/log.h>
#define TAG SERVER_TAG("sample") #define TAG SERVER_TAG("sample")
static const AUDIO_FORMAT test_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void sf_peer_rdpsnd_activated(RdpsndServerContext* context) static void sf_peer_rdpsnd_activated(RdpsndServerContext* context)
{ {
WLog_DBG(TAG, "RDPSND Activated"); WLog_DBG(TAG, "RDPSND Activated");
@ -47,15 +42,10 @@ BOOL sf_peer_rdpsnd_init(testPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm); context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p; context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context; context->rdpsnd->data = context;
context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
context->rdpsnd->server_formats = test_audio_formats; if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->num_server_formats = context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
sizeof(test_audio_formats) / sizeof(test_audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1;
context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
context->rdpsnd->Activated = sf_peer_rdpsnd_activated; context->rdpsnd->Activated = sf_peer_rdpsnd_activated;

View File

@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <winpr/windows.h> #include <winpr/windows.h>
#include <freerdp/server/server-common.h>
#include "wf_rdpsnd.h" #include "wf_rdpsnd.h"
#include "wf_info.h" #include "wf_info.h"
@ -42,19 +43,11 @@
#define TAG SERVER_TAG("windows") #define TAG SERVER_TAG("windows")
static const AUDIO_FORMAT supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void wf_peer_rdpsnd_activated(RdpsndServerContext* context) static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
{ {
wfInfo* wfi; wfInfo* wfi;
int i, j; int i, j;
wfi = wf_info_get_instance(); wfi = wf_info_get_instance();
wfi->agreed_format = NULL; wfi->agreed_format = NULL;
WLog_DBG(TAG, "Client supports the following %d formats:", context->num_client_formats); WLog_DBG(TAG, "Client supports the following %d formats:", context->num_client_formats);
@ -72,9 +65,9 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
break; break;
} }
} }
if (wfi->agreed_format != NULL) if (wfi->agreed_format != NULL)
break; break;
} }
if (wfi->agreed_format == NULL) if (wfi->agreed_format == NULL)
@ -85,43 +78,35 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
context->SelectFormat(context, i); context->SelectFormat(context, i);
context->SetVolume(context, 0x7FFF, 0x7FFF); context->SetVolume(context, 0x7FFF, 0x7FFF);
#ifdef WITH_RDPSND_DSOUND #ifdef WITH_RDPSND_DSOUND
wf_directsound_activate(context); wf_directsound_activate(context);
#else #else
wf_wasapi_activate(context); wf_wasapi_activate(context);
#endif #endif
} }
int wf_rdpsnd_lock() int wf_rdpsnd_lock()
{ {
DWORD dRes; DWORD dRes;
wfInfo* wfi; wfInfo* wfi;
wfi = wf_info_get_instance(); wfi = wf_info_get_instance();
dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE); dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE);
switch (dRes) switch (dRes)
{ {
case WAIT_ABANDONED: case WAIT_ABANDONED:
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
return TRUE; return TRUE;
break; break;
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
return FALSE; return FALSE;
break; break;
case WAIT_FAILED: case WAIT_FAILED:
WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError()); WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError());
return -1; return -1;
break; break;
} }
return -1; return -1;
@ -130,7 +115,6 @@ int wf_rdpsnd_lock()
int wf_rdpsnd_unlock() int wf_rdpsnd_unlock()
{ {
wfInfo* wfi; wfInfo* wfi;
wfi = wf_info_get_instance(); wfi = wf_info_get_instance();
if (ReleaseMutex(wfi->snd_mutex) == 0) if (ReleaseMutex(wfi->snd_mutex) == 0)
@ -155,22 +139,15 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm); context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p; context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context; context->rdpsnd->data = context;
context->rdpsnd->server_formats = supported_audio_formats; context->rdpsnd->server_formats = supported_audio_formats;
context->rdpsnd->num_server_formats = context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
sizeof(supported_audio_formats) / sizeof(supported_audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1; if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->src_format.nChannels = 2; context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
context->rdpsnd->Activated = wf_peer_rdpsnd_activated; context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd, TRUE); context->rdpsnd->Initialize(context->rdpsnd, TRUE);
wf_rdpsnd_set_latest_peer(context); wf_rdpsnd_set_latest_peer(context);
wfi->snd_stop = FALSE; wfi->snd_stop = FALSE;
return TRUE; return TRUE;
} }

View File

@ -131,3 +131,41 @@ fail:
audio_formats_free(formats, nrDefaultFormatsMax); audio_formats_free(formats, nrDefaultFormatsMax);
return 0; return 0;
} }
size_t server_rdpsnd_get_formats(AUDIO_FORMAT** dst_formats)
{
size_t x, y = 0;
/* Default supported audio formats */
static const AUDIO_FORMAT default_supported_audio_formats[] =
{
{ WAVE_FORMAT_AAC_MS, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_MPEGLAYER3, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_GSM610, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
};
AUDIO_FORMAT* supported_audio_formats = audio_formats_new(ARRAYSIZE(
default_supported_audio_formats));
if (!supported_audio_formats)
goto fail;
for (x = 0; x < ARRAYSIZE(default_supported_audio_formats); x++)
{
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
if (freerdp_dsp_supports_format(format, TRUE))
supported_audio_formats[y++] = *format;
}
/* Set default audio formats. */
*dst_formats = supported_audio_formats;
fail:
audio_formats_free(supported_audio_formats, ARRAYSIZE(default_supported_audio_formats));
if (dst_formats)
*dst_formats = NULL;
return 0;
}

View File

@ -23,6 +23,7 @@
#include <winpr/crt.h> #include <winpr/crt.h>
#include <freerdp/log.h> #include <freerdp/log.h>
#include <freerdp/codec/dsp.h> #include <freerdp/codec/dsp.h>
#include <freerdp/server/server-common.h>
#include "shadow.h" #include "shadow.h"
@ -30,17 +31,6 @@
#define TAG SERVER_TAG("shadow") #define TAG SERVER_TAG("shadow")
/* Default supported audio formats */
static const AUDIO_FORMAT default_supported_audio_formats[] =
{
{ WAVE_FORMAT_AAC_MS, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_MPEGLAYER3, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_GSM610, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
};
static AUDIO_FORMAT supported_audio_formats[ARRAYSIZE(default_supported_audio_formats)] = { 0 };
static void rdpsnd_activated(RdpsndServerContext* context) static void rdpsnd_activated(RdpsndServerContext* context)
{ {
const AUDIO_FORMAT* agreed_format = NULL; const AUDIO_FORMAT* agreed_format = NULL;
@ -89,22 +79,12 @@ int shadow_client_rdpsnd_init(rdpShadowClient* client)
} }
else else
{ {
size_t x, y = 0; rdpsnd->num_server_formats = server_rdpsnd_get_formats(&rdpsnd->server_formats);
for (x = 0; x < ARRAYSIZE(default_supported_audio_formats); x++)
{
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
if (freerdp_dsp_supports_format(format, TRUE))
supported_audio_formats[y++] = *format;
}
/* Set default audio formats. */
rdpsnd->server_formats = supported_audio_formats;
rdpsnd->num_server_formats = y;
} }
rdpsnd->src_format = rdpsnd->server_formats[0]; if (rdpsnd->num_server_formats > 0)
rdpsnd->src_format = rdpsnd->server_formats[0];
rdpsnd->Activated = rdpsnd_activated; rdpsnd->Activated = rdpsnd_activated;
rdpsnd->Initialize(rdpsnd, TRUE); rdpsnd->Initialize(rdpsnd, TRUE);
return 1; return 1;