channels/rdpsnd: refactor scheduling of sending of sound PDUs
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 21 Feb 2013 02:34:47 +0000 (21:34 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 21 Feb 2013 02:34:47 +0000 (21:34 -0500)
channels/audin/client/alsa/audin_alsa.c
channels/client/channels.c
channels/rdpsnd/client/rdpsnd_main.c
channels/sample/client/sample_main.c
include/freerdp/utils/svc_plugin.h
libfreerdp/core/channel.c
libfreerdp/core/rdp.c
libfreerdp/utils/svc_plugin.c

index 6ec44fd..11f31e4 100644 (file)
@@ -33,6 +33,7 @@
 #include <freerdp/addin.h>
 #include <freerdp/codec/dsp.h>
 #include <freerdp/utils/thread.h>
+#include <freerdp/channels/rdpsnd.h>
 
 #include "audin_main.h"
 
@@ -73,15 +74,12 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand
                         snd_strerror(error));
                return FALSE;
        }
+
        snd_pcm_hw_params_any(capture_handle, hw_params);
-       snd_pcm_hw_params_set_access(capture_handle, hw_params,
-               SND_PCM_ACCESS_RW_INTERLEAVED);
-       snd_pcm_hw_params_set_format(capture_handle, hw_params,
-               alsa->format);
-       snd_pcm_hw_params_set_rate_near(capture_handle, hw_params,
-               &alsa->actual_rate, NULL);
-       snd_pcm_hw_params_set_channels_near(capture_handle, hw_params,
-               &alsa->actual_channels);
+       snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
+       snd_pcm_hw_params_set_format(capture_handle, hw_params, alsa->format);
+       snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &alsa->actual_rate, NULL);
+       snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, &alsa->actual_channels);
        snd_pcm_hw_params(capture_handle, hw_params);
        snd_pcm_hw_params_free(hw_params);
        snd_pcm_prepare(capture_handle);
@@ -94,6 +92,7 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand
                        alsa->actual_rate, alsa->actual_channels,
                        alsa->target_rate, alsa->target_channels);
        }
+
        return TRUE;
 }
 
@@ -133,20 +132,25 @@ static BOOL audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
                        break;
 
                cframes = alsa->frames_per_packet - alsa->buffer_frames;
+
                if (cframes > frames)
                        cframes = frames;
-               memcpy(alsa->buffer + alsa->buffer_frames * tbytes_per_frame,
-                       src, cframes * tbytes_per_frame);
+
+               CopyMemory(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, src, cframes * tbytes_per_frame);
+
                alsa->buffer_frames += cframes;
+
                if (alsa->buffer_frames >= alsa->frames_per_packet)
                {
-                       if (alsa->wformat == 0x11)
+                       if (alsa->wformat == WAVE_FORMAT_DVI_ADPCM)
                        {
                                alsa->dsp_context->encode_ima_adpcm(alsa->dsp_context,
                                        alsa->buffer, alsa->buffer_frames * tbytes_per_frame,
                                        alsa->target_channels, alsa->block_size);
+
                                encoded_data = alsa->dsp_context->adpcm_buffer;
                                encoded_size = alsa->dsp_context->adpcm_size;
+
                                DEBUG_DVC("encoded %d to %d",
                                        alsa->buffer_frames * tbytes_per_frame, encoded_size);
                        }
@@ -162,11 +166,16 @@ static BOOL audin_alsa_thread_receive(AudinALSADevice* alsa, BYTE* src, int size
                                frames = 0;
                        }
                        else
+                       {
                                ret = alsa->receive(encoded_data, encoded_size, alsa->user_data);
+                       }
+
                        alsa->buffer_frames = 0;
+
                        if (!ret)
                                break;
                }
+
                src += cframes * tbytes_per_frame;
                frames -= cframes;
        }
@@ -225,8 +234,10 @@ static void* audin_alsa_thread_func(void* arg)
        } while (0);
 
        free(buffer);
+
        free(alsa->buffer);
        alsa->buffer = NULL;
+
        if (capture_handle)
                snd_pcm_close(capture_handle);
 
