|
|
@@ -37,6 +37,7 @@ struct vt_encoder {
|
|
|
uint32_t fps_den;
|
|
|
const char *rate_control;
|
|
|
uint32_t bitrate;
|
|
|
+ float quality;
|
|
|
bool limit_bitrate;
|
|
|
uint32_t rc_max_bitrate;
|
|
|
float rc_max_bitrate_window;
|
|
|
@@ -147,8 +148,8 @@ static OSStatus session_set_prop(VTCompressionSessionRef session,
|
|
|
|
|
|
static OSStatus session_set_bitrate(VTCompressionSessionRef session,
|
|
|
const char *rate_control, int new_bitrate,
|
|
|
- bool limit_bitrate, int max_bitrate,
|
|
|
- float max_bitrate_window)
|
|
|
+ float quality, bool limit_bitrate,
|
|
|
+ int max_bitrate, float max_bitrate_window)
|
|
|
{
|
|
|
OSStatus code;
|
|
|
|
|
|
@@ -174,6 +175,10 @@ static OSStatus session_set_bitrate(VTCompressionSessionRef session,
|
|
|
session, kVTCompressionPropertyKey_AverageBitRate,
|
|
|
new_bitrate * 1000));
|
|
|
can_limit_bitrate = true;
|
|
|
+ } else if (strcmp(rate_control, "CRF") == 0) {
|
|
|
+ SESSION_CHECK(session_set_prop_float(
|
|
|
+ session, kVTCompressionPropertyKey_Quality, quality));
|
|
|
+ can_limit_bitrate = true;
|
|
|
} else {
|
|
|
VT_LOG(LOG_ERROR,
|
|
|
"Selected rate control method is not supported: %s",
|
|
|
@@ -355,9 +360,10 @@ static bool create_encoder(struct vt_encoder *enc)
|
|
|
STATUS_CHECK(session_set_prop(s, kVTCompressionPropertyKey_ProfileLevel,
|
|
|
obs_to_vt_profile(enc->profile)));
|
|
|
|
|
|
- STATUS_CHECK(session_set_bitrate(
|
|
|
- s, enc->rate_control, enc->bitrate, enc->limit_bitrate,
|
|
|
- enc->rc_max_bitrate, enc->rc_max_bitrate_window));
|
|
|
+ STATUS_CHECK(session_set_bitrate(s, enc->rate_control, enc->bitrate,
|
|
|
+ enc->quality, enc->limit_bitrate,
|
|
|
+ enc->rc_max_bitrate,
|
|
|
+ enc->rc_max_bitrate_window));
|
|
|
|
|
|
STATUS_CHECK(session_set_colorspace(s, enc->colorspace));
|
|
|
|
|
|
@@ -398,6 +404,7 @@ static void dump_encoder_info(struct vt_encoder *enc)
|
|
|
"\tvt_encoder_id %s\n"
|
|
|
"\trate_control: %s\n"
|
|
|
"\tbitrate: %d (kbps)\n"
|
|
|
+ "\tquality: %f\n"
|
|
|
"\tfps_num: %d\n"
|
|
|
"\tfps_den: %d\n"
|
|
|
"\twidth: %d\n"
|
|
|
@@ -409,8 +416,8 @@ static void dump_encoder_info(struct vt_encoder *enc)
|
|
|
"\thw_enc: %s\n"
|
|
|
"\tprofile: %s\n",
|
|
|
enc->vt_encoder_id, enc->rate_control, enc->bitrate,
|
|
|
- enc->fps_num, enc->fps_den, enc->width, enc->height,
|
|
|
- enc->keyint, enc->limit_bitrate ? "on" : "off",
|
|
|
+ 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->profile != NULL && !!strlen(enc->profile)) ? enc->profile
|
|
|
@@ -464,6 +471,7 @@ static void update_params(struct vt_encoder *enc, obs_data_t *settings)
|
|
|
enc->keyint = (uint32_t)obs_data_get_int(settings, "keyint_sec");
|
|
|
enc->rate_control = obs_data_get_string(settings, "rate_control");
|
|
|
enc->bitrate = (uint32_t)obs_data_get_int(settings, "bitrate");
|
|
|
+ enc->quality = ((float)obs_data_get_int(settings, "quality")) / 100;
|
|
|
enc->profile = obs_data_get_string(settings, "profile");
|
|
|
enc->limit_bitrate = obs_data_get_bool(settings, "limit_bitrate");
|
|
|
enc->rc_max_bitrate = obs_data_get_int(settings, "max_bitrate");
|
|
|
@@ -486,7 +494,8 @@ static bool vt_update(void *data, obs_data_t *settings)
|
|
|
return true;
|
|
|
|
|
|
OSStatus code = session_set_bitrate(enc->session, enc->rate_control,
|
|
|
- enc->bitrate, enc->limit_bitrate,
|
|
|
+ enc->bitrate, enc->quality,
|
|
|
+ enc->limit_bitrate,
|
|
|
enc->rc_max_bitrate,
|
|
|
enc->rc_max_bitrate_window);
|
|
|
if (code != noErr)
|
|
|
@@ -854,6 +863,7 @@ static const char *vt_getname(void *data)
|
|
|
|
|
|
#define TEXT_VT_ENCODER obs_module_text("VTEncoder")
|
|
|
#define TEXT_BITRATE obs_module_text("Bitrate")
|
|
|
+#define TEXT_QUALITY obs_module_text("Quality")
|
|
|
#define TEXT_USE_MAX_BITRATE obs_module_text("UseMaxBitrate")
|
|
|
#define TEXT_MAX_BITRATE obs_module_text("MaxBitrate")
|
|
|
#define TEXT_MAX_BITRATE_WINDOW obs_module_text("MaxBitrateWindow")
|
|
|
@@ -868,15 +878,22 @@ static bool rate_control_limit_bitrate_modified(obs_properties_t *ppts,
|
|
|
obs_property_t *p,
|
|
|
obs_data_t *settings)
|
|
|
{
|
|
|
+ bool has_bitrate = true;
|
|
|
bool can_limit_bitrate = true;
|
|
|
bool use_limit_bitrate = obs_data_get_bool(settings, "limit_bitrate");
|
|
|
const char *rate_control =
|
|
|
obs_data_get_string(settings, "rate_control");
|
|
|
|
|
|
- if (strcmp(rate_control, "CBR") == 0)
|
|
|
+ if (strcmp(rate_control, "CBR") == 0) {
|
|
|
can_limit_bitrate = false;
|
|
|
- else if (strcmp(rate_control, "ABR") == 0)
|
|
|
+ has_bitrate = true;
|
|
|
+ } else if (strcmp(rate_control, "CRF") == 0) {
|
|
|
+ can_limit_bitrate = true;
|
|
|
+ has_bitrate = false;
|
|
|
+ } else if (strcmp(rate_control, "ABR") == 0) {
|
|
|
can_limit_bitrate = true;
|
|
|
+ has_bitrate = true;
|
|
|
+ }
|
|
|
|
|
|
p = obs_properties_get(ppts, "limit_bitrate");
|
|
|
obs_property_set_visible(p, can_limit_bitrate);
|
|
|
@@ -884,6 +901,11 @@ static bool rate_control_limit_bitrate_modified(obs_properties_t *ppts,
|
|
|
obs_property_set_visible(p, can_limit_bitrate && use_limit_bitrate);
|
|
|
p = obs_properties_get(ppts, "max_bitrate_window");
|
|
|
obs_property_set_visible(p, can_limit_bitrate && use_limit_bitrate);
|
|
|
+
|
|
|
+ p = obs_properties_get(ppts, "bitrate");
|
|
|
+ obs_property_set_visible(p, has_bitrate);
|
|
|
+ p = obs_properties_get(ppts, "quality");
|
|
|
+ obs_property_set_visible(p, !has_bitrate);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -904,12 +926,18 @@ static obs_properties_t *vt_properties(void *unused)
|
|
|
#endif
|
|
|
obs_property_list_add_string(p, "CBR", "CBR");
|
|
|
obs_property_list_add_string(p, "ABR", "ABR");
|
|
|
+#ifndef __aarch64__
|
|
|
+ if (os_get_emulation_status() == true)
|
|
|
+#endif
|
|
|
+ obs_property_list_add_string(p, "CRF", "CRF");
|
|
|
obs_property_set_modified_callback(p,
|
|
|
rate_control_limit_bitrate_modified);
|
|
|
|
|
|
p = obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000,
|
|
|
50);
|
|
|
obs_property_int_set_suffix(p, " Kbps");
|
|
|
+ obs_properties_add_int_slider(props, "quality", TEXT_QUALITY, 0, 100,
|
|
|
+ 1);
|
|
|
|
|
|
p = obs_properties_add_bool(props, "limit_bitrate",
|
|
|
TEXT_USE_MAX_BITRATE);
|
|
|
@@ -948,6 +976,7 @@ static void vt_defaults(obs_data_t *settings)
|
|
|
obs_data_set_default_string(settings, "rate_control",
|
|
|
"CBR");
|
|
|
obs_data_set_default_int(settings, "bitrate", 2500);
|
|
|
+ obs_data_set_default_int(settings, "quality", 60);
|
|
|
obs_data_set_default_bool(settings, "limit_bitrate", false);
|
|
|
obs_data_set_default_int(settings, "max_bitrate", 2500);
|
|
|
obs_data_set_default_double(settings, "max_bitrate_window", 1.5f);
|