mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-31 13:19:51 +00:00
msdkenc: set ROI region for msdk{h264, h265}enc
A reconfig is needed when ROI is changed, otherwise the ROI parameters won't take effect
This commit is contained in:
parent
84e234a8c7
commit
8512624a41
6 changed files with 156 additions and 0 deletions
|
@ -237,6 +237,115 @@ gst_msdkenc_ensure_extended_coding_options (GstMsdkEnc * thiz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return TRUE if ROI is changed and update ROI parameters in encoder_roi */
|
||||||
|
gboolean
|
||||||
|
gst_msdkenc_get_roi_params (GstMsdkEnc * thiz,
|
||||||
|
GstVideoCodecFrame * frame, mfxExtEncoderROI * encoder_roi)
|
||||||
|
{
|
||||||
|
GstBuffer *input;
|
||||||
|
guint num_roi, i, num_valid_roi = 0;
|
||||||
|
gushort roi_mode = G_MAXUINT16;
|
||||||
|
gpointer state = NULL;
|
||||||
|
mfxExtEncoderROI *curr_roi = encoder_roi;
|
||||||
|
mfxExtEncoderROI *prev_roi = encoder_roi + 1;
|
||||||
|
|
||||||
|
if (!frame || !frame->input_buffer)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
memset (curr_roi, 0, sizeof (mfxExtEncoderROI));
|
||||||
|
input = frame->input_buffer;
|
||||||
|
|
||||||
|
num_roi =
|
||||||
|
gst_buffer_get_n_meta (input, GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE);
|
||||||
|
|
||||||
|
if (num_roi == 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
curr_roi->Header.BufferId = MFX_EXTBUFF_ENCODER_ROI;
|
||||||
|
curr_roi->Header.BufferSz = sizeof (mfxExtEncoderROI);
|
||||||
|
|
||||||
|
for (i = 0; i < num_roi && num_valid_roi < 256; i++) {
|
||||||
|
GstVideoRegionOfInterestMeta *roi;
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
|
roi = (GstVideoRegionOfInterestMeta *)
|
||||||
|
gst_buffer_iterate_meta_filtered (input, &state,
|
||||||
|
GST_VIDEO_REGION_OF_INTEREST_META_API_TYPE);
|
||||||
|
|
||||||
|
if (!roi)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ignore roi if overflow */
|
||||||
|
if ((roi->x > G_MAXINT16) || (roi->y > G_MAXINT16)
|
||||||
|
|| (roi->w > G_MAXUINT16) || (roi->h > G_MAXUINT16)) {
|
||||||
|
GST_DEBUG_OBJECT (thiz, "Ignoring ROI... ROI overflow");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_LOG ("Input buffer ROI: type=%s id=%d (%d, %d) %dx%d",
|
||||||
|
g_quark_to_string (roi->roi_type), roi->id, roi->x, roi->y, roi->w,
|
||||||
|
roi->h);
|
||||||
|
|
||||||
|
curr_roi->ROI[num_valid_roi].Left = roi->x;
|
||||||
|
curr_roi->ROI[num_valid_roi].Top = roi->y;
|
||||||
|
curr_roi->ROI[num_valid_roi].Right = roi->x + roi->w;
|
||||||
|
curr_roi->ROI[num_valid_roi].Bottom = roi->y + roi->h;
|
||||||
|
|
||||||
|
s = gst_video_region_of_interest_meta_get_param (roi, "roi/msdk");
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
int value = 0;
|
||||||
|
|
||||||
|
if (roi_mode == G_MAXUINT16) {
|
||||||
|
if (gst_structure_get_int (s, "delta-qp", &value)) {
|
||||||
|
#if (MFX_VERSION >= 1022)
|
||||||
|
roi_mode = MFX_ROI_MODE_QP_DELTA;
|
||||||
|
curr_roi->ROI[num_valid_roi].DeltaQP = CLAMP (value, -51, 51);
|
||||||
|
GST_LOG ("Use delta-qp %d", value);
|
||||||
|
#else
|
||||||
|
GST_WARNING
|
||||||
|
("Ignore delta QP because the MFX doesn't support delta QP mode");
|
||||||
|
#endif
|
||||||
|
} else if (gst_structure_get_int (s, "priority", &value)) {
|
||||||
|
roi_mode = MFX_ROI_MODE_PRIORITY;
|
||||||
|
curr_roi->ROI[num_valid_roi].Priority = CLAMP (value, -3, 3);
|
||||||
|
GST_LOG ("Use priority %d", value);
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
#if (MFX_VERSION >= 1022)
|
||||||
|
} else if (roi_mode == MFX_ROI_MODE_QP_DELTA &&
|
||||||
|
gst_structure_get_int (s, "delta-qp", &value)) {
|
||||||
|
curr_roi->ROI[num_valid_roi].DeltaQP = CLAMP (value, -51, 51);
|
||||||
|
#endif
|
||||||
|
} else if (roi_mode == MFX_ROI_MODE_PRIORITY &&
|
||||||
|
gst_structure_get_int (s, "priority", &value)) {
|
||||||
|
curr_roi->ROI[num_valid_roi].Priority = CLAMP (value, -3, 3);
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
num_valid_roi++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (MFX_VERSION >= 1022)
|
||||||
|
curr_roi->ROIMode = roi_mode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
curr_roi->NumROI = num_valid_roi;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (curr_roi->NumROI == 0 && prev_roi->NumROI == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (curr_roi->NumROI != prev_roi->NumROI ||
|
||||||
|
memcmp (curr_roi, prev_roi, sizeof (mfxExtEncoderROI)) != 0) {
|
||||||
|
*prev_roi = *curr_roi;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
{
|
{
|
||||||
|
|
|
@ -204,6 +204,9 @@ gst_msdkenc_get_common_property (GObject * object, guint prop_id,
|
||||||
void
|
void
|
||||||
gst_msdkenc_ensure_extended_coding_options (GstMsdkEnc * thiz);
|
gst_msdkenc_ensure_extended_coding_options (GstMsdkEnc * thiz);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_msdkenc_get_roi_params (GstMsdkEnc * thiz,
|
||||||
|
GstVideoCodecFrame * frame, mfxExtEncoderROI * encoder_roi);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_MSDKENC_H__ */
|
#endif /* __GST_MSDKENC_H__ */
|
||||||
|
|
|
@ -480,6 +480,24 @@ gst_msdkh264enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
GST_OBJECT_UNLOCK (thiz);
|
GST_OBJECT_UNLOCK (thiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_msdkh264enc_need_reconfig (GstMsdkEnc * encoder, GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstMsdkH264Enc *h264enc = GST_MSDKH264ENC (encoder);
|
||||||
|
|
||||||
|
return gst_msdkenc_get_roi_params (encoder, frame, h264enc->roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_msdkh264enc_set_extra_params (GstMsdkEnc * encoder,
|
||||||
|
GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstMsdkH264Enc *h264enc = GST_MSDKH264ENC (encoder);
|
||||||
|
|
||||||
|
if (h264enc->roi[0].NumROI)
|
||||||
|
gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & h264enc->roi[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass)
|
gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -501,6 +519,8 @@ gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass)
|
||||||
encoder_class->set_format = gst_msdkh264enc_set_format;
|
encoder_class->set_format = gst_msdkh264enc_set_format;
|
||||||
encoder_class->configure = gst_msdkh264enc_configure;
|
encoder_class->configure = gst_msdkh264enc_configure;
|
||||||
encoder_class->set_src_caps = gst_msdkh264enc_set_src_caps;
|
encoder_class->set_src_caps = gst_msdkh264enc_set_src_caps;
|
||||||
|
encoder_class->need_reconfig = gst_msdkh264enc_need_reconfig;
|
||||||
|
encoder_class->set_extra_params = gst_msdkh264enc_set_extra_params;
|
||||||
|
|
||||||
gst_msdkenc_install_common_properties (encoder_class);
|
gst_msdkenc_install_common_properties (encoder_class);
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ struct _GstMsdkH264Enc
|
||||||
GstMsdkEnc base;
|
GstMsdkEnc base;
|
||||||
|
|
||||||
mfxExtCodingOption option;
|
mfxExtCodingOption option;
|
||||||
|
/* roi[0] for current ROI and roi[1] for previous ROI */
|
||||||
|
mfxExtEncoderROI roi[2];
|
||||||
|
|
||||||
gint profile;
|
gint profile;
|
||||||
gint level;
|
gint level;
|
||||||
|
|
|
@ -286,6 +286,24 @@ gst_msdkh265enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
GST_OBJECT_UNLOCK (thiz);
|
GST_OBJECT_UNLOCK (thiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_msdkh265enc_need_reconfig (GstMsdkEnc * encoder, GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstMsdkH265Enc *h265enc = GST_MSDKH265ENC (encoder);
|
||||||
|
|
||||||
|
return gst_msdkenc_get_roi_params (encoder, frame, h265enc->roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_msdkh265enc_set_extra_params (GstMsdkEnc * encoder,
|
||||||
|
GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstMsdkH265Enc *h265enc = GST_MSDKH265ENC (encoder);
|
||||||
|
|
||||||
|
if (h265enc->roi[0].NumROI)
|
||||||
|
gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & h265enc->roi[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_msdkh265enc_class_init (GstMsdkH265EncClass * klass)
|
gst_msdkh265enc_class_init (GstMsdkH265EncClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -303,6 +321,8 @@ gst_msdkh265enc_class_init (GstMsdkH265EncClass * klass)
|
||||||
encoder_class->set_format = gst_msdkh265enc_set_format;
|
encoder_class->set_format = gst_msdkh265enc_set_format;
|
||||||
encoder_class->configure = gst_msdkh265enc_configure;
|
encoder_class->configure = gst_msdkh265enc_configure;
|
||||||
encoder_class->set_src_caps = gst_msdkh265enc_set_src_caps;
|
encoder_class->set_src_caps = gst_msdkh265enc_set_src_caps;
|
||||||
|
encoder_class->need_reconfig = gst_msdkh265enc_need_reconfig;
|
||||||
|
encoder_class->set_extra_params = gst_msdkh265enc_set_extra_params;
|
||||||
|
|
||||||
gst_msdkenc_install_common_properties (encoder_class);
|
gst_msdkenc_install_common_properties (encoder_class);
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ struct _GstMsdkH265Enc
|
||||||
gushort num_tile_cols;
|
gushort num_tile_cols;
|
||||||
|
|
||||||
mfxExtHEVCTiles ext_tiles;
|
mfxExtHEVCTiles ext_tiles;
|
||||||
|
/* roi[0] for current ROI and roi[1] for previous ROI */
|
||||||
|
mfxExtEncoderROI roi[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMsdkH265EncClass
|
struct _GstMsdkH265EncClass
|
||||||
|
|
Loading…
Reference in a new issue