mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
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>
This commit is contained in:
parent
a61d038cb6
commit
3c975ed918
2 changed files with 142 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue