From d6d2a5b19463c2f700e5e12f48b2178018c46b67 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 4 Sep 2018 20:12:17 +0000 Subject: omxh26xenc: Negotiate subframe mode We now negotiate subframe mode through the caps. To enabled subframe mode, the caps need to specify alignment=nal: ... ! omxh264enc ! video/x-h264,alignment=nal ! ... ... ! omxh265enc ! video/x-h265,alignment=nal ! ... --- omx/gstomxh264enc.c | 28 +++++++++++++++++++++++++--- omx/gstomxh265enc.c | 24 ++++++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/omx/gstomxh264enc.c b/omx/gstomxh264enc.c index b67e0d7..2711e86 100644 --- a/omx/gstomxh264enc.c +++ b/omx/gstomxh264enc.c @@ -70,7 +70,13 @@ enum #endif #define GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff) #define GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff) +#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS +#define GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT (0) +#define ALIGNMENT "{ au, nal }" +#else #define GST_OMX_H264_VIDEO_ENC_B_FRAMES_DEFAULT (0xffffffff) +#define ALIGNMENT "au" +#endif #define GST_OMX_H264_VIDEO_ENC_ENTROPY_MODE_DEFAULT (0xffffffff) #define GST_OMX_H264_VIDEO_ENC_CONSTRAINED_INTRA_PREDICTION_DEFAULT (FALSE) #define GST_OMX_H264_VIDEO_ENC_LOOP_FILTER_MODE_DEFAULT (0xffffffff) @@ -226,7 +232,9 @@ gst_omx_h264_enc_class_init (GstOMXH264EncClass * klass) basevideoenc_class->stop = gst_omx_h264_enc_stop; videoenc_class->cdata.default_src_template_caps = "video/x-h264, " - "width=(int) [ 16, 4096 ], " "height=(int) [ 16, 4096 ]"; + "width = (int) [ 16, 4096 ], height = (int) [ 16, 4096 ], " + "framerate = (fraction) [0, MAX], stream-format=(string) byte-stream, " + "alignment = (string) " ALIGNMENT; videoenc_class->handle_output_frame = GST_DEBUG_FUNCPTR (gst_omx_h264_enc_handle_output_frame); @@ -614,6 +622,7 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, const gchar *profile_string, *level_string; OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileMax; OMX_VIDEO_AVCLEVELTYPE level = OMX_VIDEO_AVCLevelMax; + gboolean enable_subframe = FALSE; #ifdef USE_OMX_TARGET_RPI GST_OMX_INIT_STRUCT (&config_inline_header); @@ -674,6 +683,7 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc))); if (peercaps) { GstStructure *s; + const gchar *alignment_string; if (gst_caps_is_empty (peercaps)) { gst_caps_unref (peercaps); @@ -695,6 +705,10 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, goto unsupported_level; } + alignment_string = gst_structure_get_string (s, "alignment"); + if (alignment_string && g_str_equal (alignment_string, "nal")) + enable_subframe = TRUE; + gst_caps_unref (peercaps); } @@ -706,6 +720,9 @@ gst_omx_h264_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, return FALSE; } + gst_omx_port_set_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port, + enable_subframe); + if (!update_param_avc (self, profile, level)) return FALSE; @@ -730,7 +747,7 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, GstCaps *caps; OMX_ERRORTYPE err; OMX_VIDEO_PARAM_PROFILELEVELTYPE param; - const gchar *profile, *level; + const gchar *profile, *level, *alignment; GST_OMX_INIT_STRUCT (¶m); param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index; @@ -741,9 +758,14 @@ gst_omx_h264_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) return NULL; + if (gst_omx_port_get_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port)) + alignment = "nal"; + else + alignment = "au"; + caps = gst_caps_new_simple ("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", - "alignment", G_TYPE_STRING, "au", NULL); + "alignment", G_TYPE_STRING, alignment, NULL); if (err == OMX_ErrorNone) { profile = gst_omx_h264_utils_get_profile_from_enum (param.eProfile); diff --git a/omx/gstomxh265enc.c b/omx/gstomxh265enc.c index ea14ca7..6cc89d4 100644 --- a/omx/gstomxh265enc.c +++ b/omx/gstomxh265enc.c @@ -60,8 +60,10 @@ enum #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS /* zynqultrascaleplus's OMX uses a param struct different of Android's one */ #define INDEX_PARAM_VIDEO_HEVC OMX_ALG_IndexParamVideoHevc +#define ALIGNMENT "{ au, nal }" #else #define INDEX_PARAM_VIDEO_HEVC OMX_IndexParamVideoHevc +#define ALIGNMENT "au" #endif /* class initialization */ @@ -164,8 +166,8 @@ gst_omx_h265_enc_class_init (GstOMXH265EncClass * klass) videoenc_class->cdata.default_src_template_caps = "video/x-h265, " "width=(int) [ 1, MAX ], " "height=(int) [ 1, MAX ], " - "framerate = (fraction) [0, MAX], " - "stream-format=(string) byte-stream, alignment=(string) au "; + "framerate = (fraction) [0, MAX], stream-format=(string) byte-stream, " + "aligmment = (string) " ALIGNMENT; gst_element_class_set_static_metadata (element_class, "OpenMAX H.265 Video Encoder", @@ -446,6 +448,7 @@ gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, const gchar *profile_string, *level_string, *tier_string; OMX_VIDEO_HEVCPROFILETYPE profile = OMX_VIDEO_HEVCProfileUnknown; OMX_VIDEO_HEVCLEVELTYPE level = OMX_VIDEO_HEVCLevelUnknown; + gboolean enable_subframe = FALSE; #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS if (self->periodicity_idr != @@ -468,6 +471,7 @@ gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc))); if (peercaps) { GstStructure *s; + const gchar *alignment_string; if (gst_caps_is_empty (peercaps)) { gst_caps_unref (peercaps); @@ -491,6 +495,10 @@ gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, goto unsupported_level; } + alignment_string = gst_structure_get_string (s, "alignment"); + if (alignment_string && g_str_equal (alignment_string, "nal")) + enable_subframe = TRUE; + gst_caps_unref (peercaps); } @@ -506,6 +514,9 @@ gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, if (!update_param_hevc (self, profile, level)) return FALSE; + gst_omx_port_set_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port, + enable_subframe); + return TRUE; unsupported_profile: @@ -527,7 +538,7 @@ gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, GstCaps *caps; OMX_ERRORTYPE err; OMX_VIDEO_PARAM_PROFILELEVELTYPE param; - const gchar *profile, *level, *tier; + const gchar *profile, *level, *tier, *alignment; GST_OMX_INIT_STRUCT (¶m); param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index; @@ -538,9 +549,14 @@ gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex) return NULL; + if (gst_omx_port_get_subframe (GST_OMX_VIDEO_ENC (self)->enc_out_port)) + alignment = "nal"; + else + alignment = "au"; + caps = gst_caps_new_simple ("video/x-h265", "stream-format", G_TYPE_STRING, "byte-stream", - "alignment", G_TYPE_STRING, "au", NULL); + "alignment", G_TYPE_STRING, alignment, NULL); if (err == OMX_ErrorNone) { profile = gst_omx_h265_utils_get_profile_from_enum (param.eProfile); -- cgit v1.2.1