Changeset 74955 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Oct 19, 2018 6:14:51 PM (6 years ago)
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r74804 r74955 5631 5631 if ( pDisplay->i_videoRecGetFeatures() & VIDEORECFEATURE_AUDIO 5632 5632 && mAudioVideoRec) 5633 vrc = mAudioVideoRec->doAttachDriverViaEmt(mpUVM, pAutoLock); 5633 { 5634 vrc = mAudioVideoRec->applyConfiguration(pDisplay->i_videoRecGetConfig()); 5635 if (RT_SUCCESS(vrc)) 5636 vrc = mAudioVideoRec->doAttachDriverViaEmt(mpUVM, pAutoLock); 5637 } 5634 5638 # endif 5635 5639 if ( RT_SUCCESS(vrc) -
trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
r74851 r74955 136 136 /** The container's type. */ 137 137 AVRECCONTAINERTYPE enmType; 138 union 139 { 140 /** WebM file specifics. */ 141 struct 142 { 143 /** Allocated file name to write .webm file to. Must be free'd. */ 144 char *pszFile; 145 } WebM; 146 }; 138 147 139 148 } AVRECCONTAINERPARMS, *PAVRECCONTAINERPARMS; … … 262 271 /** Pointer to the DrvAudio port interface that is above us. */ 263 272 PPDMIAUDIOCONNECTOR pDrvAudio; 273 /** The driver's configured container parameters. */ 274 AVRECCONTAINERPARMS ContainerParms; 275 /** The driver's configured codec parameters. */ 276 AVRECCODECPARMS CodecParms; 264 277 /** The driver's sink for writing output to. */ 265 278 AVRECSINK Sink; … … 296 309 if (cChannels > 2) 297 310 { 298 LogRel(("VideoRec: More than 2 (stereo) channels are not supported at the moment\n"));311 LogRel(("VideoRec: Warning: More than 2 (stereo) channels are not supported at the moment\n")); 299 312 cChannels = 2; 300 313 } 301 302 LogRel2(("VideoRec: Recording audio in %RU16Hz, %RU8 channels\n", uHz, cChannels));303 314 304 315 int orc; … … 356 367 case AVRECCONTAINERTYPE_WEBM: 357 368 { 358 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA359 369 /* If we only record audio, create our own WebM writer instance here. */ 360 370 if (!pSink->Con.WebM.pWebM) /* Do we already have our WebM writer instance? */ 361 371 { 362 char szFile[RTPATH_MAX]; 363 if (RTStrPrintf(szFile, sizeof(szFile), "%s%s", 364 VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH, "DrvAudioVideoRec.webm")) 372 /** @todo Add sink name / number to file name. */ 373 const char *pszFile = pSink->Con.Parms.WebM.pszFile; 374 AssertPtr(pszFile); 375 376 pSink->Con.WebM.pWebM = new WebMWriter(); 377 rc = pSink->Con.WebM.pWebM->Open(pszFile, 378 /** @todo Add option to add some suffix if file exists instead of overwriting? */ 379 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE, 380 WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None); 381 if (RT_SUCCESS(rc)) 365 382 { 366 /** @todo Add sink name / number to file name. */ 367 368 pSink->Con.WebM.pWebM = new WebMWriter(); 369 rc = pSink->Con.WebM.pWebM->Create(szFile, 370 /** @todo Add option to add some suffix if file exists instead of overwriting? */ 371 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE, 372 WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None); 383 rc = pSink->Con.WebM.pWebM->AddAudioTrack(uHz, cChannels, cBytes * 8 /* Bits */, 384 &pSink->Con.WebM.uTrack); 373 385 if (RT_SUCCESS(rc)) 374 386 { 375 rc = pSink->Con.WebM.pWebM->AddAudioTrack(uHz, cChannels, cBytes * 8 /* Bits */, 376 &pSink->Con.WebM.uTrack); 377 if (RT_SUCCESS(rc)) 378 { 379 LogRel(("VideoRec: Recording audio to file '%s'\n", szFile)); 380 } 381 else 382 LogRel(("VideoRec: Error creating audio track for file '%s' (%Rrc)\n", szFile, rc)); 387 LogRel(("VideoRec: Recording audio to audio file '%s'\n", pszFile)); 383 388 } 384 389 else 385 LogRel(("VideoRec: Error creating audio file '%s' (%Rrc)\n",szFile, rc));390 LogRel(("VideoRec: Error creating audio track for audio file '%s' (%Rrc)\n", pszFile, rc)); 386 391 } 387 392 else 388 { 389 AssertFailed(); /* Should never happen. */ 390 LogRel(("VideoRec: Error creating audio file path\n")); 391 } 393 LogRel(("VideoRec: Error creating audio file '%s' (%Rrc)\n", pszFile, rc)); 392 394 } 393 #else394 rc = VERR_NOT_SUPPORTED;395 #endif /* VBOX_AUDIO_DEBUG_DUMP_PCM_DATA */396 395 break; 397 396 } … … 404 403 catch (std::bad_alloc &) 405 404 { 406 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA407 405 rc = VERR_NO_MEMORY; 408 #endif409 406 } 410 407 … … 615 612 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 616 613 617 AVRECCONTAINERPARMS ContainerParms; 618 ContainerParms.enmType = AVRECCONTAINERTYPE_MAIN_CONSOLE; /** @todo Make this configurable. */ 619 620 AVRECCODECPARMS CodecParms; 621 CodecParms.PCMProps.uHz = AVREC_OPUS_HZ_MAX; /** @todo Make this configurable. */ 622 CodecParms.PCMProps.cChannels = 2; /** @todo Make this configurable. */ 623 CodecParms.PCMProps.cBytes = 2; /** 16 bit @todo Make this configurable. */ 624 625 CodecParms.uBitrate = 0; /* Let Opus decide, based on the number of channels and the input sampling rate. */ 626 627 int rc = avRecSinkInit(pThis, &pThis->Sink, &ContainerParms, &CodecParms); 614 LogRel(("VideoRec: Audio driver is using %RU32Hz, %RU16bit, %RU8 %s\n", 615 pThis->CodecParms.PCMProps.uHz, pThis->CodecParms.PCMProps.cBytes * 8, 616 pThis->CodecParms.PCMProps.cChannels, pThis->CodecParms.PCMProps.cChannels == 1 ? "channel" : "channels")); 617 618 int rc = avRecSinkInit(pThis, &pThis->Sink, &pThis->ContainerParms, &pThis->CodecParms); 628 619 if (RT_FAILURE(rc)) 629 620 { … … 1051 1042 1052 1043 /** 1044 * Applies a video recording configuration to this driver instance. 1045 * 1046 * @returns IPRT status code. 1047 * @param pVideoRecCfg Pointer to video recording configuration to apply. 1048 */ 1049 int AudioVideoRec::applyConfiguration(const PVIDEORECCFG pVideoRecCfg) 1050 { 1051 /** @todo Do some validation here. */ 1052 mVideoRecCfg = *pVideoRecCfg; /* Note: Does have an own copy operator. */ 1053 return VINF_SUCCESS; 1054 } 1055 1056 1057 /** 1053 1058 * @copydoc AudioDriver::configureDriver 1054 1059 */ 1055 1060 int AudioVideoRec::configureDriver(PCFGMNODE pLunCfg) 1056 1061 { 1057 CFGMR3InsertInteger(pLunCfg, "Object", (uintptr_t)mpConsole->i_getAudioVideoRec()); 1058 CFGMR3InsertInteger(pLunCfg, "ObjectConsole", (uintptr_t)mpConsole); 1059 1060 return VINF_SUCCESS; 1062 int rc = CFGMR3InsertInteger(pLunCfg, "Object", (uintptr_t)mpConsole->i_getAudioVideoRec()); 1063 AssertRCReturn(rc, rc); 1064 rc = CFGMR3InsertInteger(pLunCfg, "ObjectConsole", (uintptr_t)mpConsole); 1065 AssertRCReturn(rc, rc); 1066 1067 rc = CFGMR3InsertInteger(pLunCfg, "ContainerType", (uint64_t)mVideoRecCfg.enmDst); 1068 AssertRCReturn(rc, rc); 1069 if (mVideoRecCfg.enmDst == VIDEORECDEST_FILE) 1070 { 1071 rc = CFGMR3InsertString(pLunCfg, "ContainerFileName", Utf8Str(mVideoRecCfg.File.strName).c_str()); 1072 AssertRCReturn(rc, rc); 1073 } 1074 rc = CFGMR3InsertInteger(pLunCfg, "CodecHz", mVideoRecCfg.Audio.uHz); 1075 AssertRCReturn(rc, rc); 1076 rc = CFGMR3InsertInteger(pLunCfg, "CodecBits", mVideoRecCfg.Audio.cBits); 1077 AssertRCReturn(rc, rc); 1078 rc = CFGMR3InsertInteger(pLunCfg, "CodecChannels", mVideoRecCfg.Audio.cChannels); 1079 AssertRCReturn(rc, rc); 1080 rc = CFGMR3InsertInteger(pLunCfg, "CodecBitrate", 0); /* Let Opus decide for now. */ 1081 AssertRCReturn(rc, rc); 1082 1083 return rc; 1061 1084 } 1062 1085 … … 1110 1133 AssertPtrReturn(pThis->pAudioVideoRec, VERR_INVALID_POINTER); 1111 1134 1135 /* 1136 * Get the recording container and codec parameters from the audio driver instance. 1137 */ 1138 PAVRECCONTAINERPARMS pConParams = &pThis->ContainerParms; 1139 PAVRECCODECPARMS pCodecParms = &pThis->CodecParms; 1140 PPDMAUDIOPCMPROPS pPCMProps = &pCodecParms->PCMProps; 1141 1142 RT_ZERO(pThis->ContainerParms); 1143 RT_ZERO(pThis->CodecParms); 1144 1145 rc = CFGMR3QueryU32(pCfg, "ContainerType", (uint32_t *)&pConParams->enmType); 1146 AssertRCReturn(rc, rc); 1147 1148 switch (pConParams->enmType) 1149 { 1150 case AVRECCONTAINERTYPE_WEBM: 1151 rc = CFGMR3QueryStringAlloc(pCfg, "ContainerFileName", &pConParams->WebM.pszFile); 1152 AssertRCReturn(rc, rc); 1153 break; 1154 1155 default: 1156 break; 1157 } 1158 1159 rc = CFGMR3QueryU32(pCfg, "CodecHz", &pPCMProps->uHz); 1160 AssertRCReturn(rc, rc); 1161 rc = CFGMR3QueryU8(pCfg, "CodecBits", &pPCMProps->cBytes); 1162 AssertRCReturn(rc, rc); 1163 rc = CFGMR3QueryU8(pCfg, "CodecChannels", &pPCMProps->cChannels); 1164 AssertRCReturn(rc, rc); 1165 rc = CFGMR3QueryU32(pCfg, "CodecBitrate", &pCodecParms->uBitrate); 1166 AssertRCReturn(rc, rc); 1167 1168 pPCMProps->cBytes = pPCMProps->cBytes / 8; /* Bits to bytes. */ 1169 pPCMProps->cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pPCMProps->cBytes, pPCMProps->cChannels); 1170 pPCMProps->fSigned = true; 1171 pPCMProps->fSwapEndian = false; 1172 1173 AssertMsgReturn(DrvAudioHlpPCMPropsAreValid(pPCMProps), 1174 ("Configuration error: Audio configuration is invalid!\n"), VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES); 1175 1176 pThis->pAudioVideoRec = (AudioVideoRec *)pvUser; 1177 AssertPtrReturn(pThis->pAudioVideoRec, VERR_INVALID_POINTER); 1178 1112 1179 pThis->pAudioVideoRec->mpDrv = pThis; 1113 1180 … … 1136 1203 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns); 1137 1204 PDRVAUDIOVIDEOREC pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVIDEOREC); 1205 1138 1206 LogFlowFuncEnter(); 1207 1208 switch (pThis->ContainerParms.enmType) 1209 { 1210 case AVRECCONTAINERTYPE_WEBM: 1211 { 1212 avRecSinkShutdown(&pThis->Sink); 1213 RTStrFree(pThis->ContainerParms.WebM.pszFile); 1214 break; 1215 } 1216 1217 default: 1218 break; 1219 } 1139 1220 1140 1221 /* … … 1147 1228 pThis->pAudioVideoRec = NULL; 1148 1229 } 1230 1231 LogFlowFuncLeave(); 1149 1232 } 1150 1233 -
trunk/src/VBox/Main/src-client/VideoRec.cpp
r74909 r74955 1337 1337 1338 1338 LogRel(("VideoRec: Recording audio in %RU16Hz, %RU8 bit, %RU8 %s\n", 1339 pCfg->Audio.uHz, pCfg->Audio.cBits, pCfg->Audio.cChannels, pCfg->Audio.cChannels ? "channel " : "channels"));1339 pCfg->Audio.uHz, pCfg->Audio.cBits, pCfg->Audio.cChannels, pCfg->Audio.cChannels ? "channels" : "channel")); 1340 1340 } 1341 1341 #endif
Note:
See TracChangeset
for help on using the changeset viewer.