summaryrefslogtreecommitdiffstats
path: root/audio/out
diff options
context:
space:
mode:
authorKevin Mitchell <kevmitch@gmail.com>2014-12-01 00:46:15 -0800
committerKevin Mitchell <kevmitch@gmail.com>2014-12-01 03:40:24 -0800
commit67c4117476976cd037e4c7cd2efa98903b417980 (patch)
tree5b49b94139b35463e7399c8d8fcbe875f4f3df5e /audio/out
parent146561cc9184fc8a17bd8cc857a8941fe2928132 (diff)
downloadmpv-67c4117476976cd037e4c7cd2efa98903b417980.tar.bz2
mpv-67c4117476976cd037e4c7cd2efa98903b417980.tar.xz
ao/wasapi: make set_ao_format EX/EXTENSIBLE agnostic
There is no guarantee that closestMatch returned by IsFormatSupported is actually a WAVEFORMATEXTENSIBLE. http://msdn.microsoft.com/en-us/library/windows/desktop/dd370876%28v=vs.85%29.aspx We should therefore not blindly treat it as such.
Diffstat (limited to 'audio/out')
-rwxr-xr-xaudio/out/ao_wasapi_utils.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 8d374dfca9..7be636753e 100755
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -230,6 +230,21 @@ static bool waveformat_is_float(WAVEFORMATEX *wf)
}
}
+static bool waveformat_is_pcm(WAVEFORMATEX *wf)
+{
+ switch(wf->wFormatTag) {
+ case WAVE_FORMAT_EXTENSIBLE:
+ {
+ WAVEFORMATEXTENSIBLE *wformat = (WAVEFORMATEXTENSIBLE *)wf;
+ return !mp_GUID_compare(&mp_KSDATAFORMAT_SUBTYPE_PCM, &wformat->SubFormat);
+ }
+ case WAVE_FORMAT_PCM:
+ return true;
+ default:
+ return false;
+ }
+}
+
static void waveformat_copy(WAVEFORMATEXTENSIBLE* dst, WAVEFORMATEX* src)
{
if ( src->wFormatTag == WAVE_FORMAT_EXTENSIBLE )
@@ -238,38 +253,37 @@ static void waveformat_copy(WAVEFORMATEXTENSIBLE* dst, WAVEFORMATEX* src)
dst->Format = *src;
}
-static bool set_ao_format(struct ao *ao,
- WAVEFORMATEXTENSIBLE wformat)
+static bool set_ao_format(struct ao *ao, WAVEFORMATEX *wf)
{
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
// explicitly disallow 8 bits - this will catch if the
// closestMatch returned by IsFormatSupported in try_format below returns
// a bit depth of less than 16
- if (wformat.Format.wBitsPerSample < 16)
+ if (wf->wBitsPerSample < 16)
return false;
int format;
- if ( !mp_GUID_compare(&mp_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, &wformat.SubFormat) ) {
+ if (waveformat_is_float(wf)){
format = AF_FORMAT_FLOAT;
- } else if ( !mp_GUID_compare(&mp_KSDATAFORMAT_SUBTYPE_PCM, &wformat.SubFormat) ) {
+ } else if (waveformat_is_pcm(wf)) {
format = AF_FORMAT_S32;
} else {
- MP_ERR(ao, "Unknown SubFormat %s\n", mp_GUID_to_str(&wformat.SubFormat));
+ MP_ERR(ao, "Unknown WAVEFORMAT\n");
return false;
}
// set the correct number of bits (the 32-bits assumed above may be wrong)
- format = af_fmt_change_bits(format, wformat.Format.wBitsPerSample);
+ format = af_fmt_change_bits(format, wf->wBitsPerSample);
if (!format)
return false;
- ao->samplerate = wformat.Format.nSamplesPerSec;
- ao->bps = wformat.Format.nAvgBytesPerSec;
+ ao->samplerate = wf->nSamplesPerSec;
+ ao->bps = wf->nAvgBytesPerSec;
ao->format = format;
- if (ao->channels.num != wformat.Format.nChannels)
- mp_chmap_from_channels(&ao->channels, wformat.Format.nChannels);
+ if (ao->channels.num != wf->nChannels)
+ mp_chmap_from_channels(&ao->channels, wf->nChannels);
- state->format = wformat;
+ waveformat_copy(&state->format, wf);
return true;
}
@@ -301,7 +315,7 @@ static bool try_format(struct ao *ao,
}
if (hr == S_FALSE) {
- if (set_ao_format(ao, wformat)) {
+ if (set_ao_format(ao, &wformat.Format)) {
MP_VERBOSE(ao, "Accepted as %dch %s @ %dhz\n",
ao->channels.num, af_fmt_to_str(ao->format), ao->samplerate);
@@ -309,7 +323,7 @@ static bool try_format(struct ao *ao,
}
} if (hr == S_OK || (!state->opt_exclusive && hr == AUDCLNT_E_UNSUPPORTED_FORMAT)) {
// AUDCLNT_E_UNSUPPORTED_FORMAT here means "works in shared, doesn't in exclusive"
- if (set_ao_format(ao, wformat)) {
+ if (set_ao_format(ao, &wformat.Format)) {
MP_VERBOSE(ao, "%dch %s @ %dhz accepted\n",
ao->channels.num, af_fmt_to_str(ao->format), samplerate);
return true;