From e6b7a60638b8b87a26981ddf12f656315fbb5647 Mon Sep 17 00:00:00 2001 From: gxalpha Date: Sun, 23 Oct 2022 03:55:20 +0200 Subject: [PATCH] UI: Add simple mode for Apple Hardware HEVC --- UI/data/locale/en-US.ini | 1 + UI/window-basic-main-outputs.cpp | 23 +++++++++++++++++++++++ UI/window-basic-main-profiles.cpp | 15 +++++++++++++++ UI/window-basic-main.hpp | 1 + UI/window-basic-settings-stream.cpp | 18 ++++++++++++++++++ UI/window-basic-settings.cpp | 23 +++++++++++++++++++++-- 6 files changed, 79 insertions(+), 2 deletions(-) diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 93956a5c1..ac57cae3a 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -950,6 +950,7 @@ Basic.Settings.Output.Simple.Encoder.Hardware.NVENC.H264="Hardware (NVENC, H.264 Basic.Settings.Output.Simple.Encoder.Hardware.NVENC.AV1="Hardware (NVENC, AV1)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC.HEVC="Hardware (NVENC, HEVC)" Basic.Settings.Output.Simple.Encoder.Hardware.Apple.H264="Hardware (Apple, H.264)" +Basic.Settings.Output.Simple.Encoder.Hardware.Apple.HEVC="Hardware (Apple, HEVC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 low CPU usage preset, increases file size)" Basic.Settings.Output.Simple.TwitchVodTrack="Twitch VOD Track (Uses Track 2)" Basic.Settings.Output.Warn.EnforceResolutionFPS.Title="Incompatible Resolution/Framerate" diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp index 1d992fd46..ce6e17cf1 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp @@ -293,6 +293,9 @@ struct SimpleOutput : BasicOutputHandler { void UpdateRecordingSettings_nvenc_hevc_av1(int cqp); void UpdateRecordingSettings_amd_cqp(int cqp); void UpdateRecordingSettings_apple(int quality); +#ifdef ENABLE_HEVC + void UpdateRecordingSettings_apple_hevc(int quality); +#endif void UpdateRecordingSettings(); void UpdateRecordingAudioSettings(); virtual void Update() override; @@ -386,6 +389,10 @@ const char *get_simple_output_encoder(const char *encoder) return "jim_av1_nvenc"; } else if (strcmp(encoder, SIMPLE_ENCODER_APPLE_H264) == 0) { return "com.apple.videotoolbox.videoencoder.ave.avc"; +#ifdef ENABLE_HEVC + } else if (strcmp(encoder, SIMPLE_ENCODER_APPLE_HEVC) == 0) { + return "com.apple.videotoolbox.videoencoder.ave.hevc"; +#endif } return "obs_x264"; @@ -703,6 +710,18 @@ void SimpleOutput::UpdateRecordingSettings_apple(int quality) obs_encoder_update(videoRecording, settings); } +#ifdef ENABLE_HEVC +void SimpleOutput::UpdateRecordingSettings_apple_hevc(int quality) +{ + OBSDataAutoRelease settings = obs_data_create(); + obs_data_set_string(settings, "rate_control", "CRF"); + obs_data_set_string(settings, "profile", "main"); + obs_data_set_int(settings, "quality", quality); + + obs_encoder_update(videoRecording, settings); +} +#endif + void SimpleOutput::UpdateRecordingSettings_amd_cqp(int cqp) { OBSDataAutoRelease settings = obs_data_create(); @@ -745,6 +764,10 @@ void SimpleOutput::UpdateRecordingSettings() } else if (videoEncoder == SIMPLE_ENCODER_APPLE_H264) { /* These are magic numbers. 0 - 100, more is better. */ UpdateRecordingSettings_apple(ultra_hq ? 70 : 50); +#ifdef ENABLE_HEVC + } else if (videoEncoder == SIMPLE_ENCODER_APPLE_HEVC) { + UpdateRecordingSettings_apple_hevc(ultra_hq ? 70 : 50); +#endif } UpdateRecordingAudioSettings(); } diff --git a/UI/window-basic-main-profiles.cpp b/UI/window-basic-main-profiles.cpp index c44e9f7a7..e0b576a4f 100644 --- a/UI/window-basic-main-profiles.cpp +++ b/UI/window-basic-main-profiles.cpp @@ -824,6 +824,7 @@ void OBSBasic::CheckForSimpleModeX264Fallback() #ifdef ENABLE_HEVC bool amd_hevc_supported = false; bool nve_hevc_supported = false; + bool apple_hevc_supported = false; #endif bool apple_supported = false; bool changed = false; @@ -847,6 +848,12 @@ void OBSBasic::CheckForSimpleModeX264Fallback() "com.apple.videotoolbox.videoencoder.ave.avc") == 0) apple_supported = true; +#ifdef ENABLE_HEVC + else if (strcmp(id, + "com.apple.videotoolbox.videoencoder.ave.hevc") == + 0) + apple_hevc_supported = true; +#endif } auto CheckEncoder = [&](const char *&name) { @@ -894,6 +901,14 @@ void OBSBasic::CheckForSimpleModeX264Fallback() name = SIMPLE_ENCODER_X264; return false; } +#ifdef ENABLE_HEVC + } else if (strcmp(name, SIMPLE_ENCODER_APPLE_HEVC) == 0) { + if (!apple_hevc_supported) { + changed = true; + name = SIMPLE_ENCODER_X264; + return false; + } +#endif } return true; diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 8f51618b5..e90f75cae 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -71,6 +71,7 @@ class OBSBasicStats; #define SIMPLE_ENCODER_AMD "amd" #define SIMPLE_ENCODER_AMD_HEVC "amd_hevc" #define SIMPLE_ENCODER_APPLE_H264 "apple_h264" +#define SIMPLE_ENCODER_APPLE_HEVC "apple_hevc" #define PREVIEW_EDGE_SIZE 10 diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp index 92821fc9e..bd9e571b1 100644 --- a/UI/window-basic-settings-stream.cpp +++ b/UI/window-basic-settings-stream.cpp @@ -1244,6 +1244,8 @@ static QString get_adv_fallback(const QString &enc) return "jim_nvenc"; if (enc == "h265_texture_amf") return "h264_texture_amf"; + if (enc == "com.apple.videotoolbox.videoencoder.ave.hevc") + return "com.apple.videotoolbox.videoencoder.ave.avc"; return "obs_x264"; } @@ -1255,6 +1257,8 @@ static QString get_simple_fallback(const QString &enc) return SIMPLE_ENCODER_NVENC; if (enc == SIMPLE_ENCODER_AMD_HEVC) return SIMPLE_ENCODER_AMD; + if (enc == SIMPLE_ENCODER_APPLE_HEVC) + return SIMPLE_ENCODER_APPLE_H264; return SIMPLE_ENCODER_X264; } @@ -1420,6 +1424,20 @@ void OBSBasicSettings::ResetEncoders(bool streamOnly) QString(SIMPLE_ENCODER_APPLE_H264)); } } +#ifdef ENABLE_HEVC + if (service_supports_encoder( + codecs, "com.apple.videotoolbox.videoencoder.ave.hevc") +#ifndef __aarch64__ + && os_get_emulation_status() == true +#endif + ) { + if (__builtin_available(macOS 13.0, *)) { + ui->simpleOutStrEncoder->addItem( + ENCODER_STR("Hardware.Apple.HEVC"), + QString(SIMPLE_ENCODER_APPLE_HEVC)); + } + } +#endif #endif #undef ENCODER_STR diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index fddc03d8c..c6c07d00a 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -3529,7 +3529,11 @@ void OBSBasicSettings::SaveOutputSettings() #endif else if (encoder == SIMPLE_ENCODER_AMD) presetType = "AMDPreset"; - else if (encoder == SIMPLE_ENCODER_APPLE_H264) + else if (encoder == SIMPLE_ENCODER_APPLE_H264 +#ifdef ENABLE_HEVC + || encoder == SIMPLE_ENCODER_APPLE_HEVC +#endif + ) /* The Apple encoders don't have presets like the other encoders do. This only exists to make sure that the x264 preset doesn't get overwritten with empty data. */ @@ -4826,6 +4830,17 @@ void OBSBasicSettings::FillSimpleRecordingValues() ui->simpleOutRecEncoder->addItem( ENCODER_STR("Hardware.Apple.H264"), QString(SIMPLE_ENCODER_APPLE_H264)); +#ifdef ENABLE_HEVC + if (EncoderAvailable("com.apple.videotoolbox.videoencoder.ave.hevc") +#ifndef __aarch64__ + && os_get_emulation_status() == true +#endif + ) + ui->simpleOutRecEncoder->addItem( + ENCODER_STR("Hardware.Apple.HEVC"), + QString(SIMPLE_ENCODER_APPLE_HEVC)); +#endif + #undef ADD_QUALITY #undef ENCODER_STR } @@ -4914,7 +4929,11 @@ void OBSBasicSettings::SimpleStreamingEncoderChanged() defaultPreset = "balanced"; preset = curAMDPreset; - } else if (encoder == SIMPLE_ENCODER_APPLE_H264) { + } else if (encoder == SIMPLE_ENCODER_APPLE_H264 +#ifdef ENABLE_HEVC + || encoder == SIMPLE_ENCODER_APPLE_HEVC +#endif + ) { ui->simpleOutAdvanced->setChecked(false); ui->simpleOutAdvanced->setVisible(false); ui->simpleOutPreset->setVisible(false);