Unified format support for rdpsnd.
This commit is contained in:
parent
26ef8c9b3b
commit
2cf0662559
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user