Support mirror rotation scale for omxmjpegdec Signed-off-by: Leo Lu diff -purN a/omx/gstomxmjpegdec.c b/omx/gstomxmjpegdec.c --- a/omx/gstomxmjpegdec.c 2022-09-27 15:31:41.826975878 +0800 +++ b/omx/gstomxmjpegdec.c 2022-09-27 15:19:10.924240508 +0800 @@ -30,8 +30,19 @@ GST_DEBUG_CATEGORY_STATIC (gst_omx_mjpeg #define GST_CAT_DEFAULT gst_omx_mjpeg_dec_debug_category #ifdef USE_OMX_TARGET_STARFIVE #define DEFAULT_FRAMERATE 0 +#define DEFAULT_MIRROR 0 +#define DEFAULT_ROTATION 0 +#define DEFAULT_SCALEH 0 +#define DEFAULT_SCALEV 0 #endif /* prototypes */ + +static gboolean +gst_omx_jepgdec_set_scale(GstOMXVideoDec *self); +static gboolean +gst_omx_jepgdec_set_rotation(GstOMXVideoDec *self); +static gboolean +gst_omx_jepgdec_set_mirror(GstOMXVideoDec *self); static gboolean gst_omx_mjpeg_dec_is_format_change (GstOMXVideoDec * dec, GstOMXPort * port, GstVideoCodecState * state); static gboolean gst_omx_mjpeg_dec_set_format (GstOMXVideoDec * dec, @@ -46,10 +57,14 @@ enum { #ifdef USE_OMX_TARGET_STARFIVE PROP_0, - PROP_FRAMERATE + PROP_FRAMERATE, #else - PROP_0 + PROP_0, #endif + PROP_MIRROR, + PROP_SCALEH, + PROP_SCALEV, + PROP_ROTATION, }; /* class initialization */ @@ -61,6 +76,71 @@ enum G_DEFINE_TYPE_WITH_CODE (GstOMXMJPEGDec, gst_omx_mjpeg_dec, GST_TYPE_OMX_VIDEO_DEC, DEBUG_INIT); +#define GST_OMX_MJPEG_DEC_MIRROR_MODE (gst_omx_mjpeg_dec_mirror_mode_get_type()) + +static GType +gst_omx_mjpeg_dec_mirror_mode_get_type(void) +{ + static GType qtype = 0; + if(qtype == 0){ + static const GEnumValue values[] = { + { OMX_MirrorNone, "None", "none"}, + { OMX_MirrorVertical, "Mirror Vertical", "V"}, + { OMX_MirrorHorizontal, "Mirror Horizontal", "H"}, + { OMX_MirrorBoth, "Mirror Both", "VH"}, + {0, NULL, NULL} + }; + + qtype = g_enum_register_static("GstOMXMJPEGDecMirrorMode",values); + + } + return qtype; + +} + +#define GST_OMX_MJPEG_DEC_ROTATION_MODE (gst_omx_mjpeg_dec_rotation_mode_get_type()) + +static GType +gst_omx_mjpeg_dec_rotation_mode_get_type(void) +{ + static GType qtype = 0; + if(qtype == 0){ + static const GEnumValue values[] = { + { ROTATION_0, "None", "none"}, + { ROTATION_90, "Rotate 90", "M1"}, + { ROTATION_180, "Rotate 180", "M2"}, + { ROTATION_270, "Rotate 270", "M3"}, + {0, NULL, NULL} + }; + + qtype = g_enum_register_static("GstOMXMJPEGDecRotationMode",values); + + } + return qtype; +} + +#define GST_OMX_MJPEG_DEC_SCALE_MODE (gst_omx_mjpeg_dec_scale_mode_get_type()) + +static GType +gst_omx_mjpeg_dec_scale_mode_get_type(void) +{ + static GType qtype = 0; + if(qtype == 0){ + static const GEnumValue values[] = { + { SCALEMODE_0, "None", "none"}, + { SCALEMODE1_2, "Scale half", "1/2"}, + { SCALEMODE1_4, "Scale quarter", "1/4"}, + { SCALEMODE1_8, "Scale eighth", "1/8"}, + {0, NULL, NULL} + }; + + qtype = g_enum_register_static("GstOMXMJPEGDecScaleMode",values); + + } + return qtype; +} + + static void gst_omx_mjpeg_dec_class_init (GstOMXMJPEGDecClass * klass) { @@ -94,12 +174,41 @@ gst_omx_mjpeg_dec_class_init (GstOMXMJPE 0, G_MAXINT, DEFAULT_FRAMERATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif + g_object_class_install_property(gobject_class,PROP_MIRROR, + g_param_spec_enum("mirror","MIRROR", + "Mirror 0(none), 1(V), 2(H), 3(VH).", + GST_OMX_MJPEG_DEC_MIRROR_MODE, + DEFAULT_MIRROR,G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class,PROP_ROTATION, + g_param_spec_enum("rotation","ROTATION", + "Rotation 0(none), 1(90), 2(180), 3(270).", + GST_OMX_MJPEG_DEC_ROTATION_MODE, + DEFAULT_ROTATION,G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class,PROP_SCALEH, + g_param_spec_enum("scaleH","ScaleH", + "Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8).", + GST_OMX_MJPEG_DEC_SCALE_MODE,DEFAULT_SCALEH, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(gobject_class,PROP_SCALEV, + g_param_spec_enum("scaleV","ScaleV", + "Vertical downscale: 0(none), 1(1/2), 2(1/4), 3(1/8).", + GST_OMX_MJPEG_DEC_SCALE_MODE,DEFAULT_SCALEV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gst_omx_set_default_role (&videodec_class->cdata, "video_decoder.mjpeg"); } static void gst_omx_mjpeg_dec_init (GstOMXMJPEGDec * self) { + self->mirror = DEFAULT_MIRROR; + self->rotation = DEFAULT_ROTATION; + self->scaleH = DEFAULT_SCALEH; + self->scaleV = DEFAULT_SCALEV; } static gboolean @@ -128,6 +237,15 @@ gst_omx_mjpeg_dec_set_format (GstOMXVide } } #endif + if(!gst_omx_jepgdec_set_mirror(dec)) + return FALSE; + + if(!gst_omx_jepgdec_set_rotation(dec)) + return FALSE; + + if(!gst_omx_jepgdec_set_scale(dec)) + return FALSE; + gst_omx_port_get_port_definition (port, &port_def); port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingMJPEG; ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone; @@ -144,6 +262,18 @@ gst_omx_mjpeg_dec_set_property (GObject case PROP_FRAMERATE: mjpeg_dec->framerate = g_value_get_int (value); break; + case PROP_MIRROR: + mjpeg_dec->mirror = g_value_get_enum(value); + break; + case PROP_ROTATION: + mjpeg_dec->rotation = g_value_get_enum(value); + break; + case PROP_SCALEH: + mjpeg_dec->scaleH = g_value_get_enum(value); + break; + case PROP_SCALEV: + mjpeg_dec->scaleV = g_value_get_enum(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -159,9 +289,168 @@ gst_omx_mjpeg_dec_get_property (GObject case PROP_FRAMERATE: g_value_set_int (value, mjpeg_dec->framerate); break; + case PROP_MIRROR: + g_value_set_enum(value, mjpeg_dec->mirror); + break; + case PROP_ROTATION: + g_value_set_enum(value, mjpeg_dec->rotation); + break; + case PROP_SCALEH: + g_value_set_enum(value, mjpeg_dec->scaleH); + break; + case PROP_SCALEV: + g_value_set_enum(value, mjpeg_dec->scaleV); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } #endif + +static gboolean +gst_omx_jepgdec_set_rotation(GstOMXVideoDec *self) +{ + OMX_ERRORTYPE err; + OMX_CONFIG_ROTATIONTYPE rotation_config; + gboolean result = TRUE; + GstOMXMJPEGDec * mjpeg_dec = GST_OMX_MJPEG_DEC (self); + + GST_OBJECT_LOCK(self); + + GST_OMX_INIT_STRUCT(&rotation_config); + rotation_config.nPortIndex = self->dec_out_port->index; + + err = gst_omx_component_get_config(self->dec, + OMX_IndexConfigCommonRotate,&rotation_config); + + if( err == OMX_ErrorNone){ + + if(mjpeg_dec->rotation >= 0 && mjpeg_dec->rotation <= 270 ) + rotation_config.nRotation = mjpeg_dec->rotation; + + err = gst_omx_component_set_config(self->dec, + OMX_IndexConfigCommonRotate,&rotation_config); + + if (err == OMX_ErrorUnsupportedIndex) { + GST_WARNING_OBJECT (self, + "Setting a rotation not supported by the component"); + } else if (err == OMX_ErrorUnsupportedSetting) { + GST_WARNING_OBJECT (self, + "Setting rotation settings %u not supported by the component", + mjpeg_dec->rotation); + } else if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to set rotation parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + result = FALSE; + } + } else { + GST_ERROR_OBJECT (self, "Failed to get rotation parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + } + + GST_OBJECT_UNLOCK(self); + return result; + + } + + + +static gboolean +gst_omx_jepgdec_set_mirror(GstOMXVideoDec *self) +{ + OMX_ERRORTYPE err; + OMX_CONFIG_MIRRORTYPE mirror_config; + gboolean result = TRUE; + GstOMXMJPEGDec * mjpeg_dec = GST_OMX_MJPEG_DEC (self); + + GST_OBJECT_LOCK(self); + + GST_OMX_INIT_STRUCT(&mirror_config); + mirror_config.nPortIndex = self->dec_out_port->index; + + err = gst_omx_component_get_config(self->dec, + OMX_IndexConfigCommonMirror,&mirror_config); + + if( err == OMX_ErrorNone){ + + if(mjpeg_dec->mirror >= 0 && mjpeg_dec->mirror <= OMX_MirrorBoth ) + mirror_config.eMirror = mjpeg_dec->mirror; + + err = gst_omx_component_set_config(self->dec, + OMX_IndexConfigCommonMirror,&mirror_config); + + if (err == OMX_ErrorUnsupportedIndex) { + GST_WARNING_OBJECT (self, + "Setting a mirror not supported by the component"); + } else if (err == OMX_ErrorUnsupportedSetting) { + GST_WARNING_OBJECT (self, + "Setting mirror settings %u not supported by the component", + mjpeg_dec->mirror); + } else if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to set mirror parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + result = FALSE; + } + } else { + GST_ERROR_OBJECT (self, "Failed to get mirror parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + } + + GST_OBJECT_UNLOCK(self); + return result; + + } + +static gboolean +gst_omx_jepgdec_set_scale(GstOMXVideoDec *self) +{ + OMX_ERRORTYPE err; + OMX_CONFIG_SCALEFACTORTYPE scale_config; + gboolean result = TRUE; + GstOMXMJPEGDec * mjpeg_dec = GST_OMX_MJPEG_DEC (self); + + GST_OBJECT_LOCK(self); + + GST_OMX_INIT_STRUCT(&scale_config); + scale_config.nPortIndex = self->dec_out_port->index; + + err = gst_omx_component_get_config(self->dec, + OMX_IndexConfigCommonScale,&scale_config); + + if( err == OMX_ErrorNone){ + + if((mjpeg_dec->scaleV >= 0 && mjpeg_dec->scaleV <= 3 ) || + ( mjpeg_dec->scaleH >= 0 && mjpeg_dec->scaleH <= 3)){ + + scale_config.xWidth = (1 << 16) >>(mjpeg_dec->scaleH &0x3); + scale_config.xHeight = (1 << 16) >> (mjpeg_dec->scaleV &0x3); + } + + err = gst_omx_component_set_config(self->dec, + OMX_IndexConfigCommonScale,&scale_config); + + if (err == OMX_ErrorUnsupportedIndex) { + GST_WARNING_OBJECT (self, + "Setting a scale not supported by the component"); + } else if (err == OMX_ErrorUnsupportedSetting) { + GST_WARNING_OBJECT (self, + "Setting scale settings %u %u not supported by the component", + mjpeg_dec->scaleV,mjpeg_dec->scaleH); + } else if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Failed to set scale parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + result = FALSE; + } + } else { + GST_ERROR_OBJECT (self, "Failed to get scale parameters: %s (0x%08x)", + gst_omx_error_to_string (err), err); + } + + GST_OBJECT_UNLOCK(self); + return result; + + } \ No newline at end of file diff -purN a/omx/gstomxmjpegdec.h b/omx/gstomxmjpegdec.h --- a/omx/gstomxmjpegdec.h 2022-09-27 15:31:41.826975878 +0800 +++ b/omx/gstomxmjpegdec.h 2022-09-27 14:14:46.115432778 +0800 @@ -55,6 +55,10 @@ struct _GstOMXMJPEGDec // gst-launch-1.0 -v filesrc location=xxx.mjpeg ! jpegparse ! omxmjpegdec framerate=xxx ! kmssink driver-name=starfive force-modesetting=1 gint framerate; #endif + guint32 mirror; + guint32 scaleH; + guint32 scaleV; + guint32 rotation; }; struct _GstOMXMJPEGDecClass @@ -68,3 +72,18 @@ G_END_DECLS #endif /* __GST_OMX_MJPEG_DEC_H__ */ +typedef enum ROTATIONTYPE { + ROTATION_0 = 0, + ROTATION_90 = 90 , + ROTATION_180 = 180, + ROTATION_270 = 270, +} ROTATIONTYPE; + + +typedef enum SCALETYPE { + SCALEMODE_0 = 0, + SCALEMODE1_2 , + SCALEMODE1_4, + SCALEMODE1_8, +} SCALETYPE; +