diff --git a/plugins/coreaudio-encoder/data/locale/en-US.ini b/plugins/coreaudio-encoder/data/locale/en-US.ini index 72df70f21..361a458ef 100644 --- a/plugins/coreaudio-encoder/data/locale/en-US.ini +++ b/plugins/coreaudio-encoder/data/locale/en-US.ini @@ -1,3 +1,5 @@ CoreAudioAAC="CoreAudio AAC encoder" Bitrate="Bitrate" AllowHEAAC="Allow HE-AAC" +OutputSamplerate="Output Sample Rate" +UseInputSampleRate="Use Input (OBS) Sample Rate (may list unsupported bitrates)" diff --git a/plugins/coreaudio-encoder/encoder.cpp b/plugins/coreaudio-encoder/encoder.cpp index 2296b0aeb..e3269ad5f 100644 --- a/plugins/coreaudio-encoder/encoder.cpp +++ b/plugins/coreaudio-encoder/encoder.cpp @@ -427,7 +427,8 @@ static bool bitrate_valid(DStr &log, ca_encoder *ca, static bool create_encoder(DStr &log, ca_encoder *ca, AudioStreamBasicDescription *in, AudioStreamBasicDescription *out, - UInt32 format_id, UInt32 bitrate, UInt32 rate_control) + UInt32 format_id, UInt32 bitrate, UInt32 samplerate, + UInt32 rate_control) { #define STATUS_CHECK(c) \ code = c; \ @@ -437,8 +438,12 @@ static bool create_encoder(DStr &log, ca_encoder *ca, return false; \ } + Float64 srate = samplerate ? + (Float64)samplerate : + (Float64)ca->samples_per_second; + auto out_ = asbd_builder() - .sample_rate((Float64)ca->samples_per_second) + .sample_rate(srate) .channels_per_frame((UInt32)ca->channels) .format_id(format_id) .asbd; @@ -550,6 +555,9 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) ca->allowed_formats = &aac_lc_formats; } + auto samplerate = + static_cast(obs_data_get_int(settings, "samplerate")); + DStr log; bool encoder_created = false; @@ -559,7 +567,7 @@ static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder) (uint32_t)format_id); if (!create_encoder(log, ca.get(), &in, &out, format_id, - bitrate, rate_control)) + bitrate, samplerate, rate_control)) continue; encoder_created = true; @@ -1031,6 +1039,7 @@ static UInt32 find_matching_bitrate(UInt32 bitrate) static void aac_defaults(obs_data_t *settings) { + obs_data_set_default_int(settings, "samplerate", 0); //match input obs_data_set_default_int(settings, "bitrate", find_matching_bitrate(128)); obs_data_set_default_bool(settings, "allow he-aac", true); @@ -1123,6 +1132,81 @@ static bool enumerate_bitrates(DStr &log, ca_encoder *ca, } #endif +static vector get_samplerates(DStr &log, ca_encoder *ca) +{ + vector samplerates; + + auto handle_samplerate = [&](UInt32 rate) + { + if (find(begin(samplerates), end(samplerates), rate) == + end(samplerates)) { + log_to_dstr(log, ca, "Adding sample rate %u\n", + static_cast(rate)); + samplerates.push_back(rate); + } else { + log_to_dstr(log, ca, "Sample rate %u already added\n", + static_cast(rate)); + } + }; + + auto helper = [&](const AudioValueRange &range) + { + auto min_ = static_cast(range.mMinimum); + auto max_ = static_cast(range.mMaximum); + + handle_samplerate(min_); + + if (min_ == max_) + return; + + log_to_dstr(log, ca, "Got actual sample rate range: %u<->%u\n", + static_cast(min_), + static_cast(max_)); + + handle_samplerate(max_); + }; + + for (UInt32 format : (ca ? *ca->allowed_formats : aac_formats)) { + log_to_dstr(log, ca, "Trying %s (0x%x)\n", + format_id_to_str(format), + static_cast(format)); + + auto asbd = asbd_builder() + .format_id(format) + .asbd; + + enumerate_samplerates(log, ca, asbd, helper); + } + + return samplerates; +} + +static void add_samplerates(obs_property_t *prop, ca_encoder *ca) +{ + obs_property_list_add_int(prop, + obs_module_text("UseInputSampleRate"), 0); + + DStr log; + + auto samplerates = get_samplerates(log, ca); + + if (!samplerates.size()) { + CA_CO_DLOG_(LOG_ERROR, "Couldn't find available sample rates"); + return; + } + + if (log->len) + CA_CO_DLOG_(LOG_DEBUG, "Sample rate enumeration log"); + + sort(begin(samplerates), end(samplerates)); + + DStr buffer; + for (UInt32 samplerate : samplerates) { + dstr_printf(buffer, "%d", static_cast(samplerate)); + obs_property_list_add_int(prop, buffer->array, samplerate); + } +} + static vector get_bitrates(DStr &log, ca_encoder *ca, Float64 samplerate) { @@ -1205,7 +1289,12 @@ static obs_properties_t *aac_properties(void *data) obs_properties_t *props = obs_properties_create(); - obs_property_t *p = obs_properties_add_list(props, "bitrate", + obs_property_t *p = obs_properties_add_list(props, "samplerate", + obs_module_text("OutputSamplerate"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + add_samplerates(p, ca); + + p = obs_properties_add_list(props, "bitrate", obs_module_text("Bitrate"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); add_bitrates(p, ca);