Changeset 89543 in vbox
- Timestamp:
- Jun 7, 2021 9:57:06 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r89510 r89543 237 237 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pvContext; 238 238 AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER); 239 LogFlowFunc(("cbData=%#x\n", cbData)); 239 240 240 241 void *pvBuf = NULL; … … 298 299 RT_NOREF(pInterface, enmDir); 299 300 return PDMAUDIOBACKENDSTS_RUNNING; 300 }301 302 303 static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgAcq)304 {305 /*306 * The VRDP server does its own mixing and resampling as it may server307 * multiple clients all with different sound formats. So, it feeds us308 * raw mixer frames (somewhat akind to stereo signed 64-bit, see309 * st_sample_t and PDMAUDIOFRAME).310 */311 PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/, 22050 /*Hz*/,312 true /*fLittleEndian*/, true /*fRaw*/);313 314 /* According to the VRDP docs, the VRDP server stores audio in 200ms chunks. */315 const uint32_t cFramesVrdpServer = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 200 /*ms*/);316 317 int rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, PDMAudioPropsFramesToBytes(&pCfgAcq->Props, cFramesVrdpServer));318 if (RT_SUCCESS(rc))319 {320 pCfgAcq->Backend.cFramesPeriod = cFramesVrdpServer;321 /** @todo r=bird: This is inconsistent with the above buffer allocation and I322 * think also ALSA and Pulse backends way of setting cFramesBufferSize. */323 pCfgAcq->Backend.cFramesBufferSize = cFramesVrdpServer * 2; /* Use "double buffering". */324 pCfgAcq->Backend.cFramesPreBuffering = cFramesVrdpServer;325 }326 327 return rc;328 }329 330 331 static int vrdeCreateStreamOut(PPDMAUDIOSTREAMCFG pCfgAcq)332 {333 /*334 * The VRDP server does its own mixing and resampling because it may be335 * sending the audio to any number of different clients all with different336 * formats (including clients which hasn't yet connected). So, it desires337 * the raw data from the mixer (somewhat akind to stereo signed 64-bit,338 * see st_sample_t and PDMAUDIOFRAME).339 */340 PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/, 22050 /*Hz*/,341 true /*fLittleEndian*/, true /*fRaw*/);342 343 /* According to the VRDP docs, the VRDP server stores audio in 200ms chunks. */344 /** @todo r=bird: So, if VRDP does 200ms chunks, why do we report 100ms345 * buffer and 20ms period? How does these parameters at all correlate346 * with the above comment?!? */347 pCfgAcq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 20 /*ms*/);348 pCfgAcq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 100 /*ms*/);349 pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod * 2;350 351 return VINF_SUCCESS;352 301 } 353 302 … … 379 328 #endif 380 329 { 330 /* 331 * The VRDP server does its own mixing and resampling because it may be 332 * sending the audio to any number of different clients all with different 333 * formats (including clients which hasn't yet connected). So, it desires 334 * the raw data from the mixer (somewhat akind to stereo signed 64-bit, 335 * see st_sample_t and PDMAUDIOFRAME). 336 */ 337 PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/, 338 22050 /*Hz - VRDP_AUDIO_CHUNK_INTERNAL_FREQ_HZ*/, 339 true /*fLittleEndian*/, true /*fRaw*/); 340 341 /* According to the VRDP docs (VRDP_AUDIO_CHUNK_TIME_MS), the VRDP server 342 stores audio in 200ms chunks. */ 343 const uint32_t cFramesVrdpServer = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 200 /*ms*/); 344 381 345 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 382 rc = vrdeCreateStreamIn(pStreamVRDE, pCfgAcq); 346 { 347 pCfgAcq->Backend.cFramesBufferSize = cFramesVrdpServer; 348 pCfgAcq->Backend.cFramesPeriod = cFramesVrdpServer / 4; /* This is utter non-sense, but whatever. */ 349 pCfgAcq->Backend.cFramesPreBuffering = pCfgReq->Backend.cFramesPreBuffering * cFramesVrdpServer 350 / RT_MAX(pCfgReq->Backend.cFramesBufferSize, 1); 351 352 rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, PDMAudioPropsFramesToBytes(&pCfgAcq->Props, cFramesVrdpServer)); 353 } 383 354 else 384 rc = vrdeCreateStreamOut(pCfgAcq); 355 { 356 /** @todo r=bird: So, if VRDP does 200ms chunks, why do we report 100ms 357 * buffer and 20ms period? How does these parameters at all correlate 358 * with the above comment?!? */ 359 pCfgAcq->Backend.cFramesPeriod = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 20 /*ms*/); 360 pCfgAcq->Backend.cFramesBufferSize = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 100 /*ms*/); 361 pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod * 2; 362 rc = VINF_SUCCESS; 363 } 364 385 365 PDMAudioStrmCfgCopy(&pStreamVRDE->Cfg, pCfgAcq); 386 366 } … … 400 380 RT_NOREF(fImmediate); 401 381 402 if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_OUT) 403 { 382 if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN) 383 { 384 LogFlowFunc(("Calling SendAudioInputEnd\n")); 404 385 if (pDrv->pConsoleVRDPServer) 405 386 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); … … 437 418 PDMAudioPropsChannels(&pStreamVRDE->Cfg.Props), 438 419 PDMAudioPropsSampleBits(&pStreamVRDE->Cfg.Props)); 420 LogFlowFunc(("SendAudioInputBegin returns %Rrc\n", rc)); 439 421 if (rc == VERR_NOT_SUPPORTED) 440 422 { … … 466 448 else if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN) 467 449 { 450 LogFlowFunc(("Calling SendAudioInputEnd\n")); 468 451 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL /* pvUserCtx */); 469 452 rc = VINF_SUCCESS; … … 541 524 static DECLCALLBACK(uint32_t) drvAudioVrdeHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 542 525 { 543 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);544 RT_NOREF(pStream);526 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 527 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 545 528 546 529 /** @todo Find some sane value here. We probably need a VRDE API VRDE to specify this. */ 547 530 if (pDrv->cClients) 548 return _16K * sizeof(int64_t) * 2;531 return PDMAudioPropsFramesToBytes(&pStreamVRDE->Cfg.Props, pStreamVRDE->Cfg.Backend.cFramesBufferSize); 549 532 return 0; 550 533 } … … 601 584 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 602 585 603 if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN) 604 { 605 /* Return frames instead of bytes here 606 * (since we specified PDMAUDIOSTREAMLAYOUT_RAW as the audio data layout). */ 607 return PDMAudioPropsBytesToFrames(&pStreamVRDE->Cfg.Props, (uint32_t)RTCircBufUsed(pStreamVRDE->In.pCircBuf)); 608 } 609 return 0; 586 AssertReturn(pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN, 0); 587 uint32_t cbRet = (uint32_t)RTCircBufUsed(pStreamVRDE->In.pCircBuf); 588 Log4Func(("returns %#x\n", cbRet)); 589 return cbRet; 610 590 } 611 591 … … 624 604 AssertPtrReturn(pcbRead, VERR_INVALID_PARAMETER); 625 605 626 size_t cbData = 0; 627 if (RTCircBufUsed(pStreamVRDE->In.pCircBuf)) 628 { 629 void *pvData = NULL; 606 *pcbRead = 0; 607 while (cbBuf > 0 && RTCircBufUsed(pStreamVRDE->In.pCircBuf) > 0) 608 { 609 size_t cbData = 0; 610 void *pvData = NULL; 630 611 RTCircBufAcquireReadBlock(pStreamVRDE->In.pCircBuf, cbBuf, &pvData, &cbData); 631 612 632 if (cbData) 633 memcpy(pvBuf, pvData, cbData); 613 memcpy(pvBuf, pvData, cbData); 634 614 635 615 RTCircBufReleaseReadBlock(pStreamVRDE->In.pCircBuf, cbData); 636 } 637 638 *pcbRead = (uint32_t)cbData; 616 617 *pcbRead += (uint32_t)cbData; 618 cbBuf -= (uint32_t)cbData; 619 pvData = (uint8_t *)pvData + cbData; 620 } 621 622 LogFlowFunc(("returns %#x bytes\n", *pcbRead)); 639 623 return VINF_SUCCESS; 640 624 }
Note:
See TracChangeset
for help on using the changeset viewer.