mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +00:00
amfcodec: Initial support of Smart Access Video
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3904>
This commit is contained in:
parent
38c3de565b
commit
351b72a59a
3 changed files with 135 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue