Changeset 65624 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Feb 6, 2017 2:13:36 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 113296
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r65596 r65624 61 61 } DRVAUDIOVRDE, *PDRVAUDIOVRDE; 62 62 63 typedef struct VRDESTREAM IN64 { 65 /** Note: Always must come first!*/66 P DMAUDIOSTREAM Stream;67 /** The PCM properties of this stream. */68 PDMAUDIOPCMPROPS Props;69 /** Number of samples this stream can handle at once. */70 uint32_t cSamplesMax;71 /** Circular buffer for holding the recorded audio samples from the host. */72 PRTCIRCBUF pCircBuf;73 } VRDESTREAMIN, *PVRDESTREAMIN; 74 75 typedef struct VRDESTREAMOUT 76 { 77 /** Note: Always must come first! */78 PDMAUDIOSTREAM Stream;79 /** The PCM properties of this stream. */80 PDMAUDIOPCMPROPS Props;81 uint64_t old_ticks;82 uint64_t cSamplesSentPerSec;83 } VRDESTREAMOUT, *PVRDESTREAMOUT; 84 85 86 87 static int vrdeCreateStreamIn(PVRDESTREAMIN pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 88 { 89 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props);63 typedef struct VRDESTREAM 64 { 65 /** The stream's acquired configuration. */ 66 PPDMAUDIOSTREAMCFG pCfg; 67 union 68 { 69 struct 70 { 71 /** Number of samples this stream can handle at once. */ 72 uint32_t cSamplesMax; 73 /** Circular buffer for holding the recorded audio samples from the host. */ 74 PRTCIRCBUF pCircBuf; 75 } In; 76 struct 77 { 78 uint64_t old_ticks; 79 uint64_t cSamplesSentPerSec; 80 } Out; 81 }; 82 } VRDESTREAM, *PVRDESTREAM; 83 84 85 static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 86 { 87 pStreamVRDE->In.cSamplesMax = _1K; /** @todo Make this configurable. */ 88 89 int rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, pStreamVRDE->In.cSamplesMax * (pCfgReq->Props.cBits / 8) /* Bytes */); 90 90 if (RT_SUCCESS(rc)) 91 91 { 92 pStreamVRDE->cSamplesMax = _1K; /** @todo Make this configurable. */ 93 94 rc = RTCircBufCreate(&pStreamVRDE->pCircBuf, pStreamVRDE->cSamplesMax * (pStreamVRDE->Props.cBits / 8) /* Bytes */); 95 if (RT_SUCCESS(rc)) 96 { 97 if (pCfgAcq) 98 pCfgAcq->cSampleBufferSize = pStreamVRDE->cSamplesMax; 99 } 92 if (pCfgAcq) 93 pCfgAcq->cSampleBufferHint = pStreamVRDE->In.cSamplesMax; 100 94 } 101 95 … … 104 98 105 99 106 static int vrdeCreateStreamOut(PVRDESTREAMOUT pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 107 { 108 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props); 109 if (RT_SUCCESS(rc)) 110 { 111 if (pCfgAcq) 112 pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */ 113 } 114 115 return rc; 116 } 117 118 119 static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAMOUT pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 100 static int vrdeCreateStreamOut(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 101 { 102 RT_NOREF(pStreamVRDE, pCfgReq); 103 104 if (pCfgAcq) 105 pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */ 106 107 return VINF_SUCCESS; 108 } 109 110 111 static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 120 112 { 121 113 RT_NOREF(pDrv, pStreamVRDE, enmStreamCmd); … … 127 119 128 120 129 static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM IN pVRDEStrmIn, PDMAUDIOSTREAMCMD enmStreamCmd)121 static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 130 122 { 131 123 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); … … 141 133 case PDMAUDIOSTREAMCMD_ENABLE: 142 134 { 143 rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, p VRDEStrmIn, pVRDEStrmIn->cSamplesMax,144 p VRDEStrmIn->Props.uHz,145 p VRDEStrmIn->Props.cChannels, pVRDEStrmIn->Props.cBits);135 rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pStreamVRDE, pStreamVRDE->In.cSamplesMax, 136 pStreamVRDE->pCfg->Props.uHz, pStreamVRDE->pCfg->Props.cChannels, 137 pStreamVRDE->pCfg->Props.cBits); 146 138 if (rc == VERR_NOT_SUPPORTED) 147 139 { … … 203 195 */ 204 196 static DECLCALLBACK(int) drvAudioVRDEStreamCapture(PPDMIHOSTAUDIO pInterface, 205 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)197 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 206 198 { 207 199 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 211 203 /* pcbRead is optional. */ 212 204 213 PVRDESTREAM IN pStreamVRDE = (PVRDESTREAMIN)pStream;205 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 214 206 215 207 size_t cbData = 0; 216 208 217 if (RTCircBufUsed(pStreamVRDE-> pCircBuf))209 if (RTCircBufUsed(pStreamVRDE->In.pCircBuf)) 218 210 { 219 211 void *pvData; 220 212 221 RTCircBufAcquireReadBlock(pStreamVRDE-> pCircBuf, cbBuf, &pvData, &cbData);213 RTCircBufAcquireReadBlock(pStreamVRDE->In.pCircBuf, cbBuf, &pvData, &cbData); 222 214 223 215 if (cbData) 224 216 memcpy(pvBuf, pvData, cbData); 225 217 226 RTCircBufReleaseReadBlock(pStreamVRDE-> pCircBuf, cbData);218 RTCircBufReleaseReadBlock(pStreamVRDE->In.pCircBuf, cbData); 227 219 } 228 220 … … 237 229 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 238 230 */ 239 static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface, 240 PPDMAUDIOSTREAM pStream,const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)231 static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 232 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 241 233 { 242 234 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 246 238 /* pcbWritten is optional. */ 247 239 248 PDRVAUDIOVRDE 249 PVRDESTREAM OUT pStreamVRDE = (PVRDESTREAMOUT)pStream;240 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 241 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 250 242 251 243 uint32_t cbLive = cbBuf; 252 244 253 245 uint64_t now = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 254 uint64_t ticks = now - pStreamVRDE-> old_ticks;246 uint64_t ticks = now - pStreamVRDE->Out.old_ticks; 255 247 uint64_t ticks_per_second = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 256 248 249 PPDMAUDIOPCMPROPS pProps = &pStreamVRDE->pCfg->Props; 250 257 251 /* Minimize the rounding error: samples = int((ticks * freq) / ticks_per_second + 0.5). */ 258 uint32_t cbToWrite = (int)((2 * ticks * p StreamVRDE->Props.uHz + ticks_per_second) / ticks_per_second / 2);252 uint32_t cbToWrite = (int)((2 * ticks * pProps->uHz + ticks_per_second) / ticks_per_second / 2); 259 253 260 254 /* Remember when samples were consumed. */ 261 pStreamVRDE-> old_ticks = now;262 263 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(p StreamVRDE->Props.uHz,264 p StreamVRDE->Props.cChannels,265 p StreamVRDE->Props.cBits,266 p StreamVRDE->Props.fSigned);255 pStreamVRDE->Out.old_ticks = now; 256 257 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pProps->uHz, 258 pProps->cChannels, 259 pProps->cBits, 260 pProps->fSigned); 267 261 268 262 Log2Func(("uFreq=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool, enmFormat=%ld, cbLive=%RU32, cbToWrite=%RU32\n", 269 pStreamVRDE->Props.uHz, pStreamVRDE->Props.cChannels, 270 pStreamVRDE->Props.cBits, pStreamVRDE->Props.fSigned, 271 format, cbLive, cbToWrite)); 263 pProps->uHz, pProps->cChannels, pProps->cBits, pProps->fSigned, format, cbLive, cbToWrite)); 272 264 273 265 /* Don't play more than available. */ … … 291 283 292 284 pDrv->pConsoleVRDPServer->SendAudioSamples((uint8_t *)pvBuf + cbWritten, 293 PDMAUDIO PCMPROPS_B2S(&pStreamVRDE->Props, cbChunk) /* Samples */, format);285 PDMAUDIOSTREAMCFG_B2S(pStreamVRDE->pCfg, cbChunk) /* Samples */, format); 294 286 cbWritten += cbChunk; 295 287 Assert(cbWritten <= cbBuf); … … 311 303 312 304 313 static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM INpStreamVRDE)305 static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE) 314 306 { 315 307 if (pDrv->pConsoleVRDPServer) 316 308 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 317 309 318 if (pStreamVRDE-> pCircBuf)319 { 320 RTCircBufDestroy(pStreamVRDE-> pCircBuf);321 pStreamVRDE-> pCircBuf = NULL;322 } 323 324 return VINF_SUCCESS; 325 } 326 327 328 static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM OUTpStreamVRDE)310 if (pStreamVRDE->In.pCircBuf) 311 { 312 RTCircBufDestroy(pStreamVRDE->In.pCircBuf); 313 pStreamVRDE->In.pCircBuf = NULL; 314 } 315 316 return VINF_SUCCESS; 317 } 318 319 320 static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE) 329 321 { 330 322 RT_NOREF(pDrv, pStreamVRDE); … … 339 331 static DECLCALLBACK(int) drvAudioVRDEGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 340 332 { 341 NOREF(pInterface);333 RT_NOREF(pInterface); 342 334 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 343 335 344 pBackendCfg->cbStreamOut = sizeof(VRDESTREAM OUT);345 pBackendCfg->cbStreamIn = sizeof(VRDESTREAM IN);336 pBackendCfg->cbStreamOut = sizeof(VRDESTREAM); 337 pBackendCfg->cbStreamIn = sizeof(VRDESTREAM); 346 338 pBackendCfg->cMaxStreamsIn = UINT32_MAX; 347 339 pBackendCfg->cMaxStreamsOut = UINT32_MAX; … … 379 371 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 380 372 */ 381 static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface, 382 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)373 static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 374 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 383 375 { 384 376 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 389 381 RT_NOREF(pInterface); 390 382 383 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 384 391 385 int rc; 392 386 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 393 { 394 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream; 395 rc = vrdeCreateStreamIn(pStreamVRDE, pCfgReq, pCfgAcq); 396 } 387 rc = vrdeCreateStreamIn (pStreamVRDE, pCfgReq, pCfgAcq); 397 388 else 398 {399 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;400 389 rc = vrdeCreateStreamOut(pStreamVRDE, pCfgReq, pCfgAcq); 390 391 if (RT_SUCCESS(rc)) 392 { 393 pStreamVRDE->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 394 if (!pStreamVRDE->pCfg) 395 rc = VERR_NO_MEMORY; 401 396 } 402 397 … … 408 403 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 409 404 */ 410 static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 405 static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 406 { 407 RT_NOREF(pInterface); 408 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 409 410 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 411 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 412 413 if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */ 414 return VINF_SUCCESS; 415 416 int rc; 417 if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN) 418 rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE); 419 else 420 rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE); 421 422 if (RT_SUCCESS(rc)) 423 { 424 DrvAudioHlpStreamCfgFree(pStreamVRDE->pCfg); 425 pStreamVRDE->pCfg = NULL; 426 } 427 428 return rc; 429 } 430 431 432 /** 433 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 434 */ 435 static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface, 436 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 411 437 { 412 438 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 413 439 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 414 440 415 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 441 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 442 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 443 444 if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */ 445 return VINF_SUCCESS; 416 446 417 447 int rc; 418 if (pStream->enmDir == PDMAUDIODIR_IN) 419 { 420 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream; 421 rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE); 422 } 448 if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN) 449 rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd); 423 450 else 424 { 425 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream; 426 rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE); 427 } 451 rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd); 428 452 429 453 return rc; … … 432 456 433 457 /** 434 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 435 */ 436 static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface, 437 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 458 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 459 */ 460 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 461 { 462 RT_NOREF(pInterface); 463 RT_NOREF(pStream); 464 465 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED 466 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE); 467 } 468 469 470 /** 471 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 472 */ 473 static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 438 474 { 439 475 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 440 476 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 441 442 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);443 444 int rc;445 if (pStream->enmDir == PDMAUDIODIR_IN)446 {447 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;448 rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd);449 }450 else451 {452 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;453 rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd);454 }455 456 return rc;457 }458 459 460 /**461 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}462 */463 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)464 {465 NOREF(pInterface);466 NOREF(pStream);467 468 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED469 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE);470 }471 472 473 /**474 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}475 */476 static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)477 {478 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);479 AssertPtrReturn(pStream, VERR_INVALID_POINTER);480 481 LogFlowFuncEnter();482 477 483 478 /* Nothing to do here for VRDE. */ … … 543 538 AssertPtrReturn(pVRDEAudioBegin, VERR_INVALID_POINTER); 544 539 545 PVRDESTREAM IN pVRDEStrmIn = (PVRDESTREAMIN)pvContext;540 PVRDESTREAM pVRDEStrmIn = (PVRDESTREAM)pvContext; 546 541 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 547 542 548 543 VRDEAUDIOFORMAT audioFmt = pVRDEAudioBegin->fmt; 549 544 550 int iSampleHz = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt); NOREF(iSampleHz);551 int cChannels = VRDE_AUDIO_FMT_CHANNELS(audioFmt); NOREF(cChannels);552 int cBits = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); NOREF(cBits);553 bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt); NOREF(fUnsigned);545 int iSampleHz = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt); RT_NOREF(iSampleHz); 546 int cChannels = VRDE_AUDIO_FMT_CHANNELS(audioFmt); RT_NOREF(cChannels); 547 int cBits = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); RT_NOREF(cBits); 548 bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt); RT_NOREF(fUnsigned); 554 549 555 550 LogFlowFunc(("cbSample=%RU32, iSampleHz=%d, cChannels=%d, cBits=%d, fUnsigned=%RTbool\n", … … 562 557 int AudioVRDE::onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData) 563 558 { 564 PVRDESTREAM IN pStreamVRDE = (PVRDESTREAMIN)pvContext;559 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pvContext; 565 560 AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER); 566 561 … … 568 563 size_t cbBuf; 569 564 570 RTCircBufAcquireWriteBlock(pStreamVRDE-> pCircBuf, cbData, &pvBuf, &cbBuf);565 RTCircBufAcquireWriteBlock(pStreamVRDE->In.pCircBuf, cbData, &pvBuf, &cbBuf); 571 566 572 567 if (cbBuf) 573 568 memcpy(pvBuf, pvData, cbBuf); 574 569 575 RTCircBufReleaseWriteBlock(pStreamVRDE-> pCircBuf, cbBuf);570 RTCircBufReleaseWriteBlock(pStreamVRDE->In.pCircBuf, cbBuf); 576 571 577 572 if (cbBuf < cbData) … … 584 579 int AudioVRDE::onVRDEInputEnd(void *pvContext) 585 580 { 586 NOREF(pvContext);581 RT_NOREF(pvContext); 587 582 588 583 return VINF_SUCCESS; -
trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
r65565 r65624 180 180 181 181 /** 182 * Audio video recording output stream. 183 */ 184 typedef struct AVRECSTREAMOUT 185 { 186 /** Note: Always must come first! */ 187 PDMAUDIOSTREAM Stream; 188 /** The PCM properties of this stream. */ 189 PDMAUDIOPCMPROPS Props; 182 * Audio video recording (output) stream. 183 */ 184 typedef struct AVRECSTREAM 185 { 186 /** The stream's acquired configuration. */ 187 PPDMAUDIOSTREAMCFG pCfg; 190 188 /** (Audio) frame buffer. */ 191 189 PRTCIRCBUF pCircBuf; 192 190 /** Pointer to sink to use for writing. */ 193 191 PAVRECSINK pSink; 194 } AVRECSTREAM OUT, *PAVRECSTREAMOUT;192 } AVRECSTREAM, *PAVRECSTREAM; 195 193 196 194 /** … … 359 357 * @returns IPRT status code. 360 358 * @param pThis Driver instance. 361 * @param pStream 359 * @param pStreamAV Audio output stream to create. 362 360 * @param pSink Recording sink to associate audio output stream to. 363 361 * @param pCfgReq Requested configuration by the audio backend. 364 362 * @param pCfgAcq Acquired configuration by the audio output stream. 365 363 */ 366 static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, P PDMAUDIOSTREAM pStream,364 static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV, 367 365 PAVRECSINK pSink, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 368 366 { 369 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 370 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 371 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 372 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 373 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 374 375 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 367 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 368 AssertPtrReturn(pStreamAV, VERR_INVALID_POINTER); 369 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 370 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 371 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 376 372 377 373 if (pCfgReq->DestSource.Dest != PDMAUDIOPLAYBACKDEST_FRONT) … … 380 376 381 377 if (pCfgAcq) 382 pCfgAcq->cSampleBuffer Size= 0;378 pCfgAcq->cSampleBufferHint = 0; 383 379 384 380 LogRel2(("VideoRec: Support for surround audio not implemented yet\n")); … … 386 382 } 387 383 388 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamOut->Props); 389 if (RT_FAILURE(rc)) 390 return rc; 384 int rc = VINF_SUCCESS; 391 385 392 386 #ifdef VBOX_WITH_LIBOPUS … … 398 392 WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None); 399 393 if (RT_SUCCESS(rc)) 400 rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, p StreamOut->Props.cChannels, pStreamOut->Props.cBits,394 rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cBits, 401 395 &pSink->Con.WebM.uTrack); 402 396 } … … 405 399 return rc; 406 400 407 rc = RTCircBufCreate(&pStream Out->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t));401 rc = RTCircBufCreate(&pStreamAV->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t)); 408 402 if (RT_SUCCESS(rc)) 409 403 { 410 pStream Out->pSink = pSink; /* Assign sink to stream. */404 pStreamAV->pSink = pSink; /* Assign sink to stream. */ 411 405 412 406 if (pCfgAcq) … … 414 408 /* Make sure to let the driver backend know that we need the audio data in 415 409 * a specific sampling rate Opus is optimized for. */ 416 pCfgAcq->uHz = pSink->Codec.Parms.uHz; 417 pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */ 410 pCfgAcq->Props.uHz = pSink->Codec.Parms.uHz; 411 pCfgAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cBits, pCfgAcq->Props.cChannels); 412 pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */ 418 413 } 419 414 } 420 415 #else 421 RT_NOREF(pThis, pSink, pStream , pCfgReq, pCfgAcq);416 RT_NOREF(pThis, pSink, pStreamAV, pCfgReq, pCfgAcq); 422 417 rc = VERR_NOT_SUPPORTED; 423 418 #endif /* VBOX_WITH_LIBOPUS */ … … 433 428 * @returns IPRT status code. 434 429 * @param pThis Driver instance. 435 * @param pStream 436 */ 437 static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, P PDMAUDIOSTREAM pStream)430 * @param pStreamAV Audio output stream to destroy. 431 */ 432 static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV) 438 433 { 439 434 RT_NOREF(pThis); 440 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 441 442 if (pStreamOut->pCircBuf) 443 { 444 RTCircBufDestroy(pStreamOut->pCircBuf); 445 pStreamOut->pCircBuf = NULL; 435 436 if (pStreamAV->pCircBuf) 437 { 438 RTCircBufDestroy(pStreamAV->pCircBuf); 439 pStreamAV->pCircBuf = NULL; 446 440 } 447 441 … … 455 449 * @returns IPRT status code. 456 450 * @param pThis Driver instance. 457 * @param pStream 451 * @param pStreamAV Audio output stream to control. 458 452 * @param enmStreamCmd Stream command to issue. 459 453 */ 460 454 static int avRecControlStreamOut(PDRVAUDIOVIDEOREC pThis, 461 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 462 { 463 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 464 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 465 RT_NOREF(enmStreamCmd); 466 467 RT_NOREF(pThis); 468 469 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 455 PAVRECSTREAM pStreamAV, PDMAUDIOSTREAMCMD enmStreamCmd) 456 { 457 RT_NOREF(pThis, pStreamAV); 470 458 471 459 switch (enmStreamCmd) … … 520 508 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 521 509 */ 522 static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface, 523 PPDMAUDIOSTREAM pStream,void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)510 static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 511 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 524 512 { 525 513 RT_NOREF(pInterface, pStream, pvBuf, cbBuf); … … 535 523 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 536 524 */ 537 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, 538 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 539 uint32_t *pcbWritten) 525 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 526 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 540 527 { 541 528 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 545 532 /* pcbWritten is optional. */ 546 533 547 PDRVAUDIOVIDEOREC pThis 534 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 548 535 RT_NOREF(pThis); 549 PAVRECSTREAM OUT pStreamOut = (PAVRECSTREAMOUT)pStream;536 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 550 537 551 538 int rc = VINF_SUCCESS; … … 557 544 */ 558 545 #ifdef VBOX_WITH_LIBOPUS 559 PAVRECSINK pSink = pStream Out->pSink;546 PAVRECSINK pSink = pStreamAV->pSink; 560 547 AssertPtr(pSink); 561 PRTCIRCBUF pCircBuf = pStream Out->pCircBuf;548 PRTCIRCBUF pCircBuf = pStreamAV->pCircBuf; 562 549 AssertPtr(pCircBuf); 563 550 … … 598 585 599 586 const uint32_t csFrame = pSink->Codec.Opus.csFrame; 600 const uint32_t cbFrame = PDMAUDIO PCMPROPS_S2B(&pStreamOut->Props, csFrame);587 const uint32_t cbFrame = PDMAUDIOSTREAMCFG_S2B(pStreamAV->pCfg, csFrame); 601 588 602 589 while (RTCircBufUsed(pCircBuf) >= cbFrame) … … 716 703 static DECLCALLBACK(int) drvAudioVideoRecGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 717 704 { 718 NOREF(pInterface);705 RT_NOREF(pInterface); 719 706 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 720 707 721 pBackendCfg->cbStreamOut = sizeof(AVRECSTREAM OUT);708 pBackendCfg->cbStreamOut = sizeof(AVRECSTREAM); 722 709 pBackendCfg->cbStreamIn = 0; 723 710 pBackendCfg->cMaxStreamsIn = 0; … … 756 743 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 757 744 */ 758 static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,745 static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 759 746 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 760 747 { 761 748 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 762 AssertPtrReturn(pStream, VERR_INVALID_POINTER);763 749 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 764 750 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 765 751 766 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 752 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 753 return VERR_NOT_SUPPORTED; 754 755 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 756 757 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 758 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 767 759 768 760 /* For now we only have one sink, namely the driver's one. … … 770 762 PAVRECSINK pSink = &pThis->Sink; 771 763 772 if (pCfgReq->enmDir == PDMAUDIODIR_OUT) 773 return avRecCreateStreamOut(pThis, pStream, pSink, pCfgReq, pCfgAcq); 774 775 return VERR_NOT_SUPPORTED; 764 int rc = avRecCreateStreamOut(pThis, pStreamAV, pSink, pCfgReq, pCfgAcq); 765 if (RT_SUCCESS(rc)) 766 { 767 pStreamAV->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 768 if (!pStreamAV->pCfg) 769 rc = VERR_NO_MEMORY; 770 } 771 772 return rc; 776 773 } 777 774 … … 780 777 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 781 778 */ 782 static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)779 static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 783 780 { 784 781 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 785 782 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 786 783 787 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 788 789 if (pStream->enmDir == PDMAUDIODIR_OUT) 790 return avRecDestroyStreamOut(pThis, pStream); 791 792 return VINF_SUCCESS; 784 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 785 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 786 787 if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */ 788 return VINF_SUCCESS; 789 790 int rc = VINF_SUCCESS; 791 792 if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT) 793 rc = avRecDestroyStreamOut(pThis, pStreamAV); 794 795 if (RT_SUCCESS(rc)) 796 { 797 DrvAudioHlpStreamCfgFree(pStreamAV->pCfg); 798 pStreamAV->pCfg = NULL; 799 } 800 801 return rc; 793 802 } 794 803 … … 798 807 */ 799 808 static DECLCALLBACK(int) drvAudioVideoRecStreamControl(PPDMIHOSTAUDIO pInterface, 800 PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)809 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 801 810 { 802 811 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 803 812 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 804 813 805 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 806 807 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 808 809 if (pStream->enmDir == PDMAUDIODIR_OUT) 810 return avRecControlStreamOut(pThis, pStream, enmStreamCmd); 814 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 815 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 816 817 if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */ 818 return VINF_SUCCESS; 819 820 if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT) 821 return avRecControlStreamOut(pThis, pStreamAV, enmStreamCmd); 811 822 812 823 return VINF_SUCCESS; … … 817 828 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 818 829 */ 819 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)820 { 821 NOREF(pInterface);822 NOREF(pStream);830 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 831 { 832 RT_NOREF(pInterface); 833 RT_NOREF(pStream); 823 834 824 835 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED … … 830 841 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 831 842 */ 832 static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)843 static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 833 844 { 834 845 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
Note:
See TracChangeset
for help on using the changeset viewer.