From ec21be498fe8b30756949df42322333f8a60a3da Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 3 Jul 2015 18:07:58 +0200 Subject: ao_coreaudio_exclusive: factor format selection --- audio/out/ao_coreaudio_exclusive.c | 79 +++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/audio/out/ao_coreaudio_exclusive.c b/audio/out/ao_coreaudio_exclusive.c index 7a845ff573..4f6eae7ac6 100644 --- a/audio/out/ao_coreaudio_exclusive.c +++ b/audio/out/ao_coreaudio_exclusive.c @@ -207,6 +207,45 @@ coreaudio_error: return -1; } +static int find_best_format(struct ao *ao, AudioStreamBasicDescription *out_fmt) +{ + struct priv *p = ao->priv; + + // Build ASBD for the input format + AudioStreamBasicDescription asbd; + ca_fill_asbd(ao, &asbd); + + *out_fmt = (AudioStreamBasicDescription){0}; + + AudioStreamRangedDescription *formats; + size_t n_formats; + OSStatus err; + + err = CA_GET_ARY(p->stream, kAudioStreamPropertyAvailablePhysicalFormats, + &formats, &n_formats); + CHECK_CA_ERROR("could not get number of stream formats"); + + for (int j = 0; j < n_formats; j++) { + AudioStreamBasicDescription *stream_asbd = &formats[j].mFormat; + + ca_print_asbd(ao, "- ", stream_asbd); + + if (!out_fmt->mFormatID || ca_asbd_is_better(&asbd, out_fmt, stream_asbd)) + *out_fmt = *stream_asbd; + } + + talloc_free(formats); + + if (!out_fmt->mFormatID) { + MP_ERR(ao, "no format found\n"); + return -1; + } + + return 0; +coreaudio_error: + return -1; +} + static int init(struct ao *ao) { struct priv *p = ao->priv; @@ -226,10 +265,6 @@ static int init(struct ao *ao) goto coreaudio_error_nounlock; } - // Build ASBD for the input format - AudioStreamBasicDescription asbd; - ca_fill_asbd(ao, &asbd); - uint32_t is_alive = 1; err = CA_GET(p->device, kAudioDevicePropertyDeviceIsAlive, &is_alive); CHECK_CA_WARN("could not check whether device is alive"); @@ -246,43 +281,17 @@ static int init(struct ao *ao) if (select_stream(ao) < 0) goto coreaudio_error; - AudioStreamRangedDescription *formats; - size_t n_formats; - - err = CA_GET_ARY(p->stream, kAudioStreamPropertyAvailablePhysicalFormats, - &formats, &n_formats); - CHECK_CA_ERROR("could not get number of stream formats"); - - int req_rate_format = -1; - int max_rate_format = -1; - - for (int j = 0; j < n_formats; j++) { - if (ca_formatid_is_compressed(formats[j].mFormat.mFormatID)) { - // select the compressed format that has exactly the same - // samplerate. If an exact match cannot be found, select - // the format with highest samplerate as backup. - if (formats[j].mFormat.mSampleRate == asbd.mSampleRate) { - req_rate_format = j; - break; - } else if (max_rate_format < 0 || - formats[j].mFormat.mSampleRate > - formats[max_rate_format].mFormat.mSampleRate) - max_rate_format = j; - } - } - - if (req_rate_format >= 0) - p->stream_asbd = formats[req_rate_format].mFormat; - else - p->stream_asbd = formats[max_rate_format].mFormat; + AudioStreamBasicDescription hwfmt; + if (find_best_format(ao, &hwfmt) < 0) + goto coreaudio_error; - talloc_free(formats); + p->stream_asbd = hwfmt; err = CA_GET(p->stream, kAudioStreamPropertyPhysicalFormat, &p->original_asbd); CHECK_CA_ERROR("could not get stream's original physical format"); - if (!ca_change_physical_format_sync(ao, p->stream, p->stream_asbd)) + if (!ca_change_physical_format_sync(ao, p->stream, hwfmt)) goto coreaudio_error; err = enable_property_listener(ao, true); -- cgit v1.2.3