From fa0911c3f69de258d10c104991c7bad597ef83a8 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Wed, 14 Feb 2018 11:42:55 +0000 Subject: [PATCH] msdk: encoder: register only the required properties The base encoder common properties are not valid for mjpeg encoder where there is no motion compensation or rate control. Delaying the property installation on the base gobject untill the subclass class_init get invoked. https://bugzilla.gnome.org/show_bug.cgi?id=791637 --- sys/msdk/gstmsdkenc.c | 425 +++++++++++++++++++++++++++++---------------- sys/msdk/gstmsdkenc.h | 37 ++++ sys/msdk/gstmsdkh264enc.c | 24 +-- sys/msdk/gstmsdkh265enc.c | 27 +++ sys/msdk/gstmsdkmpeg2enc.c | 27 +++ sys/msdk/gstmsdkvp8enc.c | 27 +++ 6 files changed, 400 insertions(+), 167 deletions(-) diff --git a/sys/msdk/gstmsdkenc.c b/sys/msdk/gstmsdkenc.c index 79b47fc..b2e5a5a 100644 --- a/sys/msdk/gstmsdkenc.c +++ b/sys/msdk/gstmsdkenc.c @@ -82,23 +82,6 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", "interlace-mode = (string) progressive") ); -enum -{ - PROP_0, - PROP_HARDWARE, - PROP_ASYNC_DEPTH, - PROP_TARGET_USAGE, - PROP_RATE_CONTROL, - PROP_BITRATE, - PROP_QPI, - PROP_QPP, - PROP_QPB, - PROP_GOP_SIZE, - PROP_REF_FRAMES, - PROP_I_FRAMES, - PROP_B_FRAMES -}; - #define PROP_HARDWARE_DEFAULT TRUE #define PROP_ASYNC_DEPTH_DEFAULT 4 #define PROP_TARGET_USAGE_DEFAULT (MFX_TARGETUSAGE_BALANCED) @@ -1261,248 +1244,386 @@ gst_msdkenc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query) query); } + static void -gst_msdkenc_set_property (GObject * object, guint prop_id, const GValue * value, - GParamSpec * pspec) +gst_msdkenc_finalize (GObject * object) +{ + GstMsdkEnc *thiz = GST_MSDKENC (object); + + if (thiz->input_state) + gst_video_codec_state_unref (thiz->input_state); + thiz->input_state = NULL; + + gst_object_replace ((GstObject **) & thiz->msdk_pool, NULL); + gst_object_replace ((GstObject **) & thiz->msdk_converted_pool, NULL); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gst_msdkenc_class_init (GstMsdkEncClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *element_class; + GstVideoEncoderClass *gstencoder_class; + + gobject_class = G_OBJECT_CLASS (klass); + element_class = GST_ELEMENT_CLASS (klass); + gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass); + + gobject_class->finalize = gst_msdkenc_finalize; + + element_class->set_context = gst_msdkenc_set_context; + + gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkenc_set_format); + gstencoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkenc_handle_frame); + gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkenc_start); + gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_msdkenc_stop); + gstencoder_class->flush = GST_DEBUG_FUNCPTR (gst_msdkenc_flush); + gstencoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkenc_finish); + gstencoder_class->propose_allocation = + GST_DEBUG_FUNCPTR (gst_msdkenc_propose_allocation); + + gst_element_class_add_static_pad_template (element_class, &sink_factory); +} + +static void +gst_msdkenc_init (GstMsdkEnc * thiz) +{ + thiz->hardware = PROP_HARDWARE_DEFAULT; + thiz->async_depth = PROP_ASYNC_DEPTH_DEFAULT; + thiz->target_usage = PROP_TARGET_USAGE_DEFAULT; + thiz->rate_control = PROP_RATE_CONTROL_DEFAULT; + thiz->bitrate = PROP_BITRATE_DEFAULT; + thiz->qpi = PROP_QPI_DEFAULT; + thiz->qpp = PROP_QPP_DEFAULT; + thiz->qpb = PROP_QPB_DEFAULT; + thiz->gop_size = PROP_GOP_SIZE_DEFAULT; + thiz->ref_frames = PROP_REF_FRAMES_DEFAULT; + thiz->i_frames = PROP_I_FRAMES_DEFAULT; + thiz->b_frames = PROP_B_FRAMES_DEFAULT; +} + +/* gst_msdkenc_set_common_property: + * + * This is a helper function to set the common property + * of base encoder from subclass implementation. + */ +gboolean +gst_msdkenc_set_common_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { GstMsdkEnc *thiz = GST_MSDKENC (object); GstState state; + gboolean ret = TRUE; GST_OBJECT_LOCK (thiz); state = GST_STATE (thiz); if ((state != GST_STATE_READY && state != GST_STATE_NULL) && - !(pspec->flags & GST_PARAM_MUTABLE_PLAYING)) + !(pspec->flags & GST_PARAM_MUTABLE_PLAYING)) { + ret = FALSE; goto wrong_state; + } switch (prop_id) { - case PROP_HARDWARE: + case GST_MSDKENC_PROP_HARDWARE: thiz->hardware = g_value_get_boolean (value); break; - case PROP_ASYNC_DEPTH: + case GST_MSDKENC_PROP_ASYNC_DEPTH: thiz->async_depth = g_value_get_uint (value); break; - case PROP_TARGET_USAGE: + case GST_MSDKENC_PROP_TARGET_USAGE: thiz->target_usage = g_value_get_uint (value); break; - case PROP_RATE_CONTROL: + case GST_MSDKENC_PROP_RATE_CONTROL: thiz->rate_control = g_value_get_enum (value); break; - case PROP_BITRATE: + case GST_MSDKENC_PROP_BITRATE: thiz->bitrate = g_value_get_uint (value); thiz->reconfig = TRUE; break; - case PROP_QPI: + case GST_MSDKENC_PROP_MAX_FRAME_SIZE: + thiz->max_frame_size = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_MAX_VBV_BITRATE: + thiz->max_vbv_bitrate = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_AVBR_ACCURACY: + thiz->accuracy = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_AVBR_CONVERGENCE: + thiz->convergence = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_RC_LOOKAHEAD_DEPTH: + thiz->lookahead_depth = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_QPI: thiz->qpi = g_value_get_uint (value); break; - case PROP_QPP: + case GST_MSDKENC_PROP_QPP: thiz->qpp = g_value_get_uint (value); break; - case PROP_QPB: + case GST_MSDKENC_PROP_QPB: thiz->qpb = g_value_get_uint (value); break; - case PROP_GOP_SIZE: + case GST_MSDKENC_PROP_GOP_SIZE: thiz->gop_size = g_value_get_uint (value); break; - case PROP_REF_FRAMES: + case GST_MSDKENC_PROP_REF_FRAMES: thiz->ref_frames = g_value_get_uint (value); break; - case PROP_I_FRAMES: + case GST_MSDKENC_PROP_I_FRAMES: thiz->i_frames = g_value_get_uint (value); break; - case PROP_B_FRAMES: + case GST_MSDKENC_PROP_B_FRAMES: thiz->b_frames = g_value_get_uint (value); break; + case GST_MSDKENC_PROP_NUM_SLICES: + thiz->num_slices = g_value_get_uint (value); + break; + case GST_MSDKENC_PROP_MBBRC: + thiz->mbbrc = g_value_get_enum (value); + break; + case GST_MSDKENC_PROP_ADAPTIVE_I: + thiz->adaptive_i = g_value_get_enum (value); + break; + case GST_MSDKENC_PROP_ADAPTIVE_B: + thiz->adaptive_b = g_value_get_enum (value); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + ret = FALSE; break; } GST_OBJECT_UNLOCK (thiz); - return; + return ret; /* ERROR */ wrong_state: { GST_WARNING_OBJECT (thiz, "setting property in wrong state"); GST_OBJECT_UNLOCK (thiz); + return ret; } } -static void -gst_msdkenc_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) +/* gst_msdkenc_get_common_property: + * + * This is a helper function to get the common property + * of base encoder from subclass implementation. + */ +gboolean +gst_msdkenc_get_common_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { GstMsdkEnc *thiz = GST_MSDKENC (object); + gboolean ret = TRUE; GST_OBJECT_LOCK (thiz); switch (prop_id) { - case PROP_HARDWARE: + case GST_MSDKENC_PROP_HARDWARE: g_value_set_boolean (value, thiz->hardware); break; - case PROP_ASYNC_DEPTH: + case GST_MSDKENC_PROP_ASYNC_DEPTH: g_value_set_uint (value, thiz->async_depth); break; - case PROP_TARGET_USAGE: + case GST_MSDKENC_PROP_TARGET_USAGE: g_value_set_uint (value, thiz->target_usage); break; - case PROP_RATE_CONTROL: + case GST_MSDKENC_PROP_RATE_CONTROL: g_value_set_enum (value, thiz->rate_control); break; - case PROP_BITRATE: + case GST_MSDKENC_PROP_BITRATE: g_value_set_uint (value, thiz->bitrate); break; - case PROP_QPI: + case GST_MSDKENC_PROP_MAX_FRAME_SIZE: + g_value_set_uint (value, thiz->max_frame_size); + break; + case GST_MSDKENC_PROP_MAX_VBV_BITRATE: + g_value_set_uint (value, thiz->max_vbv_bitrate); + break; + case GST_MSDKENC_PROP_AVBR_ACCURACY: + g_value_set_uint (value, thiz->accuracy); + break; + case GST_MSDKENC_PROP_AVBR_CONVERGENCE: + g_value_set_uint (value, thiz->convergence); + break; + case GST_MSDKENC_PROP_RC_LOOKAHEAD_DEPTH: + g_value_set_uint (value, thiz->lookahead_depth); + break; + case GST_MSDKENC_PROP_QPI: g_value_set_uint (value, thiz->qpi); break; - case PROP_QPP: + case GST_MSDKENC_PROP_QPP: g_value_set_uint (value, thiz->qpp); break; - case PROP_QPB: + case GST_MSDKENC_PROP_QPB: g_value_set_uint (value, thiz->qpb); break; - case PROP_GOP_SIZE: + case GST_MSDKENC_PROP_GOP_SIZE: g_value_set_uint (value, thiz->gop_size); break; - case PROP_REF_FRAMES: + case GST_MSDKENC_PROP_REF_FRAMES: g_value_set_uint (value, thiz->ref_frames); break; - case PROP_I_FRAMES: + case GST_MSDKENC_PROP_I_FRAMES: g_value_set_uint (value, thiz->i_frames); break; - case PROP_B_FRAMES: + case GST_MSDKENC_PROP_B_FRAMES: g_value_set_uint (value, thiz->b_frames); break; + case GST_MSDKENC_PROP_NUM_SLICES: + g_value_set_uint (value, thiz->num_slices); + break; + case GST_MSDKENC_PROP_MBBRC: + g_value_set_enum (value, thiz->mbbrc); + break; + case GST_MSDKENC_PROP_ADAPTIVE_I: + g_value_set_enum (value, thiz->adaptive_i); + break; + case GST_MSDKENC_PROP_ADAPTIVE_B: + g_value_set_enum (value, thiz->adaptive_b); + break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + ret = FALSE; break; } GST_OBJECT_UNLOCK (thiz); + return ret; } -static void -gst_msdkenc_finalize (GObject * object) -{ - GstMsdkEnc *thiz = GST_MSDKENC (object); - - if (thiz->input_state) - gst_video_codec_state_unref (thiz->input_state); - thiz->input_state = NULL; - - gst_object_replace ((GstObject **) & thiz->msdk_pool, NULL); - gst_object_replace ((GstObject **) & thiz->msdk_converted_pool, NULL); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_msdkenc_class_init (GstMsdkEncClass * klass) +/* gst_msdkenc_install_common_properties: + * @thiz: a #GstMsdkEnc + * + * This is a helper function to install common properties + * of base encoder from subclass implementation. + * Encoders like jpeg do't require all the common properties + * and they can avoid installing it into base gobject. + */ +void +gst_msdkenc_install_common_properties (GstMsdkEncClass * klass) { - GObjectClass *gobject_class; - GstElementClass *element_class; - GstVideoEncoderClass *gstencoder_class; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GParamSpec *obj_properties[GST_MSDKENC_PROP_MAX] = { NULL, }; - gobject_class = G_OBJECT_CLASS (klass); - element_class = GST_ELEMENT_CLASS (klass); - gstencoder_class = GST_VIDEO_ENCODER_CLASS (klass); - - gobject_class->set_property = gst_msdkenc_set_property; - gobject_class->get_property = gst_msdkenc_get_property; - gobject_class->finalize = gst_msdkenc_finalize; - - element_class->set_context = gst_msdkenc_set_context; - - gstencoder_class->set_format = GST_DEBUG_FUNCPTR (gst_msdkenc_set_format); - gstencoder_class->handle_frame = GST_DEBUG_FUNCPTR (gst_msdkenc_handle_frame); - gstencoder_class->start = GST_DEBUG_FUNCPTR (gst_msdkenc_start); - gstencoder_class->stop = GST_DEBUG_FUNCPTR (gst_msdkenc_stop); - gstencoder_class->flush = GST_DEBUG_FUNCPTR (gst_msdkenc_flush); - gstencoder_class->finish = GST_DEBUG_FUNCPTR (gst_msdkenc_finish); - gstencoder_class->propose_allocation = - GST_DEBUG_FUNCPTR (gst_msdkenc_propose_allocation); - - g_object_class_install_property (gobject_class, PROP_HARDWARE, + obj_properties[GST_MSDKENC_PROP_HARDWARE] = g_param_spec_boolean ("hardware", "Hardware", "Enable hardware encoders", - PROP_HARDWARE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + PROP_HARDWARE_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_ASYNC_DEPTH, + obj_properties[GST_MSDKENC_PROP_ASYNC_DEPTH] = g_param_spec_uint ("async-depth", "Async Depth", - "Depth of asynchronous pipeline", - 1, 20, PROP_ASYNC_DEPTH_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Depth of asynchronous pipeline", + 1, 20, PROP_ASYNC_DEPTH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_TARGET_USAGE, + obj_properties[GST_MSDKENC_PROP_TARGET_USAGE] = g_param_spec_uint ("target-usage", "Target Usage", - "1: Best quality, 4: Balanced, 7: Best speed", - 1, 7, PROP_TARGET_USAGE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "1: Best quality, 4: Balanced, 7: Best speed", + 1, 7, PROP_TARGET_USAGE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_RATE_CONTROL, + obj_properties[GST_MSDKENC_PROP_RATE_CONTROL] = g_param_spec_enum ("rate-control", "Rate Control", - "Rate control method", GST_MSDKENC_RATE_CONTROL_TYPE, - PROP_RATE_CONTROL_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Rate control method", GST_MSDKENC_RATE_CONTROL_TYPE, + PROP_RATE_CONTROL_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_BITRATE, + obj_properties[GST_MSDKENC_PROP_BITRATE] = g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1, - 2000 * 1024, PROP_BITRATE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | - GST_PARAM_MUTABLE_PLAYING)); - - g_object_class_install_property (gobject_class, PROP_QPI, + 2000 * 1024, PROP_BITRATE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING); + + obj_properties[GST_MSDKENC_PROP_MAX_FRAME_SIZE] = + g_param_spec_uint ("max-frame-size", "Max Frame Size", + "Maximum possible size (in kb) of any compressed frames (0: auto-calculate)", + 0, G_MAXUINT16, PROP_MAX_FRAME_SIZE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_MAX_VBV_BITRATE] = + g_param_spec_uint ("max-vbv-bitrate", "Max VBV Bitrate", + "Maximum bitrate(kbit/sec) at which data enters Video Buffering Verifier (0: auto-calculate)", + 0, G_MAXUINT16, PROP_MAX_VBV_BITRATE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_AVBR_ACCURACY] = + g_param_spec_uint ("accuracy", "Accuracy", "The AVBR Accuracy in " + "the unit of tenth of percent", 0, G_MAXUINT16, + PROP_AVBR_ACCURACY_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_AVBR_CONVERGENCE] = + g_param_spec_uint ("convergence", "Convergence", + "The AVBR Convergence in the unit of 100 frames", 0, G_MAXUINT16, + PROP_AVBR_CONVERGENCE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_RC_LOOKAHEAD_DEPTH] = + g_param_spec_uint ("rc-lookahead", "Look-ahead depth", + "Number of frames to look ahead for Rate control", 10, 100, + PROP_RC_LOOKAHEAD_DEPTH_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_QPI] = g_param_spec_uint ("qpi", "QPI", - "Constant quantizer for I frames (0 unlimited)", - 0, 51, PROP_QPI_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Constant quantizer for I frames (0 unlimited)", + 0, 51, PROP_QPI_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_QPP, + obj_properties[GST_MSDKENC_PROP_QPP] = g_param_spec_uint ("qpp", "QPP", - "Constant quantizer for P frames (0 unlimited)", - 0, 51, PROP_QPP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Constant quantizer for P frames (0 unlimited)", + 0, 51, PROP_QPP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_QPB, + obj_properties[GST_MSDKENC_PROP_QPB] = g_param_spec_uint ("qpb", "QPB", - "Constant quantizer for B frames (0 unlimited)", - 0, 51, PROP_QPB_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Constant quantizer for B frames (0 unlimited)", + 0, 51, PROP_QPB_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_GOP_SIZE, + obj_properties[GST_MSDKENC_PROP_GOP_SIZE] = g_param_spec_uint ("gop-size", "GOP Size", "GOP Size", 0, - G_MAXINT, PROP_GOP_SIZE_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + G_MAXINT, PROP_GOP_SIZE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_REF_FRAMES, + obj_properties[GST_MSDKENC_PROP_REF_FRAMES] = g_param_spec_uint ("ref-frames", "Reference Frames", - "Number of reference frames", - 0, G_MAXINT, PROP_REF_FRAMES_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Number of reference frames", + 0, G_MAXINT, PROP_REF_FRAMES_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_I_FRAMES, + obj_properties[GST_MSDKENC_PROP_I_FRAMES] = g_param_spec_uint ("i-frames", "I Frames", - "Number of I frames between IDR frames", - 0, G_MAXINT, PROP_I_FRAMES_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Number of I frames between IDR frames", + 0, G_MAXINT, PROP_I_FRAMES_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (gobject_class, PROP_B_FRAMES, + obj_properties[GST_MSDKENC_PROP_B_FRAMES] = g_param_spec_uint ("b-frames", "B Frames", - "Number of B frames between I and P frames", - 0, G_MAXINT, PROP_B_FRAMES_DEFAULT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - - gst_element_class_add_static_pad_template (element_class, &sink_factory); -} - -static void -gst_msdkenc_init (GstMsdkEnc * thiz) -{ - thiz->hardware = PROP_HARDWARE_DEFAULT; - thiz->async_depth = PROP_ASYNC_DEPTH_DEFAULT; - thiz->target_usage = PROP_TARGET_USAGE_DEFAULT; - thiz->rate_control = PROP_RATE_CONTROL_DEFAULT; - thiz->bitrate = PROP_BITRATE_DEFAULT; - thiz->qpi = PROP_QPI_DEFAULT; - thiz->qpp = PROP_QPP_DEFAULT; - thiz->qpb = PROP_QPB_DEFAULT; - thiz->gop_size = PROP_GOP_SIZE_DEFAULT; - thiz->ref_frames = PROP_REF_FRAMES_DEFAULT; - thiz->i_frames = PROP_I_FRAMES_DEFAULT; - thiz->b_frames = PROP_B_FRAMES_DEFAULT; + "Number of B frames between I and P frames", + 0, G_MAXINT, PROP_B_FRAMES_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_NUM_SLICES] = + g_param_spec_uint ("num-slices", "Number of Slices", + "Number of slices per frame, Zero tells the encoder to " + "choose any slice partitioning allowed by the codec standard", + 0, G_MAXINT, PROP_NUM_SLICES_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_MBBRC] = + g_param_spec_enum ("mbbrc", "MB level bitrate control", + "Macroblock level bitrate control", + gst_msdkenc_mbbrc_get_type (), + PROP_MBBRC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_ADAPTIVE_I] = + g_param_spec_enum ("i-adapt", "Adaptive I-Frame Insertion", + "Adaptive I-Frame Insertion control", + gst_msdkenc_adaptive_i_get_type (), + PROP_ADAPTIVE_I_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_properties[GST_MSDKENC_PROP_ADAPTIVE_B] = + g_param_spec_enum ("b-adapt", "Adaptive B-Frame Insertion", + "Adaptive B-Frame Insertion control", + gst_msdkenc_adaptive_b_get_type (), + PROP_ADAPTIVE_B_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, + GST_MSDKENC_PROP_MAX, obj_properties); } diff --git a/sys/msdk/gstmsdkenc.h b/sys/msdk/gstmsdkenc.h index d591585..6813099 100644 --- a/sys/msdk/gstmsdkenc.h +++ b/sys/msdk/gstmsdkenc.h @@ -58,6 +58,33 @@ typedef struct _GstMsdkEnc GstMsdkEnc; typedef struct _GstMsdkEncClass GstMsdkEncClass; typedef struct _MsdkEncTask MsdkEncTask; +enum +{ + GST_MSDKENC_PROP_0, + GST_MSDKENC_PROP_HARDWARE, + GST_MSDKENC_PROP_ASYNC_DEPTH, + GST_MSDKENC_PROP_TARGET_USAGE, + GST_MSDKENC_PROP_RATE_CONTROL, + GST_MSDKENC_PROP_BITRATE, + GST_MSDKENC_PROP_MAX_FRAME_SIZE, + GST_MSDKENC_PROP_MAX_VBV_BITRATE, + GST_MSDKENC_PROP_AVBR_ACCURACY, + GST_MSDKENC_PROP_AVBR_CONVERGENCE, + GST_MSDKENC_PROP_RC_LOOKAHEAD_DEPTH, + GST_MSDKENC_PROP_QPI, + GST_MSDKENC_PROP_QPP, + GST_MSDKENC_PROP_QPB, + GST_MSDKENC_PROP_GOP_SIZE, + GST_MSDKENC_PROP_REF_FRAMES, + GST_MSDKENC_PROP_I_FRAMES, + GST_MSDKENC_PROP_B_FRAMES, + GST_MSDKENC_PROP_NUM_SLICES, + GST_MSDKENC_PROP_MBBRC, + GST_MSDKENC_PROP_ADAPTIVE_I, + GST_MSDKENC_PROP_ADAPTIVE_B, + GST_MSDKENC_PROP_MAX, +}; + struct _GstMsdkEnc { GstVideoEncoder element; @@ -133,6 +160,16 @@ GType gst_msdkenc_get_type (void); void gst_msdkenc_add_extra_param (GstMsdkEnc * thiz, mfxExtBuffer * param); +void +gst_msdkenc_install_common_properties (GstMsdkEncClass *encoder_class); + +gboolean +gst_msdkenc_set_common_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +gboolean +gst_msdkenc_get_common_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + G_END_DECLS #endif /* __GST_MSDKENC_H__ */ diff --git a/sys/msdk/gstmsdkh264enc.c b/sys/msdk/gstmsdkh264enc.c index 8851c89..7e0904b 100644 --- a/sys/msdk/gstmsdkh264enc.c +++ b/sys/msdk/gstmsdkh264enc.c @@ -43,8 +43,7 @@ GST_DEBUG_CATEGORY_EXTERN (gst_msdkh264enc_debug); enum { - PROP_0, - PROP_CABAC, + PROP_CABAC = GST_MSDKENC_PROP_MAX, PROP_LOW_POWER, PROP_FRAME_PACKING, }; @@ -382,14 +381,11 @@ gst_msdkh264enc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object); - GstState state; - GST_OBJECT_LOCK (thiz); + if (gst_msdkenc_set_common_property (object, prop_id, value, pspec)) + return; - state = GST_STATE (thiz); - if ((state != GST_STATE_READY && state != GST_STATE_NULL) && - !(pspec->flags & GST_PARAM_MUTABLE_PLAYING)) - goto wrong_state; + GST_OBJECT_LOCK (thiz); switch (prop_id) { case PROP_CABAC: @@ -407,13 +403,6 @@ gst_msdkh264enc_set_property (GObject * object, guint prop_id, } GST_OBJECT_UNLOCK (thiz); return; - - /* ERROR */ -wrong_state: - { - GST_WARNING_OBJECT (thiz, "setting property in wrong state"); - GST_OBJECT_UNLOCK (thiz); - } } static void @@ -422,6 +411,9 @@ gst_msdkh264enc_get_property (GObject * object, guint prop_id, GValue * value, { GstMsdkH264Enc *thiz = GST_MSDKH264ENC (object); + if (gst_msdkenc_get_common_property (object, prop_id, value, pspec)) + return; + GST_OBJECT_LOCK (thiz); switch (prop_id) { case PROP_CABAC: @@ -462,6 +454,8 @@ gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass) encoder_class->configure = gst_msdkh264enc_configure; encoder_class->set_src_caps = gst_msdkh264enc_set_src_caps; + gst_msdkenc_install_common_properties (encoder_class); + g_object_class_install_property (gobject_class, PROP_CABAC, g_param_spec_boolean ("cabac", "CABAC", "Enable CABAC entropy coding", PROP_CABAC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); diff --git a/sys/msdk/gstmsdkh265enc.c b/sys/msdk/gstmsdkh265enc.c index 525c3d6..d0361e4 100644 --- a/sys/msdk/gstmsdkh265enc.c +++ b/sys/msdk/gstmsdkh265enc.c @@ -156,18 +156,45 @@ gst_msdkh265enc_set_src_caps (GstMsdkEnc * encoder) } static void +gst_msdkh265enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstMsdkH265Enc *thiz = GST_MSDKH265ENC (object); + + if (!gst_msdkenc_set_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to set common encode property"); +} + +static void +gst_msdkh265enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstMsdkH265Enc *thiz = GST_MSDKH265ENC (object); + + if (!gst_msdkenc_get_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to get common encode property"); +} + +static void gst_msdkh265enc_class_init (GstMsdkH265EncClass * klass) { + GObjectClass *gobject_class; GstElementClass *element_class; GstMsdkEncClass *encoder_class; + gobject_class = G_OBJECT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass); encoder_class = GST_MSDKENC_CLASS (klass); + gobject_class->set_property = gst_msdkh265enc_set_property; + gobject_class->get_property = gst_msdkh265enc_get_property; + encoder_class->set_format = gst_msdkh265enc_set_format; encoder_class->configure = gst_msdkh265enc_configure; encoder_class->set_src_caps = gst_msdkh265enc_set_src_caps; + gst_msdkenc_install_common_properties (encoder_class); + gst_element_class_set_static_metadata (element_class, "Intel MSDK H265 encoder", "Codec/Encoder/Video", diff --git a/sys/msdk/gstmsdkmpeg2enc.c b/sys/msdk/gstmsdkmpeg2enc.c index c81c1ed..948096e 100644 --- a/sys/msdk/gstmsdkmpeg2enc.c +++ b/sys/msdk/gstmsdkmpeg2enc.c @@ -149,18 +149,45 @@ gst_msdkmpeg2enc_set_src_caps (GstMsdkEnc * encoder) } static void +gst_msdkmpeg2enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstMsdkMPEG2Enc *thiz = GST_MSDKMPEG2ENC (object); + + if (!gst_msdkenc_set_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to set common encode property"); +} + +static void +gst_msdkmpeg2enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstMsdkMPEG2Enc *thiz = GST_MSDKMPEG2ENC (object); + + if (!gst_msdkenc_get_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to get common encode property"); +} + +static void gst_msdkmpeg2enc_class_init (GstMsdkMPEG2EncClass * klass) { + GObjectClass *gobject_class; GstElementClass *element_class; GstMsdkEncClass *encoder_class; + gobject_class = G_OBJECT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass); encoder_class = GST_MSDKENC_CLASS (klass); + gobject_class->set_property = gst_msdkmpeg2enc_set_property; + gobject_class->get_property = gst_msdkmpeg2enc_get_property; + encoder_class->set_format = gst_msdkmpeg2enc_set_format; encoder_class->configure = gst_msdkmpeg2enc_configure; encoder_class->set_src_caps = gst_msdkmpeg2enc_set_src_caps; + gst_msdkenc_install_common_properties (encoder_class); + gst_element_class_set_static_metadata (element_class, "Intel MSDK MPEG2 encoder", "Codec/Encoder/Video", diff --git a/sys/msdk/gstmsdkvp8enc.c b/sys/msdk/gstmsdkvp8enc.c index e42eb9d..c4a4ec0 100644 --- a/sys/msdk/gstmsdkvp8enc.c +++ b/sys/msdk/gstmsdkvp8enc.c @@ -175,18 +175,45 @@ gst_msdkvp8enc_set_src_caps (GstMsdkEnc * encoder) } static void +gst_msdkvp8enc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstMsdkVP8Enc *thiz = GST_MSDKVP8ENC (object); + + if (!gst_msdkenc_set_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to set common encode property"); +} + +static void +gst_msdkvp8enc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstMsdkVP8Enc *thiz = GST_MSDKVP8ENC (object); + + if (!gst_msdkenc_get_common_property (object, prop_id, value, pspec)) + GST_WARNING_OBJECT (thiz, "Failed to get common encode property"); +} + +static void gst_msdkvp8enc_class_init (GstMsdkVP8EncClass * klass) { + GObjectClass *gobject_class; GstElementClass *element_class; GstMsdkEncClass *encoder_class; + gobject_class = G_OBJECT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass); encoder_class = GST_MSDKENC_CLASS (klass); + gobject_class->set_property = gst_msdkvp8enc_set_property; + gobject_class->get_property = gst_msdkvp8enc_get_property; + encoder_class->set_format = gst_msdkvp8enc_set_format; encoder_class->configure = gst_msdkvp8enc_configure; encoder_class->set_src_caps = gst_msdkvp8enc_set_src_caps; + gst_msdkenc_install_common_properties (encoder_class); + gst_element_class_set_static_metadata (element_class, "Intel MSDK VP8 encoder", "Codec/Encoder/Video", -- 2.7.4