From patchwork Wed Jan 29 03:32:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dufresne X-Patchwork-Id: 2748 Return-Path: Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 633B7608D4 for ; Wed, 29 Jan 2020 04:35:34 +0100 (CET) Received: from nicolas-tpx395.localdomain (unknown [IPv6:2002:c0de:c115:0:66fc:8b:2a38:8313]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: nicolas) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 53DCF28EA9F; Wed, 29 Jan 2020 03:35:33 +0000 (GMT) From: Nicolas Dufresne To: libcamera-devel@lists.libcamera.org Cc: Nicolas Dufresne Date: Tue, 28 Jan 2020 22:32:01 -0500 Message-Id: <20200129033210.278800-15-nicolas@ndufresne.ca> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200129033210.278800-1-nicolas@ndufresne.ca> References: <20200129033210.278800-1-nicolas@ndufresne.ca> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 14/23] gst: utils: Add StreamConfiguration helpers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jan 2020 03:35:35 -0000 From: Nicolas Dufresne This add helpers to deal with the conversion from StreamConfiguration to caps and vis-versa. This is needed to implement caps negotiation. Signed-off-by: Nicolas Dufresne --- src/gstreamer/gstlibcamera-utils.cpp | 61 ++++++++++++++++++++++++++++ src/gstreamer/gstlibcamera-utils.h | 3 ++ 2 files changed, 64 insertions(+) diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index 2540be0..d9b217a 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -41,6 +41,18 @@ drm_to_gst_format(guint drm_fourcc) return GST_VIDEO_FORMAT_UNKNOWN; } +static inline guint +gst_format_to_drm(GstVideoFormat gst_format) +{ + if (gst_format == GST_VIDEO_FORMAT_ENCODED) + return DRM_FORMAT_INVALID; + + for (guint i = 0; i < FORMAT_MAP_SIZE; i++) + if (format_map[i].gst_format == gst_format) + return format_map[i].drm_fourcc; + return DRM_FORMAT_INVALID; +} + static GstStructure * bare_structure_from_fourcc(guint fourcc) { @@ -100,3 +112,52 @@ gst_libcamera_stream_formats_to_caps(const StreamFormats &formats) return caps; } + +GstCaps * +gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg) +{ + GstCaps *caps = gst_caps_new_empty(); + GstStructure *s = bare_structure_from_fourcc(stream_cfg.pixelFormat); + + gst_structure_set(s, + "width", G_TYPE_INT, stream_cfg.size.width, + "height", G_TYPE_INT, stream_cfg.size.height, + NULL); + gst_caps_append_structure(caps, s); + + return caps; +} + +void +gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, + GstCaps *caps) +{ + GstVideoFormat gst_format = drm_to_gst_format(stream_cfg.pixelFormat); + + /* First fixate the caps using default configuration value */ + g_assert(gst_caps_is_writable(caps)); + caps = gst_caps_truncate(caps); + GstStructure *s = gst_caps_get_structure(caps, 0); + + gst_structure_fixate_field_nearest_int(s, "width", stream_cfg.size.width); + gst_structure_fixate_field_nearest_int(s, "height", stream_cfg.size.height); + + if (gst_structure_has_name(s, "video/x-raw")) { + const gchar *format = gst_video_format_to_string(gst_format); + gst_structure_fixate_field_string(s, "format", format); + } + + /* The configure the stream with the result. */ + if (gst_structure_has_name(s, "video/x-raw")) { + const gchar *format = gst_structure_get_string(s, "format"); + gst_format = gst_video_format_from_string(format); + stream_cfg.pixelFormat = gst_format_to_drm(gst_format); + } else if (gst_structure_has_name(s, "image/jpeg")) { + stream_cfg.pixelFormat = DRM_FORMAT_MJPEG; + } else { + g_critical("Unsupported media type: %s", gst_structure_get_name(s)); + } + + gst_structure_get_int(s, "width", (gint *)&stream_cfg.size.width); + gst_structure_get_int(s, "height", (gint *)&stream_cfg.size.height); +} diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index 528dc2c..91cfdcd 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -16,5 +16,8 @@ #define GST_OBJECT_LOCKER(obj) g_autoptr(GMutexLocker) locker = g_mutex_locker_new(GST_OBJECT_GET_LOCK(obj)) GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats); +GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg); +void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg, + GstCaps *caps); #endif /* __GST_LIBCAMERA_UTILS_H_ */