@@ -253,7 +264,7 @@ static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* forma
 {
        switch (format->wFormatTag)
        {
-               case 1: /* PCM */
+               case WAVE_FORMAT_PCM:
                        if (format->cbSize == 0 &&
                                (format->nSamplesPerSec <= 48000) &&
                                (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
@@ -263,7 +274,7 @@ static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* forma
                        }
                        break;
 
-               case 0x11: /* IMA ADPCM */
+               case WAVE_FORMAT_DVI_ADPCM:
                        if ((format->nSamplesPerSec <= 48000) &&
                                (format->wBitsPerSample == 4) &&
                                (format->nChannels == 1 || format->nChannels == 2))
@@ -272,6 +283,7 @@ static BOOL audin_alsa_format_supported(IAudinDevice* device, audinFormat* forma
                        }
                        break;
        }
+
        return FALSE;
 }
 
@@ -284,9 +296,10 @@ static void audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
        alsa->actual_rate = format->nSamplesPerSec;
        alsa->target_channels = format->nChannels;
        alsa->actual_channels = format->nChannels;
+
        switch (format->wFormatTag)
        {
-               case 1: /* PCM */
+               case WAVE_FORMAT_PCM:
                        switch (format->wBitsPerSample)
                        {
                                case 8:
@@ -300,7 +313,7 @@ static void audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
                        }
                        break;
 
-               case 0x11: /* IMA ADPCM */
+               case WAVE_FORMAT_DVI_ADPCM:
                        alsa->format = SND_PCM_FORMAT_S16_LE;
                        alsa->bytes_per_channel = 2;
                        bs = (format->nBlockAlign - 4 * format->nChannels) * 4;
@@ -310,6 +323,7 @@ static void audin_alsa_set_format(IAudinDevice* device, audinFormat* format, UIN
                                alsa->frames_per_packet);
                        break;
        }
+
        alsa->wformat = format->wFormatTag;
        alsa->block_size = format->nBlockAlign;
 }
index e6038cf..e31d052 100644 (file)
@@ -505,6 +505,7 @@ static rdpChannels* freerdp_channels_find_by_instance(freerdp* instance)
        for (channels_list = g_channels_list; channels_list; channels_list = channels_list->next)
        {
                channels = channels_list->channels;
+
                if (channels->instance == instance)
                {
                        ReleaseMutex(g_mutex_list);
@@ -709,13 +710,13 @@ static UINT32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, UINT32* pOpenHa
 
        channels = ((rdpInitHandle*) pInitHandle)->channels;
 
-       if (pOpenHandle == 0)
+       if (!pOpenHandle)
        {
                DEBUG_CHANNELS("error bad channel handle");
                return CHANNEL_RC_BAD_CHANNEL_HANDLE;
        }
 
-       if (pChannelOpenEventProc == 0)
+       if (!pChannelOpenEventProc)
        {
                DEBUG_CHANNELS("error bad proc");
                return CHANNEL_RC_BAD_PROC;
@@ -729,7 +730,7 @@ static UINT32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, UINT32* pOpenHa
 
        lchannel_data = freerdp_channels_find_channel_data_by_name(channels, pChannelName, &index);
 
-       if (lchannel_data == 0)
+       if (!lchannel_data)
        {
                DEBUG_CHANNELS("error channel name");
                return CHANNEL_RC_UNKNOWN_CHANNEL_NAME;
@@ -803,13 +804,13 @@ static UINT32 FREERDP_CC MyVirtualChannelWrite(UINT32 openHandle, void* pData, U
                return CHANNEL_RC_NOT_CONNECTED;
        }
 
-       if (pData == 0)
+       if (!pData)
        {
                DEBUG_CHANNELS("error bad pData");
                return CHANNEL_RC_NULL_DATA;
        }
 
-       if (dataLength == 0)
+       if (!dataLength)
        {
                DEBUG_CHANNELS("error bad dataLength");
                return CHANNEL_RC_ZERO_LENGTH;
@@ -851,7 +852,7 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, RDP_EVENT*
 
        channels = freerdp_channels_find_by_open_handle(openHandle, &index);
 
-       if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
+       if ((!channels) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
        {
                DEBUG_CHANNELS("error bad channels handle");
                return CHANNEL_RC_BAD_CHANNEL_HANDLE;
@@ -863,7 +864,7 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, RDP_EVENT*
                return CHANNEL_RC_NOT_CONNECTED;
        }
 
-       if (event == NULL)
+       if (!event)
        {
                DEBUG_CHANNELS("error bad event");
                return CHANNEL_RC_NULL_DATA;
@@ -888,6 +889,7 @@ static UINT32 FREERDP_CC MyVirtualChannelEventPush(UINT32 openHandle, RDP_EVENT*
        }
 
        channels->event = event;
+
        /* set the event */
        SetEvent(channels->signal);
 
@@ -1144,15 +1146,15 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat
 
        channels = freerdp_channels_find_by_instance(instance);
 
-       if (channels == 0)
+       if (!channels)
        {
                DEBUG_CHANNELS("could not find channel manager");
                return 1;
        }
 
-       lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings,
-               channel_id, &index);
-       if (lrdp_channel == 0)
+       lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings, channel_id, &index);
+
+       if (!lrdp_channel)
        {
                DEBUG_CHANNELS("could not find channel id");
                return 1;
@@ -1160,7 +1162,7 @@ int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int dat
 
        lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->Name, &index);
 
-       if (lchannel_data == 0)
+       if (!lchannel_data)
        {
                DEBUG_CHANNELS("could not find channel name");
                return 1;
@@ -1245,10 +1247,10 @@ static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instan
                lrdp_channel = freerdp_channels_find_channel_by_name(channels, instance->settings,
                        lchannel_data->name, &item->Index);
 
-               if (lrdp_channel != NULL)
+               if (lrdp_channel)
                        instance->SendChannelData(instance, lrdp_channel->ChannelId, item->Data, item->DataLength);
 
-               if (lchannel_data->open_event_proc != 0)
+               if (lchannel_data->open_event_proc)
                {
                        lchannel_data->open_event_proc(lchannel_data->open_handle,
                                CHANNEL_EVENT_WRITE_COMPLETE, item->UserData, sizeof(void*), sizeof(void*), 0);
index fd718e8..6327e55 100644 (file)
 #include <freerdp/addin.h>
 #include <freerdp/constants.h>
 #include <freerdp/utils/stream.h>
-#include <freerdp/utils/list.h>
 #include <freerdp/utils/svc_plugin.h>
 
 #include "rdpsnd_main.h"
 
+#define TIME_DELAY_MS  250
+
 struct rdpsnd_plugin
 {
        rdpSvcPlugin plugin;
 
        wMessagePipe* MsgPipe;
+       HANDLE thread;
 
        BYTE cBlockNo;
        rdpsndFormat* supported_formats;
@@ -77,35 +79,44 @@ struct rdpsnd_plugin
        rdpsndDevicePlugin* device;
 };
 
-/* process the linked list of data that has queued to be sent */
-static void rdpsnd_process_interval(rdpSvcPlugin* plugin)
+static void* rdpsnd_schedule_thread(void* arg)
 {
        STREAM* data;
        wMessage message;
+       UINT16 wTimeDiff;
        UINT16 wTimeStamp;
        UINT16 wCurrentTime;
-       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
+       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) arg;
 
-       while (MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, FALSE))
+       while (1)
        {
+               if (!MessageQueue_Wait(rdpsnd->MsgPipe->Out))
+                       break;
+
+               if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
+                       break;
+
                if (message.id == WMQ_QUIT)
                        break;
 
                wTimeStamp = (UINT16) (size_t) message.lParam;
                wCurrentTime = (UINT16) GetTickCount();
 
-               if (wCurrentTime <= wTimeStamp)
-                       break;
+               //printf("wTimeStamp: %d wCurrentTime: %d\n", wTimeStamp, wCurrentTime);
 
-               if (MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
+               if (wCurrentTime <= wTimeStamp)
                {
-                       data = (STREAM*) message.wParam;
-                       svc_plugin_send(plugin, data);
-
-                       DEBUG_SVC("processed output data");
+                       wTimeDiff = wTimeStamp - wCurrentTime;
+                       //printf("Sleeping %d ms\n", wTimeDiff);
+                       Sleep(wTimeDiff);
                }
+
+               data = (STREAM*) message.wParam;
+               svc_plugin_send((rdpSvcPlugin*) rdpsnd, data);
+               DEBUG_SVC("processed output data");
        }
 
+#if 0
        if (rdpsnd->is_open && (rdpsnd->close_timestamp > 0))
        {
                if (GetTickCount() > rdpsnd->close_timestamp)
@@ -119,9 +130,9 @@ static void rdpsnd_process_interval(rdpSvcPlugin* plugin)
                        DEBUG_SVC("processed close");
                }
        }
+#endif
 
-       if ((MessageQueue_Size(rdpsnd->MsgPipe->Out) == 0) && !rdpsnd->is_open)
-               rdpsnd->plugin.interval_ms = 0;
+       return NULL;
 }
 
 static void rdpsnd_free_supported_formats(rdpsndPlugin* rdpsnd)
@@ -339,7 +350,6 @@ static void rdpsnd_process_message_wave_info(rdpsndPlugin* rdpsnd, STREAM* data_
 static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
 {
        STREAM* data;
-       UINT32 delay_ms;
        UINT16 wTimeStamp;
 
        rdpsnd->expectingWave = 0;
@@ -357,11 +367,7 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
                IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in));
        }
 
-       delay_ms = 250;
-       wTimeStamp = rdpsnd->wTimeStamp + delay_ms;
-
-       DEBUG_SVC("data_size %d delay_ms %u process_ms %u",
-               stream_get_size(data_in), delay_ms, process_ms);
+       wTimeStamp = rdpsnd->wTimeStamp + TIME_DELAY_MS;
 
        data = stream_new(8);
        stream_write_BYTE(data, SNDC_WAVECONFIRM);
@@ -371,10 +377,8 @@ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in)
        stream_write_BYTE(data, rdpsnd->cBlockNo); /* cConfirmedBlockNo */
        stream_write_BYTE(data, 0); /* bPad */
 
-       wTimeStamp = rdpsnd->wave_timestamp + delay_ms;
+       wTimeStamp = rdpsnd->wave_timestamp + TIME_DELAY_MS;
        MessageQueue_Post(rdpsnd->MsgPipe->Out, NULL, 0, (void*) data, (void*) (size_t) wTimeStamp);
-
-       rdpsnd->plugin.interval_ms = 10;
 }
 
 static void rdpsnd_process_message_close(rdpsndPlugin* rdpsnd)
@@ -387,7 +391,6 @@ static void rdpsnd_process_message_close(rdpsndPlugin* rdpsnd)
        }
 
        rdpsnd->close_timestamp = GetTickCount() + 2000;
-       rdpsnd->plugin.interval_ms = 10;
 }
 
 static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_in)
