Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mac-videotoolbox: Add Spatial AQ option (macOS 15) #11442

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/build-project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
macos-build:
name: macOS 🍏
runs-on: macos-14
runs-on: macos-15
needs: check-event
strategy:
fail-fast: false
Expand All @@ -80,10 +80,6 @@ jobs:
: Set Up Environment 🔧
if (( ${+RUNNER_DEBUG} )) setopt XTRACE
print '::group::Enable Xcode 15.4'
sudo xcode-select --switch /Applications/Xcode_15.4.app/Contents/Developer
print '::endgroup::'
print '::group::Clean Homebrew Environment'
local -a to_remove=()
Expand Down
4 changes: 2 additions & 2 deletions cmake/macos/compilerconfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ endif()
set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS arm64 x86_64)

# Ensure recent enough Xcode and platform SDK
set(_obs_macos_minimum_sdk 14.2) # Keep in sync with Xcode
set(_obs_macos_minimum_xcode 15.1) # Keep in sync with SDK
set(_obs_macos_minimum_sdk 15.0) # Keep in sync with Xcode
set(_obs_macos_minimum_xcode 16.0) # Keep in sync with SDK
message(DEBUG "macOS SDK Path: ${CMAKE_OSX_SYSROOT}")
string(REGEX MATCH ".+/MacOSX.platform/Developer/SDKs/MacOSX([0-9]+\\.[0-9])+\\.sdk$" _ ${CMAKE_OSX_SYSROOT})
set(_obs_macos_current_sdk ${CMAKE_MATCH_1})
Expand Down
4 changes: 4 additions & 0 deletions plugins/mac-videotoolbox/data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ MaxBitrateWindow="Maximum bitrate window"
KeyframeIntervalSec="Keyframe Interval (0=auto)"
Profile="Profile"
UseBFrames="Use B-Frames"
SpatialAQ="Spatial AQ"
SpatialAQ.Auto="Automatic"
SpatialAQ.Disabled="Disabled"
SpatialAQ.Enabled="Enabled"
RateControl="Rate Control"
ColorFormatUnsupported="The selected color format is not supported by the selected Apple VT encoder. Select a compatible color format in Settings -> Advanced or use a different encoder."
FullRangeUnsupported="Full range color is not supported by 16-bit Apple VT encoders. Select limited range color in Settings -> Advanced."
Expand Down
42 changes: 41 additions & 1 deletion plugins/mac-videotoolbox/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
codec_type_to_print_fmt(codec_type), ##__VA_ARGS__)
#define VT_BLOG(level, format, ...) VT_LOG_ENCODER(enc->encoder, enc->codec_type, level, format, ##__VA_ARGS__)

enum aq_mode {
AQ_INVALID = 0,
AQ_AUTO,
AQ_DISABLED,
AQ_ENABLED,
};

struct vt_encoder_type_data {
const char *disp_name;
const char *id;
Expand Down Expand Up @@ -56,6 +63,7 @@ struct vt_encoder {
const char *profile;
CMVideoCodecType codec_type;
bool bframes;
bool spatial_aq;

int vt_pix_fmt;
enum video_colorspace colorspace;
Expand Down Expand Up @@ -567,6 +575,20 @@ static OSStatus create_encoder(struct vt_encoder *enc)
if (code != noErr) {
return code;
}

if (__builtin_available(macOS 15.0, *)) {
int spatial_aq = enc->spatial_aq ? kVTQPModulationLevel_Default : kVTQPModulationLevel_Disable;
CFNumberRef spatialAQ = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &spatial_aq);

code = VTSessionSetProperty(s, kVTCompressionPropertyKey_SpatialAdaptiveQPLevel, spatialAQ);

if (code != noErr) {
log_osstatus(LOG_WARNING, enc,
"setting kVTCompressionPropertyKey_SpatialAdaptiveQPLevel failed", code);
}

CFRelease(spatialAQ);
}
}

// This can fail depending on hardware configuration
Expand Down Expand Up @@ -624,11 +646,12 @@ static void dump_encoder_info(struct vt_encoder *enc)
"\trc_max_bitrate: %d (kbps)\n"
"\trc_max_bitrate_window: %f (s)\n"
"\thw_enc: %s\n"
"\tspatial_aq: %s\n"
"\tprofile: %s\n"
"\tcodec_type: %.4s\n",
enc->vt_encoder_id, enc->rate_control, enc->bitrate, enc->quality, enc->fps_num, enc->fps_den,
enc->width, enc->height, enc->keyint, enc->limit_bitrate ? "on" : "off", enc->rc_max_bitrate,
enc->rc_max_bitrate_window, enc->hw_enc ? "on" : "off",
enc->rc_max_bitrate_window, enc->hw_enc ? "on" : "off", enc->spatial_aq ? "on" : "off",
(enc->profile != NULL && !!strlen(enc->profile)) ? enc->profile : "default",
codec_type_to_print_fmt(enc->codec_type));
}
Expand Down Expand Up @@ -724,6 +747,14 @@ static bool update_params(struct vt_encoder *enc, obs_data_t *settings)
enc->rc_max_bitrate_window = obs_data_get_double(settings, "max_bitrate_window");
enc->bframes = obs_data_get_bool(settings, "bframes");

enum aq_mode spatia_aq_mode = obs_data_get_int(settings, "spatial_aq_mode");
if (spatia_aq_mode == AQ_AUTO) {
/* Only enable by default in CRF mode. */
enc->spatial_aq = strcmp(enc->rate_control, "CRF") == 0;
} else {
enc->spatial_aq = spatia_aq_mode == AQ_ENABLED;
}

return true;
}

Expand Down Expand Up @@ -1261,6 +1292,14 @@ static obs_properties_t *vt_properties_h26x(void *data __unused, void *type_data

obs_properties_add_bool(props, "bframes", obs_module_text("UseBFrames"));

if (__builtin_available(macOS 15.0, *)) {
p = obs_properties_add_list(props, "spatial_aq_mode", obs_module_text("SpatialAQ"), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(p, obs_module_text("SpatialAQ.Auto"), AQ_AUTO);
obs_property_list_add_int(p, obs_module_text("SpatialAQ.Disabled"), AQ_DISABLED);
obs_property_list_add_int(p, obs_module_text("SpatialAQ.Enabled"), AQ_ENABLED);
}

return props;
}

Expand Down Expand Up @@ -1346,6 +1385,7 @@ static void vt_defaults(obs_data_t *settings, void *data)
type_data->codec_type == kCMVideoCodecType_H264 ? "high" : "main");
obs_data_set_default_int(settings, "codec_type", kCMVideoCodecType_AppleProRes422);
obs_data_set_default_bool(settings, "bframes", true);
obs_data_set_default_int(settings, "spatial_aq_mode", AQ_AUTO);
}

static void vt_free_type_data(void *data)
Expand Down
Loading