summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gstreamer/gstlibcamera-utils.cpp105
-rw-r--r--src/gstreamer/gstlibcamera-utils.h19
-rw-r--r--src/gstreamer/meson.build1
3 files changed, 125 insertions, 0 deletions
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
new file mode 100644
index 00000000..386ec364
--- /dev/null
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+ *
+ * gstlibcamera-utils.c - GStreamer libcamera Utility Function
+ */
+
+#include "gstlibcamera-utils.h"
+
+#include <linux/drm_fourcc.h>
+
+using namespace libcamera;
+
+static struct {
+ GstVideoFormat gst_format;
+ guint drm_fourcc;
+} format_map[] = {
+ { GST_VIDEO_FORMAT_ENCODED, DRM_FORMAT_MJPEG },
+ { GST_VIDEO_FORMAT_RGB, DRM_FORMAT_BGR888 },
+ { GST_VIDEO_FORMAT_BGR, DRM_FORMAT_RGB888 },
+ { GST_VIDEO_FORMAT_ARGB, DRM_FORMAT_BGRA8888 },
+ { GST_VIDEO_FORMAT_NV12, DRM_FORMAT_NV12 },
+ { GST_VIDEO_FORMAT_NV21, DRM_FORMAT_NV21 },
+ { GST_VIDEO_FORMAT_NV16, DRM_FORMAT_NV16 },
+ { GST_VIDEO_FORMAT_NV61, DRM_FORMAT_NV61 },
+ { GST_VIDEO_FORMAT_NV24, DRM_FORMAT_NV24 },
+ { GST_VIDEO_FORMAT_UYVY, DRM_FORMAT_UYVY },
+ { GST_VIDEO_FORMAT_VYUY, DRM_FORMAT_VYUY },
+ { GST_VIDEO_FORMAT_YUY2, DRM_FORMAT_YUYV },
+ { GST_VIDEO_FORMAT_YVYU, DRM_FORMAT_YVYU },
+ /* \todo NV42 is used in libcamera but is not mapped in GStreamer yet. */
+};
+
+static GstVideoFormat
+drm_to_gst_format(guint drm_fourcc)
+{
+ for (const auto &item : format_map) {
+ if (item.drm_fourcc == drm_fourcc)
+ return item.gst_format;
+ }
+ return GST_VIDEO_FORMAT_UNKNOWN;
+}
+
+static GstStructure *
+bare_structure_from_fourcc(guint fourcc)
+{
+ GstVideoFormat gst_format = drm_to_gst_format(fourcc);
+
+ if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
+ return nullptr;
+
+ if (gst_format != GST_VIDEO_FORMAT_ENCODED)
+ return gst_structure_new("video/x-raw", "format", G_TYPE_STRING,
+ gst_video_format_to_string(gst_format), nullptr);
+
+ switch (fourcc) {
+ case DRM_FORMAT_MJPEG:
+ return gst_structure_new_empty("image/jpeg");
+ default:
+ return nullptr;
+ }
+}
+
+GstCaps *
+gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)
+{
+ GstCaps *caps = gst_caps_new_empty();
+
+ for (unsigned int fourcc : formats.pixelformats()) {
+ g_autoptr(GstStructure) bare_s = bare_structure_from_fourcc(fourcc);
+
+ if (!bare_s) {
+ GST_WARNING("Unsupported DRM format %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS(fourcc));
+ continue;
+ }
+
+ for (const Size &size : formats.sizes(fourcc)) {
+ GstStructure *s = gst_structure_copy(bare_s);
+ gst_structure_set(s,
+ "width", G_TYPE_INT, size.width,
+ "height", G_TYPE_INT, size.height,
+ nullptr);
+ gst_caps_append_structure(caps, s);
+ }
+
+ const SizeRange &range = formats.range(fourcc);
+ if (range.hStep && range.vStep) {
+ GstStructure *s = gst_structure_copy(bare_s);
+ GValue val = G_VALUE_INIT;
+
+ g_value_init(&val, GST_TYPE_INT_RANGE);
+ gst_value_set_int_range_step(&val, range.min.width, range.max.width, range.hStep);
+ gst_structure_set_value(s, "width", &val);
+ gst_value_set_int_range_step(&val, range.min.height, range.max.height, range.vStep);
+ gst_structure_set_value(s, "height", &val);
+ g_value_unset(&val);
+
+ gst_caps_append_structure(caps, s);
+ }
+ }
+
+ return caps;
+}
diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h
new file mode 100644
index 00000000..2e4e3042
--- /dev/null
+++ b/src/gstreamer/gstlibcamera-utils.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+ *
+ * gstlibcamera-utils.h - GStreamer libcamera Utility Functions
+ */
+
+#ifndef __GST_LIBCAMERA_UTILS_H__
+#define __GST_LIBCAMERA_UTILS_H__
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+#include <libcamera/stream.h>
+
+GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);
+
+#endif /* __GST_LIBCAMERA_UTILS_H__ */
diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build
index 490e030e..9b11a46f 100644
--- a/src/gstreamer/meson.build
+++ b/src/gstreamer/meson.build
@@ -1,4 +1,5 @@
libcamera_gst_sources = [
+ 'gstlibcamera-utils.cpp',
'gstlibcamera.c',
'gstlibcamerasrc.cpp',
]