FreeRDP
wf_rdpsnd.c
1 
21 #include <freerdp/config.h>
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include <winpr/windows.h>
27 #include <freerdp/server/server-common.h>
28 
29 #include "wf_rdpsnd.h"
30 #include "wf_info.h"
31 
32 #ifdef WITH_RDPSND_DSOUND
33 
34 #include "wf_directsound.h"
35 
36 #else
37 
38 #include "wf_wasapi.h"
39 
40 #endif
41 
42 #include <freerdp/log.h>
43 #define TAG SERVER_TAG("windows")
44 
45 static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
46 {
47  wfInfo* wfi;
48  wfi = wf_info_get_instance();
49  wfi->agreed_format = NULL;
50  WLog_DBG(TAG, "Client supports the following %d formats:", context->num_client_formats);
51 
52  size_t i = 0;
53  for (; i < context->num_client_formats; i++)
54  {
55  // TODO: improve the way we agree on a format
56  for (size_t j = 0; j < context->num_server_formats; j++)
57  {
58  if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) &&
59  (context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
60  (context->client_formats[i].nSamplesPerSec ==
61  context->server_formats[j].nSamplesPerSec))
62  {
63  WLog_DBG(TAG, "agreed on format!");
64  wfi->agreed_format = (AUDIO_FORMAT*)&context->server_formats[j];
65  break;
66  }
67  }
68 
69  if (wfi->agreed_format != NULL)
70  break;
71  }
72 
73  if (wfi->agreed_format == NULL)
74  {
75  WLog_ERR(TAG, "Could not agree on a audio format with the server");
76  return;
77  }
78 
79  context->SelectFormat(context, i);
80  context->SetVolume(context, 0x7FFF, 0x7FFF);
81 #ifdef WITH_RDPSND_DSOUND
82  wf_directsound_activate(context);
83 #else
84  wf_wasapi_activate(context);
85 #endif
86 }
87 
88 int wf_rdpsnd_lock()
89 {
90  DWORD dRes;
91  wfInfo* wfi;
92  wfi = wf_info_get_instance();
93  dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE);
94 
95  switch (dRes)
96  {
97  case WAIT_ABANDONED:
98  case WAIT_OBJECT_0:
99  return TRUE;
100  break;
101 
102  case WAIT_TIMEOUT:
103  return FALSE;
104  break;
105 
106  case WAIT_FAILED:
107  WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError());
108  return -1;
109  break;
110  }
111 
112  return -1;
113 }
114 
115 int wf_rdpsnd_unlock()
116 {
117  wfInfo* wfi;
118  wfi = wf_info_get_instance();
119 
120  if (ReleaseMutex(wfi->snd_mutex) == 0)
121  {
122  WLog_DBG(TAG, "wf_rdpsnd_unlock failed with 0x%08lX", GetLastError());
123  return -1;
124  }
125 
126  return TRUE;
127 }
128 
129 BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
130 {
131  wfInfo* wfi = wf_info_get_instance();
132 
133  if (!wfi)
134  return FALSE;
135 
136  if (!(wfi->snd_mutex = CreateMutex(NULL, FALSE, NULL)))
137  return FALSE;
138 
139  context->rdpsnd = rdpsnd_server_context_new(context->vcm);
140  context->rdpsnd->rdpcontext = &context->_p;
141  context->rdpsnd->data = context;
142  context->rdpsnd->num_server_formats =
143  server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
144 
145  if (context->rdpsnd->num_server_formats > 0)
146  context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
147 
148  context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
149  context->rdpsnd->Initialize(context->rdpsnd, TRUE);
150  wf_rdpsnd_set_latest_peer(context);
151  wfi->snd_stop = FALSE;
152  return TRUE;
153 }