[libcamera-devel] [PATCH v2 02/27] gst: Add utility to convert StreamFormats to GstCaps
Nicolas Dufresne
nicolas.dufresne at collabora.com
Fri Mar 6 17:38:17 CET 2020
Le samedi 29 février 2020 à 15:17 +0200, Laurent Pinchart a écrit :
> Hi Nicolas,
>
> Thank you for the patch.
>
> On Thu, Feb 27, 2020 at 03:03:42PM -0500, Nicolas Dufresne wrote:
> > This transforms the basic information found in StreamFormats to GstCaps.
> > This can be handy to reply to early caps query or inside a device
> > provider. Note that we ignored generated range as they are harmful to
> > caps negotiation. We also don't simplify the caps for readability
> > reasons, so some of the discrete value may be included in a range.
> >
> > Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> > ---
> > src/gstreamer/gstlibcamera-utils.cpp | 98 ++++++++++++++++++++++++++++
> > src/gstreamer/gstlibcamera-utils.h | 18 +++++
> > src/gstreamer/meson.build | 1 +
> > 3 files changed, 117 insertions(+)
> > create mode 100644 src/gstreamer/gstlibcamera-utils.cpp
> > create mode 100644 src/gstreamer/gstlibcamera-utils.h
> >
> > diff --git a/src/gstreamer/gstlibcamera-utils.cpp
> > b/src/gstreamer/gstlibcamera-utils.cpp
> > new file mode 100644
> > index 0000000..dc129c3
> > --- /dev/null
> > +++ b/src/gstreamer/gstlibcamera-utils.cpp
> > @@ -0,0 +1,98 @@
> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> > +/*
> > + * Copyright (C) 2020, Collabora Ltd.
> > + * Author: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> > + *
> > + * gstlibcamera-utils.c - GStreamer libcamera Utility Function
> > + */
> > +
> > +#include "gstlibcamera-utils.h"
>
> Missing blank line here.
>
> > +#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 inline GstVideoFormat
I'm also dropping the inline here, which you asked and I missed in v2.
> > +drm_to_gst_format(guint drm_fourcc)
> > +{
> > + for (const auto &item : format_map)
>
> for (const auto &item : format_map) {
> > + if (item.drm_fourcc == drm_fourcc)
> > + return item.gst_format;
> }
>
> Sweet, I didn't know C++ allowed range loops on plain C arrays :-)
>
> > + 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);
> > + gst_structure_set(s,
> > + "width", GST_TYPE_INT_RANGE,
> > range.min.width, range.max.width, range.hStep,
> > + "height", GST_TYPE_INT_RANGE,
> > range.min.height, range.max.height, range.vStep,
> > + nullptr);
> > + 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 0000000..33160b8
> > --- /dev/null
> > +++ b/src/gstreamer/gstlibcamera-utils.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> > +/*
> > + * Copyright (C) 2020, Collabora Ltd.
> > + * Author: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> > + *
> > + * gstlibcamera-utils.h - GStreamer libcamera Utility Functions
> > + */
> > +
> > +#ifndef __GST_LIBCAMERA_UTILS_H_
>
> s/__GST_LIBCAMERA_UTILS_H_/__GST_LIBCAMERA_UTILS_H__/
>
> Missing
>
> #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_ */
>
> __GST_LIBCAMERA_UTILS_H__ here too.
>
> > diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build
> > index 832b8a5..f409107 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',
> > ]
More information about the libcamera-devel
mailing list