summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@intel.com>2021-07-26 16:09:19 +0800
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2021-09-13 06:37:28 +0000
commit3c975ed918808d7d38b1b7a045f679c15b088262 (patch)
treefc6baa3a271bc4f534b642665d783b6cf4c71559 /gst-libs
parenta61d038cb67c9384d06da7a7d5e669f3e10ee31a (diff)
downloadgstreamer-plugins-bad-3c975ed918808d7d38b1b7a045f679c15b088262.tar.gz
codecs: h264dec: Add a compliance property to control behavior.
Some features such as the low-latency DPB bumping and mapping the baseline profile as the constrained-baseline profile do not conform to the H264 offical spec. But in practice, they are very useful and are widely needed. We add this compliance property to control the behavior of the decoder, make it fit more requirement. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2432>
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/codecs/gsth264decoder.c98
-rw-r--r--gst-libs/gst/codecs/gsth264decoder.h44
2 files changed, 142 insertions, 0 deletions
diff --git a/gst-libs/gst/codecs/gsth264decoder.c b/gst-libs/gst/codecs/gsth264decoder.c
index 263289688..2ac022b35 100644
--- a/gst-libs/gst/codecs/gsth264decoder.c
+++ b/gst-libs/gst/codecs/gsth264decoder.c
@@ -80,6 +80,8 @@ typedef enum
struct _GstH264DecoderPrivate
{
+ GstH264DecoderCompliance compliance;
+
gint width, height;
/* input codec_data, if any */
@@ -210,6 +212,84 @@ static GstH264Picture *gst_h264_decoder_new_field_picture (GstH264Decoder *
static void
gst_h264_decoder_clear_output_frame (GstH264DecoderOutputFrame * output_frame);
+enum
+{
+ PROP_0,
+ PROP_COMPLIANCE,
+};
+
+/**
+ * gst_h264_decoder_compliance_get_type:
+ *
+ * Get the compliance type of the h264 decoder.
+ *
+ * Since: 1.20
+ */
+GType
+gst_h264_decoder_compliance_get_type (void)
+{
+ static gsize h264_decoder_compliance_type = 0;
+ static const GEnumValue compliances[] = {
+ {GST_H264_DECODER_COMPLIANCE_AUTO, "GST_H264_DECODER_COMPLIANCE_AUTO",
+ "auto"},
+ {GST_H264_DECODER_COMPLIANCE_STRICT, "GST_H264_DECODER_COMPLIANCE_STRICT",
+ "strict"},
+ {GST_H264_DECODER_COMPLIANCE_NORMAL, "GST_H264_DECODER_COMPLIANCE_NORMAL",
+ "normal"},
+ {GST_H264_DECODER_COMPLIANCE_FLEXIBLE,
+ "GST_H264_DECODER_COMPLIANCE_FLEXIBLE", "flexible"},
+ {0, NULL, NULL},
+ };
+
+
+ if (g_once_init_enter (&h264_decoder_compliance_type)) {
+ GType _type;
+
+ _type = g_enum_register_static ("GstH264DecoderCompliance", compliances);
+ g_once_init_leave (&h264_decoder_compliance_type, _type);
+ }
+
+ return (GType) h264_decoder_compliance_type;
+}
+
+static void
+gst_h264_decoder_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstH264Decoder *self = GST_H264_DECODER (object);
+ GstH264DecoderPrivate *priv = self->priv;
+
+ switch (property_id) {
+ case PROP_COMPLIANCE:
+ GST_OBJECT_LOCK (self);
+ g_value_set_enum (value, priv->compliance);
+ GST_OBJECT_UNLOCK (self);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_h264_decoder_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstH264Decoder *self = GST_H264_DECODER (object);
+ GstH264DecoderPrivate *priv = self->priv;
+
+ switch (property_id) {
+ case PROP_COMPLIANCE:
+ GST_OBJECT_LOCK (self);
+ priv->compliance = g_value_get_enum (value);
+ GST_OBJECT_UNLOCK (self);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
static void
gst_h264_decoder_class_init (GstH264DecoderClass * klass)
{
@@ -217,6 +297,8 @@ gst_h264_decoder_class_init (GstH264DecoderClass * klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = GST_DEBUG_FUNCPTR (gst_h264_decoder_finalize);
+ object_class->get_property = gst_h264_decoder_get_property;
+ object_class->set_property = gst_h264_decoder_set_property;
decoder_class->start = GST_DEBUG_FUNCPTR (gst_h264_decoder_start);
decoder_class->stop = GST_DEBUG_FUNCPTR (gst_h264_decoder_stop);
@@ -226,6 +308,22 @@ gst_h264_decoder_class_init (GstH264DecoderClass * klass)
decoder_class->drain = GST_DEBUG_FUNCPTR (gst_h264_decoder_drain);
decoder_class->handle_frame =
GST_DEBUG_FUNCPTR (gst_h264_decoder_handle_frame);
+
+ /**
+ * GstH264Decoder:compliance:
+ *
+ * The compliance controls the behavior of the decoder to handle some
+ * subtle cases and contexts, such as the low-latency DPB bumping or
+ * mapping the baseline profile as the constrained-baseline profile,
+ * etc.
+ *
+ * Since: 1.20
+ */
+ g_object_class_install_property (object_class, PROP_COMPLIANCE,
+ g_param_spec_enum ("compliance", "Decoder Compliance",
+ "The decoder's behavior in compliance with the h264 spec.",
+ GST_TYPE_H264_DECODER_COMPLIANCE, GST_H264_DECODER_COMPLIANCE_AUTO,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
}
static void
diff --git a/gst-libs/gst/codecs/gsth264decoder.h b/gst-libs/gst/codecs/gsth264decoder.h
index 8015659f7..710b6c9fc 100644
--- a/gst-libs/gst/codecs/gsth264decoder.h
+++ b/gst-libs/gst/codecs/gsth264decoder.h
@@ -36,6 +36,49 @@ G_BEGIN_DECLS
#define GST_IS_H264_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_H264_DECODER))
#define GST_H264_DECODER_CAST(obj) ((GstH264Decoder*)obj)
+/**
+ * GstH264DecoderCompliance:
+ * @GST_H264_DECODER_COMPLIANCE_AUTO: The decoder behavior is
+ * automatically choosen.
+ * @GST_H264_DECODER_COMPLIANCE_STRICT: The decoder behavior strictly
+ * conforms to the SPEC. All the decoder behaviors conform to the
+ * SPEC, not including any nonstandard behavior which is not
+ * mentioned in the SPEC.
+ * @GST_H264_DECODER_COMPLIANCE_NORMAL: The decoder behavior normally
+ * conforms to the SPEC. Most behaviors conform to the SPEC but
+ * including some nonstandard features which are widely used or
+ * often used in the industry practice. This meets the request of
+ * real streams and usages, but may not 100% conform to the
+ * SPEC. It has very low risk. E.g., we will output pictures
+ * without waiting DPB being full for the lower latency, which may
+ * cause B frame disorder when there are reference frames with
+ * smaller POC after it in decoder order. And the baseline profile
+ * may be mapped to the constrained-baseline profile, but it may
+ * have problems when a real baseline stream comes with FMO or
+ * ASO.
+ * @GST_H264_DECODER_COMPLIANCE_FLEXIBLE: The decoder behavior
+ * flexibly conforms to the SPEC. It uses the nonstandard features
+ * more aggressively in order to get better performance(for
+ * example, lower latency). It may change the result of the
+ * decoder and should be used carefully. Besides including all
+ * risks in *normal* mode, it has more risks, such as frames
+ * disorder when reference frames POC decrease in decoder order.
+ *
+ * Since: 1.20
+ */
+typedef enum
+{
+ GST_H264_DECODER_COMPLIANCE_AUTO,
+ GST_H264_DECODER_COMPLIANCE_STRICT,
+ GST_H264_DECODER_COMPLIANCE_NORMAL,
+ GST_H264_DECODER_COMPLIANCE_FLEXIBLE
+} GstH264DecoderCompliance;
+
+#define GST_TYPE_H264_DECODER_COMPLIANCE (gst_h264_decoder_compliance_get_type())
+
+GST_CODECS_API
+GType gst_h264_decoder_compliance_get_type (void);
+
typedef struct _GstH264Decoder GstH264Decoder;
typedef struct _GstH264DecoderClass GstH264DecoderClass;
typedef struct _GstH264DecoderPrivate GstH264DecoderPrivate;
@@ -65,6 +108,7 @@ struct _GstH264Decoder
*/
struct _GstH264DecoderClass
{
+ /*< private >*/
GstVideoDecoderClass parent_class;
/**