mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
omxvideoenc: Add long-term-ref support to ZYNQ_USCALE_PLUS encoder
Custom API that upstream elements can use to notify encoders about marking longterm ref. pictures or using longterm ref. pictures in encoding process. This patch adds below properties: long-term-ref: Enable/Disable dynamically marking long-term reference pictures in encoding process long-term-freq: Periodicity of long-term reference picture marking in encoding process. If a picture is marked as long-term reference picture then it remains in the DPB list for ever unless it overrides with new long-term pitcure with same index. Encoder can use this long-term picture as refence for encoding. This feature is mostly useful to avoid visual artifacts propagation in streaming use cases when packet loss happens. Instead of requesting for IDR, client can request for use long-term reference picture for encoding.
This commit is contained in:
parent
f1353ae41d
commit
bfd8306ef6
2 changed files with 126 additions and 0 deletions
|
@ -253,6 +253,9 @@ static GstFlowReturn gst_omx_video_enc_drain (GstOMXVideoEnc * self);
|
|||
static GstFlowReturn gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc *
|
||||
self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame);
|
||||
|
||||
static gboolean gst_omx_video_enc_sink_event (GstVideoEncoder * encoder,
|
||||
GstEvent * event);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
@ -277,6 +280,8 @@ enum
|
|||
PROP_SLICE_SIZE,
|
||||
PROP_DEPENDENT_SLICE,
|
||||
PROP_DEFAULT_ROI_QUALITY,
|
||||
PROP_LONGTERM_REF,
|
||||
PROP_LONGTERM_FREQUENCY,
|
||||
};
|
||||
|
||||
/* FIXME: Better defaults */
|
||||
|
@ -301,6 +306,12 @@ enum
|
|||
#define GST_OMX_VIDEO_ENC_SLICE_SIZE_DEFAULT (0)
|
||||
#define GST_OMX_VIDEO_ENC_DEPENDENT_SLICE_DEFAULT (FALSE)
|
||||
#define GST_OMX_VIDEO_ENC_DEFAULT_ROI_QUALITY OMX_ALG_ROI_QUALITY_HIGH
|
||||
#define GST_OMX_VIDEO_ENC_LONGTERM_REF_DEFAULT (FALSE)
|
||||
#define GST_OMX_VIDEO_ENC_LONGTERM_FREQUENCY_DEFAULT (0)
|
||||
|
||||
/* ZYNQ_USCALE_PLUS encoder custom events */
|
||||
#define OMX_ALG_GST_EVENT_INSERT_LONGTERM "omx-alg/insert-longterm"
|
||||
#define OMX_ALG_GST_EVENT_USE_LONGTERM "omx-alg/use-longterm"
|
||||
|
||||
/* class initialization */
|
||||
#define do_init \
|
||||
|
@ -484,6 +495,22 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass)
|
|||
GST_TYPE_OMX_VIDEO_ENC_ROI_QUALITY,
|
||||
GST_OMX_VIDEO_ENC_DEFAULT_ROI_QUALITY,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_LONGTERM_REF,
|
||||
g_param_spec_boolean ("long-term-ref", "LongTerm Reference Pictures",
|
||||
"If enabled, encoder accepts dynamically inserting and using long-term reference "
|
||||
"picture events from upstream elements",
|
||||
GST_OMX_VIDEO_ENC_LONGTERM_REF_DEFAULT,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
GST_PARAM_MUTABLE_READY));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_LONGTERM_FREQUENCY,
|
||||
g_param_spec_uint ("long-term-freq", "LongTerm reference frequency",
|
||||
"Periodicity of LongTerm reference picture marking in encoding process "
|
||||
"Units in frames, distance between two consequtive long-term reference pictures",
|
||||
0, G_MAXUINT, GST_OMX_VIDEO_ENC_LONGTERM_REF_DEFAULT,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||
GST_PARAM_MUTABLE_READY));
|
||||
#endif
|
||||
|
||||
element_class->change_state =
|
||||
|
@ -502,6 +529,8 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass)
|
|||
video_encoder_class->propose_allocation =
|
||||
GST_DEBUG_FUNCPTR (gst_omx_video_enc_propose_allocation);
|
||||
video_encoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_omx_video_enc_getcaps);
|
||||
video_encoder_class->sink_event =
|
||||
GST_DEBUG_FUNCPTR (gst_omx_video_enc_sink_event);
|
||||
video_encoder_class->decide_allocation =
|
||||
GST_DEBUG_FUNCPTR (gst_omx_video_enc_decide_allocation);
|
||||
|
||||
|
@ -538,6 +567,8 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self)
|
|||
self->slice_size = GST_OMX_VIDEO_ENC_SLICE_SIZE_DEFAULT;
|
||||
self->dependent_slice = GST_OMX_VIDEO_ENC_DEPENDENT_SLICE_DEFAULT;
|
||||
self->default_roi_quality = GST_OMX_VIDEO_ENC_DEFAULT_ROI_QUALITY;
|
||||
self->long_term_ref = GST_OMX_VIDEO_ENC_LONGTERM_REF_DEFAULT;
|
||||
self->long_term_freq = GST_OMX_VIDEO_ENC_LONGTERM_FREQUENCY_DEFAULT;
|
||||
#endif
|
||||
|
||||
self->default_target_bitrate = GST_OMX_PROP_OMX_DEFAULT;
|
||||
|
@ -808,6 +839,22 @@ set_zynqultrascaleplus_props (GstOMXVideoEnc * self)
|
|||
CHECK_ERR ("slices");
|
||||
}
|
||||
|
||||
{
|
||||
OMX_ALG_VIDEO_PARAM_LONG_TERM longterm;
|
||||
GST_OMX_INIT_STRUCT (&longterm);
|
||||
longterm.nPortIndex = self->enc_out_port->index;
|
||||
longterm.bEnableLongTerm = self->long_term_ref;
|
||||
longterm.nLongTermFrequency = self->long_term_freq;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "setting long-term ref to %d, long-term-freq to %d",
|
||||
self->long_term_ref, self->long_term_freq);
|
||||
|
||||
err =
|
||||
gst_omx_component_set_parameter (self->enc,
|
||||
(OMX_INDEXTYPE) OMX_ALG_IndexParamVideoLongTerm, &longterm);
|
||||
CHECK_ERR ("longterm");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
@ -1140,6 +1187,12 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id,
|
|||
case PROP_DEFAULT_ROI_QUALITY:
|
||||
self->default_roi_quality = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_LONGTERM_REF:
|
||||
self->long_term_ref = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_LONGTERM_FREQUENCY:
|
||||
self->long_term_freq = g_value_get_uint (value);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -1220,6 +1273,12 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_DEFAULT_ROI_QUALITY:
|
||||
g_value_set_enum (value, self->default_roi_quality);
|
||||
break;
|
||||
case PROP_LONGTERM_REF:
|
||||
g_value_set_boolean (value, self->long_term_ref);
|
||||
break;
|
||||
case PROP_LONGTERM_FREQUENCY:
|
||||
g_value_set_uint (value, self->long_term_freq);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -3366,6 +3425,71 @@ gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
|
||||
static gboolean
|
||||
handle_longterm_event (GstOMXVideoEnc * self, GstEvent * event)
|
||||
{
|
||||
OMX_ALG_VIDEO_CONFIG_INSERT longterm;
|
||||
OMX_ERRORTYPE err;
|
||||
OMX_INDEXTYPE omx_index_long_term;
|
||||
|
||||
GST_OMX_INIT_STRUCT (&longterm);
|
||||
longterm.nPortIndex = self->enc_in_port->index;
|
||||
|
||||
/* If long-term-ref is enabled then "omx-alg/insert-longterm" event
|
||||
* marks the encoding picture as long term reference picture and
|
||||
* "omx-alg/use-longterm" event informs the encoder that encoding picture
|
||||
* should use existing long term picture in the dpb as reference for encoding process */
|
||||
|
||||
if (self->long_term_ref) {
|
||||
if (gst_event_has_name (event, OMX_ALG_GST_EVENT_INSERT_LONGTERM)) {
|
||||
GST_LOG_OBJECT (self, "received omx-alg/insert-longterm event");
|
||||
omx_index_long_term =
|
||||
(OMX_INDEXTYPE) OMX_ALG_IndexConfigVideoInsertLongTerm;
|
||||
} else {
|
||||
GST_LOG_OBJECT (self, "received omx-alg/use-longterm event");
|
||||
omx_index_long_term = (OMX_INDEXTYPE) OMX_ALG_IndexConfigVideoUseLongTerm;
|
||||
}
|
||||
|
||||
err =
|
||||
gst_omx_component_set_config (self->enc, omx_index_long_term,
|
||||
&longterm);
|
||||
|
||||
if (err != OMX_ErrorNone)
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Failed to longterm events: %s (0x%08x)",
|
||||
gst_omx_error_to_string (err), err);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"LongTerm events are not handled because long_term_ref is disabled");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_enc_sink_event (GstVideoEncoder * encoder, GstEvent * event)
|
||||
{
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_CUSTOM_DOWNSTREAM:
|
||||
{
|
||||
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
|
||||
GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder);
|
||||
if (gst_event_has_name (event, OMX_ALG_GST_EVENT_INSERT_LONGTERM)
|
||||
|| gst_event_has_name (event, OMX_ALG_GST_EVENT_USE_LONGTERM))
|
||||
return handle_longterm_event (self, event);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return
|
||||
GST_VIDEO_ENCODER_CLASS (gst_omx_video_enc_parent_class)->sink_event
|
||||
(encoder, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_enc_decide_allocation (GstVideoEncoder * encoder,
|
||||
GstQuery * query)
|
||||
|
|
|
@ -92,6 +92,8 @@ struct _GstOMXVideoEnc
|
|||
guint32 slice_size;
|
||||
gboolean dependent_slice;
|
||||
gint default_roi_quality;
|
||||
gboolean long_term_ref;
|
||||
guint32 long_term_freq;
|
||||
#endif
|
||||
|
||||
guint32 default_target_bitrate;
|
||||
|
|
Loading…
Reference in a new issue