wfreerdp-server: merging Corey's sound support with C# binding improvements

This commit is contained in:
Marc-André Moreau 2012-10-16 19:43:45 -04:00
commit e87df0b7cc
12 changed files with 658 additions and 127 deletions

View File

@ -72,6 +72,7 @@ struct rdp_freerdp_peer
psPeerSendChannelData SendChannelData;
psPeerReceiveChannelData ReceiveChannelData;
int pId;
UINT32 ack_frame_id;
BOOL local;
BOOL connected;

View File

@ -48,10 +48,13 @@ else()
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
endif()
if(WITH_WIN8)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} d3d11 dxgi dxguid)
endif()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} dsound)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-server)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS

View File

@ -1,21 +1,21 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Windows Server
*
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Windows Server
*
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -100,7 +100,7 @@ wfInfo* wf_info_init()
{
wfInfo* wfi;
/*
/*
OSVERSIONINFOEX osvi;
SYSTEM_INFO si;
BOOL bOsVersionInfoEx;
@ -136,19 +136,32 @@ wfInfo* wf_info_init()
_tprintf(_T("Failed to create update thread\n"));
}
wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * 32);
wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * WF_INFO_MAXPEERS);
memset(wfi->peers, 0, sizeof(freerdp_peer*) * WF_INFO_MAXPEERS);
wfi->framesPerSecond = 24;
//Set FPS
wfi->framesPerSecond = WF_INFO_DEFAULT_FPS;
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey, _T("FramesPerSecond"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
wfi->framesPerSecond = dwValue;
}
RegCloseKey(hKey);
//Set input toggle
wfi->input_disabled = FALSE;
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey, _T("DisableInput"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
{
if (dwValue != 0)
wfi->input_disabled = TRUE;
}
}
RegCloseKey(hKey);
//detect windows version
@ -190,6 +203,15 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
{
if (wf_info_lock(wfi) > 0)
{
int i;
int peerId;
if (wfi->peerCount == WF_INFO_MAXPEERS)
{
context->socketClose = TRUE;
wf_info_unlock(wfi);
return;
}
context->info = wfi;
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@ -199,12 +221,25 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
#else
wf_mirror_driver_activate(wfi);
#endif
//look trhough the array of peers until an empty slot
for(i=0; i<WF_INFO_MAXPEERS; ++i)
{
//empty index will be our peer id
if (wfi->peers[i] == NULL)
{
peerId = i;
break;
}
}
wfi->peers[wfi->peerCount++] = ((rdpContext*) context)->peer;
printf("Registering Peer: %d\n", wfi->peerCount);
wfi->peers[peerId] = ((rdpContext*) context)->peer;
wfi->peers[peerId]->pId = peerId;
wfi->peerCount++;
printf("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount);
wf_info_unlock(wfi);
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT);
}
}
@ -212,10 +247,14 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
{
if (wf_info_lock(wfi) > 0)
{
wfi->peers[--(wfi->peerCount)] = NULL;
int peerId;
peerId = ((rdpContext*) context)->peer->pId;
wfi->peers[peerId] = NULL;
wfi->peerCount--;
CloseHandle(context->updateEvent);
printf("Unregistering Peer: %d\n", wfi->peerCount);
printf("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount);
#ifdef WITH_WIN8
if (wfi->peerCount == 0)
@ -223,6 +262,8 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
#endif
wf_info_unlock(wfi);
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_DISCONNECT);
}
}

View File

@ -22,6 +22,9 @@
#include "wf_interface.h"
#define WF_INFO_DEFAULT_FPS 24
#define WF_INFO_MAXPEERS 32
int wf_info_lock(wfInfo* wfi);
int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);
int wf_info_unlock(wfInfo* wfi);

View File

@ -164,3 +164,20 @@ void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1
wf_peer_mouse_event(input, flags, x, y);
}
}
void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
{
}
void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
{
}
void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
}
void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
}

View File

@ -27,4 +27,10 @@ void wf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
void wf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
//dummy versions
void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
#endif /* WF_INPUT_H */

View File

@ -3,6 +3,7 @@
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,15 +22,20 @@
#include "config.h"
#endif
#include <winpr/tchar.h>
#include <winpr/windows.h>
#include <freerdp/utils/tcp.h>
#include <freerdp\listener.h>
#include "wf_peer.h"
#include "wf_settings.h"
#include "wf_info.h"
#include "wf_interface.h"
cbCallback cbEvent;
DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
{
int i, fds;
@ -38,11 +44,15 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
void* rfds[32];
fd_set rfds_set;
freerdp_listener* instance;
wfInfo* wfi;
wfi = wf_info_get_instance();
wfi->force_all_disconnect = FALSE;
ZeroMemory(rfds, sizeof(rfds));
instance = (freerdp_listener*) lpParam;
while (1)
while(wfi->force_all_disconnect == FALSE)
{
rcount = 0;
@ -68,6 +78,7 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
if (max_fds == 0)
break;
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
if (instance->CheckFileDescriptor(instance) != TRUE)
@ -77,6 +88,8 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
}
}
printf("wf_server_main_loop terminating\n");
instance->Close(instance);
return 0;
@ -103,6 +116,13 @@ BOOL wfreerdp_server_start(wfServer* server)
BOOL wfreerdp_server_stop(wfServer* server)
{
wfInfo* wfi;
wfi = wf_info_get_instance();
printf("Stopping server\n");
wfi->force_all_disconnect = TRUE;
server->instance->Close(server->instance);
return TRUE;
}
@ -120,6 +140,8 @@ wfServer* wfreerdp_server_new()
server->port = 3389;
}
cbEvent = NULL;
return server;
}
@ -132,3 +154,141 @@ void wfreerdp_server_free(wfServer* server)
freerdp_wsa_cleanup();
}
FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server)
{
DWORD tStatus;
BOOL bRet;
bRet = GetExitCodeThread(server->thread, &tStatus);
if (bRet == 0)
{
printf("Error in call to GetExitCodeThread\n");
return FALSE;
}
if (tStatus == STILL_ACTIVE)
return TRUE;
return FALSE;
}
FREERDP_API UINT32 wfreerdp_server_num_peers()
{
wfInfo* wfi;
wfi = wf_info_get_instance();
return wfi->peerCount;
}
FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr)
{
wfInfo* wfi;
freerdp_peer* peer;
wfi = wf_info_get_instance();
peer = wfi->peers[pId];
if (peer)
{
UINT32 sLen;
sLen = strnlen_s(peer->hostname, 50);
swprintf(dstStr, 50, L"%hs", peer->hostname);
return sLen;
}
else
{
printf("nonexistent peer id=%d\n", pId);
return 0;
}
}
FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId)
{
wfInfo* wfi;
freerdp_peer* peer;
wfi = wf_info_get_instance();
peer = wfi->peers[pId];
if (peer)
{
return peer->local;
}
else
{
return FALSE;
}
}
FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId)
{
wfInfo* wfi;
freerdp_peer* peer;
wfi = wf_info_get_instance();
peer = wfi->peers[pId];
if (peer)
{
return peer->connected;
}
else
{
return FALSE;
}
}
FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId)
{
wfInfo* wfi;
freerdp_peer* peer;
wfi = wf_info_get_instance();
peer = wfi->peers[pId];
if (peer)
{
return peer->activated;
}
else
{
return FALSE;
}
}
FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId)
{
wfInfo* wfi;
freerdp_peer* peer;
wfi = wf_info_get_instance();
peer = wfi->peers[pId];
if (peer)
{
return peer->authenticated;
}
else
{
return FALSE;
}
}
FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb)
{
cbEvent = cb;
}
void wfreerdp_server_peer_callback_event(int pId, UINT32 eType)
{
if (cbEvent)
cbEvent(pId, eType);
}

