channels/rdpsnd: further experimentation with async alsa

This commit is contained in:
Marc-André Moreau 2013-02-21 10:46:11 -05:00
parent 4df376739d
commit 05bd6cff73
3 changed files with 65 additions and 65 deletions

View File

@ -46,7 +46,6 @@ struct rdpsnd_alsa_plugin
rdpsndDevicePlugin device;
HANDLE mutex;
HANDLE thread;
char* device_name;
snd_pcm_t* pcm_handle;
snd_mixer_t* mixer_handle;
@ -80,7 +79,7 @@ static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa)
snd_pcm_drop(alsa->pcm_handle);
#ifdef RDPSND_ALSA_ASYNC
//snd_async_add_pcm_handler(&alsa->pcm_callback, alsa->pcm_handle, rdpsnd_alsa_async_handler, (void*) alsa);
snd_async_add_pcm_handler(&alsa->pcm_callback, alsa->pcm_handle, rdpsnd_alsa_async_handler, (void*) alsa);
#endif
status = snd_pcm_hw_params_malloc(&hw_params);
@ -246,7 +245,10 @@ static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, i
DEBUG_SVC("opening");
mode = 0;
//mode |= SND_PCM_NONBLOCK;
#ifdef RDPSND_ALSA_ASYNC
mode |= SND_PCM_NONBLOCK;
#endif
status = snd_pcm_open(&alsa->pcm_handle, alsa->device_name, SND_PCM_STREAM_PLAYBACK, mode);
@ -374,6 +376,7 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa)
BYTE* pindex;
int rbytes_per_frame;
int sbytes_per_frame;
snd_pcm_sframes_t avail;
sbytes_per_frame = alsa->source_channels * alsa->bytes_per_channel;
rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
@ -382,18 +385,24 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa)
pindex = alsa->audio_data;
end = pindex + alsa->audio_data_left;
avail = snd_pcm_avail_update(alsa->pcm_handle);
while (pindex + alsa->period_size * rbytes_per_frame <= end)
{
length = end - pindex;
status = snd_pcm_writei(alsa->pcm_handle, pindex, alsa->period_size);
avail = snd_pcm_avail_update(alsa->pcm_handle);
if (status == -EPIPE)
{
snd_pcm_recover(alsa->pcm_handle, status, 0);
status = 0;
}
else if (status == -EAGAIN)
{
break;
}
else if (status < 0)
{
DEBUG_WARN("snd_pcm_writei status %d", status);
@ -418,14 +427,11 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa)
void rdpsnd_alsa_async_handler(snd_async_handler_t* pcm_callback)
{
snd_pcm_t* pcm_handle;
snd_pcm_sframes_t avail;
rdpsndAlsaPlugin* alsa;
pcm_handle = snd_async_handler_get_pcm(pcm_callback);
alsa = (rdpsndAlsaPlugin*) snd_async_handler_get_callback_private(pcm_callback);
avail = snd_pcm_avail_update(pcm_handle);
rdpsnd_alsa_process_audio_data(alsa);
}
@ -501,9 +507,7 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size)
ReleaseMutex(alsa->mutex);
#ifndef RDPSND_ALSA_ASYNC
rdpsnd_alsa_process_audio_data(alsa);
#endif
}
static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
@ -516,21 +520,6 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device)
snd_pcm_start(alsa->pcm_handle);
}
void* rdpsnd_alsa_thread(void* arg)
{
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) arg;
while (1)
{
if (alsa->pcm_handle)
rdpsnd_alsa_process_audio_data(alsa);
Sleep(10);
}
return NULL;
}
COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
@ -593,10 +582,6 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
alsa->mutex = CreateMutex(NULL, FALSE, NULL);
#ifdef RDPSND_ALSA_ASYNC
alsa->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_alsa_thread, (void*) alsa, 0, NULL);
#endif
if (!alsa->device_name)
alsa->device_name = _strdup("default");

View File

@ -40,6 +40,7 @@
#include <freerdp/addin.h>
#include <freerdp/constants.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/signal.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpsnd_main.h"
@ -408,9 +409,9 @@ static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_
static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
BYTE msgType;
UINT16 BodySize;
rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
if (rdpsnd->expectingWave)
{
@ -577,7 +578,6 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
DEBUG_SVC("connecting");
rdpsnd->latency = -1;
rdpsnd->MsgPipe = MessagePipe_New();
rdpsnd->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, (void*) plugin, 0, NULL);
@ -674,6 +674,15 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
_p->plugin.event_callback = rdpsnd_process_event;
_p->plugin.terminate_callback = rdpsnd_process_terminate;
#ifndef _WIN32
{
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGIO);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
}
#endif
svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
return 1;

View File

@ -64,46 +64,49 @@ static void fatal_handler(int signum)
raise(signum);
}
int freerdp_handle_signals(void)
const int fatal_signals[] =
{
const int fatal_signals[] = {
SIGABRT,
SIGALRM,
SIGBUS,
SIGFPE,
SIGHUP,
SIGILL,
SIGINT,
SIGKILL,
SIGPIPE,
SIGQUIT,
SIGSEGV,
SIGSTOP,
SIGTERM,
SIGTSTP,
SIGTTIN,
SIGTTOU,
SIGUSR1,
SIGUSR2,
SIGABRT,
SIGALRM,
SIGBUS,
SIGFPE,
SIGHUP,
SIGILL,
SIGINT,
SIGKILL,
SIGPIPE,
SIGQUIT,
SIGSEGV,
SIGSTOP,
SIGTERM,
SIGTSTP,
SIGTTIN,
SIGTTOU,
SIGUSR1,
SIGUSR2,
#ifdef SIGPOLL
SIGPOLL,
SIGPOLL,
#endif
#ifdef SIGPROF
SIGPROF,
SIGPROF,
#endif
#ifdef SIGSYS
SIGSYS,
SIGSYS,
#endif
SIGTRAP,
SIGTRAP,
#ifdef SIGVTALRM
SIGVTALRM,
SIGVTALRM,
#endif
SIGXCPU,
SIGXFSZ
};
SIGXCPU,
SIGXFSZ
};
int freerdp_handle_signals(void)
{
int signal_index;
sigset_t orig_set;
struct sigaction orig_sigaction, fatal_sigaction;
struct sigaction orig_sigaction;
struct sigaction fatal_sigaction;
sigfillset(&(fatal_sigaction.sa_mask));
sigdelset(&(fatal_sigaction.sa_mask), SIGCONT);
@ -112,16 +115,19 @@ int freerdp_handle_signals(void)
fatal_sigaction.sa_handler = fatal_handler;
fatal_sigaction.sa_flags = 0;
for (signal_index = 0;
signal_index < ARRAYSIZE(fatal_signals);
signal_index++)
if (sigaction(fatal_signals[signal_index],
NULL, &orig_sigaction) == 0)
for (signal_index = 0; signal_index < ARRAYSIZE(fatal_signals); signal_index++)
{
if (sigaction(fatal_signals[signal_index], NULL, &orig_sigaction) == 0)
{
if (orig_sigaction.sa_handler != SIG_IGN)
sigaction(fatal_signals[signal_index],
&fatal_sigaction, NULL);
{
sigaction(fatal_signals[signal_index], &fatal_sigaction, NULL);
}
}
}
pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
return 0;
}