|
@@ -99,6 +99,8 @@ struct obs_qsv {
|
|
|
size_t sei_size;
|
|
|
|
|
|
os_performance_token_t *performance_token;
|
|
|
+
|
|
|
+ uint32_t roi_increment;
|
|
|
};
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
@@ -1377,6 +1379,37 @@ static void parse_packet_hevc(struct obs_qsv *obsqsv,
|
|
|
g_bFirst = false;
|
|
|
}
|
|
|
|
|
|
+static void roi_cb(void *param, struct obs_encoder_roi *roi)
|
|
|
+{
|
|
|
+ struct darray *da = param;
|
|
|
+ darray_push_back(sizeof(struct obs_encoder_roi), da, roi);
|
|
|
+}
|
|
|
+
|
|
|
+static void obs_qsv_setup_rois(struct obs_qsv *obsqsv)
|
|
|
+{
|
|
|
+ const uint32_t increment =
|
|
|
+ obs_encoder_get_roi_increment(obsqsv->encoder);
|
|
|
+ if (obsqsv->roi_increment == increment)
|
|
|
+ return;
|
|
|
+
|
|
|
+ qsv_encoder_clear_roi(obsqsv->context);
|
|
|
+ /* Because we pass-through the ROIs more or less directly we need to
|
|
|
+ * pass them in reverse order, so make a temporary copy and then use
|
|
|
+ * that instead. */
|
|
|
+ DARRAY(struct obs_encoder_roi) rois;
|
|
|
+ da_init(rois);
|
|
|
+
|
|
|
+ obs_encoder_enum_roi(obsqsv->encoder, roi_cb, &rois);
|
|
|
+
|
|
|
+ size_t idx = rois.num;
|
|
|
+ while (idx)
|
|
|
+ qsv_encoder_add_roi(obsqsv->context, &rois.array[--idx]);
|
|
|
+
|
|
|
+ da_free(rois);
|
|
|
+
|
|
|
+ obsqsv->roi_increment = increment;
|
|
|
+}
|
|
|
+
|
|
|
static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
|
|
|
struct encoder_packet *packet, bool *received_packet)
|
|
|
{
|
|
@@ -1396,6 +1429,9 @@ static bool obs_qsv_encode(void *data, struct encoder_frame *frame,
|
|
|
|
|
|
mfxU64 qsvPTS = ts_obs_to_mfx(frame->pts, voi);
|
|
|
|
|
|
+ if (obs_encoder_has_roi(obsqsv->encoder))
|
|
|
+ obs_qsv_setup_rois(obsqsv);
|
|
|
+
|
|
|
// FIXME: remove null check from the top of this function
|
|
|
// if we actually do expect null frames to complete output.
|
|
|
if (frame)
|
|
@@ -1452,6 +1488,9 @@ static bool obs_qsv_encode_tex(void *data, uint32_t handle, int64_t pts,
|
|
|
|
|
|
mfxU64 qsvPTS = ts_obs_to_mfx(pts, voi);
|
|
|
|
|
|
+ if (obs_encoder_has_roi(obsqsv->encoder))
|
|
|
+ obs_qsv_setup_rois(obsqsv);
|
|
|
+
|
|
|
ret = qsv_encoder_encode_tex(obsqsv->context, qsvPTS, handle, lock_key,
|
|
|
next_key, &pBS);
|
|
|
|
|
@@ -1516,7 +1555,8 @@ struct obs_encoder_info obs_qsv_encoder_tex_v2 = {
|
|
|
.get_name = obs_qsv_getname,
|
|
|
.create = obs_qsv_create_tex_h264_v2,
|
|
|
.destroy = obs_qsv_destroy,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
.encode_texture = obs_qsv_encode_tex,
|
|
|
.update = obs_qsv_update,
|
|
|
.get_properties = obs_qsv_props_h264_v2,
|
|
@@ -1540,7 +1580,8 @@ struct obs_encoder_info obs_qsv_encoder_v2 = {
|
|
|
.get_extra_data = obs_qsv_extra_data,
|
|
|
.get_sei_data = obs_qsv_sei,
|
|
|
.get_video_info = obs_qsv_video_info,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
};
|
|
|
|
|
|
struct obs_encoder_info obs_qsv_av1_encoder_tex = {
|
|
@@ -1550,7 +1591,8 @@ struct obs_encoder_info obs_qsv_av1_encoder_tex = {
|
|
|
.get_name = obs_qsv_getname_av1,
|
|
|
.create = obs_qsv_create_tex_av1,
|
|
|
.destroy = obs_qsv_destroy,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
.encode_texture = obs_qsv_encode_tex,
|
|
|
.update = obs_qsv_update,
|
|
|
.get_properties = obs_qsv_props_av1,
|
|
@@ -1572,7 +1614,8 @@ struct obs_encoder_info obs_qsv_av1_encoder = {
|
|
|
.get_defaults = obs_qsv_defaults_av1,
|
|
|
.get_extra_data = obs_qsv_extra_data,
|
|
|
.get_video_info = obs_qsv_video_plus_hdr_info,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
};
|
|
|
|
|
|
struct obs_encoder_info obs_qsv_hevc_encoder_tex = {
|
|
@@ -1582,7 +1625,8 @@ struct obs_encoder_info obs_qsv_hevc_encoder_tex = {
|
|
|
.get_name = obs_qsv_getname_hevc,
|
|
|
.create = obs_qsv_create_tex_hevc,
|
|
|
.destroy = obs_qsv_destroy,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_PASS_TEXTURE |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
.encode_texture = obs_qsv_encode_tex,
|
|
|
.update = obs_qsv_update,
|
|
|
.get_properties = obs_qsv_props_hevc,
|
|
@@ -1604,5 +1648,6 @@ struct obs_encoder_info obs_qsv_hevc_encoder = {
|
|
|
.get_defaults = obs_qsv_defaults_hevc,
|
|
|
.get_extra_data = obs_qsv_extra_data,
|
|
|
.get_video_info = obs_qsv_video_plus_hdr_info,
|
|
|
- .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
|
|
|
+ .caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL |
|
|
|
+ OBS_ENCODER_CAP_ROI,
|
|
|
};
|