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,
PROP_SLICE_SIZE,
PROP_DEPENDENT_SLICE,
PROP_DEFAULT_ROI_QUALITY,
+ PROP_LONGTERM_REF,
+ PROP_LONGTERM_FREQUENCY,
};
/* FIXME: Better defaults */
#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 \
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 =
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);
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;
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
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);
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);
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)