VirtualBox

Changeset 88371 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Apr 6, 2021 1:45:57 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143618
Message:

DrvHostAudioDSound: Try enumerate devices using MMDeviceEnumerator if we can. Fixed leak in internal device enumeration (dsoundUpdateStatusInternal) and disable it because it doesn't seem to be at all necessary. bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp

    r88362 r88371  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
     23#define INITGUID
    2324#include <VBox/log.h>
    2425#include <iprt/win/windows.h>
    2526#include <dsound.h>
     27#include <Mmdeviceapi.h>
     28#include <functiondiscoverykeys_devpkey.h>
    2629
    2730#include <iprt/alloc.h>
     
    5962 * Messages which always should go to the release log use LogRel.
    6063 */
    61 /* General code behavior. */
     64/** General code behavior. */
    6265#define DSLOG(a)    do { LogRel2(a); } while(0)
    63 /* Something which produce a lot of logging during playback/recording. */
     66/** Something which produce a lot of logging during playback/recording. */
    6467#define DSLOGF(a)   do { LogRel3(a); } while(0)
    65 /* Important messages like errors. Limited in the default release log to avoid log flood. */
     68/** Important messages like errors. Limited in the default release log to avoid log flood. */
    6669#define DSLOGREL(a) \
    6770    do {  \
     
    215218    /** List of devices of last enumeration. */
    216219    PDMAUDIOHOSTENUM            DeviceEnum;
    217     /** Whether this backend supports any audio input. */
     220    /** Whether this backend supports any audio input.
     221     * @todo r=bird: This is not actually used for anything. */
    218222    bool                        fEnabledIn;
    219     /** Whether this backend supports any audio output. */
     223    /** Whether this backend supports any audio output.
     224     * @todo r=bird: This is not actually used for anything. */
    220225    bool                        fEnabledOut;
    221226    /** The Direct Sound playback interface. */
     
    639644           wfx.cbSize));
    640645
     646    /** @todo r=bird: Why is this called every time?  It triggers a device
     647     * enumeration. Andy claimed on IRC that enumeration was only done once...
     648     * It's generally a 'ing waste of time here too, as we dont really use any of
     649     * the information we gather there. */
    641650    dsoundUpdateStatusInternal(pThis);
    642651
     
    13801389        return E_INVALIDARG;
    13811390
     1391    /** @todo r=bird: Why is this called every time?  It triggers a device
     1392     * enumeration. Andy claimed on IRC that enumeration was only done once... */
    13821393    dsoundUpdateStatusInternal(pThis);
    13831394
     
    15691580 * @param   lpContext           Pointer to PDSOUNDENUMCBCTX context for storing the enumerated information.
    15701581 *
    1571  * @note    Carbon copy of dsoundDevicesEnumCbPlayback with OUT direction.
     1582 * @note    Carbon copy of dsoundDevicesEnumCbCapture with OUT direction.
    15721583 */
    15731584static BOOL CALLBACK dsoundDevicesEnumCbPlayback(LPGUID pGUID, LPCWSTR pwszDescription, LPCWSTR pwszModule, PVOID lpContext)
     
    17751786}
    17761787
     1788
     1789/**
     1790 * Queries information for @a pDevice and adds an entry to the enumeration.
     1791 *
     1792 * @returns VBox status code.
     1793 * @param   pDevEnm     The enumeration to add the device to.
     1794 * @param   pDevice     The device.
     1795 * @param   enmType     The type of device.
     1796 * @param   fDefault    Whether it's the default device.
     1797 */
     1798static int dsoundDeviceNewStyleAdd(PPDMAUDIOHOSTENUM pDevEnm, IMMDevice *pDevice, EDataFlow enmType, bool fDefault)
     1799{
     1800    int rc = VINF_SUCCESS; /* ignore most errors */
     1801
     1802    /*
     1803     * Gather the necessary properties.
     1804     */
     1805    IPropertyStore *pProperties = NULL;
     1806    HRESULT hrc = pDevice->OpenPropertyStore(STGM_READ, &pProperties);
     1807    if (SUCCEEDED(hrc))
     1808    {
     1809        /* Get the friendly name. */
     1810        PROPVARIANT VarName;
     1811        PropVariantInit(&VarName);
     1812        hrc = pProperties->GetValue(PKEY_Device_FriendlyName, &VarName);
     1813        if (SUCCEEDED(hrc))
     1814        {
     1815            /* Get the DirectSound GUID. */
     1816            PROPVARIANT VarGUID;
     1817            PropVariantInit(&VarGUID);
     1818            hrc = pProperties->GetValue(PKEY_AudioEndpoint_GUID, &VarGUID);
     1819            if (SUCCEEDED(hrc))
     1820            {
     1821                /* Get the device format. */
     1822                PROPVARIANT VarFormat;
     1823                PropVariantInit(&VarFormat);
     1824                hrc = pProperties->GetValue(PKEY_AudioEngine_DeviceFormat, &VarFormat);
     1825                if (SUCCEEDED(hrc))
     1826                {
     1827                    WAVEFORMATEX const * const pFormat = (WAVEFORMATEX const *)VarFormat.blob.pBlobData;
     1828                    AssertPtr(pFormat);
     1829
     1830                    /*
     1831                     * Create a enumeration entry for it.
     1832                     */
     1833                    PDSOUNDDEV pDev = (PDSOUNDDEV)PDMAudioHostDevAlloc(sizeof(DSOUNDDEV));
     1834                    if (pDev)
     1835                    {
     1836                        pDev->Core.enmUsage = enmType == eRender ? PDMAUDIODIR_OUT : PDMAUDIODIR_IN;
     1837                        pDev->Core.enmType  = PDMAUDIODEVICETYPE_BUILTIN;
     1838                        if (enmType == eRender)
     1839                            pDev->Core.cMaxOutputChannels = pFormat->nChannels;
     1840                        else
     1841                            pDev->Core.cMaxInputChannels  = pFormat->nChannels;
     1842
     1843                        RT_NOREF(fDefault);
     1844                        //if (fDefault)
     1845                            hrc = UuidFromStringW(VarGUID.pwszVal, &pDev->Guid);
     1846                        if (SUCCEEDED(hrc))
     1847                        {
     1848                            char *pszName;
     1849                            rc = RTUtf16ToUtf8(VarName.pwszVal, &pszName);
     1850                            if (RT_SUCCESS(rc))
     1851                            {
     1852                                RTStrCopy(pDev->Core.szName, sizeof(pDev->Core.szName), pszName);
     1853                                RTStrFree(pszName);
     1854
     1855                                PDMAudioHostEnumAppend(pDevEnm, &pDev->Core);
     1856                            }
     1857                            else
     1858                                PDMAudioHostDevFree(&pDev->Core);
     1859                        }
     1860                        else
     1861                        {
     1862                            LogFunc(("UuidFromStringW(%ls): %Rhrc\n", VarGUID.pwszVal, hrc));
     1863                            PDMAudioHostDevFree(&pDev->Core);
     1864                        }
     1865                    }
     1866                    else
     1867                        rc = VERR_NO_MEMORY;
     1868                    PropVariantClear(&VarFormat);
     1869                }
     1870                else
     1871                    LogFunc(("Failed to get PKEY_AudioEngine_DeviceFormat: %Rhrc\n", hrc));
     1872                PropVariantClear(&VarGUID);
     1873            }
     1874            else
     1875                LogFunc(("Failed to get PKEY_AudioEndpoint_GUID: %Rhrc\n", hrc));
     1876            PropVariantClear(&VarName);
     1877        }
     1878        else
     1879            LogFunc(("Failed to get PKEY_Device_FriendlyName: %Rhrc\n", hrc));
     1880        pProperties->Release();
     1881    }
     1882    else
     1883        LogFunc(("OpenPropertyStore failed: %Rhrc\n", hrc));
     1884
     1885    if (hrc == E_OUTOFMEMORY && RT_SUCCESS_NP(rc))
     1886        rc = VERR_NO_MEMORY;
     1887    return rc;
     1888}
     1889
    17771890/**
    17781891 * Does a (Re-)enumeration of the host's playback + capturing devices.
     
    17891902    DSLOG(("DSound: Enumerating devices ...\n"));
    17901903
     1904    /*
     1905     * Use the Vista+ API.
     1906     */
     1907    IMMDeviceEnumerator *pEnumerator;
     1908    HRESULT hrc = CoCreateInstance(__uuidof(MMDeviceEnumerator), 0, CLSCTX_ALL,
     1909                                   __uuidof(IMMDeviceEnumerator), (void **)&pEnumerator);
     1910    if (SUCCEEDED(hrc))
     1911    {
     1912        int rc = VINF_SUCCESS;
     1913        for (unsigned idxPass = 0; idxPass < 2 && RT_SUCCESS(rc); idxPass++)
     1914        {
     1915            EDataFlow const enmType = idxPass == 0 ? EDataFlow::eRender : EDataFlow::eCapture;
     1916
     1917            /* Get the default device first. */
     1918            IMMDevice *pDefaultDevice = NULL;
     1919            hrc = pEnumerator->GetDefaultAudioEndpoint(enmType, eMultimedia, &pDefaultDevice);
     1920            if (SUCCEEDED(hrc))
     1921                rc = dsoundDeviceNewStyleAdd(pDevEnm, pDefaultDevice, enmType, true);
     1922            else
     1923                pDefaultDevice = NULL;
     1924
     1925            /* Enumerate the devices. */
     1926            IMMDeviceCollection *pCollection = NULL;
     1927            hrc = pEnumerator->EnumAudioEndpoints(enmType, DEVICE_STATE_ACTIVE /*| DEVICE_STATE_UNPLUGGED?*/, &pCollection);
     1928            if (SUCCEEDED(hrc) && pCollection != NULL)
     1929            {
     1930                UINT cDevices = 0;
     1931                hrc = pCollection->GetCount(&cDevices);
     1932                if (SUCCEEDED(hrc))
     1933                {
     1934                    for (UINT idxDevice = 0; idxDevice < cDevices && RT_SUCCESS(rc); idxDevice++)
     1935                    {
     1936                        IMMDevice *pDevice = NULL;
     1937                        hrc = pCollection->Item(idxDevice, &pDevice);
     1938                        if (SUCCEEDED(hrc) && pDevice)
     1939                        {
     1940                            if (pDevice != pDefaultDevice)
     1941                                rc = dsoundDeviceNewStyleAdd(pDevEnm, pDevice, enmType, false);
     1942                            pDevice->Release();
     1943                        }
     1944                    }
     1945                }
     1946                pCollection->Release();
     1947            }
     1948            else
     1949                LogRelMax(10, ("EnumAudioEndpoints(%s) failed: %Rhrc\n", idxPass == 0 ? "output" : "input", hrc));
     1950
     1951            if (pDefaultDevice)
     1952                pDefaultDevice->Release();
     1953        }
     1954        pEnumerator->Release();
     1955        if (pDevEnm->cDevices > 0 || RT_FAILURE(rc))
     1956        {
     1957            DSLOG(("DSound: Enumerating devices done - %u device (%Rrc)\n", pDevEnm->cDevices, rc));
     1958            return rc;
     1959        }
     1960    }
     1961
     1962    /*
     1963     * Fall back on dsound.
     1964     */
    17911965    RTLDRMOD hDSound = NULL;
    17921966    int rc = RTLdrLoadSystem("dsound.dll", true /*fNoUnload*/, &hDSound);
     
    18552029 * state and all connected (native) audio streams.
    18562030 *
     2031 * @todo r=bird: This is a 'ing waste of 'ing time!  We're doing this everytime
     2032 *       an 'ing stream is created and we doesn't 'ing use the information here
     2033 *       for any darn thing!  Given the reported slowness of enumeration and
     2034 *       issues with eh 'ing code the only appropriate response is:
     2035 *       AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARG!!!!!!!
     2036 *
    18572037 * @param   pThis               Host audio driver instance.
    18582038 */
    18592039static void dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis)
    18602040{
     2041#if 0 /** @todo r=bird: This isn't doing *ANYTHING* useful. So, I've just disabled it.  */
    18612042    AssertPtrReturnVoid(pThis);
    1862     /* pCfg is optional. */
    1863 
    18642043    LogFlowFuncEnter();
    18652044
     2045    PDMAudioHostEnumDelete(&pThis->DeviceEnum);
    18662046    int rc = dsoundDevicesEnumerate(pThis, &pThis->DeviceEnum);
    18672047    if (RT_SUCCESS(rc))
     
    18802060
    18812061    LogFlowFuncLeaveRC(rc);
     2062#else
     2063    RT_NOREF(pThis);
     2064#endif
    18822065}
    18832066
Note: See TracChangeset for help on using the changeset viewer.

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