| /* GStreamer |
| * Copyright (C) <2010> Thiago Santos <thiago.sousa.santos@collabora.co.uk> |
| * |
| * gstopencvutils.c: miscellaneous utility functions |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include "gstopencvutils.h" |
| #include <opencv2/core/types_c.h> |
| |
| static gboolean |
| gst_opencv_get_ipl_depth_and_channels (GstStructure * structure, |
| gint * ipldepth, gint * channels, GError ** err) |
| { |
| GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; |
| const GstVideoFormatInfo *info; |
| gint depth = 0, i; |
| const gchar *s; |
| |
| if (gst_structure_has_name (structure, "video/x-raw")) { |
| if (!(s = gst_structure_get_string (structure, "format"))) |
| return FALSE; |
| format = gst_video_format_from_string (s); |
| if (format == GST_VIDEO_FORMAT_UNKNOWN) |
| return FALSE; |
| } |
| |
| info = gst_video_format_get_info (format); |
| |
| if (GST_VIDEO_FORMAT_INFO_IS_RGB (info)) |
| *channels = 3; |
| else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (info)) |
| *channels = 1; |
| else { |
| g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, |
| "Unsupported structure %s", gst_structure_get_name (structure)); |
| return FALSE; |
| } |
| |
| for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_COMPONENTS (info); i++) |
| depth += GST_VIDEO_FORMAT_INFO_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; |
| } |
| |
| gboolean |
| gst_opencv_parse_iplimage_params_from_structure (GstStructure * structure, |
| gint * width, gint * height, gint * ipldepth, gint * channels, |
| GError ** err) |
| { |
| if (!gst_opencv_get_ipl_depth_and_channels (structure, ipldepth, channels, |
| err)) { |
| return FALSE; |
| } |
| |
| if (!gst_structure_get_int (structure, "width", width) || |
| !gst_structure_get_int (structure, "height", height)) { |
| g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, |
| "No width/height in caps"); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| gboolean |
| gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width, |
| gint * height, gint * ipldepth, gint * channels, GError ** err) |
| { |
| GstVideoInfo info; |
| gint i, depth = 0; |
| |
| if (!gst_video_info_from_caps (&info, caps)) { |
| GST_ERROR ("Failed to get the videoinfo from caps"); |
| g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, |
| "No width/heighti/depth/channels in caps"); |
| 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 caps %s", gst_caps_to_string (caps)); |
| 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; |
| } |
| |
| GstCaps * |
| gst_opencv_caps_from_cv_image_type (int cv_type) |
| { |
| GstCaps *c = gst_caps_new_empty (); |
| switch (cv_type) { |
| case CV_8UC1: |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("GRAY8"))); |
| break; |
| case CV_8UC3: |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGB"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("BGR"))); |
| break; |
| case CV_8UC4: |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGBx"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("xRGB"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("BGRx"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("xBGR"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGBA"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("ARGB"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("BGRA"))); |
| gst_caps_append (c, gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("ABGR"))); |
| break; |
| case CV_16UC1: |
| gst_caps_append (c, |
| gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("GRAY16_LE"))); |
| gst_caps_append (c, |
| gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("GRAY16_BE"))); |
| break; |
| } |
| return c; |
| } |