From 6ad48ddb201318dc72fa40aff2ae260dbc2822a7 Mon Sep 17 00:00:00 2001 From: Palana Date: Mon, 10 Aug 2015 13:30:12 +0200 Subject: [PATCH] coreaudio-encoder: Update default bitrate matching/logging --- plugins/coreaudio-encoder/encoder.cpp | 121 ++++++++++++++++---------- 1 file changed, 77 insertions(+), 44 deletions(-) diff --git a/plugins/coreaudio-encoder/encoder.cpp b/plugins/coreaudio-encoder/encoder.cpp index 42f62c7ae..0f2b16e7a 100644 --- a/plugins/coreaudio-encoder/encoder.cpp +++ b/plugins/coreaudio-encoder/encoder.cpp @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include #include #ifndef _WIN32 @@ -1027,64 +1029,95 @@ static AudioConverterRef he_aac_default_converter(void) return get_default_converter(kAudioFormatMPEG4AAC_HE); } -struct find_matching_bitrate_helper { - UInt32 bitrate; - UInt32 best_match; - int diff; -}; -typedef struct find_matching_bitrate_helper find_matching_bitrate_helper; - -static void find_matching_bitrate_func(void *data, UInt32 min, UInt32 max) +static bool find_best_match(DStr &log, ca_encoder *ca, UInt32 bitrate, + UInt32 &best_match) { - find_matching_bitrate_helper *helper = - static_cast(data); + UInt32 actual_bitrate = bitrate * 1000; + bool found_match = false; - int min_diff = abs((int)helper->bitrate - (int)min); - int max_diff = abs((int)helper->bitrate - (int)max); + auto handle_bitrate = [&](UInt32 candidate) + { + if (abs(static_cast(actual_bitrate - candidate)) < + abs(static_cast(actual_bitrate - best_match))) { + log_to_dstr(log, ca, "Found new best match %u\n", + static_cast(candidate)); - if (min_diff < helper->diff) { - helper->best_match = min; - helper->diff = min_diff; + found_match = true; + best_match = candidate; + } + }; + + auto helper = [&](UInt32 min_, UInt32 max_) + { + handle_bitrate(min_); + + if (min_ == max_) + return; + + log_to_dstr(log, ca, "Got actual bit rate range: %u<->%u\n", + static_cast(min_), + static_cast(max_)); + + handle_bitrate(max_); + }; + + for (UInt32 format_id : aac_formats) { + log_to_dstr(log, ca, "Trying %s (0x%x)\n", + format_id_to_str(format_id), format_id); + + auto out = get_default_out_asbd_builder() + .format_id(format_id) + .asbd; + + auto converter = get_converter(log, ca, out); + + if (converter) + enumerate_bitrates(log, ca, converter.get(), + helper); + else + log_to_dstr(log, ca, "Could not get converter\n"); } - if (max_diff < helper->diff) { - helper->best_match = max; - helper->diff = max_diff; - } + best_match /= 1000; + + return found_match; } static UInt32 find_matching_bitrate(UInt32 bitrate) { - find_matching_bitrate_helper helper; - helper.bitrate = bitrate * 1000; - helper.best_match = 0; - helper.diff = INT_MAX; + static UInt32 match = bitrate; - AudioConverterRef converter = aac_default_converter(); - if (!converter) { - CA_LOG(LOG_ERROR, "Could not get converter to match " - "default bitrate"); - return bitrate; - } + static once_flag once; - bool has_bitrates = enumerate_bitrates(NULL, converter, - find_matching_bitrate_func, &helper); - AudioConverterDispose(converter); + call_once(once, [&]() + { + DStr log; + ca_encoder *ca = nullptr; - if (!has_bitrates) { - CA_LOG(LOG_ERROR, "No bitrates found while matching " - "default bitrate"); - AudioConverterDispose(converter); - return bitrate; - } + if (!find_best_match(log, ca, bitrate, match)) { + CA_CO_DLOG(LOG_ERROR, "No matching bitrates found for " + "target bitrate %u", + static_cast(bitrate)); - if (helper.best_match != helper.bitrate) - CA_LOG(LOG_INFO, "Returning closest matching bitrate %u " - "instead of requested bitrate %u", - (uint32_t)helper.best_match / 1000, - (uint32_t)bitrate); + match = bitrate; + return; + } - return helper.best_match / 1000; + if (match != bitrate) { + CA_CO_DLOG(LOG_INFO, "Default bitrate (%u) isn't " + "supported, returning %u as closest match", + static_cast(bitrate), + static_cast(match)); + return; + } + + if (log->len) + CA_CO_DLOG(LOG_DEBUG, "Default bitrate matching log " + "for bitrate %u", + static_cast(bitrate)); + }); + + return match; } static void aac_defaults(obs_data_t *settings)