View File

@ -1,21 +1,22 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WF_INTERFACE_H
#define WF_INTERFACE_H
@ -30,6 +31,11 @@
#include <freerdp/codec/rfx.h>
#include <freerdp/server/rdpsnd.h>
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
#define WF_SRV_CALLBACK_EVENT_DISCONNECT 2
#define WF_SRV_CALLBACK_EVENT_ACTIVATE 4
#define WF_SRV_CALLBACK_EVENT_AUTH 8
typedef struct wf_info wfInfo;
typedef struct wf_peer_context wfPeerContext;
@ -51,6 +57,9 @@ struct wf_info
BOOL mirrorDriverActive;
UINT framesWaiting;
HANDLE snd_mutex;
BOOL snd_stop;
RECT invalid;
HANDLE mutex;
BOOL updatePending;
@ -61,6 +70,9 @@ struct wf_info
unsigned long lastUpdate;
unsigned long nextUpdate;
SURFACE_BITS_COMMAND cmd;
BOOL input_disabled;
BOOL force_all_disconnect;
};
struct wf_peer_context
@ -87,10 +99,25 @@ struct wf_server
};
typedef struct wf_server wfServer;
typedef void (__stdcall* cbCallback) (int, UINT32);
FREERDP_API BOOL wfreerdp_server_start(wfServer* server);
FREERDP_API BOOL wfreerdp_server_stop(wfServer* server);
FREERDP_API wfServer* wfreerdp_server_new();
FREERDP_API void wfreerdp_server_free(wfServer* server);
FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server);
FREERDP_API UINT32 wfreerdp_server_num_peers();
FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr);
FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId);
FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId);
FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId);
FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId);
FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb);
void wfreerdp_server_peer_callback_event(int pId, UINT32 eType);
#endif /* WF_INTERFACE_H */

