From f6021e001603ed45e63236608c16770299a04435 Mon Sep 17 00:00:00 2001 From: Philippe Renon Date: Sat, 26 Nov 2016 13:34:26 +0100 Subject: [PATCH] opencv: account for sparse/padded formats when converting caps to cv image type https://bugzilla.gnome.org/show_bug.cgi?id=774576 --- gst-libs/gst/opencv/gstopencvutils.cpp | 79 +++++++++++++++++--------- gst-libs/gst/opencv/gstopencvutils.h | 5 +- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/gst-libs/gst/opencv/gstopencvutils.cpp b/gst-libs/gst/opencv/gstopencvutils.cpp index e070c707b6..92771e5316 100644 --- a/gst-libs/gst/opencv/gstopencvutils.cpp +++ b/gst-libs/gst/opencv/gstopencvutils.cpp @@ -26,17 +26,19 @@ #include "gstopencvutils.h" #include - gboolean gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width, gint * height, gint * ipldepth, gint * channels, GError ** err) { GstVideoInfo info; + gchar *caps_str; if (!gst_video_info_from_caps (&info, caps)) { - GST_ERROR ("Failed to get the videoinfo from caps"); + caps_str = gst_caps_to_string (caps); + GST_ERROR ("Failed to get video info from caps %s", caps_str); g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, - "No width/heighti/depth/channels in caps"); + "Failed to get video info from caps %s", caps_str); + g_free (caps_str); return FALSE; } @@ -48,35 +50,58 @@ gboolean gst_opencv_iplimage_params_from_video_info (GstVideoInfo * info, gint * width, gint * height, gint * ipldepth, gint * channels, GError ** err) { - gint depth = 0; - guint i; + GstVideoFormat format; + int cv_type; + + format = GST_VIDEO_INFO_FORMAT (info); + if (!gst_opencv_cv_image_type_from_video_format (format, &cv_type, err)) { + return FALSE; + } *width = GST_VIDEO_INFO_WIDTH (info); *height = GST_VIDEO_INFO_HEIGHT (info); - if (GST_VIDEO_INFO_IS_RGB (info)) - *channels = 3; - else if (GST_VIDEO_INFO_IS_GRAY (info)) - *channels = 1; - else { - g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, - "Unsupported video format %s", - gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info))); - return FALSE; + + *ipldepth = cvIplDepth (cv_type); + *channels = CV_MAT_CN (cv_type); + + return TRUE; +} + +gboolean +gst_opencv_cv_image_type_from_video_format (GstVideoFormat format, + int * cv_type, GError ** err) +{ + const gchar *format_str; + + switch (format) { + case GST_VIDEO_FORMAT_GRAY8: + *cv_type = CV_8UC1; + break; + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + *cv_type = CV_8UC3; + break; + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_ABGR: + *cv_type = CV_8UC4; + break; + case GST_VIDEO_FORMAT_GRAY16_LE: + case GST_VIDEO_FORMAT_GRAY16_BE: + *cv_type = CV_16UC1; + break; + default: + format_str = gst_video_format_to_string (format); + g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, + "Unsupported video format %s", format_str); + return FALSE; } - for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++) - depth += GST_VIDEO_INFO_COMP_DEPTH (info, i); - - if (depth / *channels == 8) { - /* TODO signdness? */ - *ipldepth = IPL_DEPTH_8U; - } else if (depth / *channels == 16) { - *ipldepth = IPL_DEPTH_16U; - } else { - g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, - "Unsupported depth/channels %d/%d", depth, *channels); - return FALSE; - } return TRUE; } diff --git a/gst-libs/gst/opencv/gstopencvutils.h b/gst-libs/gst/opencv/gstopencvutils.h index 4cd32d8b80..47d1c06860 100644 --- a/gst-libs/gst/opencv/gstopencvutils.h +++ b/gst-libs/gst/opencv/gstopencvutils.h @@ -29,7 +29,6 @@ #include #include - G_BEGIN_DECLS gboolean gst_opencv_parse_iplimage_params_from_caps @@ -40,7 +39,11 @@ gboolean gst_opencv_iplimage_params_from_video_info (GstVideoInfo * info, gint * width, gint * height, gint * depth, gint * channels, GError ** err); +gboolean gst_opencv_cv_image_type_from_video_format (GstVideoFormat format, + int * cv_type, GError ** err); + GstCaps * gst_opencv_caps_from_cv_image_type (int cv_type); + G_END_DECLS #endif /* __GST_OPENCV_UTILS__ */