diff --git a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfav1enc.cpp b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfav1enc.cpp index a6ba46b2d7..e3f27d6339 100644 --- a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfav1enc.cpp +++ b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfav1enc.cpp @@ -73,6 +73,7 @@ typedef struct amf_int64 max_gop_size; amf_int64 default_gop_size; guint valign; + gboolean smart_access_supported; } GstAmfAv1EncDeviceCaps; /** @@ -264,6 +265,7 @@ enum PROP_QP_I, PROP_QP_P, PROP_REF_FRAMES, + PROP_SMART_ACCESS }; #define DEFAULT_USAGE AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING @@ -273,6 +275,7 @@ enum #define DEFAULT_MAX_BITRATE 0 #define DEFAULT_MIN_MAX_QP -1 #define DEFAULT_REF_FRAMES 1 +#define DEFAULT_SMART_ACCESS FALSE #define DOC_SINK_CAPS_COMM \ "format = (string) {NV12, P010_10LE}, " \ @@ -305,6 +308,7 @@ typedef struct _GstAmfAv1Enc guint qp_i; guint qp_p; guint ref_frames; + gboolean smart_access; } GstAmfAv1Enc; typedef struct _GstAmfAv1EncClass @@ -410,6 +414,16 @@ gst_amf_av1_enc_class_init (GstAmfAv1EncClass * klass, gpointer data) g_param_spec_uint ("ref-frames", "Reference Frames", "Number of reference frames", 0, 8, DEFAULT_REF_FRAMES, param_flags)); + if (cdata->dev_caps.smart_access_supported) { + g_object_class_install_property (object_class, PROP_SMART_ACCESS, + g_param_spec_boolean ("smart-access-video", "Smart Access Video", + "Enable AMF SmartAccess Video feature for optimal distribution" + " between multiple AMD hardware instances", DEFAULT_SMART_ACCESS, + (GParamFlags) (G_PARAM_READWRITE | + GST_PARAM_CONDITIONALLY_AVAILABLE | + GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS))); + } + gst_element_class_set_metadata (element_class, "AMD AMF AV1 Video Encoder", "Codec/Encoder/Video/Hardware", @@ -480,6 +494,7 @@ gst_amf_av1_enc_init (GstAmfAv1Enc * self) self->qp_i = (guint) dev_caps->default_qp_i; self->qp_p = (guint) dev_caps->default_qp_p; self->ref_frames = DEFAULT_REF_FRAMES; + self->smart_access = DEFAULT_SMART_ACCESS; } static void @@ -528,6 +543,18 @@ update_enum (GstAmfAv1Enc * self, gint * old_val, const GValue * new_val) self->property_updated = TRUE; } +static void +update_bool (GstAmfAv1Enc * self, gboolean * old_val, const GValue * new_val) +{ + gboolean val = g_value_get_boolean (new_val); + + if (*old_val == val) + return; + + *old_val = val; + self->property_updated = TRUE; +} + static void gst_amf_av1_enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -575,6 +602,9 @@ gst_amf_av1_enc_set_property (GObject * object, guint prop_id, case PROP_REF_FRAMES: update_uint (self, &self->ref_frames, value); break; + case PROP_SMART_ACCESS: + update_bool (self, &self->smart_access, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -632,6 +662,9 @@ gst_amf_av1_enc_get_property (GObject * object, guint prop_id, case PROP_REF_FRAMES: g_value_set_uint (value, self->ref_frames); break; + case PROP_SMART_ACCESS: + g_value_set_boolean (value, self->smart_access); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -643,6 +676,8 @@ gst_amf_av1_enc_set_format (GstAmfEncoder * encoder, GstVideoCodecState * state, gpointer component) { GstAmfAv1Enc *self = GST_AMF_AV1_ENC (encoder); + GstAmfAv1EncClass *klass = GST_AMF_AV1_ENC_GET_CLASS (self); + GstAmfAv1EncDeviceCaps *dev_caps = &klass->dev_caps; AMFComponent *comp = (AMFComponent *) component; GstVideoInfo *info = &state->info; AMF_RESULT result; @@ -726,6 +761,14 @@ gst_amf_av1_enc_set_format (GstAmfEncoder * encoder, goto error; } + if (dev_caps->smart_access_supported) { + result = comp->SetProperty (AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO, + (amf_bool) self->smart_access); + if (result != AMF_OK) { + GST_WARNING_OBJECT (self, "Failed to set smart access video, result %" + GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result)); + } + } color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN; switch (cinfo->matrix) { case GST_VIDEO_COLOR_MATRIX_BT601: @@ -1050,6 +1093,7 @@ gst_amf_av1_enc_create_class_data (GstD3D11Device * device, AMFComponent * comp) amf_int32 in_min_height = 0, in_max_height = 0; amf_int32 out_min_width = 0, out_max_width = 0; amf_int32 out_min_height = 0, out_max_height = 0; + amf_bool smart_access_supported; amf_int32 num_val; std::set < std::string > formats; std::string format_str; @@ -1203,6 +1247,11 @@ gst_amf_av1_enc_create_class_data (GstD3D11Device * device, AMFComponent * comp) QUERY_DEFAULT_PROP (AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER, default_qp_p, 26); #undef QUERY_DEFAULT_PROP + result = comp->GetProperty (AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO, + &smart_access_supported); + if (result == AMF_OK) + dev_caps.smart_access_supported = TRUE; + { const AMFPropertyInfo *pinfo = nullptr; result = comp->GetPropertyInfo (AMF_VIDEO_ENCODER_AV1_GOP_SIZE, &pinfo); diff --git a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh264enc.cpp b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh264enc.cpp index cb29720bbf..76b67e192b 100644 --- a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh264enc.cpp +++ b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh264enc.cpp @@ -77,6 +77,7 @@ typedef struct amf_int64 default_qp_b; gboolean interlace_supported; guint valign; + gboolean smart_access_supported; } GstAmfH264EncDeviceCaps; /** @@ -273,6 +274,7 @@ enum PROP_REF_FRAMES, PROP_AUD, PROP_CABAC, + PROP_SMART_ACCESS }; #define DEFAULT_USAGE AMF_VIDEO_ENCODER_USAGE_TRANSCODING @@ -284,6 +286,7 @@ enum #define DEFAULT_MIN_MAX_QP -1 #define DEFAULT_AUD TRUE #define DEFAULT_CABAC TRUE +#define DEFAULT_SMART_ACCESS FALSE #define DOC_SINK_CAPS_COMM \ "format = (string) NV12, " \ @@ -322,6 +325,7 @@ typedef struct _GstAmfH264Enc gboolean aud; gboolean cabac; + gboolean smart_access; } GstAmfH264Enc; typedef struct _GstAmfH264EncClass @@ -429,6 +433,16 @@ gst_amf_h264_enc_class_init (GstAmfH264EncClass * klass, gpointer data) g_param_spec_boolean ("cabac", "CABAC", "Enable CABAC entropy coding", TRUE, param_flags)); + if (cdata->dev_caps.smart_access_supported) { + g_object_class_install_property (object_class, PROP_SMART_ACCESS, + g_param_spec_boolean ("smart-access-video", "Smart Access Video", + "Enable AMF SmartAccess Video feature for optimal distribution" + " between multiple AMD hardware instances", DEFAULT_SMART_ACCESS, + (GParamFlags) (G_PARAM_READWRITE | + GST_PARAM_CONDITIONALLY_AVAILABLE | + GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS))); + } + gst_element_class_set_metadata (element_class, "AMD AMF H.264 Video Encoder", "Codec/Encoder/Video/Hardware", @@ -502,6 +516,7 @@ gst_amf_h264_enc_init (GstAmfH264Enc * self) self->ref_frames = (guint) dev_caps->min_ref_frames; self->aud = DEFAULT_AUD; self->cabac = DEFAULT_CABAC; + self->smart_access = DEFAULT_SMART_ACCESS; } static void @@ -611,6 +626,9 @@ gst_amf_h264_enc_set_property (GObject * object, guint prop_id, case PROP_CABAC: update_bool (self, &self->cabac, value); break; + case PROP_SMART_ACCESS: + update_bool (self, &self->smart_access, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -668,6 +686,9 @@ gst_amf_h264_enc_get_property (GObject * object, guint prop_id, case PROP_CABAC: g_value_set_boolean (value, self->cabac); break; + case PROP_SMART_ACCESS: + g_value_set_boolean (value, self->smart_access); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -927,6 +948,15 @@ gst_amf_h264_enc_set_format (GstAmfEncoder * encoder, } } + if (dev_caps->smart_access_supported) { + result = comp->SetProperty (AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, + (amf_bool) self->smart_access); + if (result != AMF_OK) { + GST_WARNING_OBJECT (self, "Failed to set smart access video, result %" + GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result)); + } + } + result = comp->Init (AMF_SURFACE_NV12, info->width, info->height); if (result != AMF_OK) { GST_ERROR_OBJECT (self, "Failed to init component, result %" @@ -1330,6 +1360,7 @@ gst_amf_h264_enc_create_class_data (GstD3D11Device * device, amf_int32 out_min_width = 0, out_max_width = 0; amf_int32 out_min_height = 0, out_max_height = 0; amf_bool interlace_supported; + amf_bool smart_access_supported; amf_int32 num_val; gboolean have_nv12 = FALSE; gboolean d3d11_supported = FALSE; @@ -1461,6 +1492,11 @@ gst_amf_h264_enc_create_class_data (GstD3D11Device * device, QUERY_DEFAULT_PROP (AMF_VIDEO_ENCODER_QP_I, default_qp_b, 22); #undef QUERY_DEFAULT_PROP + result = comp->GetProperty (AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, + &smart_access_supported); + if (result == AMF_OK) + dev_caps.smart_access_supported = TRUE; + min_width = MAX (in_min_width, 1); max_width = in_max_width; if (max_width == 0) { diff --git a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh265enc.cpp b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh265enc.cpp index 40aee81e7c..57359c6c0a 100644 --- a/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh265enc.cpp +++ b/subprojects/gst-plugins-bad/sys/amfcodec/gstamfh265enc.cpp @@ -75,6 +75,7 @@ typedef struct amf_int64 max_gop_size; amf_int64 default_gop_size; guint valign; + gboolean smart_access_supported; } GstAmfH265EncDeviceCaps; /** @@ -273,6 +274,7 @@ enum PROP_QP_P, PROP_REF_FRAMES, PROP_AUD, + PROP_SMART_ACCESS }; #define DEFAULT_USAGE AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING @@ -282,6 +284,7 @@ enum #define DEFAULT_MAX_BITRATE 0 #define DEFAULT_MIN_MAX_QP -1 #define DEFAULT_AUD TRUE +#define DEFAULT_SMART_ACCESS FALSE #define DOC_SINK_CAPS_COMM \ "format = (string) {NV12, P010_10LE}, " \ @@ -318,6 +321,7 @@ typedef struct _GstAmfH265Enc guint ref_frames; gboolean aud; + gboolean smart_access; } GstAmfH265Enc; typedef struct _GstAmfH265EncClass @@ -431,6 +435,16 @@ gst_amf_h265_enc_class_init (GstAmfH265EncClass * klass, gpointer data) g_param_spec_boolean ("aud", "AUD", "Use AU (Access Unit) delimiter", DEFAULT_AUD, param_flags)); + if (cdata->dev_caps.smart_access_supported) { + g_object_class_install_property (object_class, PROP_SMART_ACCESS, + g_param_spec_boolean ("smart-access-video", "Smart Access Video", + "Enable AMF SmartAccess Video feature for optimal distribution" + " between multiple AMD hardware instances", DEFAULT_SMART_ACCESS, + (GParamFlags) (G_PARAM_READWRITE | + GST_PARAM_CONDITIONALLY_AVAILABLE | + GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS))); + } + gst_element_class_set_metadata (element_class, "AMD AMF H.265 Video Encoder", "Codec/Encoder/Video/Hardware", @@ -503,6 +517,7 @@ gst_amf_h265_enc_init (GstAmfH265Enc * self) self->qp_p = (guint) dev_caps->default_qp_p; self->ref_frames = (guint) dev_caps->min_ref_frames; self->aud = DEFAULT_AUD; + self->smart_access = DEFAULT_SMART_ACCESS; } static void @@ -551,6 +566,18 @@ update_enum (GstAmfH265Enc * self, gint * old_val, const GValue * new_val) self->property_updated = TRUE; } +static void +update_bool (GstAmfH265Enc * self, gboolean * old_val, const GValue * new_val) +{ + gboolean val = g_value_get_boolean (new_val); + + if (*old_val == val) + return; + + *old_val = val; + self->property_updated = TRUE; +} + static void gst_amf_h265_enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -602,6 +629,9 @@ gst_amf_h265_enc_set_property (GObject * object, guint prop_id, /* This is per frame property, don't need to reset encoder */ self->aud = g_value_get_boolean (value); break; + case PROP_SMART_ACCESS: + update_bool (self, &self->smart_access, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -662,6 +692,9 @@ gst_amf_h265_enc_get_property (GObject * object, guint prop_id, case PROP_AUD: g_value_set_boolean (value, self->aud); break; + case PROP_SMART_ACCESS: + g_value_set_boolean (value, self->smart_access); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -773,6 +806,8 @@ gst_amf_h265_enc_set_format (GstAmfEncoder * encoder, GstVideoCodecState * state, gpointer component) { GstAmfH265Enc *self = GST_AMF_H265_ENC (encoder); + GstAmfH265EncClass *klass = GST_AMF_H265_ENC_GET_CLASS (self); + GstAmfH265EncDeviceCaps *dev_caps = &klass->dev_caps; AMFComponent *comp = (AMFComponent *) component; GstVideoInfo *info = &state->info; const GstVideoColorimetry *cinfo = &info->colorimetry; @@ -893,6 +928,15 @@ gst_amf_h265_enc_set_format (GstAmfEncoder * encoder, goto error; } + if (dev_caps->smart_access_supported) { + result = + comp->SetProperty (AMF_VIDEO_ENCODER_HEVC_ENABLE_SMART_ACCESS_VIDEO, + (amf_bool) self->smart_access); + if (result != AMF_OK) { + GST_WARNING_OBJECT (self, "Failed to set smart access video, result %" + GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result)); + } + } color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN; switch (cinfo->matrix) { case GST_VIDEO_COLOR_MATRIX_BT601: @@ -1233,6 +1277,7 @@ gst_amf_h265_enc_create_class_data (GstD3D11Device * device, amf_int32 in_min_height = 0, in_max_height = 0; amf_int32 out_min_width = 0, out_max_width = 0; amf_int32 out_min_height = 0, out_max_height = 0; + amf_bool smart_access_supported; amf_int32 num_val; std::set < std::string > formats; std::string format_str; @@ -1370,6 +1415,11 @@ gst_amf_h265_enc_create_class_data (GstD3D11Device * device, QUERY_DEFAULT_PROP (AMF_VIDEO_ENCODER_HEVC_QP_P, default_qp_p, 26); #undef QUERY_DEFAULT_PROP + result = comp->GetProperty (AMF_VIDEO_ENCODER_HEVC_ENABLE_SMART_ACCESS_VIDEO, + &smart_access_supported); + if (result == AMF_OK) + dev_caps.smart_access_supported = TRUE; + { const AMFPropertyInfo *pinfo = nullptr; result = comp->GetPropertyInfo (AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, &pinfo);