View File

@ -1,21 +1,22 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -50,7 +51,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
wf_info_peer_unregister(context->info, context);
if (context->rdpsnd)
{
printf("snd_free\n");
wf_rdpsnd_lock();
context->info->snd_stop = TRUE;
rdpsnd_server_context_free(context->rdpsnd);
wf_rdpsnd_unlock();
}
WTSDestroyVirtualChannelManager(context->vcm);
}
@ -118,6 +125,8 @@ BOOL wf_peer_activate(freerdp_peer* client)
client->activated = TRUE;
wf_update_peer_activate(wfi, context);
wfreerdp_server_peer_callback_event(((rdpContext*) context)->peer->pId, WF_SRV_CALLBACK_EVENT_ACTIVATE);
return TRUE;
}
@ -131,6 +140,8 @@ BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL
identity->User, identity->Domain, identity->Password);
}
wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH);
return TRUE;
}
@ -239,7 +250,20 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
client->Initialize(client);
context = (wfPeerContext*) client->context;
if (context->socketClose)
return 0;
wfi = context->info;
if (wfi->input_disabled == TRUE)
{
printf("client input is disabled\n");
client->input->KeyboardEvent = wf_peer_keyboard_event_dummy;
client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy;
client->input->MouseEvent = wf_peer_mouse_event_dummy;
client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy;
}
context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
printf("socketEvent created\n");
@ -288,6 +312,13 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
break;
}
//force disconnect
if(wfi->force_all_disconnect == TRUE)
{
printf("Forcing Disconnect -> ");
break;
}
/* FIXME: we should wait on this, instead of calling it every time */
if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE)
break;

View File

