diff options
author | CrystalP <crystalp@kodi.tv> | 2024-09-26 13:46:55 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-26 13:46:55 -0400 |
commit | a33ebe22438ff7f179811a74d03d1a6d1612e2d2 (patch) | |
tree | d7c78539a9e5817c156a6c1611c0b545fdec8886 | |
parent | c49d1be73b0825bf712f3070533c579e7a84d973 (diff) | |
parent | c1864c86b533e84cc9f1ab769a71499d346eead5 (diff) |
Merge pull request #25759 from CrystalP/fix-wasapi
[Windows][AE} WASAPI sink fixes and improvements
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp index 5877e9f319..02357c123d 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp @@ -254,8 +254,7 @@ unsigned int CAESinkWASAPI::AddPackets(uint8_t **data, unsigned int frames, unsi return 0; HRESULT hr; - BYTE *buf; - DWORD flags = 0; + BYTE* buf; #ifndef _DEBUG LARGE_INTEGER timerStart; @@ -293,9 +292,8 @@ unsigned int CAESinkWASAPI::AddPackets(uint8_t **data, unsigned int frames, unsi return INT_MAX; } - memset(buf, 0, NumFramesRequested * m_format.m_frameSize); //fill buffer with silence - - hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, flags); //pass back to audio driver + hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, + AUDCLNT_BUFFERFLAGS_SILENT); //pass back to audio driver if (FAILED(hr)) { #ifdef _DEBUG @@ -359,7 +357,7 @@ unsigned int CAESinkWASAPI::AddPackets(uint8_t **data, unsigned int frames, unsi NumFramesRequested * m_format.m_frameSize); m_bufferPtr = 0; - hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, flags); //pass back to audio driver + hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, 0); //pass back to audio driver if (FAILED(hr)) { #ifdef _DEBUG @@ -396,7 +394,10 @@ void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool fo deviceInfo.m_channels.Reset(); deviceInfo.m_dataFormats.clear(); deviceInfo.m_sampleRates.clear(); + deviceInfo.m_streamTypes.clear(); deviceChannels.Reset(); + add192 = false; + add48 = false; for (unsigned int c = 0; c < WASAPI_SPEAKER_COUNT; c++) { @@ -592,8 +593,23 @@ void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool fo wfxex.dwChannelMask = KSAUDIO_SPEAKER_STEREO; wfxex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfxex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - wfxex.Format.wBitsPerSample = 16; - wfxex.Samples.wValidBitsPerSample = 16; + + // 16 bits is most widely supported and likely to have the widest range of sample rates + if (deviceInfo.m_dataFormats.empty() || + std::find(deviceInfo.m_dataFormats.cbegin(), deviceInfo.m_dataFormats.cend(), + AE_FMT_S16NE) != deviceInfo.m_dataFormats.cend()) + { + wfxex.Format.wBitsPerSample = 16; + wfxex.Samples.wValidBitsPerSample = 16; + } + else + { + const AEDataFormat fmt = deviceInfo.m_dataFormats.front(); + wfxex.Format.wBitsPerSample = CAEUtil::DataFormatToBits(fmt); + wfxex.Samples.wValidBitsPerSample = + (fmt == AE_FMT_S24NE4MSB ? 24 : wfxex.Format.wBitsPerSample); + } + wfxex.Format.nChannels = 2; wfxex.Format.nBlockAlign = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3); wfxex.Format.nAvgBytesPerSec = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign; @@ -745,17 +761,17 @@ bool CAESinkWASAPI::InitializeExclusive(AEAudioFormat &format) else if (format.m_dataFormat == AE_FMT_RAW) //No sense in trying other formats for passthrough. return false; - CLog::Log(LOGWARNING, - "AESinkWASAPI: IsFormatSupported failed ({}) - trying to find a compatible format", - WASAPIErrToStr(hr)); + CLog::LogF(LOGWARNING, + "format {} not supported by the device - trying to find a compatible format", + CAEUtil::DataFormatToStr(format.m_dataFormat)); requestedChannels = wfxex.Format.nChannels; desired_map = CAESinkFactoryWin::SpeakerMaskFromAEChannels(format.m_channelLayout); /* The requested format is not supported by the device. Find something that works */ - CLog::Log(LOGWARNING, - "AESinkWASAPI: Input channels are [{}] - Trying to find a matching output layout", - std::string(format.m_channelLayout)); + CLog::LogF(LOGWARNING, "Input channels are [{}] - Trying to find a matching output layout", + std::string(format.m_channelLayout)); + for (int layout = -1; layout <= (int)ARRAYSIZE(layoutsList); layout++) { // if requested layout is not supported, try standard layouts which contain @@ -886,6 +902,20 @@ initialize: format.m_sampleRate = wfxex.Format.nSamplesPerSec; //PCM: Sample rate. RAW: Link speed format.m_frameSize = (wfxex.Format.wBitsPerSample >> 3) * wfxex.Format.nChannels; + ComPtr<IAudioClient2> audioClient2; + if (SUCCEEDED(m_pAudioClient.As(&audioClient2))) + { + AudioClientProperties props = {}; + props.cbSize = sizeof(props); + // ForegroundOnlyMedia/BackgroundCapableMedia replaced in Windows 10 by Movie/Media + props.eCategory = CSysInfo::IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin10) + ? AudioCategory_Media + : AudioCategory_ForegroundOnlyMedia; + + if (FAILED(hr = audioClient2->SetClientProperties(&props))) + CLog::LogF(LOGERROR, "unable to set audio category, {}", WASAPIErrToStr(hr)); + } + REFERENCE_TIME audioSinkBufferDurationMsec, hnsLatency; audioSinkBufferDurationMsec = (REFERENCE_TIME)500000; |