mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +00:00
amfcodec: Initial support of preanalysis and preencoding for AMF encoders
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3847>
This commit is contained in:
parent
e8060c40f5
commit
00988e70ac
5 changed files with 1510 additions and 8 deletions
|
@ -73,7 +73,9 @@ typedef struct
|
|||
amf_int64 max_gop_size;
|
||||
amf_int64 default_gop_size;
|
||||
guint valign;
|
||||
gboolean pre_encode_supported;
|
||||
gboolean smart_access_supported;
|
||||
GstAmfEncoderPASupportedOptions pa_supported;
|
||||
} GstAmfAv1EncDeviceCaps;
|
||||
|
||||
/**
|
||||
|
@ -265,7 +267,23 @@ enum
|
|||
PROP_QP_I,
|
||||
PROP_QP_P,
|
||||
PROP_REF_FRAMES,
|
||||
PROP_SMART_ACCESS
|
||||
PROP_SMART_ACCESS,
|
||||
PROP_PRE_ENCODE,
|
||||
PROP_PRE_ANALYSIS,
|
||||
PROP_PA_ACTIVITY_TYPE,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_INITIAL_QP,
|
||||
PROP_PA_MAX_QP,
|
||||
PROP_PA_CAQ_STRENGTH,
|
||||
PROP_PA_FRAME_SAD,
|
||||
PROP_PA_LTR,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
PROP_PA_PAQ_MODE,
|
||||
PROP_PA_TAQ_MODE,
|
||||
PROP_PA_HQMB_MODE,
|
||||
};
|
||||
|
||||
#define DEFAULT_USAGE AMF_VIDEO_ENCODER_AV1_USAGE_TRANSCODING
|
||||
|
@ -276,6 +294,7 @@ enum
|
|||
#define DEFAULT_MIN_MAX_QP -1
|
||||
#define DEFAULT_REF_FRAMES 1
|
||||
#define DEFAULT_SMART_ACCESS FALSE
|
||||
#define DEFAULT_PRE_ENCODE FALSE
|
||||
|
||||
#define DOC_SINK_CAPS_COMM \
|
||||
"format = (string) {NV12, P010_10LE}, " \
|
||||
|
@ -309,6 +328,8 @@ typedef struct _GstAmfAv1Enc
|
|||
guint qp_p;
|
||||
guint ref_frames;
|
||||
gboolean smart_access;
|
||||
gboolean pre_encode;
|
||||
GstAmfEncoderPreAnalysis pa;
|
||||
} GstAmfAv1Enc;
|
||||
|
||||
typedef struct _GstAmfAv1EncClass
|
||||
|
@ -346,8 +367,11 @@ gst_amf_av1_enc_class_init (GstAmfAv1EncClass * klass, gpointer data)
|
|||
GstAmfEncoderClass *amf_class = GST_AMF_ENCODER_CLASS (klass);
|
||||
GstAmfAv1EncClassData *cdata = (GstAmfAv1EncClassData *) data;
|
||||
GstAmfAv1EncDeviceCaps *dev_caps = &cdata->dev_caps;
|
||||
GstAmfEncoderPASupportedOptions *pa_supported = &dev_caps->pa_supported;
|
||||
GParamFlags param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS);
|
||||
GParamFlags pa_param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS | GST_PARAM_CONDITIONALLY_AVAILABLE);
|
||||
GstPadTemplate *pad_templ;
|
||||
GstCaps *doc_caps;
|
||||
|
||||
|
@ -413,7 +437,12 @@ gst_amf_av1_enc_class_init (GstAmfAv1EncClass * klass, gpointer data)
|
|||
g_object_class_install_property (object_class, PROP_REF_FRAMES,
|
||||
g_param_spec_uint ("ref-frames", "Reference Frames",
|
||||
"Number of reference frames", 0, 8, DEFAULT_REF_FRAMES, param_flags));
|
||||
|
||||
if (cdata->dev_caps.pre_encode_supported) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ENCODE,
|
||||
g_param_spec_boolean ("pre-encode", "Pre-encode",
|
||||
"Enable pre-encode", DEFAULT_PRE_ENCODE,
|
||||
(GParamFlags) (param_flags | GST_PARAM_CONDITIONALLY_AVAILABLE)));
|
||||
}
|
||||
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",
|
||||
|
@ -424,6 +453,113 @@ gst_amf_av1_enc_class_init (GstAmfAv1EncClass * klass, gpointer data)
|
|||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS)));
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ANALYSIS,
|
||||
g_param_spec_boolean ("pre-analysis", "Pre-analysis",
|
||||
"Enable pre-analysis", DEFAULT_PRE_ANALYSIS, param_flags));
|
||||
if (pa_supported->activity_type) {
|
||||
g_object_class_install_property (object_class, PROP_PA_ACTIVITY_TYPE,
|
||||
g_param_spec_enum ("pa-activity-type", "Pre-analysis activity type",
|
||||
"Set the type of activity analysis for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_ACTIVITY_TYPE, DEFAULT_PA_ACTIVITY_TYPE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
g_param_spec_boolean ("pa-scene-change-detection",
|
||||
"Pre-analysis scene change detection",
|
||||
"Enable scene change detection for pre-analysis",
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-scene-change-detection-sensitivity",
|
||||
"Pre-analysis scene change detection sensitivity",
|
||||
"Set the sensitivity of scene change detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
g_param_spec_boolean ("pa-static-scene-detection",
|
||||
"Pre-analysis static scene detection",
|
||||
"Enable static scene detection for pre-analysis",
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-static-scene-detection-sensitivity",
|
||||
"Pre-analysis static scene detection sensitivity",
|
||||
"Set the sensitivity of static scene detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->initial_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_INITIAL_QP,
|
||||
g_param_spec_uint ("pa-initial-qp", "Pre-analysis initial QP",
|
||||
"The QP value that is used immediately after a scene change", 0,
|
||||
51, DEFAULT_PA_INITIAL_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->max_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_MAX_QP,
|
||||
g_param_spec_uint ("pa-max-qp", "Pre-analysis max QP",
|
||||
"The QP threshold to allow a skip frame", 0, 51,
|
||||
DEFAULT_PA_MAX_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->caq_strength) {
|
||||
g_object_class_install_property (object_class, PROP_PA_CAQ_STRENGTH,
|
||||
g_param_spec_enum ("pa-caq-strength", "Pre-analysis CAQ strength",
|
||||
"Content Adaptive Quantization strength for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_CAQ_STRENGTH, DEFAULT_PA_CAQ_STRENGTH,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->frame_sad) {
|
||||
g_object_class_install_property (object_class, PROP_PA_FRAME_SAD,
|
||||
g_param_spec_boolean ("pa-frame-sad", "Pre-analysis SAD algorithm",
|
||||
"Enable Frame SAD algorithm", DEFAULT_PA_FRAME_SAD,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->ltr) {
|
||||
g_object_class_install_property (object_class, PROP_PA_LTR,
|
||||
g_param_spec_boolean ("pa-ltr", "Pre-analysis LTR",
|
||||
"Enable long term reference frame management", DEFAULT_PA_LTR,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->lookahead_buffer_depth) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
g_param_spec_uint ("pa-lookahead-buffer-depth",
|
||||
"Pre-analysis lookahead buffer depth",
|
||||
"Set the PA lookahead buffer size", 0, 41,
|
||||
DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->paq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_PAQ_MODE,
|
||||
g_param_spec_enum ("pa-paq-mode", "Pre-analysis PAQ mode",
|
||||
"Set the perceptual adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_PAQ_MODE, DEFAULT_PA_PAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->taq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_TAQ_MODE,
|
||||
g_param_spec_enum ("pa-taq-mode", "Pre-analysis TAQ mode",
|
||||
"Set the temporal adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_TAQ_MODE, DEFAULT_PA_TAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->hmqb_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_HQMB_MODE,
|
||||
g_param_spec_enum ("pa-hqmb-mode", "Pre-analysis HQMB mode",
|
||||
"Set the PA high motion quality boost mode",
|
||||
GST_TYPE_AMF_ENC_PA_HQMB_MODE, DEFAULT_PA_HQMB_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_class_set_metadata (element_class,
|
||||
"AMD AMF AV1 Video Encoder",
|
||||
"Codec/Encoder/Video/Hardware",
|
||||
|
@ -495,6 +631,25 @@ gst_amf_av1_enc_init (GstAmfAv1Enc * self)
|
|||
self->qp_p = (guint) dev_caps->default_qp_p;
|
||||
self->ref_frames = DEFAULT_REF_FRAMES;
|
||||
self->smart_access = DEFAULT_SMART_ACCESS;
|
||||
self->pre_encode = DEFAULT_PRE_ENCODE;
|
||||
// Init pre-analysis options
|
||||
self->pa.pre_analysis = DEFAULT_PRE_ANALYSIS;
|
||||
self->pa.activity_type = DEFAULT_PA_ACTIVITY_TYPE;
|
||||
self->pa.scene_change_detection = DEFAULT_PA_SCENE_CHANGE_DETECTION;
|
||||
self->pa.scene_change_detection_sensitivity =
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY;
|
||||
self->pa.static_scene_detection = DEFAULT_PA_STATIC_SCENE_DETECTION;
|
||||
self->pa.static_scene_detection_sensitivity =
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY;
|
||||
self->pa.initial_qp = DEFAULT_PA_INITIAL_QP;
|
||||
self->pa.max_qp = DEFAULT_PA_MAX_QP;
|
||||
self->pa.caq_strength = DEFAULT_PA_CAQ_STRENGTH;
|
||||
self->pa.frame_sad = DEFAULT_PA_FRAME_SAD;
|
||||
self->pa.ltr = DEFAULT_PA_LTR;
|
||||
self->pa.lookahead_buffer_depth = DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH;
|
||||
self->pa.paq_mode = DEFAULT_PA_PAQ_MODE;
|
||||
self->pa.taq_mode = DEFAULT_PA_TAQ_MODE;
|
||||
self->pa.hmqb_mode = DEFAULT_PA_HQMB_MODE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -605,6 +760,53 @@ gst_amf_av1_enc_set_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
update_bool (self, &self->smart_access, value);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
update_bool (self, &self->pre_encode, value);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
update_bool (self, &self->pa.pre_analysis, value);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
update_enum (self, &self->pa.activity_type, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
update_bool (self, &self->pa.scene_change_detection, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.scene_change_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
update_bool (self, &self->pa.static_scene_detection, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.static_scene_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
update_uint (self, &self->pa.initial_qp, value);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
update_uint (self, &self->pa.max_qp, value);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
update_enum (self, &self->pa.caq_strength, value);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
update_bool (self, &self->pa.frame_sad, value);
|
||||
case PROP_PA_LTR:
|
||||
update_bool (self, &self->pa.ltr, value);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
update_uint (self, &self->pa.lookahead_buffer_depth, value);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
update_enum (self, &self->pa.paq_mode, value);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
update_enum (self, &self->pa.taq_mode, value);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
update_enum (self, &self->pa.hmqb_mode, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -665,6 +867,54 @@ gst_amf_av1_enc_get_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
g_value_set_boolean (value, self->smart_access);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
g_value_set_boolean (value, self->pre_encode);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
g_value_set_boolean (value, self->pa.pre_analysis);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
g_value_set_enum (value, self->pa.activity_type);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.scene_change_detection);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.scene_change_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.static_scene_detection);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.static_scene_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
g_value_set_uint (value, self->pa.initial_qp);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
g_value_set_uint (value, self->pa.max_qp);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
g_value_set_enum (value, self->pa.caq_strength);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
g_value_set_boolean (value, self->pa.frame_sad);
|
||||
break;
|
||||
case PROP_PA_LTR:
|
||||
g_value_set_boolean (value, self->pa.ltr);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
g_value_set_uint (value, self->pa.lookahead_buffer_depth);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.paq_mode);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.taq_mode);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
g_value_set_enum (value, self->pa.hmqb_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -871,6 +1121,33 @@ gst_amf_av1_enc_set_format (GstAmfEncoder * encoder,
|
|||
}
|
||||
}
|
||||
|
||||
if (dev_caps->pre_encode_supported) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_PREENCODE,
|
||||
(amf_bool) self->pre_encode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-encode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) self->pa.pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
if (self->pa.pre_analysis) {
|
||||
result =
|
||||
gst_amf_encoder_set_pre_analysis_options (encoder, comp, &self->pa,
|
||||
&dev_caps->pa_supported);
|
||||
if (result != AMF_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
result = comp->Init (surface_format, info->width, info->height);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to init component, result %"
|
||||
|
@ -1093,6 +1370,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 pre_encode_supported;
|
||||
amf_bool smart_access_supported;
|
||||
amf_int32 num_val;
|
||||
std::set < std::string > formats;
|
||||
|
@ -1247,11 +1525,41 @@ 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_RATE_CONTROL_PREENCODE,
|
||||
&pre_encode_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.pre_encode_supported = TRUE;
|
||||
|
||||
result = comp->GetProperty (AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO,
|
||||
&smart_access_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.smart_access_supported = TRUE;
|
||||
|
||||
if (dev_caps.pre_analysis) {
|
||||
amf_bool pre_analysis = FALSE;
|
||||
// Store initial pre-analysis value
|
||||
result =
|
||||
comp->GetProperty (AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE,
|
||||
&pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to get pre-analysis option");
|
||||
}
|
||||
// We need to enable pre-analysis for checking options availability
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) TRUE);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis option");
|
||||
}
|
||||
gst_amf_encoder_check_pa_supported_options (&dev_caps.pa_supported, comp);
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_AV1_PRE_ANALYSIS_ENABLE,
|
||||
pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis option");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const AMFPropertyInfo *pinfo = nullptr;
|
||||
result = comp->GetPropertyInfo (AMF_VIDEO_ENCODER_AV1_GOP_SIZE, &pinfo);
|
||||
|
|
|
@ -35,6 +35,300 @@ using namespace Microsoft::WRL;
|
|||
using namespace amf;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
* GstAmfEncPAActivityType:
|
||||
*
|
||||
* Determines whether activity analysis is performed on the Luma component
|
||||
* only (Y) or on both Luma and Chroma (YUV).
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_activity_get_type (void)
|
||||
{
|
||||
static GType pa_activity_type = 0;
|
||||
static const GEnumValue activity_types[] = {
|
||||
/**
|
||||
* GstAmfEncPAActivityType::y:
|
||||
*
|
||||
* Activity analysis is performed on the Luma component only (Y)
|
||||
*/
|
||||
{AMF_PA_ACTIVITY_Y, "Luma (Y) component only",
|
||||
"y"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPAActivityType::yuv:
|
||||
*
|
||||
* Activity analysis is performed on both Luma and Chroma components (YUV)
|
||||
*/
|
||||
{AMF_PA_ACTIVITY_YUV, "Luma and Chroma components (YUV)", "yuv"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_activity_type)) {
|
||||
GType type =
|
||||
g_enum_register_static ("GstAmfEncPAActivityType", activity_types);
|
||||
g_once_init_leave (&pa_activity_type, type);
|
||||
}
|
||||
|
||||
return pa_activity_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPASceneChangeDetectionSensitivity:
|
||||
*
|
||||
* Sensitivity of scene change detection. The higher the sensitivity, the more
|
||||
* restrictive it is to detect a scene change. This parameter takes effect
|
||||
* only when AMF_PA_LOOKAHEAH_BUFFER_DEPTH is set to 0.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_scene_change_detection_sensitivity_get_type (void)
|
||||
{
|
||||
static GType pa_scene_change_detection_sensitivity = 0;
|
||||
static const GEnumValue sensitivity_types[] = {
|
||||
/**
|
||||
* GstAmfEncPASceneChangeDetectionSensitivity::low:
|
||||
*
|
||||
* Low sensitivity
|
||||
*/
|
||||
{AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_LOW, "Low", "low"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPASceneChangeDetectionSensitivity::medium:
|
||||
*
|
||||
* Medium sensitivity
|
||||
*/
|
||||
{AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_MEDIUM, "Medium", "medium"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPASceneChangeDetectionSensitivity::high:
|
||||
*
|
||||
* High sensitivity
|
||||
*/
|
||||
{AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_HIGH, "High", "high"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_scene_change_detection_sensitivity)) {
|
||||
GType type =
|
||||
g_enum_register_static
|
||||
("GstAmfEncPASceneChangeDetectionSensitivity", sensitivity_types);
|
||||
g_once_init_leave (&pa_scene_change_detection_sensitivity, type);
|
||||
}
|
||||
|
||||
return pa_scene_change_detection_sensitivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPAStaticSceneDetectionSensitivity:
|
||||
*
|
||||
* Sensitivity of static scene detection. The higher the sensitivity, the more
|
||||
* restrictive it is to detect a static scene.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_static_scene_detection_sensitivity_get_type (void)
|
||||
{
|
||||
static GType pa_static_scene_detection_sensitivity = 0;
|
||||
static const GEnumValue sensitivity_types[] = {
|
||||
/**
|
||||
* GstAmfEncPAStaticSceneDetectionSensitivity::low:
|
||||
*
|
||||
* Low sensitivity
|
||||
*/
|
||||
{AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_LOW, "Low", "low"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPAStaticSceneDetectionSensitivity::medium:
|
||||
*
|
||||
* Medium sensitivity
|
||||
*/
|
||||
{AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_MEDIUM, "Medium", "medium"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPAStaticSceneDetectionSensitivity::high:
|
||||
*
|
||||
* High sensitivity
|
||||
*/
|
||||
{AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH, "High", "high"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_static_scene_detection_sensitivity)) {
|
||||
GType type =
|
||||
g_enum_register_static
|
||||
("GstAmfEncPAStaticSceneDetectionSensitivity", sensitivity_types);
|
||||
g_once_init_leave (&pa_static_scene_detection_sensitivity, type);
|
||||
}
|
||||
|
||||
return pa_static_scene_detection_sensitivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPACAQStrength:
|
||||
*
|
||||
* Content Adaptive Quantization strength. Stronger CAQ strength means larger
|
||||
* variation in block level QP assignment.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_caq_strength_get_type (void)
|
||||
{
|
||||
static GType pa_caq_strength = 0;
|
||||
static const GEnumValue strength_types[] = {
|
||||
/**
|
||||
* GstAmfEncPACAQStrength::low:
|
||||
*
|
||||
* Low strength
|
||||
*/
|
||||
{AMF_PA_CAQ_STRENGTH_LOW, "Low", "low"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPACAQStrength::medium:
|
||||
*
|
||||
* Medium strength
|
||||
*/
|
||||
{AMF_PA_CAQ_STRENGTH_MEDIUM, "Medium", "medium"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPACAQStrength::high:
|
||||
*
|
||||
* High strength
|
||||
*/
|
||||
{AMF_PA_CAQ_STRENGTH_HIGH, "High", "high"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_caq_strength)) {
|
||||
GType type =
|
||||
g_enum_register_static ("GstAmfEncPACAQStrength", strength_types);
|
||||
g_once_init_leave (&pa_caq_strength, type);
|
||||
}
|
||||
|
||||
return pa_caq_strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPAPAQMode:
|
||||
*
|
||||
* Sets the perceptual adaptive quantization mode.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_paq_mode_get_type (void)
|
||||
{
|
||||
static GType pa_paq_mode = 0;
|
||||
static const GEnumValue paq_modes[] = {
|
||||
/**
|
||||
* GstAmfEncPAPAQMode::none:
|
||||
*
|
||||
* No perceptual adaptive quantization
|
||||
*/
|
||||
{AMF_PA_PAQ_MODE_NONE, "None", "none"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPAPAQMode::caq:
|
||||
*
|
||||
* Content Adaptive Quantization (CAQ) mode
|
||||
*/
|
||||
{AMF_PA_PAQ_MODE_CAQ, "Content Adaptive Quantization (CAQ) mode", "caq"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_paq_mode)) {
|
||||
GType type = g_enum_register_static ("GstAmfEncPAPAQMode", paq_modes);
|
||||
g_once_init_leave (&pa_paq_mode, type);
|
||||
}
|
||||
|
||||
return pa_paq_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPATAQMode:
|
||||
*
|
||||
* Sets the temporal adaptive quantization mode. MODE_1 is suitable for non-gaming
|
||||
* applications whereas MODE_2 is suitable for gaming applications.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_taq_mode_get_type (void)
|
||||
{
|
||||
static GType pa_taq_mode = 0;
|
||||
static const GEnumValue taq_modes[] = {
|
||||
/**
|
||||
* GstAmfEncPATAQMode::none:
|
||||
*
|
||||
* No temporal adaptive quantization
|
||||
*/
|
||||
{AMF_PA_TAQ_MODE_NONE, "None", "none"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPATAQMode::mode1:
|
||||
*
|
||||
* MODE_1 is suitable for non-gaming applications
|
||||
*/
|
||||
{AMF_PA_TAQ_MODE_1, "Mode_1 is suitable for non-gaming applications",
|
||||
"mode1"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPATAQMode::mode2:
|
||||
*
|
||||
* MODE_2 is suitable for for gaming applications
|
||||
*/
|
||||
{AMF_PA_TAQ_MODE_2, "Mode_2 is suitable for gaming applications", "mode2"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_taq_mode)) {
|
||||
GType type = g_enum_register_static ("GstAmfEncPATAQMode", taq_modes);
|
||||
g_once_init_leave (&pa_taq_mode, type);
|
||||
}
|
||||
|
||||
return pa_taq_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* GstAmfEncPAHQMBMode:
|
||||
*
|
||||
* Sets the PA high motion quality boost (HQMB) mode to help the encoder in motion search.
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
GType
|
||||
gst_amf_enc_pa_hmbq_mode_get_type (void)
|
||||
{
|
||||
static GType pa_hmbq_mode = 0;
|
||||
static const GEnumValue hmbq_modes[] = {
|
||||
/**
|
||||
* GstAmfEncPAHQMBMode::none:
|
||||
*
|
||||
* No high motion quality boost
|
||||
*/
|
||||
{AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_NONE, "None", "none"},
|
||||
|
||||
/**
|
||||
* GstAmfEncPAHQMBMode::auto:
|
||||
*
|
||||
* Automatic mode
|
||||
*/
|
||||
{AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_AUTO, "Auto", "auto"},
|
||||
{0, nullptr, nullptr}
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&pa_hmbq_mode)) {
|
||||
GType type = g_enum_register_static ("GstAmfEncPAHQMBMode", hmbq_modes);
|
||||
g_once_init_leave (&pa_hmbq_mode, type);
|
||||
}
|
||||
|
||||
return pa_hmbq_mode;
|
||||
}
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_amf_encoder_debug);
|
||||
#define GST_CAT_DEFAULT gst_amf_encoder_debug
|
||||
|
||||
|
@ -122,6 +416,22 @@ gst_amf_encoder_class_init (GstAmfEncoderClass * klass)
|
|||
"amfencoder", 0, "amfencoder");
|
||||
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENCODER, (GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENC_PA_ACTIVITY_TYPE,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api
|
||||
(GST_TYPE_AMF_ENC_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api
|
||||
(GST_TYPE_AMF_ENC_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENC_PA_CAQ_STRENGTH,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENC_PA_PAQ_MODE,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENC_PA_TAQ_MODE,
|
||||
(GstPluginAPIFlags) 0);
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AMF_ENC_PA_HQMB_MODE,
|
||||
(GstPluginAPIFlags) 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -466,7 +776,7 @@ gst_amf_encoder_prepare_internal_pool (GstAmfEncoder * self)
|
|||
GST_VIDEO_INFO_SIZE (info), 0, 0);
|
||||
|
||||
params = gst_d3d11_allocation_params_new (priv->device, info,
|
||||
GST_D3D11_ALLOCATION_FLAG_DEFAULT, 0, 0);
|
||||
GST_D3D11_ALLOCATION_FLAG_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0);
|
||||
params->desc[0].MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, params);
|
||||
|
@ -775,7 +1085,8 @@ gst_amf_encoder_upload_buffer (GstAmfEncoder * self, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
gst_d3d11_memory_get_texture_desc (dmem, &desc);
|
||||
if (desc.Usage != D3D11_USAGE_DEFAULT) {
|
||||
if (desc.Usage != D3D11_USAGE_DEFAULT
|
||||
|| (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) == 0) {
|
||||
GST_TRACE_OBJECT (self, "Not a default usage texture, d3d11 copy");
|
||||
gst_d3d11_device_lock (priv->device);
|
||||
ret = gst_amf_encoder_copy_d3d11 (self, buffer, FALSE);
|
||||
|
@ -1012,6 +1323,7 @@ gst_amf_encoder_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
|
|||
GstCapsFeatures *features;
|
||||
gboolean is_d3d11 = FALSE;
|
||||
guint min_buffers = 0;
|
||||
GstD3D11AllocationParams *params;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, nullptr);
|
||||
if (!caps) {
|
||||
|
@ -1048,6 +1360,11 @@ gst_amf_encoder_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
|
|||
size = GST_VIDEO_INFO_SIZE (&info);
|
||||
gst_buffer_pool_config_set_params (config, caps, size, min_buffers, 0);
|
||||
|
||||
params = gst_d3d11_allocation_params_new (device, &info,
|
||||
GST_D3D11_ALLOCATION_FLAG_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0);
|
||||
gst_buffer_pool_config_set_d3d11_allocation_params (config, params);
|
||||
gst_d3d11_allocation_params_free (params);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config)) {
|
||||
GST_WARNING_OBJECT (self, "Failed to set pool config");
|
||||
gst_object_unref (pool);
|
||||
|
@ -1082,3 +1399,181 @@ gst_amf_encoder_set_subclass_data (GstAmfEncoder * encoder, gint64 adapter_luid,
|
|||
priv->codec_id = codec_id;
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
|
||||
AMF_RESULT
|
||||
gst_amf_encoder_set_pre_analysis_options (GstAmfEncoder * self,
|
||||
AMFComponent * comp, const GstAmfEncoderPreAnalysis * pa,
|
||||
GstAmfEncoderPASupportedOptions * pa_supported)
|
||||
{
|
||||
AMF_RESULT result;
|
||||
if (pa_supported->activity_type) {
|
||||
result = comp->SetProperty (AMF_PA_ACTIVITY_TYPE,
|
||||
(AMF_PA_ACTIVITY_TYPE_ENUM) pa->activity_type);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis activity type, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->scene_change_detection) {
|
||||
result = comp->SetProperty (AMF_PA_SCENE_CHANGE_DETECTION_ENABLE,
|
||||
(amf_bool) pa->scene_change_detection);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis scene change detection, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->scene_change_detection_sensitivity) {
|
||||
result = comp->SetProperty (AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
(AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_ENUM)
|
||||
pa->scene_change_detection_sensitivity);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis scene change detection sensitivity, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->static_scene_detection) {
|
||||
result = comp->SetProperty (AMF_PA_STATIC_SCENE_DETECTION_ENABLE,
|
||||
(amf_bool) pa->static_scene_detection);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis static scene detection, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->static_scene_detection_sensitivity) {
|
||||
result = comp->SetProperty (AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
(AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_ENUM)
|
||||
pa->static_scene_detection_sensitivity);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis static scene detection sensitivity, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->initial_qp) {
|
||||
result = comp->SetProperty (AMF_PA_INITIAL_QP_AFTER_SCENE_CHANGE,
|
||||
(amf_int64) pa->initial_qp);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis initial QP, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->max_qp) {
|
||||
result = comp->SetProperty (AMF_PA_MAX_QP_BEFORE_FORCE_SKIP,
|
||||
(amf_int64) pa->max_qp);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis max QP, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->caq_strength) {
|
||||
result = comp->SetProperty (AMF_PA_CAQ_STRENGTH,
|
||||
(amf_int64) pa->caq_strength);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis CAQ strength, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->frame_sad) {
|
||||
result = comp->SetProperty (AMF_PA_FRAME_SAD_ENABLE,
|
||||
(amf_bool) pa->frame_sad);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis frame SAD algorithm, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->ltr) {
|
||||
result = comp->SetProperty (AMF_PA_LTR_ENABLE, (amf_bool) pa->ltr);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis automatic Long Term Reference frame management, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->lookahead_buffer_depth) {
|
||||
result = comp->SetProperty (AMF_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
(amf_int64) pa->lookahead_buffer_depth);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis lookahead buffer depth, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->paq_mode) {
|
||||
result = comp->SetProperty (AMF_PA_PAQ_MODE, (amf_int64) pa->paq_mode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis PAQ mode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->taq_mode) {
|
||||
result = comp->SetProperty (AMF_PA_TAQ_MODE, (amf_int64) pa->taq_mode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis TAQ mode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (pa_supported->hmqb_mode) {
|
||||
result = comp->SetProperty (AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE,
|
||||
(amf_int64) pa->hmqb_mode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to set pre-analysis high motion quality boost mode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return AMF_OK;
|
||||
}
|
||||
|
||||
void
|
||||
gst_amf_encoder_check_pa_supported_options (GstAmfEncoderPASupportedOptions *
|
||||
pa_supported, AMFComponent * comp)
|
||||
{
|
||||
if (comp->HasProperty (AMF_PA_ACTIVITY_TYPE))
|
||||
pa_supported->activity_type = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_SCENE_CHANGE_DETECTION_ENABLE))
|
||||
pa_supported->scene_change_detection = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY))
|
||||
pa_supported->scene_change_detection_sensitivity = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_STATIC_SCENE_DETECTION_ENABLE))
|
||||
pa_supported->static_scene_detection = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY))
|
||||
pa_supported->static_scene_detection_sensitivity = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_INITIAL_QP_AFTER_SCENE_CHANGE))
|
||||
pa_supported->initial_qp = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_MAX_QP_BEFORE_FORCE_SKIP))
|
||||
pa_supported->max_qp = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_CAQ_STRENGTH))
|
||||
pa_supported->caq_strength = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_FRAME_SAD_ENABLE))
|
||||
pa_supported->frame_sad = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_LTR_ENABLE))
|
||||
pa_supported->ltr = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_LOOKAHEAD_BUFFER_DEPTH))
|
||||
pa_supported->lookahead_buffer_depth = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_PAQ_MODE))
|
||||
pa_supported->paq_mode = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_TAQ_MODE))
|
||||
pa_supported->taq_mode = TRUE;
|
||||
if (comp->HasProperty (AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE))
|
||||
pa_supported->hmqb_mode = TRUE;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <components/Component.h>
|
||||
#include <components/PreAnalysis.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include "gstamfutils.h"
|
||||
|
@ -37,6 +39,42 @@ typedef struct _GstAmfEncoder GstAmfEncoder;
|
|||
typedef struct _GstAmfEncoderClass GstAmfEncoderClass;
|
||||
typedef struct _GstAmfEncoderPrivate GstAmfEncoderPrivate;
|
||||
|
||||
typedef struct _GstAmfEncoderPASupportedOptions {
|
||||
gboolean activity_type;
|
||||
gboolean scene_change_detection;
|
||||
gboolean scene_change_detection_sensitivity;
|
||||
gboolean static_scene_detection;
|
||||
gboolean static_scene_detection_sensitivity;
|
||||
gboolean initial_qp;
|
||||
gboolean max_qp;
|
||||
gboolean caq_strength;
|
||||
gboolean frame_sad;
|
||||
gboolean ltr;
|
||||
gboolean lookahead_buffer_depth;
|
||||
gboolean paq_mode;
|
||||
gboolean taq_mode;
|
||||
gboolean hmqb_mode;
|
||||
} GstAmfEncoderPASupportedOptions;
|
||||
|
||||
typedef struct _GstAmfEncoderPreAnalysis
|
||||
{
|
||||
gboolean pre_analysis;
|
||||
gint activity_type;
|
||||
gboolean scene_change_detection;
|
||||
gint scene_change_detection_sensitivity;
|
||||
gboolean static_scene_detection;
|
||||
gint static_scene_detection_sensitivity;
|
||||
guint initial_qp;
|
||||
guint max_qp;
|
||||
gint caq_strength;
|
||||
gboolean frame_sad;
|
||||
gboolean ltr;
|
||||
guint lookahead_buffer_depth;
|
||||
gint paq_mode;
|
||||
gint taq_mode;
|
||||
gint hmqb_mode;
|
||||
} GstAmfEncoderPreAnalysis;
|
||||
|
||||
struct _GstAmfEncoder
|
||||
{
|
||||
GstVideoEncoder parent;
|
||||
|
@ -47,7 +85,7 @@ struct _GstAmfEncoder
|
|||
struct _GstAmfEncoderClass
|
||||
{
|
||||
GstVideoEncoderClass parent_class;
|
||||
|
||||
GstAmfEncoderPASupportedOptions pa_supported;
|
||||
gboolean (*set_format) (GstAmfEncoder * encoder,
|
||||
GstVideoCodecState * state,
|
||||
gpointer component);
|
||||
|
@ -73,6 +111,53 @@ void gst_amf_encoder_set_subclass_data (GstAmfEncoder * encoder,
|
|||
gint64 adapter_luid,
|
||||
const wchar_t * codec_id);
|
||||
|
||||
AMF_RESULT gst_amf_encoder_set_pre_analysis_options (GstAmfEncoder * self,
|
||||
amf::AMFComponent * comp,
|
||||
const GstAmfEncoderPreAnalysis * pa,
|
||||
GstAmfEncoderPASupportedOptions * pa_supported);
|
||||
|
||||
void gst_amf_encoder_check_pa_supported_options (GstAmfEncoderPASupportedOptions * pa_supported,
|
||||
amf::AMFComponent * comp);
|
||||
|
||||
// Pre-analysis settings
|
||||
#define DEFAULT_PRE_ANALYSIS FALSE
|
||||
#define DEFAULT_PA_ACTIVITY_TYPE AMF_PA_ACTIVITY_Y
|
||||
#define DEFAULT_PA_SCENE_CHANGE_DETECTION TRUE
|
||||
#define DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_MEDIUM
|
||||
#define DEFAULT_PA_STATIC_SCENE_DETECTION FALSE
|
||||
#define DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH
|
||||
|
||||
#define DEFAULT_PA_INITIAL_QP 0
|
||||
#define DEFAULT_PA_MAX_QP 35
|
||||
#define DEFAULT_PA_CAQ_STRENGTH AMF_PA_CAQ_STRENGTH_MEDIUM
|
||||
#define DEFAULT_PA_FRAME_SAD TRUE
|
||||
#define DEFAULT_PA_LTR FALSE
|
||||
#define DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH 0
|
||||
#define DEFAULT_PA_PAQ_MODE AMF_PA_PAQ_MODE_NONE
|
||||
#define DEFAULT_PA_TAQ_MODE AMF_PA_TAQ_MODE_NONE
|
||||
#define DEFAULT_PA_HQMB_MODE AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_NONE
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_ACTIVITY_TYPE (gst_amf_enc_pa_activity_get_type ())
|
||||
GType gst_amf_enc_pa_activity_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_SCENE_CHANGE_DETECTION_SENSITIVITY (gst_amf_enc_pa_scene_change_detection_sensitivity_get_type ())
|
||||
GType gst_amf_enc_pa_scene_change_detection_sensitivity_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_STATIC_SCENE_DETECTION_SENSITIVITY (gst_amf_enc_pa_static_scene_detection_sensitivity_get_type ())
|
||||
GType gst_amf_enc_pa_static_scene_detection_sensitivity_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_CAQ_STRENGTH (gst_amf_enc_pa_caq_strength_get_type ())
|
||||
GType gst_amf_enc_pa_caq_strength_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_PAQ_MODE (gst_amf_enc_pa_paq_mode_get_type ())
|
||||
GType gst_amf_enc_pa_paq_mode_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_TAQ_MODE (gst_amf_enc_pa_taq_mode_get_type ())
|
||||
GType gst_amf_enc_pa_taq_mode_get_type (void);
|
||||
|
||||
#define GST_TYPE_AMF_ENC_PA_HQMB_MODE (gst_amf_enc_pa_hmbq_mode_get_type ())
|
||||
GType gst_amf_enc_pa_hmbq_mode_get_type (void);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAmfEncoder, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -77,7 +77,9 @@ typedef struct
|
|||
amf_int64 default_qp_b;
|
||||
gboolean interlace_supported;
|
||||
guint valign;
|
||||
gboolean pre_encode_supported;
|
||||
gboolean smart_access_supported;
|
||||
GstAmfEncoderPASupportedOptions pa_supported;
|
||||
} GstAmfH264EncDeviceCaps;
|
||||
|
||||
/**
|
||||
|
@ -274,7 +276,23 @@ enum
|
|||
PROP_REF_FRAMES,
|
||||
PROP_AUD,
|
||||
PROP_CABAC,
|
||||
PROP_SMART_ACCESS
|
||||
PROP_SMART_ACCESS,
|
||||
PROP_PRE_ENCODE,
|
||||
PROP_PRE_ANALYSIS,
|
||||
PROP_PA_ACTIVITY_TYPE,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_INITIAL_QP,
|
||||
PROP_PA_MAX_QP,
|
||||
PROP_PA_CAQ_STRENGTH,
|
||||
PROP_PA_FRAME_SAD,
|
||||
PROP_PA_LTR,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
PROP_PA_PAQ_MODE,
|
||||
PROP_PA_TAQ_MODE,
|
||||
PROP_PA_HQMB_MODE,
|
||||
};
|
||||
|
||||
#define DEFAULT_USAGE AMF_VIDEO_ENCODER_USAGE_TRANSCODING
|
||||
|
@ -287,6 +305,7 @@ enum
|
|||
#define DEFAULT_AUD TRUE
|
||||
#define DEFAULT_CABAC TRUE
|
||||
#define DEFAULT_SMART_ACCESS FALSE
|
||||
#define DEFAULT_PRE_ENCODE FALSE
|
||||
|
||||
#define DOC_SINK_CAPS_COMM \
|
||||
"format = (string) NV12, " \
|
||||
|
@ -301,6 +320,7 @@ enum
|
|||
"profile = (string) { main, high, constrained-baseline, baseline }, " \
|
||||
"stream-format = (string) { avc, byte-stream }, alignment = (string) au"
|
||||
|
||||
|
||||
typedef struct _GstAmfH264Enc
|
||||
{
|
||||
GstAmfEncoder parent;
|
||||
|
@ -326,6 +346,8 @@ typedef struct _GstAmfH264Enc
|
|||
gboolean aud;
|
||||
gboolean cabac;
|
||||
gboolean smart_access;
|
||||
gboolean pre_encode;
|
||||
GstAmfEncoderPreAnalysis pa;
|
||||
} GstAmfH264Enc;
|
||||
|
||||
typedef struct _GstAmfH264EncClass
|
||||
|
@ -366,8 +388,11 @@ gst_amf_h264_enc_class_init (GstAmfH264EncClass * klass, gpointer data)
|
|||
GstAmfEncoderClass *amf_class = GST_AMF_ENCODER_CLASS (klass);
|
||||
GstAmfH264EncClassData *cdata = (GstAmfH264EncClassData *) data;
|
||||
GstAmfH264EncDeviceCaps *dev_caps = &cdata->dev_caps;
|
||||
GstAmfEncoderPASupportedOptions *pa_supported = &dev_caps->pa_supported;
|
||||
GParamFlags param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS);
|
||||
GParamFlags pa_param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS | GST_PARAM_CONDITIONALLY_AVAILABLE);
|
||||
GstPadTemplate *pad_templ;
|
||||
GstCaps *doc_caps;
|
||||
|
||||
|
@ -432,7 +457,12 @@ gst_amf_h264_enc_class_init (GstAmfH264EncClass * klass, gpointer data)
|
|||
g_object_class_install_property (object_class, PROP_CABAC,
|
||||
g_param_spec_boolean ("cabac", "CABAC",
|
||||
"Enable CABAC entropy coding", TRUE, param_flags));
|
||||
|
||||
if (cdata->dev_caps.pre_encode_supported) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ENCODE,
|
||||
g_param_spec_boolean ("pre-encode", "Pre-encode",
|
||||
"Enable pre-encode", DEFAULT_PRE_ENCODE,
|
||||
(GParamFlags) (param_flags | GST_PARAM_CONDITIONALLY_AVAILABLE)));
|
||||
}
|
||||
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",
|
||||
|
@ -443,6 +473,112 @@ gst_amf_h264_enc_class_init (GstAmfH264EncClass * klass, gpointer data)
|
|||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS)));
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ANALYSIS,
|
||||
g_param_spec_boolean ("pre-analysis", "Pre Analysis",
|
||||
"Enable pre-analysis", DEFAULT_PRE_ANALYSIS, param_flags));
|
||||
if (pa_supported->activity_type) {
|
||||
g_object_class_install_property (object_class, PROP_PA_ACTIVITY_TYPE,
|
||||
g_param_spec_enum ("pa-activity-type", "Pre-analysis activity type",
|
||||
"Set the type of activity analysis for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_ACTIVITY_TYPE, DEFAULT_PA_ACTIVITY_TYPE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
g_param_spec_boolean ("pa-scene-change-detection",
|
||||
"Pre-analysis scene change detection",
|
||||
"Enable scene change detection for pre-analysis",
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-scene-change-detection-sensitivity",
|
||||
"Pre-analysis scene change detection sensitivity",
|
||||
"Set the sensitivity of scene change detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
g_param_spec_boolean ("pa-static-scene-detection",
|
||||
"Pre-analysis static scene detection",
|
||||
"Enable static scene detection for pre-analysis",
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-static-scene-detection-sensitivity",
|
||||
"Pre-analysis static scene detection sensitivity",
|
||||
"Set the sensitivity of static scene detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->initial_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_INITIAL_QP,
|
||||
g_param_spec_uint ("pa-initial-qp", "Pre-analysis initial QP",
|
||||
"The QP value that is used immediately after a scene change", 0,
|
||||
51, DEFAULT_PA_INITIAL_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->max_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_MAX_QP,
|
||||
g_param_spec_uint ("pa-max-qp", "Pre-analysis max QP",
|
||||
"The QP threshold to allow a skip frame", 0, 51,
|
||||
DEFAULT_PA_MAX_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->caq_strength) {
|
||||
g_object_class_install_property (object_class, PROP_PA_CAQ_STRENGTH,
|
||||
g_param_spec_enum ("pa-caq-strength", "Pre-analysis CAQ strength",
|
||||
"Content Adaptive Quantization strength for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_CAQ_STRENGTH, DEFAULT_PA_CAQ_STRENGTH,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->frame_sad) {
|
||||
g_object_class_install_property (object_class, PROP_PA_FRAME_SAD,
|
||||
g_param_spec_boolean ("pa-frame-sad", "Pre-analysis SAD algorithm",
|
||||
"Enable Frame SAD algorithm", DEFAULT_PA_FRAME_SAD,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->ltr) {
|
||||
g_object_class_install_property (object_class, PROP_PA_LTR,
|
||||
g_param_spec_boolean ("pa-ltr", "Pre-analysis LTR",
|
||||
"Enable long term reference frame management", DEFAULT_PA_LTR,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->lookahead_buffer_depth) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
g_param_spec_uint ("pa-lookahead-buffer-depth",
|
||||
"Pre-analysis lookahead buffer depth",
|
||||
"Set the PA lookahead buffer size", 0, 41,
|
||||
DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->paq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_PAQ_MODE,
|
||||
g_param_spec_enum ("pa-paq-mode", "Pre-analysis PAQ mode",
|
||||
"Set the perceptual adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_PAQ_MODE, DEFAULT_PA_PAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->taq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_TAQ_MODE,
|
||||
g_param_spec_enum ("pa-taq-mode", "Pre-analysis TAQ mode",
|
||||
"Set the temporal adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_TAQ_MODE, DEFAULT_PA_TAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->hmqb_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_HQMB_MODE,
|
||||
g_param_spec_enum ("pa-hqmb-mode", "Pre-analysis HQMB mode",
|
||||
"Set the PA high motion quality boost mode",
|
||||
GST_TYPE_AMF_ENC_PA_HQMB_MODE, DEFAULT_PA_HQMB_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
}
|
||||
gst_element_class_set_metadata (element_class,
|
||||
"AMD AMF H.264 Video Encoder",
|
||||
"Codec/Encoder/Video/Hardware",
|
||||
|
@ -517,6 +653,25 @@ gst_amf_h264_enc_init (GstAmfH264Enc * self)
|
|||
self->aud = DEFAULT_AUD;
|
||||
self->cabac = DEFAULT_CABAC;
|
||||
self->smart_access = DEFAULT_SMART_ACCESS;
|
||||
self->pre_encode = DEFAULT_PRE_ENCODE;
|
||||
// Init pre-analysis options
|
||||
self->pa.pre_analysis = DEFAULT_PRE_ANALYSIS;
|
||||
self->pa.activity_type = DEFAULT_PA_ACTIVITY_TYPE;
|
||||
self->pa.scene_change_detection = DEFAULT_PA_SCENE_CHANGE_DETECTION;
|
||||
self->pa.scene_change_detection_sensitivity =
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY;
|
||||
self->pa.static_scene_detection = DEFAULT_PA_STATIC_SCENE_DETECTION;
|
||||
self->pa.static_scene_detection_sensitivity =
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY;
|
||||
self->pa.initial_qp = DEFAULT_PA_INITIAL_QP;
|
||||
self->pa.max_qp = DEFAULT_PA_MAX_QP;
|
||||
self->pa.caq_strength = DEFAULT_PA_CAQ_STRENGTH;
|
||||
self->pa.frame_sad = DEFAULT_PA_FRAME_SAD;
|
||||
self->pa.ltr = DEFAULT_PA_LTR;
|
||||
self->pa.lookahead_buffer_depth = DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH;
|
||||
self->pa.paq_mode = DEFAULT_PA_PAQ_MODE;
|
||||
self->pa.taq_mode = DEFAULT_PA_TAQ_MODE;
|
||||
self->pa.hmqb_mode = DEFAULT_PA_HQMB_MODE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -629,6 +784,53 @@ gst_amf_h264_enc_set_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
update_bool (self, &self->smart_access, value);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
update_bool (self, &self->pre_encode, value);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
update_bool (self, &self->pa.pre_analysis, value);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
update_enum (self, &self->pa.activity_type, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
update_bool (self, &self->pa.scene_change_detection, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.scene_change_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
update_bool (self, &self->pa.static_scene_detection, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.static_scene_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
update_uint (self, &self->pa.initial_qp, value);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
update_uint (self, &self->pa.max_qp, value);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
update_enum (self, &self->pa.caq_strength, value);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
update_bool (self, &self->pa.frame_sad, value);
|
||||
case PROP_PA_LTR:
|
||||
update_bool (self, &self->pa.ltr, value);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
update_uint (self, &self->pa.lookahead_buffer_depth, value);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
update_enum (self, &self->pa.paq_mode, value);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
update_enum (self, &self->pa.taq_mode, value);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
update_enum (self, &self->pa.hmqb_mode, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -689,6 +891,54 @@ gst_amf_h264_enc_get_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
g_value_set_boolean (value, self->smart_access);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
g_value_set_boolean (value, self->pre_encode);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
g_value_set_boolean (value, self->pa.pre_analysis);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
g_value_set_enum (value, self->pa.activity_type);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.scene_change_detection);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.scene_change_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.static_scene_detection);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.static_scene_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
g_value_set_uint (value, self->pa.initial_qp);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
g_value_set_uint (value, self->pa.max_qp);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
g_value_set_enum (value, self->pa.caq_strength);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
g_value_set_boolean (value, self->pa.frame_sad);
|
||||
break;
|
||||
case PROP_PA_LTR:
|
||||
g_value_set_boolean (value, self->pa.ltr);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
g_value_set_uint (value, self->pa.lookahead_buffer_depth);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.paq_mode);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.taq_mode);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
g_value_set_enum (value, self->pa.hmqb_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -956,7 +1206,32 @@ gst_amf_h264_enc_set_format (GstAmfEncoder * encoder,
|
|||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
}
|
||||
}
|
||||
if (dev_caps->pre_encode_supported) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_PREENCODE_ENABLE,
|
||||
(amf_bool) self->pre_encode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-encode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) self->pa.pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
if (self->pa.pre_analysis) {
|
||||
result =
|
||||
gst_amf_encoder_set_pre_analysis_options (encoder, comp, &self->pa,
|
||||
&dev_caps->pa_supported);
|
||||
if (result != AMF_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
result = comp->Init (AMF_SURFACE_NV12, info->width, info->height);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to init component, result %"
|
||||
|
@ -1360,6 +1635,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 pre_encode_supported;
|
||||
amf_bool smart_access_supported;
|
||||
amf_int32 num_val;
|
||||
gboolean have_nv12 = FALSE;
|
||||
|
@ -1492,11 +1768,40 @@ 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_PREENCODE_ENABLE,
|
||||
&pre_encode_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.pre_encode_supported = TRUE;
|
||||
|
||||
result = comp->GetProperty (AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO,
|
||||
&smart_access_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.smart_access_supported = TRUE;
|
||||
|
||||
if (dev_caps.pre_analysis) {
|
||||
amf_bool pre_analysis = FALSE;
|
||||
// Store initial pre-analysis value
|
||||
result =
|
||||
comp->GetProperty (AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE,
|
||||
&pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to get pre-analysis option");
|
||||
}
|
||||
// We need to enable pre-analysis for checking options availability
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) TRUE);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis option");
|
||||
}
|
||||
gst_amf_encoder_check_pa_supported_options (&dev_caps.pa_supported, comp);
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis options");
|
||||
}
|
||||
}
|
||||
|
||||
min_width = MAX (in_min_width, 1);
|
||||
max_width = in_max_width;
|
||||
if (max_width == 0) {
|
||||
|
|
|
@ -75,7 +75,9 @@ typedef struct
|
|||
amf_int64 max_gop_size;
|
||||
amf_int64 default_gop_size;
|
||||
guint valign;
|
||||
gboolean pre_encode_supported;
|
||||
gboolean smart_access_supported;
|
||||
GstAmfEncoderPASupportedOptions pa_supported;
|
||||
} GstAmfH265EncDeviceCaps;
|
||||
|
||||
/**
|
||||
|
@ -274,7 +276,23 @@ enum
|
|||
PROP_QP_P,
|
||||
PROP_REF_FRAMES,
|
||||
PROP_AUD,
|
||||
PROP_SMART_ACCESS
|
||||
PROP_SMART_ACCESS,
|
||||
PROP_PRE_ENCODE,
|
||||
PROP_PRE_ANALYSIS,
|
||||
PROP_PA_ACTIVITY_TYPE,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
PROP_PA_INITIAL_QP,
|
||||
PROP_PA_MAX_QP,
|
||||
PROP_PA_CAQ_STRENGTH,
|
||||
PROP_PA_FRAME_SAD,
|
||||
PROP_PA_LTR,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
PROP_PA_PAQ_MODE,
|
||||
PROP_PA_TAQ_MODE,
|
||||
PROP_PA_HQMB_MODE,
|
||||
};
|
||||
|
||||
#define DEFAULT_USAGE AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING
|
||||
|
@ -285,6 +303,7 @@ enum
|
|||
#define DEFAULT_MIN_MAX_QP -1
|
||||
#define DEFAULT_AUD TRUE
|
||||
#define DEFAULT_SMART_ACCESS FALSE
|
||||
#define DEFAULT_PRE_ENCODE FALSE
|
||||
|
||||
#define DOC_SINK_CAPS_COMM \
|
||||
"format = (string) {NV12, P010_10LE}, " \
|
||||
|
@ -322,6 +341,8 @@ typedef struct _GstAmfH265Enc
|
|||
|
||||
gboolean aud;
|
||||
gboolean smart_access;
|
||||
gboolean pre_encode;
|
||||
GstAmfEncoderPreAnalysis pa;
|
||||
} GstAmfH265Enc;
|
||||
|
||||
typedef struct _GstAmfH265EncClass
|
||||
|
@ -362,8 +383,11 @@ gst_amf_h265_enc_class_init (GstAmfH265EncClass * klass, gpointer data)
|
|||
GstAmfEncoderClass *amf_class = GST_AMF_ENCODER_CLASS (klass);
|
||||
GstAmfH265EncClassData *cdata = (GstAmfH265EncClassData *) data;
|
||||
GstAmfH265EncDeviceCaps *dev_caps = &cdata->dev_caps;
|
||||
GstAmfEncoderPASupportedOptions *pa_supported = &dev_caps->pa_supported;
|
||||
GParamFlags param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS);
|
||||
GParamFlags pa_param_flags = (GParamFlags) (G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS | GST_PARAM_CONDITIONALLY_AVAILABLE);
|
||||
GstPadTemplate *pad_templ;
|
||||
GstCaps *doc_caps;
|
||||
|
||||
|
@ -434,6 +458,12 @@ gst_amf_h265_enc_class_init (GstAmfH265EncClass * klass, gpointer data)
|
|||
g_object_class_install_property (object_class, PROP_AUD,
|
||||
g_param_spec_boolean ("aud", "AUD",
|
||||
"Use AU (Access Unit) delimiter", DEFAULT_AUD, param_flags));
|
||||
if (cdata->dev_caps.pre_encode_supported) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ENCODE,
|
||||
g_param_spec_boolean ("pre-encode", "Pre-encode",
|
||||
"Enable pre-encode", DEFAULT_PRE_ENCODE,
|
||||
(GParamFlags) (param_flags | GST_PARAM_CONDITIONALLY_AVAILABLE)));
|
||||
}
|
||||
|
||||
if (cdata->dev_caps.smart_access_supported) {
|
||||
g_object_class_install_property (object_class, PROP_SMART_ACCESS,
|
||||
|
@ -445,6 +475,113 @@ gst_amf_h265_enc_class_init (GstAmfH265EncClass * klass, gpointer data)
|
|||
GST_PARAM_MUTABLE_PLAYING | G_PARAM_STATIC_STRINGS)));
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
g_object_class_install_property (object_class, PROP_PRE_ANALYSIS,
|
||||
g_param_spec_boolean ("pre-analysis", "Pre-analysis",
|
||||
"Enable pre-analysis", DEFAULT_PRE_ANALYSIS, param_flags));
|
||||
if (pa_supported->activity_type) {
|
||||
g_object_class_install_property (object_class, PROP_PA_ACTIVITY_TYPE,
|
||||
g_param_spec_enum ("pa-activity-type", "Pre-analysis activity type",
|
||||
"Set the type of activity analysis for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_ACTIVITY_TYPE, DEFAULT_PA_ACTIVITY_TYPE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION,
|
||||
g_param_spec_boolean ("pa-scene-change-detection",
|
||||
"Pre-analysis scene change detection",
|
||||
"Enable scene change detection for pre-analysis",
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->scene_change_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-scene-change-detection-sensitivity",
|
||||
"Pre-analysis scene change detection sensitivity",
|
||||
"Set the sensitivity of scene change detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_SCENE_CHANGE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION,
|
||||
g_param_spec_boolean ("pa-static-scene-detection",
|
||||
"Pre-analysis static scene detection",
|
||||
"Enable static scene detection for pre-analysis",
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->static_scene_detection_sensitivity) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
g_param_spec_enum ("pa-static-scene-detection-sensitivity",
|
||||
"Pre-analysis static scene detection sensitivity",
|
||||
"Set the sensitivity of static scene detection for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_STATIC_SCENE_DETECTION_SENSITIVITY,
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->initial_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_INITIAL_QP,
|
||||
g_param_spec_uint ("pa-initial-qp", "Pre-analysis initial QP",
|
||||
"The QP value that is used immediately after a scene change", 0,
|
||||
51, DEFAULT_PA_INITIAL_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->max_qp) {
|
||||
g_object_class_install_property (object_class, PROP_PA_MAX_QP,
|
||||
g_param_spec_uint ("pa-max-qp", "Pre-analysis max QP",
|
||||
"The QP threshold to allow a skip frame", 0, 51,
|
||||
DEFAULT_PA_MAX_QP, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->caq_strength) {
|
||||
g_object_class_install_property (object_class, PROP_PA_CAQ_STRENGTH,
|
||||
g_param_spec_enum ("pa-caq-strength", "Pre-analysis CAQ strength",
|
||||
"Content Adaptive Quantization strength for pre-analysis",
|
||||
GST_TYPE_AMF_ENC_PA_CAQ_STRENGTH, DEFAULT_PA_CAQ_STRENGTH,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->frame_sad) {
|
||||
g_object_class_install_property (object_class, PROP_PA_FRAME_SAD,
|
||||
g_param_spec_boolean ("pa-frame-sad", "Pre-analysis SAD algorithm",
|
||||
"Enable Frame SAD algorithm", DEFAULT_PA_FRAME_SAD,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->ltr) {
|
||||
g_object_class_install_property (object_class, PROP_PA_LTR,
|
||||
g_param_spec_boolean ("pa-ltr", "Pre-analysis LTR",
|
||||
"Enable long term reference frame management", DEFAULT_PA_LTR,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->lookahead_buffer_depth) {
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PA_LOOKAHEAD_BUFFER_DEPTH,
|
||||
g_param_spec_uint ("pa-lookahead-buffer-depth",
|
||||
"Pre-analysis lookahead buffer depth",
|
||||
"Set the PA lookahead buffer size", 0, 41,
|
||||
DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH, pa_param_flags));
|
||||
}
|
||||
if (pa_supported->paq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_PAQ_MODE,
|
||||
g_param_spec_enum ("pa-paq-mode", "Pre-analysis PAQ mode",
|
||||
"Set the perceptual adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_PAQ_MODE, DEFAULT_PA_PAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->taq_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_TAQ_MODE,
|
||||
g_param_spec_enum ("pa-taq-mode", "Pre-analysis TAQ mode",
|
||||
"Set the temporal adaptive quantization mode",
|
||||
GST_TYPE_AMF_ENC_PA_TAQ_MODE, DEFAULT_PA_TAQ_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
if (pa_supported->hmqb_mode) {
|
||||
g_object_class_install_property (object_class, PROP_PA_HQMB_MODE,
|
||||
g_param_spec_enum ("pa-hqmb-mode", "Pre-analysis HQMB mode",
|
||||
"Set the PA high motion quality boost mode",
|
||||
GST_TYPE_AMF_ENC_PA_HQMB_MODE, DEFAULT_PA_HQMB_MODE,
|
||||
pa_param_flags));
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_class_set_metadata (element_class,
|
||||
"AMD AMF H.265 Video Encoder",
|
||||
"Codec/Encoder/Video/Hardware",
|
||||
|
@ -518,6 +655,25 @@ gst_amf_h265_enc_init (GstAmfH265Enc * self)
|
|||
self->ref_frames = (guint) dev_caps->min_ref_frames;
|
||||
self->aud = DEFAULT_AUD;
|
||||
self->smart_access = DEFAULT_SMART_ACCESS;
|
||||
self->pre_encode = DEFAULT_PRE_ENCODE;
|
||||
// Init pre-analysis options
|
||||
self->pa.pre_analysis = DEFAULT_PRE_ANALYSIS;
|
||||
self->pa.activity_type = DEFAULT_PA_ACTIVITY_TYPE;
|
||||
self->pa.scene_change_detection = DEFAULT_PA_SCENE_CHANGE_DETECTION;
|
||||
self->pa.scene_change_detection_sensitivity =
|
||||
DEFAULT_PA_SCENE_CHANGE_DETECTION_SENSITIVITY;
|
||||
self->pa.static_scene_detection = DEFAULT_PA_STATIC_SCENE_DETECTION;
|
||||
self->pa.static_scene_detection_sensitivity =
|
||||
DEFAULT_PA_STATIC_SCENE_DETECTION_SENSITIVITY;
|
||||
self->pa.initial_qp = DEFAULT_PA_INITIAL_QP;
|
||||
self->pa.max_qp = DEFAULT_PA_MAX_QP;
|
||||
self->pa.caq_strength = DEFAULT_PA_CAQ_STRENGTH;
|
||||
self->pa.frame_sad = DEFAULT_PA_FRAME_SAD;
|
||||
self->pa.ltr = DEFAULT_PA_LTR;
|
||||
self->pa.lookahead_buffer_depth = DEFAULT_PA_LOOKAHEAD_BUFFER_DEPTH;
|
||||
self->pa.paq_mode = DEFAULT_PA_PAQ_MODE;
|
||||
self->pa.taq_mode = DEFAULT_PA_TAQ_MODE;
|
||||
self->pa.hmqb_mode = DEFAULT_PA_HQMB_MODE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -632,6 +788,53 @@ gst_amf_h265_enc_set_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
update_bool (self, &self->smart_access, value);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
update_bool (self, &self->pre_encode, value);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
update_bool (self, &self->pa.pre_analysis, value);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
update_enum (self, &self->pa.activity_type, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
update_bool (self, &self->pa.scene_change_detection, value);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.scene_change_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
update_bool (self, &self->pa.static_scene_detection, value);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
update_enum (self, &self->pa.static_scene_detection_sensitivity, value);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
update_uint (self, &self->pa.initial_qp, value);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
update_uint (self, &self->pa.max_qp, value);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
update_enum (self, &self->pa.caq_strength, value);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
update_bool (self, &self->pa.frame_sad, value);
|
||||
case PROP_PA_LTR:
|
||||
update_bool (self, &self->pa.ltr, value);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
update_uint (self, &self->pa.lookahead_buffer_depth, value);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
update_enum (self, &self->pa.paq_mode, value);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
update_enum (self, &self->pa.taq_mode, value);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
update_enum (self, &self->pa.hmqb_mode, value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -695,6 +898,54 @@ gst_amf_h265_enc_get_property (GObject * object, guint prop_id,
|
|||
case PROP_SMART_ACCESS:
|
||||
g_value_set_boolean (value, self->smart_access);
|
||||
break;
|
||||
case PROP_PRE_ENCODE:
|
||||
g_value_set_boolean (value, self->pre_encode);
|
||||
break;
|
||||
case PROP_PRE_ANALYSIS:
|
||||
g_value_set_boolean (value, self->pa.pre_analysis);
|
||||
break;
|
||||
case PROP_PA_ACTIVITY_TYPE:
|
||||
g_value_set_enum (value, self->pa.activity_type);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.scene_change_detection);
|
||||
break;
|
||||
case PROP_PA_SCENE_CHANGE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.scene_change_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION:
|
||||
g_value_set_boolean (value, self->pa.static_scene_detection);
|
||||
break;
|
||||
case PROP_PA_STATIC_SCENE_DETECTION_SENSITIVITY:
|
||||
g_value_set_enum (value, self->pa.static_scene_detection_sensitivity);
|
||||
break;
|
||||
case PROP_PA_INITIAL_QP:
|
||||
g_value_set_uint (value, self->pa.initial_qp);
|
||||
break;
|
||||
case PROP_PA_MAX_QP:
|
||||
g_value_set_uint (value, self->pa.max_qp);
|
||||
break;
|
||||
case PROP_PA_CAQ_STRENGTH:
|
||||
g_value_set_enum (value, self->pa.caq_strength);
|
||||
break;
|
||||
case PROP_PA_FRAME_SAD:
|
||||
g_value_set_boolean (value, self->pa.frame_sad);
|
||||
break;
|
||||
case PROP_PA_LTR:
|
||||
g_value_set_boolean (value, self->pa.ltr);
|
||||
break;
|
||||
case PROP_PA_LOOKAHEAD_BUFFER_DEPTH:
|
||||
g_value_set_uint (value, self->pa.lookahead_buffer_depth);
|
||||
break;
|
||||
case PROP_PA_PAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.paq_mode);
|
||||
break;
|
||||
case PROP_PA_TAQ_MODE:
|
||||
g_value_set_enum (value, self->pa.taq_mode);
|
||||
break;
|
||||
case PROP_PA_HQMB_MODE:
|
||||
g_value_set_enum (value, self->pa.hmqb_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1038,6 +1289,33 @@ gst_amf_h265_enc_set_format (GstAmfEncoder * encoder,
|
|||
}
|
||||
}
|
||||
|
||||
if (dev_caps->pre_encode_supported) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_HEVC_PREENCODE_ENABLE,
|
||||
(amf_bool) self->pre_encode);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-encode, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_caps->pre_analysis) {
|
||||
result = comp->SetProperty (AMF_VIDEO_ENCODER_HEVC_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) self->pa.pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to set pre-analysis, result %"
|
||||
GST_AMF_RESULT_FORMAT, GST_AMF_RESULT_ARGS (result));
|
||||
goto error;
|
||||
}
|
||||
if (self->pa.pre_analysis) {
|
||||
result =
|
||||
gst_amf_encoder_set_pre_analysis_options (encoder, comp, &self->pa,
|
||||
&dev_caps->pa_supported);
|
||||
if (result != AMF_OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
result = comp->Init (surface_format, info->width, info->height);
|
||||
if (result != AMF_OK) {
|
||||
GST_ERROR_OBJECT (self, "Failed to init component, result %"
|
||||
|
@ -1277,6 +1555,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 pre_encode_supported;
|
||||
amf_bool smart_access_supported;
|
||||
amf_int32 num_val;
|
||||
std::set < std::string > formats;
|
||||
|
@ -1415,11 +1694,41 @@ 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_PREENCODE_ENABLE,
|
||||
&pre_encode_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.pre_encode_supported = TRUE;
|
||||
|
||||
result = comp->GetProperty (AMF_VIDEO_ENCODER_HEVC_ENABLE_SMART_ACCESS_VIDEO,
|
||||
&smart_access_supported);
|
||||
if (result == AMF_OK)
|
||||
dev_caps.smart_access_supported = TRUE;
|
||||
|
||||
if (dev_caps.pre_analysis) {
|
||||
amf_bool pre_analysis = FALSE;
|
||||
// Store initial pre-analysis value
|
||||
result =
|
||||
comp->GetProperty (AMF_VIDEO_ENCODER_HEVC_PRE_ANALYSIS_ENABLE,
|
||||
&pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to get pre-analysis option");
|
||||
}
|
||||
// We need to enable pre-analysis for checking options availability
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_HEVC_PRE_ANALYSIS_ENABLE,
|
||||
(amf_bool) TRUE);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis option");
|
||||
}
|
||||
gst_amf_encoder_check_pa_supported_options (&dev_caps.pa_supported, comp);
|
||||
result =
|
||||
comp->SetProperty (AMF_VIDEO_ENCODER_HEVC_PRE_ANALYSIS_ENABLE,
|
||||
pre_analysis);
|
||||
if (result != AMF_OK) {
|
||||
GST_WARNING_OBJECT (device, "Failed to set pre-analysis option");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const AMFPropertyInfo *pinfo = nullptr;
|
||||
result = comp->GetPropertyInfo (AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, &pinfo);
|
||||
|
|
Loading…
Reference in a new issue