@@ -405,7 +408,7 @@ static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_
 
 static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
 {
-       rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin;
+       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
        BYTE msgType;
        UINT16 BodySize;
 
@@ -573,11 +576,10 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
 
        DEBUG_SVC("connecting");
 
-       plugin->interval_callback = rdpsnd_process_interval;
-
        rdpsnd->latency = -1;
 
        rdpsnd->MsgPipe = MessagePipe_New();
+       rdpsnd->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, (void*) plugin, 0, NULL);
 
        args = (ADDIN_ARGV*) plugin->channel_entry_points.pExtendedData;
 
index 77f176c..0c8d357 100644 (file)
@@ -45,14 +45,8 @@ struct sample_plugin
        rdpSvcPlugin plugin;
 
        /* put your private data here */
-
 };
 
-static void sample_process_interval(rdpSvcPlugin* plugin)
-{
-       printf("sample_process_interval:\n");
-}
-
 static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
 {
        int bytes;
@@ -61,17 +55,18 @@ static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
 
        printf("sample_process_receive:\n");
 
-       if (sample == NULL)
+       if (!sample)
        {
                printf("sample_process_receive: sample is nil\n");
                return;
        }
 
-       /* process data in(from server) here */
+       /* process data in (from server) here */
        /* here we just send the same data back */
 
        bytes = stream_get_size(data_in);
        printf("sample_process_receive: got bytes %d\n", bytes);
+
        if (bytes > 0)
        {
                data_out = stream_new(bytes);
@@ -95,22 +90,15 @@ static void sample_process_connect(rdpSvcPlugin* plugin)
 
        printf("sample_process_connect:\n");
 
-       if (sample == NULL)
-       {
+       if (!sample)
                return;
-       }
-
-       /* if you want a call from channel thread once is a while do this */
-       plugin->interval_ms = 1000;
-       plugin->interval_callback = sample_process_interval;
-
 }
 
 static void sample_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
 {
        printf("sample_process_event:\n");
 
-       /* events comming from main freerdp window to plugin */
+       /* events coming from main freerdp window to plugin */
        /* send them back with svc_plugin_send_event */
 
        freerdp_event_free(event);
@@ -118,14 +106,12 @@ static void sample_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
 
 static void sample_process_terminate(rdpSvcPlugin* plugin)
 {
-       samplePlugin* sample = (samplePlugin*)plugin;
+       samplePlugin* sample = (samplePlugin*) plugin;
 
        printf("sample_process_terminate:\n");
 
-       if (sample == NULL)
-       {
+       if (!sample)
                return;
-       }
 
        /* put your cleanup here */
 
index dcce975..ca792f8 100644 (file)
@@ -43,12 +43,9 @@ struct rdp_svc_plugin
        CHANNEL_ENTRY_POINTS_EX channel_entry_points;
        CHANNEL_DEF channel_def;
 
-       int interval_ms;
-
        void (*connect_callback)(rdpSvcPlugin* plugin);
        void (*receive_callback)(rdpSvcPlugin* plugin, STREAM* data_in);
        void (*event_callback)(rdpSvcPlugin* plugin, RDP_EVENT* event);
-       void (*interval_callback)(rdpSvcPlugin* plugin);
        void (*terminate_callback)(rdpSvcPlugin* plugin);
 
        HANDLE thread;
index b9bccc9..ba92402 100644 (file)
@@ -50,7 +50,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channel_id, BYTE* data, int size)
                }
        }
 
-       if (channel == NULL)
+       if (!channel)
        {
                printf("freerdp_channel_send: unknown channel_id %d\n", channel_id);
                return FALSE;
@@ -58,6 +58,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channel_id, BYTE* data, int size)
 
        flags = CHANNEL_FLAG_FIRST;
        left = size;
+
        while (left > 0)
        {
                s = rdp_send_stream_init(rdp);
@@ -71,6 +72,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channel_id, BYTE* data, int size)
                        chunk_size = left;
                        flags |= CHANNEL_FLAG_LAST;
                }
+
                if ((channel->options & CHANNEL_OPTION_SHOW_PROTOCOL))
                {
                        flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
@@ -97,14 +99,16 @@ BOOL freerdp_channel_process(freerdp* instance, STREAM* s, UINT16 channel_id)
        UINT32 flags;
        int chunk_length;
 
-       if(stream_get_left(s) < 8)
+       if (stream_get_left(s) < 8)
                return FALSE;
+
        stream_read_UINT32(s, length);
        stream_read_UINT32(s, flags);
        chunk_length = stream_get_left(s);
 
        IFCALL(instance->ReceiveChannelData, instance,
                channel_id, stream_get_tail(s), chunk_length, flags, length);
+
        return TRUE;
 }
 
index eb39d6a..544a9dd 100644 (file)
@@ -420,6 +420,7 @@ BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id)
        length += rdp_security_stream_out(rdp, s, length);
 
        stream_set_pos(s, length);
+
        if (transport_write(rdp->transport, s) < 0)
                return FALSE;
 
index f03cca1..f0ccf63 100644 (file)
@@ -189,15 +189,8 @@ static void* svc_plugin_thread_func(void* arg)
 
        while (1)
        {
-               if (plugin->interval_ms > 0)
-               {
-                       Sleep(plugin->interval_ms);
-               }
-               else
-               {
-                       if (!MessageQueue_Wait(plugin->MsgPipe->In))
-                               break;
-               }
+               if (!MessageQueue_Wait(plugin->MsgPipe->In))
+                       break;
 
                if (MessageQueue_Peek(plugin->MsgPipe->In, &message, TRUE))
                {
@@ -215,9 +208,6 @@ static void* svc_plugin_thread_func(void* arg)
                                IFCALL(plugin->event_callback, plugin, event);
                        }
                }
-
-               if (plugin->interval_ms > 0)
-                       IFCALL(plugin->interval_callback, plugin);
        }
 
        DEBUG_SVC("out");