@ -24,9 +24,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <winpr\windows.h>
#define CINTERFACE
#include <mmsystem.h>
#include <dsound.h>
#include <freerdp/server/rdpsnd.h>
#include "wf_rdpsnd.h"
#include "wf_info.h"
/*
* Here are some temp things that shall be moved
*
*/
IDirectSoundCapture8 * cap;
IDirectSoundCaptureBuffer8* capBuf;
DSCBUFFERDESC dscbd;
DWORD capturePos;
#define BYTESPERSEC 176400
//FIXME support multiple clients
wfPeerContext* latestPeer;
static const rdpsndFormat test_audio_formats[] =
{
@ -44,11 +64,107 @@ static const rdpsndFormat test_audio_formats[] =
static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context)
{
HRESULT hr;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, BYTESPERSEC, 4, 16, 0};
printf("RDPSND Activated\n");
hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create sound capture device\n"));
return;
}
_tprintf(_T("Created sound capture device\n"));
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = BYTESPERSEC;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create capture buffer\n"));
}
_tprintf(_T("Created capture buffer"));
hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to QI capture buffer\n"));
}
_tprintf(_T("Created IDirectSoundCaptureBuffer8\n"));
pDSCB->lpVtbl->Release(pDSCB);
context->SelectFormat(context, 4);
context->SetVolume(context, 0x7FFF, 0x7FFF);
capturePos = 0;
CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL);
}
int wf_rdpsnd_lock()
{
DWORD dRes;
wfInfo* wfi;
wfi = wf_info_get_instance();
dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE);
switch (dRes)
{
case WAIT_ABANDONED:
case WAIT_OBJECT_0:
return TRUE;
break;
case WAIT_TIMEOUT:
return FALSE;
break;
case WAIT_FAILED:
printf("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError());
return -1;
break;
}
return -1;
}
int wf_rdpsnd_unlock()
{
wfInfo* wfi;
wfi = wf_info_get_instance();
if (ReleaseMutex(wfi->snd_mutex) == 0)
{
printf("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError());
return -1;
}
return TRUE;
}
BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
{
wfInfo* wfi;
wfi = wf_info_get_instance();
wfi->snd_mutex = CreateMutex(NULL, FALSE, NULL);
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->data = context;
@ -65,5 +181,121 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
context->rdpsnd->Initialize(context->rdpsnd);
latestPeer = context;
wfi->snd_stop = FALSE;
return TRUE;
}
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
{
HRESULT hr;
DWORD beg, end;
DWORD diff, rate;
wfPeerContext* context;
wfInfo* wfi;
wfi = wf_info_get_instance();
context = (wfPeerContext*)lpParam;
rate = 1000 / 5;
_tprintf(_T("Trying to start capture\n"));
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
if (FAILED(hr))
{
_tprintf(_T("Failed to start capture\n"));
}
_tprintf(_T("Capture started\n"));
while (1)
{
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2;
VOID* pbPlayData = NULL;
DWORD dwReadPos;
LONG lLockSize;
beg = GetTickCount();
if (wf_rdpsnd_lock() > 0)
{
//check for main exit condition
if (wfi->snd_stop == TRUE)
{
wf_rdpsnd_unlock();
break;
}
hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos);
if (FAILED(hr))
{
_tprintf(_T("Failed to get read pos\n"));
wf_rdpsnd_unlock();
break;
}
lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes;
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
if (lLockSize == 0)
{
wf_rdpsnd_unlock();
continue;
}
hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
if (FAILED(hr))
{
_tprintf(_T("Failed to lock sound capture buffer\n"));
wf_rdpsnd_unlock();
break;
}
//fwrite(pbCaptureData, 1, dwCaptureLength, pFile);
//fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile);
//FIXME: frames = bytes/(bytespersample * channels)
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength/4);
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2/4);
hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2);
if (FAILED(hr))
{
_tprintf(_T("Failed to unlock sound capture buffer\n"));
wf_rdpsnd_unlock();
return 0;
}
//TODO keep track of location in buffer
capturePos += dwCaptureLength;
capturePos %= dscbd.dwBufferBytes;
capturePos += dwCaptureLength2;
capturePos %= dscbd.dwBufferBytes;
wf_rdpsnd_unlock();
}
end = GetTickCount();
diff = end - beg;
if (diff < rate)
{
Sleep(rate - diff);
}
}
_tprintf(_T("Trying to stop sound capture\n"));
hr = capBuf->lpVtbl->Stop(capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to stop capture\n"));
}
_tprintf(_T("Capture stopped\n"));
return 0;
}

View File

@ -26,7 +26,11 @@
#include "wf_interface.h"
int wf_rdpsnd_lock();
int wf_rdpsnd_unlock();
BOOL wf_peer_rdpsnd_init(wfPeerContext* context);
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam);
#endif /* WF_RDPSND_H */

View File

@ -1,21 +1,22 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Windows Server
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -37,6 +38,7 @@
DWORD WINAPI wf_update_thread(LPVOID lpParam)
{
int index;
int peerindex;
DWORD fps;
wfInfo* wfi;
DWORD beg, end;
@ -62,16 +64,20 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam)
wf_update_encode(wfi);
//printf("Start of parallel sending\n");
for (index = 0; index < wfi->peerCount; index++)
index = 0;
for (peerindex = 0; peerindex < wfi->peerCount; peerindex++)
{
if (wfi->peers[index]->activated)
for (; index < WF_INFO_MAXPEERS; index++)
{
if (wfi->peers[index] && wfi->peers[index]->activated)
{
//printf("Setting event for %d of %d\n", index + 1, wfi->activePeerCount);
SetEvent(((wfPeerContext*) wfi->peers[index]->context)->updateEvent);
}
}
}
for (index = 0; index < wfi->activePeerCount; index++)
{
//printf("Waiting for %d of %d\n", index + 1, wfi->activePeerCount);