From cf2cd20ba0fcf37c4a9d35cfe4203c5384c2fe0a Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 13 Jun 2023 03:36:45 +0900 Subject: [PATCH] nvdecoder: Add max-display-delay property The same as in old nvdec implementation so that user can control the number of delayed output frames. Part-of: --- .../sys/nvcodec/gstnvav1dec.cpp | 28 +++++++++++++++++++ .../sys/nvcodec/gstnvh264dec.cpp | 28 +++++++++++++++++++ .../sys/nvcodec/gstnvh265dec.cpp | 28 +++++++++++++++++++ .../sys/nvcodec/gstnvvp8dec.cpp | 28 +++++++++++++++++++ .../sys/nvcodec/gstnvvp9dec.cpp | 28 +++++++++++++++++++ 5 files changed, 140 insertions(+) diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.cpp index 783a8e7eca..63dec188bc 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.cpp @@ -73,6 +73,7 @@ typedef struct _GstNvAV1Dec guint num_output_surfaces; guint init_max_width; guint init_max_height; + gint max_display_delay; } GstNvAV1Dec; typedef struct _GstNvAV1DecClass @@ -90,9 +91,11 @@ enum PROP_NUM_OUTPUT_SURFACES, PROP_INIT_MAX_WIDTH, PROP_INIT_MAX_HEIGHT, + PROP_MAX_DISPLAY_DELAY, }; #define DEFAULT_NUM_OUTPUT_SURFACES 0 +#define DEFAULT_MAX_DISPLAY_DELAY -1 static GTypeClass *parent_class = nullptr; @@ -201,6 +204,19 @@ gst_nv_av1_dec_class_init (GstNvAV1DecClass * klass, (GParamFlags) (GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstNvAV1Dec:max-display-delay: + * + * Maximum display delay + * + * Since: 1.24 + */ + g_object_class_install_property (object_class, PROP_MAX_DISPLAY_DELAY, + g_param_spec_int ("max-display-delay", "Max Display Delay", + "Improves pipelining of decode with display, 0 means no delay " + "(auto = -1)", -1, 16, DEFAULT_MAX_DISPLAY_DELAY, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_av1_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -254,6 +270,7 @@ static void gst_nv_av1_dec_init (GstNvAV1Dec * self) { self->num_output_surfaces = DEFAULT_NUM_OUTPUT_SURFACES; + self->max_display_delay = DEFAULT_MAX_DISPLAY_DELAY; } static void @@ -272,6 +289,9 @@ gst_nv_av1_dec_set_property (GObject * object, guint prop_id, case PROP_INIT_MAX_HEIGHT: self->init_max_height = g_value_get_uint (value); break; + case PROP_MAX_DISPLAY_DELAY: + self->max_display_delay = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -298,6 +318,9 @@ gst_nv_av1_dec_get_property (GObject * object, guint prop_id, GValue * value, case PROP_INIT_MAX_HEIGHT: g_value_set_uint (value, self->init_max_height); break; + case PROP_MAX_DISPLAY_DELAY: + g_value_set_int (value, self->max_display_delay); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1028,6 +1051,11 @@ static guint gst_nv_av1_dec_get_preferred_output_delay (GstAV1Decoder * decoder, gboolean is_live) { + GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder); + + if (self->max_display_delay >= 0) + return self->max_display_delay; + /* Prefer to zero latency for live pipeline */ if (is_live) return 0; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp index 9cd83ac1d6..415fc8dd4c 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp @@ -129,6 +129,7 @@ typedef struct _GstNvH264Dec guint num_output_surfaces; guint init_max_width; guint init_max_height; + gint max_display_delay; } GstNvH264Dec; typedef struct _GstNvH264DecClass @@ -146,9 +147,11 @@ enum PROP_NUM_OUTPUT_SURFACES, PROP_INIT_MAX_WIDTH, PROP_INIT_MAX_HEIGHT, + PROP_MAX_DISPLAY_DELAY, }; #define DEFAULT_NUM_OUTPUT_SURFACES 0 +#define DEFAULT_MAX_DISPLAY_DELAY -1 static GTypeClass *parent_class = nullptr; @@ -270,6 +273,19 @@ gst_nv_h264_dec_class_init (GstNvH264DecClass * klass, (GParamFlags) (GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstNvH264Dec:max-display-delay: + * + * Maximum display delay + * + * Since: 1.24 + */ + g_object_class_install_property (object_class, PROP_MAX_DISPLAY_DELAY, + g_param_spec_int ("max-display-delay", "Max Display Delay", + "Improves pipelining of decode with display, 0 means no delay " + "(auto = -1)", -1, 16, DEFAULT_MAX_DISPLAY_DELAY, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -329,6 +345,7 @@ gst_nv_h264_dec_init (GstNvH264Dec * self) (GDestroyNotify) gst_clear_h264_picture); self->num_output_surfaces = DEFAULT_NUM_OUTPUT_SURFACES; + self->max_display_delay = DEFAULT_MAX_DISPLAY_DELAY; } static void @@ -357,6 +374,9 @@ gst_nv_h264_dec_set_property (GObject * object, guint prop_id, case PROP_INIT_MAX_HEIGHT: self->init_max_height = g_value_get_uint (value); break; + case PROP_MAX_DISPLAY_DELAY: + self->max_display_delay = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -383,6 +403,9 @@ gst_nv_h264_dec_get_property (GObject * object, guint prop_id, GValue * value, case PROP_INIT_MAX_HEIGHT: g_value_set_uint (value, self->init_max_height); break; + case PROP_MAX_DISPLAY_DELAY: + g_value_set_int (value, self->max_display_delay); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1082,6 +1105,11 @@ static guint gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder, gboolean live) { + GstNvH264Dec *self = GST_NV_H264_DEC (decoder); + + if (self->max_display_delay >= 0) + return self->max_display_delay; + /* Prefer to zero latency for live pipeline */ if (live) return 0; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.cpp index 8240ff8147..8a7a404a2c 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.cpp @@ -125,6 +125,7 @@ typedef struct _GstNvH265Dec guint num_output_surfaces; guint init_max_width; guint init_max_height; + gint max_display_delay; } GstNvH265Dec; typedef struct _GstNvH265DecClass @@ -142,9 +143,11 @@ enum PROP_NUM_OUTPUT_SURFACES, PROP_INIT_MAX_WIDTH, PROP_INIT_MAX_HEIGHT, + PROP_MAX_DISPLAY_DELAY, }; #define DEFAULT_NUM_OUTPUT_SURFACES 0 +#define DEFAULT_MAX_DISPLAY_DELAY -1 static GTypeClass *parent_class = nullptr; @@ -261,6 +264,19 @@ gst_nv_h265_dec_class_init (GstNvH265DecClass * klass, (GParamFlags) (GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstNvH265Dec:max-display-delay: + * + * Maximum display delay + * + * Since: 1.24 + */ + g_object_class_install_property (object_class, PROP_MAX_DISPLAY_DELAY, + g_param_spec_int ("max-display-delay", "Max Display Delay", + "Improves pipelining of decode with display, 0 means no delay " + "(auto = -1)", -1, 16, DEFAULT_MAX_DISPLAY_DELAY, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -313,6 +329,7 @@ static void gst_nv_h265_dec_init (GstNvH265Dec * self) { self->num_output_surfaces = DEFAULT_NUM_OUTPUT_SURFACES; + self->max_display_delay = DEFAULT_MAX_DISPLAY_DELAY; } static void @@ -331,6 +348,9 @@ gst_nv_h265_dec_set_property (GObject * object, guint prop_id, case PROP_INIT_MAX_HEIGHT: self->init_max_height = g_value_get_uint (value); break; + case PROP_MAX_DISPLAY_DELAY: + self->max_display_delay = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -357,6 +377,9 @@ gst_nv_h265_dec_get_property (GObject * object, guint prop_id, GValue * value, case PROP_INIT_MAX_HEIGHT: g_value_set_uint (value, self->init_max_height); break; + case PROP_MAX_DISPLAY_DELAY: + g_value_set_int (value, self->max_display_delay); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1123,6 +1146,11 @@ static guint gst_nv_h265_dec_get_preferred_output_delay (GstH265Decoder * decoder, gboolean live) { + GstNvH265Dec *self = GST_NV_H265_DEC (decoder); + + if (self->max_display_delay >= 0) + return self->max_display_delay; + /* Prefer to zero latency for live pipeline */ if (live) return 0; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.cpp index 4241580ed6..b07f9898e1 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.cpp @@ -57,6 +57,7 @@ typedef struct _GstNvVp8Dec guint num_output_surfaces; guint init_max_width; guint init_max_height; + gint max_display_delay; } GstNvVp8Dec; typedef struct _GstNvVp8DecClass @@ -74,9 +75,11 @@ enum PROP_NUM_OUTPUT_SURFACES, PROP_INIT_MAX_WIDTH, PROP_INIT_MAX_HEIGHT, + PROP_MAX_DISPLAY_DELAY, }; #define DEFAULT_NUM_OUTPUT_SURFACES 0 +#define DEFAULT_MAX_DISPLAY_DELAY -1 static GTypeClass *parent_class = nullptr; @@ -187,6 +190,19 @@ gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass, (GParamFlags) (GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstNvVp8Dec:max-display-delay: + * + * Maximum display delay + * + * Since: 1.24 + */ + g_object_class_install_property (object_class, PROP_MAX_DISPLAY_DELAY, + g_param_spec_int ("max-display-delay", "Max Display Delay", + "Improves pipelining of decode with display, 0 means no delay " + "(auto = -1)", -1, 16, DEFAULT_MAX_DISPLAY_DELAY, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -235,6 +251,7 @@ static void gst_nv_vp8_dec_init (GstNvVp8Dec * self) { self->num_output_surfaces = DEFAULT_NUM_OUTPUT_SURFACES; + self->max_display_delay = DEFAULT_MAX_DISPLAY_DELAY; } static void @@ -253,6 +270,9 @@ gst_nv_vp8_dec_set_property (GObject * object, guint prop_id, case PROP_INIT_MAX_HEIGHT: self->init_max_height = g_value_get_uint (value); break; + case PROP_MAX_DISPLAY_DELAY: + self->max_display_delay = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -279,6 +299,9 @@ gst_nv_vp8_dec_get_property (GObject * object, guint prop_id, GValue * value, case PROP_INIT_MAX_HEIGHT: g_value_set_uint (value, self->init_max_height); break; + case PROP_MAX_DISPLAY_DELAY: + g_value_set_int (value, self->max_display_delay); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -644,6 +667,11 @@ static guint gst_nv_vp8_dec_get_preferred_output_delay (GstVp8Decoder * decoder, gboolean is_live) { + GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder); + + if (self->max_display_delay >= 0) + return self->max_display_delay; + /* Prefer to zero latency for live pipeline */ if (is_live) return 0; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.cpp index 17799ab768..69370a5ff4 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.cpp @@ -58,6 +58,7 @@ typedef struct _GstNvVp9Dec guint num_output_surfaces; guint init_max_width; guint init_max_height; + gint max_display_delay; } GstNvVp9Dec; typedef struct _GstNvVp9DecClass @@ -75,9 +76,11 @@ enum PROP_NUM_OUTPUT_SURFACES, PROP_INIT_MAX_WIDTH, PROP_INIT_MAX_HEIGHT, + PROP_MAX_DISPLAY_DELAY, }; #define DEFAULT_NUM_OUTPUT_SURFACES 0 +#define DEFAULT_MAX_DISPLAY_DELAY -1 static GTypeClass *parent_class = nullptr; @@ -190,6 +193,19 @@ gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass, (GParamFlags) (GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstNvVp9Dec:max-display-delay: + * + * Maximum display delay + * + * Since: 1.24 + */ + g_object_class_install_property (object_class, PROP_MAX_DISPLAY_DELAY, + g_param_spec_int ("max-display-delay", "Max Display Delay", + "Improves pipelining of decode with display, 0 means no delay " + "(auto = -1)", -1, 16, DEFAULT_MAX_DISPLAY_DELAY, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -240,6 +256,7 @@ static void gst_nv_vp9_dec_init (GstNvVp9Dec * self) { self->num_output_surfaces = DEFAULT_NUM_OUTPUT_SURFACES; + self->max_display_delay = DEFAULT_MAX_DISPLAY_DELAY; } static void @@ -258,6 +275,9 @@ gst_nv_vp9_dec_set_property (GObject * object, guint prop_id, case PROP_INIT_MAX_HEIGHT: self->init_max_height = g_value_get_uint (value); break; + case PROP_MAX_DISPLAY_DELAY: + self->max_display_delay = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -284,6 +304,9 @@ gst_nv_vp9_dec_get_property (GObject * object, guint prop_id, GValue * value, case PROP_INIT_MAX_HEIGHT: g_value_set_uint (value, self->init_max_height); break; + case PROP_MAX_DISPLAY_DELAY: + g_value_set_int (value, self->max_display_delay); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -740,6 +763,11 @@ static guint gst_nv_vp9_dec_get_preferred_output_delay (GstVp9Decoder * decoder, gboolean is_live) { + GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder); + + if (self->max_display_delay >= 0) + return self->max_display_delay; + /* Prefer to zero latency for live pipeline */ if (is_live) return 0;