VirtualBox

Changeset 74955 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Oct 19, 2018 6:14:51 PM (6 years ago)
Author:
vboxsync
Message:

VideoRec/Main: Implemented applying audio driver configuration at runtime (when being attached).

Location:
trunk/src/VBox/Main/src-client
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r74804 r74955  
    56315631                if (   pDisplay->i_videoRecGetFeatures() & VIDEORECFEATURE_AUDIO
    56325632                    && 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                }
    56345638# endif
    56355639                if (   RT_SUCCESS(vrc)
  • trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp

    r74851 r74955  
    136136    /** The container's type. */
    137137    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    };
    138147
    139148} AVRECCONTAINERPARMS, *PAVRECCONTAINERPARMS;
     
    262271    /** Pointer to the DrvAudio port interface that is above us. */
    263272    PPDMIAUDIOCONNECTOR  pDrvAudio;
     273    /** The driver's configured container parameters. */
     274    AVRECCONTAINERPARMS  ContainerParms;
     275    /** The driver's configured codec parameters. */
     276    AVRECCODECPARMS      CodecParms;
    264277    /** The driver's sink for writing output to. */
    265278    AVRECSINK            Sink;
     
    296309    if (cChannels > 2)
    297310    {
    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"));
    299312        cChannels = 2;
    300313    }
    301 
    302     LogRel2(("VideoRec: Recording audio in %RU16Hz, %RU8 channels\n", uHz, cChannels));
    303314
    304315    int orc;
     
    356367            case AVRECCONTAINERTYPE_WEBM:
    357368            {
    358 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA
    359369                /* If we only record audio, create our own WebM writer instance here. */
    360370                if (!pSink->Con.WebM.pWebM) /* Do we already have our WebM writer instance? */
    361371                {
    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))
    365382                    {
    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);
    373385                        if (RT_SUCCESS(rc))
    374386                        {
    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));
    383388                        }
    384389                        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));
    386391                    }
    387392                    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));
    392394                }
    393 #else
    394                 rc = VERR_NOT_SUPPORTED;
    395 #endif /* VBOX_AUDIO_DEBUG_DUMP_PCM_DATA */
    396395                break;
    397396            }
     
    404403    catch (std::bad_alloc &)
    405404    {
    406 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA
    407405        rc = VERR_NO_MEMORY;
    408 #endif
    409406    }
    410407
     
    615612    PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
    616613
    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);
    628619    if (RT_FAILURE(rc))
    629620    {
     
    10511042
    10521043/**
     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 */
     1049int 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/**
    10531058 * @copydoc AudioDriver::configureDriver
    10541059 */
    10551060int AudioVideoRec::configureDriver(PCFGMNODE pLunCfg)
    10561061{
    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;
    10611084}
    10621085
     
    11101133    AssertPtrReturn(pThis->pAudioVideoRec, VERR_INVALID_POINTER);
    11111134
     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
    11121179    pThis->pAudioVideoRec->mpDrv = pThis;
    11131180
     
    11361203    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    11371204    PDRVAUDIOVIDEOREC pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVIDEOREC);
     1205
    11381206    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    }
    11391220
    11401221    /*
     
    11471228        pThis->pAudioVideoRec = NULL;
    11481229    }
     1230
     1231    LogFlowFuncLeave();
    11491232}
    11501233
  • trunk/src/VBox/Main/src-client/VideoRec.cpp

    r74909 r74955  
    13371337
    13381338                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"));
    13401340            }
    13411341#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette