未验证 提交 9ebc3d13 编写于 作者: J Jim 提交者: GitHub

Merge pull request #2220 from dionney/rate_control_vaapi

obs-ffmpeg: Enable VAAPI Rate Control
......@@ -160,19 +160,69 @@ static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path)
return true;
}
/* "Allowed" options per Rate Control
* See FFMPEG libavcodec/vaapi_encode.c (vaapi_encode_rc_modes)
*/
typedef struct {
const char *name;
bool qp;
bool bitrate;
bool maxrate;
} rc_mode_t;
static const rc_mode_t *get_rc_mode(const char *name)
{
/* Set "allowed" options per Rate Control */
static const rc_mode_t RC_MODES[] = {
{.name = "CBR", .qp = false, .bitrate = true, .maxrate = false},
{.name = "CQP", .qp = true, .bitrate = false, .maxrate = false},
{.name = "VBR", .qp = false, .bitrate = true, .maxrate = true},
NULL};
const rc_mode_t *rc_mode = RC_MODES;
while (!!rc_mode && strcmp(rc_mode->name, name) != 0)
rc_mode++;
return rc_mode ? rc_mode : RC_MODES;
}
static bool vaapi_update(void *data, obs_data_t *settings)
{
struct vaapi_encoder *enc = data;
const char *device = obs_data_get_string(settings, "vaapi_device");
const char *rate_control =
obs_data_get_string(settings, "rate_control");
const rc_mode_t *rc_mode = get_rc_mode(rate_control);
bool cbr = strcmp(rc_mode->name, "CBR") == 0;
int profile = (int)obs_data_get_int(settings, "profile");
int bf = (int)obs_data_get_int(settings, "bf");
int qp = rc_mode->qp ? (int)obs_data_get_int(settings, "qp") : 0;
av_opt_set_int(enc->context->priv_data, "qp", qp, 0);
int level = (int)obs_data_get_int(settings, "level");
int bitrate = (int)obs_data_get_int(settings, "bitrate");
int bitrate = rc_mode->bitrate
? (int)obs_data_get_int(settings, "bitrate")
: 0;
int maxrate = rc_mode->maxrate
? (int)obs_data_get_int(settings, "maxrate")
: 0;
int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
/* For Rate Control which allows maxrate, FFMPEG will give
* an error if maxrate > bitrate. To prevent that set maxrate
* to 0.
* For CBR, maxrate = bitrate
*/
if (cbr)
maxrate = bitrate;
else if (rc_mode->maxrate && maxrate && maxrate < bitrate)
maxrate = 0;
video_t *video = obs_encoder_video(enc->encoder);
const struct video_output_info *voi = video_output_get_info(video);
struct video_scale_info info;
......@@ -187,7 +237,7 @@ static bool vaapi_update(void *data, obs_data_t *settings)
enc->context->max_b_frames = bf;
enc->context->level = level;
enc->context->bit_rate = bitrate * 1000;
enc->context->rc_max_rate = bitrate * 1000;
enc->context->rc_max_rate = maxrate * 1000;
enc->context->width = obs_encoder_get_width(enc->encoder);
enc->context->height = obs_encoder_get_height(enc->encoder);
......@@ -212,15 +262,18 @@ static bool vaapi_update(void *data, obs_data_t *settings)
info("settings:\n"
"\tdevice: %s\n"
"\trate_control: %s\n"
"\tprofile: %d\n"
"\tlevel: %d\n"
"\tqp: %d\n"
"\tbitrate: %d\n"
"\tmaxrate: %d\n"
"\tkeyint: %d\n"
"\twidth: %d\n"
"\theight: %d\n"
"\tb-frames: %d\n",
device, profile, level, bitrate, enc->context->gop_size,
enc->context->width, enc->context->height,
device, rate_control, profile, level, qp, bitrate, maxrate,
enc->context->gop_size, enc->context->width, enc->context->height,
enc->context->max_b_frames);
return vaapi_init_codec(enc, device);
......@@ -446,6 +499,27 @@ static void vaapi_defaults(obs_data_t *settings)
obs_data_set_default_int(settings, "keyint_sec", 0);
obs_data_set_default_int(settings, "bf", 0);
obs_data_set_default_int(settings, "rendermode", 0);
obs_data_set_default_string(settings, "rate_control", "CBR");
obs_data_set_default_int(settings, "qp", 20);
obs_data_set_default_int(settings, "maxrate", 0);
}
static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
obs_data_t *settings)
{
UNUSED_PARAMETER(p);
const char *rate_control =
obs_data_get_string(settings, "rate_control");
const rc_mode_t *rc_mode = get_rc_mode(rate_control);
/* Set options visibility per Rate Control */
set_visible(ppts, "qp", rc_mode->qp);
set_visible(ppts, "bitrate", rc_mode->bitrate);
set_visible(ppts, "maxrate", rc_mode->maxrate);
return true;
}
static obs_properties_t *vaapi_properties(void *unused)
......@@ -486,14 +560,30 @@ static obs_properties_t *vaapi_properties(void *unused)
obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41);
obs_property_list_add_int(list, "1080p60 (4.2)", 42);
list = obs_properties_add_list(props, "rate_control",
obs_module_text("RateControl"),
OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_STRING);
obs_property_list_add_string(list, "CBR (default)", "CBR");
obs_property_list_add_string(list, "CQP", "CQP");
obs_property_list_add_string(list, "VBR", "VBR");
obs_property_set_modified_callback(list, rate_control_modified);
obs_property_t *p;
p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"),
0, 300000, 50);
obs_property_int_set_suffix(p, " Kbps");
p = obs_properties_add_int(
props, "maxrate", obs_module_text("MaxBitrate"), 0, 300000, 50);
obs_property_int_set_suffix(p, " Kbps");
obs_properties_add_int(props, "qp", "QP", 0, 51, 1);
obs_properties_add_int(props, "keyint_sec",
obs_module_text("Keyframe Interval (seconds)"),
0, 20, 1);
obs_module_text("KeyframeIntervalSec"), 0, 20,
1);
return props;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册