Changeset 34906 in vbox for trunk/src/VBox
- Timestamp:
- Dec 9, 2010 4:29:49 PM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/audio.c
r33400 r34906 1551 1551 1552 1552 if (s->drv_opaque) { 1553 /* Filter must be installed before initializing voices. */ 1554 drv = filteraudio_install(drv, s->drv_opaque); 1553 1555 audio_init_nb_voices_out (s, drv); 1554 1556 audio_init_nb_voices_in (s, drv); -
trunk/src/VBox/Devices/Audio/audio_int.h
r12977 r34906 314 314 unsigned cSamples); 315 315 316 /* 317 * Filter interface. 318 */ 319 typedef DECLCALLBACK(int) FNAUDIOINPUTCALLBACK(void* pvCtx, uint32_t cbSamples, const void *pvSamples); 320 typedef FNAUDIOINPUTCALLBACK *PFNAUDIOINPUTCALLBACK; 321 322 int filter_output_intercepted(void); 323 int filter_output_begin(void **ppvOutputCtx, struct audio_pcm_info *pinfo, int samples); 324 void filter_output_end(void *pvOutputCtx); 325 326 int filter_input_intercepted(void); 327 int filter_input_begin(void **ppvInputCtx, PFNAUDIOINPUTCALLBACK pfnCallback, void *pvCallback, HWVoiceIn *phw, int samples); 328 void filter_input_end(void *pvInputCtx); 329 330 struct audio_driver *filteraudio_install(struct audio_driver *pDrv, void *pDrvOpaque); 331 316 332 #endif /* audio_int.h */ -
trunk/src/VBox/Devices/Audio/audiosniffer.c
r32339 r34906 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 22 23 23 #include <VBox/log.h> 24 #include <iprt/asm.h> 24 25 #include <iprt/assert.h> 25 26 #include <iprt/uuid.h> … … 40 41 /** Whether audio should reach the host driver too. */ 41 42 bool fKeepHostAudio; 43 44 /** Whether audio input operations should be forwarded to the connector. */ 45 bool fInterceptAudioInput; 42 46 43 47 /** Pointer to device instance. */ … … 100 104 101 105 /* 102 * Audio Sniffer PDM device. 103 */ 106 * Filter interface. 107 */ 108 109 /* Internal audio input context, which makes sure that: 110 * - the filter audio input callback is not called after the filter has issued filter_input_end; 111 * - maintains internal information and state of the audio stream. 112 */ 113 typedef struct SnifferInputCtx 114 { 115 /* Whether the context is still in use by the filter or I'll check. */ 116 int32_t volatile cRefs; 117 118 /* The filter callback for incoming audio data. */ 119 PFNAUDIOINPUTCALLBACK pfnFilterCallback; 120 void *pvFilterCallback; 121 122 /* Whether the stream has been ended by the filter. */ 123 bool fEndedByFilter; 124 125 /* Context pointer returned by pfnAudioInputBegin. */ 126 void *pvUserCtx; 127 128 /* Audio format used for recording. */ 129 HWVoiceIn *phw; 130 131 /* Number of bytes per frame (bitsPerSample * channels) of the actual input format. */ 132 uint32_t cBytesPerFrame; 133 134 /* Frequency of the actual audio format. */ 135 int iFreq; 136 137 /* Convertion from the actual input format to st_sample_t. */ 138 t_sample *conv; 139 140 /* If the actual format frequence differs from the requested format, this is not NULL. */ 141 void *rate; 142 143 } SnifferInputCtx; 144 145 /* 146 * Filter audio output. 147 */ 148 149 /* Whether the filter should intercept audio output. */ 150 int filter_output_intercepted(void) 151 { 152 return 0; /* @todo Not implemented yet.*/ 153 } 154 155 /* Filter informs that an audio output is starting. */ 156 int filter_output_begin(void **ppvOutputCtx, struct audio_pcm_info *pinfo, int samples) 157 { 158 return VERR_NOT_SUPPORTED; /* @todo Not implemented yet.*/ 159 } 160 161 /* Filter informs that the audio output has been stopped. */ 162 void filter_output_end(void *pvOutputCtx) 163 { 164 return; /* @todo Not implemented yet.*/ 165 } 166 167 /* 168 * Filter audio input. 169 */ 170 171 /* Whether the filter should intercept audio input. */ 172 int filter_input_intercepted(void) 173 { 174 if (!g_pData || !g_pData->pDrv) 175 { 176 return 0; 177 } 178 179 return g_pData->fInterceptAudioInput; 180 } 181 182 /* Filter informs that an audio input is starting. */ 183 int filter_input_begin (void **ppvInputCtx, PFNAUDIOINPUTCALLBACK pfnCallback, void *pvCallback, HWVoiceIn *phw, int cSamples) 184 { 185 int rc = VINF_SUCCESS; 186 187 SnifferInputCtx *pCtx = NULL; 188 189 if (!g_pData || !g_pData->pDrv) 190 { 191 return VERR_NOT_SUPPORTED; 192 } 193 194 pCtx = (SnifferInputCtx *)RTMemAlloc(sizeof(SnifferInputCtx)); 195 196 if (!pCtx) 197 { 198 return VERR_NO_MEMORY; 199 } 200 201 pCtx->cRefs = 2; /* Context is used by both the filter and the user. */ 202 pCtx->pfnFilterCallback = pfnCallback; 203 pCtx->pvFilterCallback = pvCallback; 204 pCtx->fEndedByFilter = false; 205 pCtx->pvUserCtx = NULL; 206 pCtx->phw = phw; 207 pCtx->cBytesPerFrame = 1; 208 pCtx->iFreq = 0; 209 pCtx->conv = NULL; 210 pCtx->rate = NULL; 211 212 rc = g_pData->pDrv->pfnAudioInputBegin (g_pData->pDrv, 213 &pCtx->pvUserCtx, /* Returned by the pDrv. */ 214 pCtx, 215 cSamples, /* How many samples in one block is preferred. */ 216 phw->info.freq, /* Required frequency. */ 217 phw->info.nchannels, /* Number of audio channels. */ 218 phw->info.bits); /* A sample size in one channel, samples are signed. */ 219 220 if (RT_SUCCESS(rc)) 221 { 222 *ppvInputCtx = pCtx; 223 } 224 else 225 { 226 RTMemFree(pCtx); 227 } 228 229 Log(("input_begin rc = %Rrc\n", rc)); 230 231 return rc; 232 } 233 234 /* Filter informs that the audio input must be stopped. */ 235 void filter_input_end(void *pvCtx) 236 { 237 int32_t c; 238 239 SnifferInputCtx *pCtx = (SnifferInputCtx *)pvCtx; 240 241 void *pvUserCtx = pCtx->pvUserCtx; 242 243 pCtx->fEndedByFilter = true; 244 245 c = ASMAtomicDecU32(&pCtx->cRefs); 246 247 if (c == 0) 248 { 249 /* The caller will not use this context anymore. */ 250 if (pCtx->rate) 251 { 252 st_rate_stop (pCtx->rate); 253 } 254 RTMemFree(pCtx); 255 pCtx = NULL; 256 } 257 258 if (!g_pData || !g_pData->pDrv) 259 { 260 AssertFailed(); 261 return; 262 } 263 264 g_pData->pDrv->pfnAudioInputEnd (g_pData->pDrv, 265 pvUserCtx); 266 267 Log(("input_end\n")); 268 } 269 270 271 /* 272 * Audio PDM device. 273 */ 274 static DECLCALLBACK(int) iface_AudioInputIntercept (PPDMIAUDIOSNIFFERPORT pInterface, bool fIntercept) 275 { 276 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IPort); 277 278 Assert(g_pData == pThis); 279 280 pThis->fInterceptAudioInput = fIntercept; 281 282 return VINF_SUCCESS; 283 } 284 285 static DECLCALLBACK(int) iface_AudioInputEventBegin (PPDMIAUDIOSNIFFERPORT pInterface, 286 void *pvContext, 287 int iSampleHz, 288 int cChannels, 289 int cBits, 290 bool fUnsigned) 291 { 292 int bitIdx; 293 294 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IPort); 295 296 int rc = VINF_SUCCESS; 297 298 SnifferInputCtx *pCtx = (SnifferInputCtx *)pvContext; 299 300 Log(("FilterAudio: AudioInputEventBegin: %dHz,%dch,%dbits,%d ended %d\n", 301 iSampleHz, cChannels, cBits, fUnsigned, pCtx->fEndedByFilter)); 302 303 Assert(g_pData == pThis); 304 305 /* Prepare a format convertion for the actually used format. */ 306 pCtx->cBytesPerFrame = ((cBits + 7) / 8) * cChannels; 307 308 if (cBits == 16) 309 { 310 bitIdx = 1; 311 } 312 else if (cBits == 32) 313 { 314 bitIdx = 2; 315 } 316 else 317 { 318 bitIdx = 0; 319 } 320 321 pCtx->conv = mixeng_conv[(cChannels == 2)? 1: 0] /* stereo */ 322 [!fUnsigned] /* sign */ 323 [0] /* big endian */ 324 [bitIdx]; /* bits */ 325 326 if (iSampleHz && iSampleHz != pCtx->phw->info.freq) 327 { 328 pCtx->rate = st_rate_start (iSampleHz, pCtx->phw->info.freq); 329 pCtx->iFreq = iSampleHz; 330 } 331 332 return rc; 333 } 334 335 static DECLCALLBACK(int) iface_AudioInputEventData (PPDMIAUDIOSNIFFERPORT pInterface, 336 void *pvContext, 337 const void *pvData, 338 uint32_t cbData) 339 { 340 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IPort); 341 342 int rc = VINF_SUCCESS; 343 344 SnifferInputCtx *pCtx = (SnifferInputCtx *)pvContext; 345 346 Log(("FilterAudio: AudioInputEventData: pvData %p. cbData %d, ended %d\n", pvData, cbData, pCtx->fEndedByFilter)); 347 348 Assert(g_pData == pThis); 349 350 if ( !pCtx->fEndedByFilter 351 && pCtx->conv) 352 { 353 /* Convert PCM samples to st_sample_t. 354 * And then apply rate convertion if necessary. 355 */ 356 /* @todo Optimization: allocate ps buffer once per context and reallocate if cbData changes. */ 357 uint32_t cs = cbData / pCtx->cBytesPerFrame; 358 st_sample_t *ps = (st_sample_t *)RTMemAlloc(cs * sizeof(st_sample_t)); 359 if (ps) 360 { 361 void *pvSamplesRateDst = NULL; 362 363 void *pvSamples = NULL; 364 uint32_t cbSamples = 0; 365 366 pCtx->conv(ps, pvData, cs, &nominal_volume); 367 368 if (pCtx->rate) 369 { 370 uint32_t csConverted = (cs * pCtx->phw->info.freq) / pCtx->iFreq; 371 pvSamplesRateDst = RTMemAlloc(csConverted * sizeof(st_sample_t)); 372 373 if (pvSamplesRateDst) 374 { 375 int csSrc = cs; 376 int csDst = csConverted; 377 378 st_rate_flow (pCtx->rate, 379 ps, (st_sample_t *)pvSamplesRateDst, 380 &csSrc, &csDst); 381 382 pvSamples = pvSamplesRateDst; 383 cbSamples = csDst * sizeof(st_sample_t); 384 } 385 else 386 { 387 rc = VERR_NO_MEMORY; 388 } 389 } 390 else 391 { 392 pvSamples = ps; 393 cbSamples = cs * sizeof(st_sample_t); 394 } 395 396 if (cbSamples) 397 { 398 rc = pCtx->pfnFilterCallback(pCtx->pvFilterCallback, cbSamples, pvSamples); 399 } 400 401 RTMemFree(pvSamplesRateDst); 402 RTMemFree(ps); 403 } 404 else 405 { 406 rc = VERR_NO_MEMORY; 407 } 408 } 409 410 return rc; 411 } 412 413 static DECLCALLBACK(void) iface_AudioInputEventEnd (PPDMIAUDIOSNIFFERPORT pInterface, 414 void *pvContext) 415 { 416 int32_t c; 417 418 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IPort); 419 420 SnifferInputCtx *pCtx = (SnifferInputCtx *)pvContext; 421 422 Log(("FilterAudio: AudioInputEventEnd: ended %d\n", pCtx->fEndedByFilter)); 423 424 Assert(g_pData == pThis); 425 426 c = ASMAtomicDecU32(&pCtx->cRefs); 427 428 if (c == 0) 429 { 430 /* The caller will not use this context anymore. */ 431 if (pCtx->rate) 432 { 433 st_rate_stop (pCtx->rate); 434 } 435 RTMemFree(pCtx); 436 } 437 } 438 104 439 105 440 static DECLCALLBACK(int) iface_Setup (PPDMIAUDIOSNIFFERPORT pInterface, bool fEnable, bool fKeepHostAudio) … … 159 494 * Validate configuration. 160 495 */ 161 if (!CFGMR3AreValuesValid(pCfgHandle, " \0"))496 if (!CFGMR3AreValuesValid(pCfgHandle, "InterceptAudioInput\0")) 162 497 { 163 498 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; … … 170 505 pThis->fKeepHostAudio = true; 171 506 pThis->pDrv = NULL; 507 rc = CFGMR3QueryBoolDef(pCfgHandle, "InterceptAudioInput", &pThis->fInterceptAudioInput, false); 508 if (RT_FAILURE(rc)) 509 return PDMDEV_SET_ERROR(pDevIns, rc, 510 N_("Configuration error: Failed to get the \"YieldOnLSRRead\" value")); 172 511 173 512 /* … … 179 518 /* Audio Sniffer port */ 180 519 pThis->IPort.pfnSetup = iface_Setup; 520 pThis->IPort.pfnAudioInputIntercept = iface_AudioInputIntercept; 521 pThis->IPort.pfnAudioInputEventBegin = iface_AudioInputEventBegin; 522 pThis->IPort.pfnAudioInputEventData = iface_AudioInputEventData; 523 pThis->IPort.pfnAudioInputEventEnd = iface_AudioInputEventEnd; 181 524 182 525 /* -
trunk/src/VBox/Devices/Makefile.kmk
r34876 r34906 794 794 Audio/mixeng.c \ 795 795 Audio/noaudio.c \ 796 Audio/filteraudio.c \ 796 797 Input/DrvKeyboardQueue.cpp \ 797 798 Input/DrvMouseQueue.cpp \ -
trunk/src/VBox/Main/AudioSnifferInterface.cpp
r33004 r34906 113 113 } 114 114 115 DECLCALLBACK(int) iface_AudioInputBegin (PPDMIAUDIOSNIFFERCONNECTOR pInterface, 116 void **ppvUserCtx, 117 void *pvContext, 118 uint32_t cSamples, 119 uint32_t iSampleHz, 120 uint32_t cChannels, 121 uint32_t cBits) 122 { 123 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 124 125 return pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputBegin(ppvUserCtx, 126 pvContext, 127 cSamples, 128 iSampleHz, 129 cChannels, 130 cBits); 131 } 132 133 DECLCALLBACK(void) iface_AudioInputEnd (PPDMIAUDIOSNIFFERCONNECTOR pInterface, 134 void *pvUserCtx) 135 { 136 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 137 138 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputEnd(pvUserCtx); 139 } 140 115 141 116 142 /** … … 175 201 pThis->Connector.pfnAudioSamplesOut = iface_AudioSamplesOut; 176 202 pThis->Connector.pfnAudioVolumeOut = iface_AudioVolumeOut; 203 pThis->Connector.pfnAudioInputBegin = iface_AudioInputBegin; 204 pThis->Connector.pfnAudioInputEnd = iface_AudioInputEnd; 177 205 178 206 /* -
trunk/src/VBox/Main/ConsoleVRDPServer.cpp
r34574 r34906 21 21 #include "KeyboardImpl.h" 22 22 #include "MouseImpl.h" 23 #include "AudioSnifferInterface.h" 23 24 #ifdef VBOX_WITH_EXTPACK 24 25 # include "ExtPackManagerImpl.h" … … 510 511 PFNVRDECREATESERVER ConsoleVRDPServer::mpfnVRDECreateServer = NULL; 511 512 512 VRDEENTRYPOINTS_1 *ConsoleVRDPServer::mpEntryPoints = NULL; 513 514 VRDECALLBACKS_1 ConsoleVRDPServer::mCallbacks = 515 { 516 { VRDE_INTERFACE_VERSION_1, sizeof(VRDECALLBACKS_1) }, 513 VRDEENTRYPOINTS_3 ConsoleVRDPServer::mEntryPoints; /* A copy of the server entry points. */ 514 VRDEENTRYPOINTS_3 *ConsoleVRDPServer::mpEntryPoints = NULL; 515 516 VRDECALLBACKS_3 ConsoleVRDPServer::mCallbacks = 517 { 518 { VRDE_INTERFACE_VERSION_3, sizeof(VRDECALLBACKS_3) }, 517 519 ConsoleVRDPServer::VRDPCallbackQueryProperty, 518 520 ConsoleVRDPServer::VRDPCallbackClientLogon, … … 526 528 ConsoleVRDPServer::VRDPCallbackFramebufferUnlock, 527 529 ConsoleVRDPServer::VRDPCallbackInput, 528 ConsoleVRDPServer::VRDPCallbackVideoModeHint 530 ConsoleVRDPServer::VRDPCallbackVideoModeHint, 531 ConsoleVRDPServer::VRDECallbackAudioIn 529 532 }; 530 533 … … 851 854 852 855 server->mConsole->VRDPClientDisconnect(u32ClientId, fu32Intercepted); 856 857 if (ASMAtomicReadU32(&server->mu32AudioInputClientId) == u32ClientId) 858 { 859 Log(("AUDIOIN: disconnected client %u\n", u32ClientId)); 860 ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0); 861 862 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 863 if (pPort) 864 { 865 // @todo dynamic filter attach does not yet work pPort->pfnAudioInputIntercept(pPort, false); 866 } 867 else 868 { 869 AssertFailed(); 870 } 871 } 853 872 } 854 873 … … 887 906 } 888 907 rc = VINF_SUCCESS; 908 } break; 909 910 case VRDE_CLIENT_INTERCEPT_AUDIO_INPUT: 911 { 912 /* This request is processed internally by the ConsoleVRDPServer. 913 * Only one client is allowed to intercept audio input. 914 */ 915 if (ASMAtomicCmpXchgU32(&server->mu32AudioInputClientId, u32ClientId, 0) == true) 916 { 917 Log(("AUDIOIN: connected client %u\n", u32ClientId)); 918 919 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 920 if (pPort) 921 { 922 // @todo dynamic filter attach does not yet work pPort->pfnAudioInputIntercept(pPort, true); 923 if (ppvIntercept) 924 { 925 *ppvIntercept = server; 926 } 927 } 928 else 929 { 930 AssertFailed(); 931 ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0); 932 rc = VERR_NOT_SUPPORTED; 933 } 934 } 935 else 936 { 937 Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, server->mu32AudioInputClientId)); 938 rc = VERR_NOT_SUPPORTED; 939 } 889 940 } break; 890 941 … … 1139 1190 } 1140 1191 1192 DECLCALLBACK(void) ConsoleVRDPServer::VRDECallbackAudioIn(void *pvCallback, 1193 void *pvCtx, 1194 uint32_t u32ClientId, 1195 uint32_t u32Event, 1196 const void *pvData, 1197 uint32_t cbData) 1198 { 1199 ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback); 1200 1201 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 1202 1203 switch (u32Event) 1204 { 1205 case VRDE_AUDIOIN_BEGIN: 1206 { 1207 const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData; 1208 1209 pPort->pfnAudioInputEventBegin (pPort, pvCtx, 1210 VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt), 1211 VRDE_AUDIO_FMT_CHANNELS(pParms->fmt), 1212 VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt), 1213 VRDE_AUDIO_FMT_SIGNED(pParms->fmt) 1214 ); 1215 } break; 1216 1217 case VRDE_AUDIOIN_DATA: 1218 { 1219 pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData); 1220 } break; 1221 1222 case VRDE_AUDIOIN_END: 1223 { 1224 pPort->pfnAudioInputEventEnd (pPort, pvCtx); 1225 } break; 1226 1227 default: 1228 return; 1229 } 1230 } 1231 1232 1141 1233 ConsoleVRDPServer::ConsoleVRDPServer(Console *console) 1142 1234 { … … 1159 1251 1160 1252 mhServer = 0; 1253 mServerInterfaceVersion = 0; 1161 1254 1162 1255 m_fGuestWantsAbsolute = false; … … 1191 1284 1192 1285 mAuthLibrary = 0; 1286 1287 mu32AudioInputClientId = 0; 1193 1288 } 1194 1289 … … 1272 1367 if (RT_SUCCESS(vrc)) 1273 1368 { 1274 vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&mpEntryPoints, &mhServer); 1369 VRDEENTRYPOINTS_3 *pEntryPoints3; 1370 vrc = mpfnVRDECreateServer(&mCallbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints3, &mhServer); 1371 1372 if (RT_SUCCESS(vrc)) 1373 { 1374 mServerInterfaceVersion = 3; 1375 mEntryPoints = *pEntryPoints3; 1376 mpEntryPoints = &mEntryPoints; 1377 } 1378 else if (vrc == VERR_VERSION_MISMATCH) 1379 { 1380 /* An older version of VRDE is installed, try version 1. */ 1381 VRDEENTRYPOINTS_1 *pEntryPoints1; 1382 1383 VRDECALLBACKS_1 callbacks = 1384 { 1385 { VRDE_INTERFACE_VERSION_1, sizeof(VRDECALLBACKS_1) }, 1386 ConsoleVRDPServer::VRDPCallbackQueryProperty, 1387 ConsoleVRDPServer::VRDPCallbackClientLogon, 1388 ConsoleVRDPServer::VRDPCallbackClientConnect, 1389 ConsoleVRDPServer::VRDPCallbackClientDisconnect, 1390 ConsoleVRDPServer::VRDPCallbackIntercept, 1391 ConsoleVRDPServer::VRDPCallbackUSB, 1392 ConsoleVRDPServer::VRDPCallbackClipboard, 1393 ConsoleVRDPServer::VRDPCallbackFramebufferQuery, 1394 ConsoleVRDPServer::VRDPCallbackFramebufferLock, 1395 ConsoleVRDPServer::VRDPCallbackFramebufferUnlock, 1396 ConsoleVRDPServer::VRDPCallbackInput, 1397 ConsoleVRDPServer::VRDPCallbackVideoModeHint 1398 }; 1399 1400 vrc = mpfnVRDECreateServer(&callbacks.header, this, (VRDEINTERFACEHDR **)&pEntryPoints1, &mhServer); 1401 if (RT_SUCCESS(vrc)) 1402 { 1403 LogRel(("VRDE: loaded an older version of the server.\n")); 1404 1405 mServerInterfaceVersion = 3; 1406 mEntryPoints.header = pEntryPoints1->header; 1407 mEntryPoints.VRDEDestroy = pEntryPoints1->VRDEDestroy; 1408 mEntryPoints.VRDEEnableConnections = pEntryPoints1->VRDEEnableConnections; 1409 mEntryPoints.VRDEDisconnect = pEntryPoints1->VRDEDisconnect; 1410 mEntryPoints.VRDEResize = pEntryPoints1->VRDEResize; 1411 mEntryPoints.VRDEUpdate = pEntryPoints1->VRDEUpdate; 1412 mEntryPoints.VRDEColorPointer = pEntryPoints1->VRDEColorPointer; 1413 mEntryPoints.VRDEHidePointer = pEntryPoints1->VRDEHidePointer; 1414 mEntryPoints.VRDEAudioSamples = pEntryPoints1->VRDEAudioSamples; 1415 mEntryPoints.VRDEAudioVolume = pEntryPoints1->VRDEAudioVolume; 1416 mEntryPoints.VRDEUSBRequest = pEntryPoints1->VRDEUSBRequest; 1417 mEntryPoints.VRDEClipboard = pEntryPoints1->VRDEClipboard; 1418 mEntryPoints.VRDEQueryInfo = pEntryPoints1->VRDEQueryInfo; 1419 mEntryPoints.VRDERedirect = NULL; 1420 mEntryPoints.VRDEAudioInOpen = NULL; 1421 mEntryPoints.VRDEAudioInClose = NULL; 1422 mpEntryPoints = &mEntryPoints; 1423 } 1424 } 1425 1275 1426 if (RT_SUCCESS(vrc)) 1276 1427 { … … 1282 1433 { 1283 1434 if (vrc != VERR_NET_ADDRESS_IN_USE) 1284 LogRel(("VRDE: Could not start VRDPserver rc = %Rrc\n", vrc));1435 LogRel(("VRDE: Could not start the server rc = %Rrc\n", vrc)); 1285 1436 /* Don't unload the lib, because it prevents us trying again or 1286 1437 because there may be other users? */ … … 2098 2249 } 2099 2250 } 2251 2252 /* @todo rc not needed? */ 2253 int ConsoleVRDPServer::SendAudioInputBegin(void **ppvUserCtx, 2254 void *pvContext, 2255 uint32_t cSamples, 2256 uint32_t iSampleHz, 2257 uint32_t cChannels, 2258 uint32_t cBits) 2259 { 2260 if (mpEntryPoints && mhServer && mpEntryPoints->VRDEAudioInOpen) 2261 { 2262 uint32_t u32ClientId = ASMAtomicReadU32(&mu32AudioInputClientId); 2263 if (u32ClientId != 0) /* 0 would mean broadcast to all clients. */ 2264 { 2265 VRDEAUDIOFORMAT audioFormat = VRDE_AUDIO_FMT_MAKE(iSampleHz, cChannels, cBits, 0); 2266 mpEntryPoints->VRDEAudioInOpen (mhServer, 2267 pvContext, 2268 u32ClientId, 2269 audioFormat, 2270 cSamples); 2271 *ppvUserCtx = NULL; /* This is the ConsoleVRDP server context. 2272 * Currently not used because only one client is allowed to 2273 * do audio input and the client id is saved by the ConsoleVRDPServer. 2274 */ 2275 2276 return VINF_SUCCESS; 2277 } 2278 } 2279 return VERR_NOT_SUPPORTED; 2280 } 2281 2282 void ConsoleVRDPServer::SendAudioInputEnd(void *pvUserCtx) 2283 { 2284 if (mpEntryPoints && mhServer && mpEntryPoints->VRDEAudioInClose) 2285 { 2286 uint32_t u32ClientId = ASMAtomicReadU32(&mu32AudioInputClientId); 2287 if (u32ClientId != 0) /* 0 would mean broadcast to all clients. */ 2288 { 2289 mpEntryPoints->VRDEAudioInClose(mhServer, u32ClientId); 2290 } 2291 } 2292 } 2293 2294 2100 2295 2101 2296 void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const -
trunk/src/VBox/Main/include/ConsoleImpl.h
r34587 r34906 168 168 Display *getDisplay() const { return mDisplay; } 169 169 MachineDebugger *getMachineDebugger() const { return mDebugger; } 170 AudioSniffer *getAudioSniffer() const { return mAudioSniffer; } 170 171 171 172 const ComPtr<IMachine> &machine() const { return mMachine; } -
trunk/src/VBox/Main/include/ConsoleVRDPServer.h
r34563 r34906 128 128 void QueryInfo (uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const; 129 129 130 int SendAudioInputBegin(void **ppvUserCtx, 131 void *pvContext, 132 uint32_t cSamples, 133 uint32_t iSampleHz, 134 uint32_t cChannels, 135 uint32_t cBits); 136 137 void SendAudioInputEnd(void *pvUserCtx); 138 130 139 private: 131 140 /* Note: This is not a ComObjPtr here, because the ConsoleVRDPServer object … … 135 144 136 145 HVRDESERVER mhServer; 146 int mServerInterfaceVersion; 137 147 138 148 static int loadVRDPLibrary (const char *pszLibraryName); … … 143 153 static PFNVRDECREATESERVER mpfnVRDECreateServer; 144 154 145 static VRDEENTRYPOINTS_1 *mpEntryPoints; 146 static VRDECALLBACKS_1 mCallbacks; 155 static VRDEENTRYPOINTS_3 mEntryPoints; 156 static VRDEENTRYPOINTS_3 *mpEntryPoints; 157 static VRDECALLBACKS_3 mCallbacks; 147 158 148 159 static DECLCALLBACK(int) VRDPCallbackQueryProperty (void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); … … 158 169 static DECLCALLBACK(void) VRDPCallbackInput (void *pvCallback, int type, const void *pvInput, unsigned cbInput); 159 170 static DECLCALLBACK(void) VRDPCallbackVideoModeHint (void *pvCallback, unsigned cWidth, unsigned cHeight, unsigned cBitsPerPixel, unsigned uScreenId); 171 static DECLCALLBACK(void) VRDECallbackAudioIn (void *pvCallback, void *pvCtx, uint32_t u32ClientId, uint32_t u32Event, const void *pvData, uint32_t cbData); 160 172 161 173 bool m_fGuestWantsAbsolute; … … 212 224 PAUTHENTRY2 mpfnAuthEntry2; 213 225 PAUTHENTRY3 mpfnAuthEntry3; 226 227 uint32_t volatile mu32AudioInputClientId; 214 228 }; 215 229
Note:
See TracChangeset
for help on using the changeset viewer.