Message ID | 20200129033210.278800-6-nicolas@ndufresne.ca |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Nicolas, Thank you for the patch. On Tue, Jan 28, 2020 at 10:31:52PM -0500, Nicolas Dufresne wrote: > From: Nicolas Dufresne <nicolas.dufresne@collabora.com> > > This simply add the boiler plate for pads on the source element. The s/add/adds/ > design is that we have one pad, called "src", that will always be > present, and then more pads can be requested prior in READY or less > state. Initially pads have one property "stream-role" that let you > decide which role this pad will have. > > Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> > --- > src/gstreamer/gstlibcamerapad.cpp | 101 ++++++++++++++++++++++++++++++ > src/gstreamer/gstlibcamerapad.h | 19 ++++++ > src/gstreamer/gstlibcamerasrc.cpp | 19 ++++++ > src/gstreamer/meson.build | 1 + > 4 files changed, 140 insertions(+) > create mode 100644 src/gstreamer/gstlibcamerapad.cpp > create mode 100644 src/gstreamer/gstlibcamerapad.h > > diff --git a/src/gstreamer/gstlibcamerapad.cpp b/src/gstreamer/gstlibcamerapad.cpp > new file mode 100644 > index 0000000..c6c22e4 > --- /dev/null > +++ b/src/gstreamer/gstlibcamerapad.cpp > @@ -0,0 +1,101 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2019, Collabora Ltd. > + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> > + * > + * gstlibcamerapad.cpp - GStreamer Capture Pad > + */ > + > +#include "gstlibcamerapad.h" > +#include "gstlibcamera-utils.h" > + > +#include <libcamera/stream.h> > + > +using namespace libcamera; > + > +struct _GstLibcameraPad { > + GstPad parent; > + StreamRole role; > +}; > + > +enum { > + PROP_0, > + PROP_STREAM_ROLE > +}; > + > +G_DEFINE_TYPE(GstLibcameraPad, gst_libcamera_pad, GST_TYPE_PAD); > + > +static void > +gst_libcamera_pad_set_property(GObject *object, guint prop_id, > + const GValue *value, GParamSpec *pspec) > +{ > + auto *self = GST_LIBCAMERA_PAD(object); > + GST_OBJECT_LOCKER(self); > + > + switch (prop_id) { > + case PROP_STREAM_ROLE: > + self->role = (StreamRole)g_value_get_enum(value); > + break; > + default: > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > + break; > + } > +} > + > +static void > +gst_libcamera_pad_get_property(GObject *object, guint prop_id, GValue *value, > + GParamSpec *pspec) > +{ > + auto *self = GST_LIBCAMERA_PAD(object); > + GST_OBJECT_LOCKER(self); > + > + switch (prop_id) { > + case PROP_STREAM_ROLE: > + g_value_set_enum(value, self->role); > + break; > + default: > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > + break; > + } > +} > + > +static void > +gst_libcamera_pad_init(GstLibcameraPad *self) > +{ > +} > + > +static GType > +gst_libcamera_stream_role_get_type(void) > +{ > + static GType type = 0; > + static const GEnumValue values[] = { > + { StillCapture, "libcamera::StillCapture", "still-capture" }, > + { VideoRecording, "libcamera::VideoRecording", "video-recording" }, > + { Viewfinder, "libcamera::Viewfinder", "view-finder" }, > + { 0, NULL, NULL } > + }; > + > + if (!type) > + type = g_enum_register_static("GstLibcameraStreamRole", values); > + > + return type; > +} > + > +static void > +gst_libcamera_pad_class_init(GstLibcameraPadClass *klass) > +{ > + auto *object_class = G_OBJECT_CLASS(klass); > + > + object_class->set_property = gst_libcamera_pad_set_property; > + object_class->get_property = gst_libcamera_pad_get_property; > + > + auto *spec = g_param_spec_enum("stream-role", "Stream Role", > + "The selected stream role", > + gst_libcamera_stream_role_get_type(), > + VideoRecording, > + (GParamFlags)(GST_PARAM_MUTABLE_READY > + | G_PARAM_CONSTRUCT > + | G_PARAM_READWRITE > + | G_PARAM_STATIC_STRINGS)); > + g_object_class_install_property(object_class, PROP_STREAM_ROLE, spec); > +} > diff --git a/src/gstreamer/gstlibcamerapad.h b/src/gstreamer/gstlibcamerapad.h > new file mode 100644 > index 0000000..2e745f1 > --- /dev/null > +++ b/src/gstreamer/gstlibcamerapad.h > @@ -0,0 +1,19 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2019, Collabora Ltd. > + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> > + * > + * gstlibcamerapad.h - GStreamer Capture Element > + */ > + > +#include <gst/gst.h> > + > +#ifndef __GST_LIBCAMERA_PAD_H__ > +#define __GST_LIBCAMERA_PAD_H__ > + > +#define GST_TYPE_LIBCAMERA_PAD gst_libcamera_pad_get_type() > +G_DECLARE_FINAL_TYPE(GstLibcameraPad, gst_libcamera_pad, > + GST_LIBCAMERA, PAD, GstPad) > + > + > +#endif /* __GST_LIBCAMERA_PAD_H__ */ > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp > index 39a06a4..a8bcede 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -7,6 +7,7 @@ > */ > > #include "gstlibcamerasrc.h" > +#include "gstlibcamerapad.h" Alphabetical order here too (I'll stop saying it now :-)). > > struct _GstLibcameraSrc { > GstElement parent; > @@ -14,6 +15,18 @@ struct _GstLibcameraSrc { > > G_DEFINE_TYPE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT); > > +#define TEMPLATE_CAPS GST_STATIC_CAPS("video/x-raw;image/jpeg") JPEG is only supported by UVC in libcamera. Should we default to a YUV format ? > + > +/* For the simple case, we have a src pad that is always present. */ > +GstStaticPadTemplate src_template = { > + "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS > +}; > + > +/* More pads can be requested in state < PAUSED */ > +GstStaticPadTemplate request_src_template = { > + "src_%s", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS > +}; > + > static void > gst_libcamera_src_init(GstLibcameraSrc *self) > { > @@ -28,4 +41,10 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) > "LibCamera Source", "Source/Video", > "Linux Camera source using libcamera", > "Nicolas Dufresne <nicolas.dufresne@collabora.com"); > + gst_element_class_add_static_pad_template_with_gtype(element_class, > + &src_template, > + GST_TYPE_LIBCAMERA_PAD); > + gst_element_class_add_static_pad_template_with_gtype(element_class, > + &request_src_template, > + GST_TYPE_LIBCAMERA_PAD); > } > diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build > index 7769b78..e497bf4 100644 > --- a/src/gstreamer/meson.build > +++ b/src/gstreamer/meson.build > @@ -3,6 +3,7 @@ libcamera_gst_sources = [ > 'gstlibcamera-utils.cpp', > 'gstlibcamerasrc.cpp', > 'gstlibcameraprovider.cpp', > + 'gstlibcamerapad.cpp', > ] > > libcamera_gst_c_args = [
On mar, 2020-02-11 at 21:21 +0200, Laurent Pinchart wrote: > Hi Nicolas, > > Thank you for the patch. > > On Tue, Jan 28, 2020 at 10:31:52PM -0500, Nicolas Dufresne wrote: > > From: Nicolas Dufresne <nicolas.dufresne@collabora.com> > > > > This simply add the boiler plate for pads on the source element. The > > s/add/adds/ > > > design is that we have one pad, called "src", that will always be > > present, and then more pads can be requested prior in READY or less > > state. Initially pads have one property "stream-role" that let you > > decide which role this pad will have. > > > > Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> > > --- > > src/gstreamer/gstlibcamerapad.cpp | 101 ++++++++++++++++++++++++++++++ > > src/gstreamer/gstlibcamerapad.h | 19 ++++++ > > src/gstreamer/gstlibcamerasrc.cpp | 19 ++++++ > > src/gstreamer/meson.build | 1 + > > 4 files changed, 140 insertions(+) > > create mode 100644 src/gstreamer/gstlibcamerapad.cpp > > create mode 100644 src/gstreamer/gstlibcamerapad.h > > > > diff --git a/src/gstreamer/gstlibcamerapad.cpp > > b/src/gstreamer/gstlibcamerapad.cpp > > new file mode 100644 > > index 0000000..c6c22e4 > > --- /dev/null > > +++ b/src/gstreamer/gstlibcamerapad.cpp > > @@ -0,0 +1,101 @@ > > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > > +/* > > + * Copyright (C) 2019, Collabora Ltd. > > + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> > > + * > > + * gstlibcamerapad.cpp - GStreamer Capture Pad > > + */ > > + > > +#include "gstlibcamerapad.h" > > +#include "gstlibcamera-utils.h" > > + > > +#include <libcamera/stream.h> > > + > > +using namespace libcamera; > > + > > +struct _GstLibcameraPad { > > + GstPad parent; > > + StreamRole role; > > +}; > > + > > +enum { > > + PROP_0, > > + PROP_STREAM_ROLE > > +}; > > + > > +G_DEFINE_TYPE(GstLibcameraPad, gst_libcamera_pad, GST_TYPE_PAD); > > + > > +static void > > +gst_libcamera_pad_set_property(GObject *object, guint prop_id, > > + const GValue *value, GParamSpec *pspec) > > +{ > > + auto *self = GST_LIBCAMERA_PAD(object); > > + GST_OBJECT_LOCKER(self); > > + > > + switch (prop_id) { > > + case PROP_STREAM_ROLE: > > + self->role = (StreamRole)g_value_get_enum(value); > > + break; > > + default: > > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > > + break; > > + } > > +} > > + > > +static void > > +gst_libcamera_pad_get_property(GObject *object, guint prop_id, GValue > > *value, > > + GParamSpec *pspec) > > +{ > > + auto *self = GST_LIBCAMERA_PAD(object); > > + GST_OBJECT_LOCKER(self); > > + > > + switch (prop_id) { > > + case PROP_STREAM_ROLE: > > + g_value_set_enum(value, self->role); > > + break; > > + default: > > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > > + break; > > + } > > +} > > + > > +static void > > +gst_libcamera_pad_init(GstLibcameraPad *self) > > +{ > > +} > > + > > +static GType > > +gst_libcamera_stream_role_get_type(void) > > +{ > > + static GType type = 0; > > + static const GEnumValue values[] = { > > + { StillCapture, "libcamera::StillCapture", "still-capture" }, > > + { VideoRecording, "libcamera::VideoRecording", "video-recording" > > }, > > + { Viewfinder, "libcamera::Viewfinder", "view-finder" }, > > + { 0, NULL, NULL } > > + }; > > + > > + if (!type) > > + type = g_enum_register_static("GstLibcameraStreamRole", values); > > + > > + return type; > > +} > > + > > +static void > > +gst_libcamera_pad_class_init(GstLibcameraPadClass *klass) > > +{ > > + auto *object_class = G_OBJECT_CLASS(klass); > > + > > + object_class->set_property = gst_libcamera_pad_set_property; > > + object_class->get_property = gst_libcamera_pad_get_property; > > + > > + auto *spec = g_param_spec_enum("stream-role", "Stream Role", > > + "The selected stream role", > > + gst_libcamera_stream_role_get_type(), > > + VideoRecording, > > + (GParamFlags)(GST_PARAM_MUTABLE_READY > > + | G_PARAM_CONSTRUCT > > + | G_PARAM_READWRITE > > + | G_PARAM_STATIC_STRINGS)); > > + g_object_class_install_property(object_class, PROP_STREAM_ROLE, spec); > > +} > > diff --git a/src/gstreamer/gstlibcamerapad.h > > b/src/gstreamer/gstlibcamerapad.h > > new file mode 100644 > > index 0000000..2e745f1 > > --- /dev/null > > +++ b/src/gstreamer/gstlibcamerapad.h > > @@ -0,0 +1,19 @@ > > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > > +/* > > + * Copyright (C) 2019, Collabora Ltd. > > + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> > > + * > > + * gstlibcamerapad.h - GStreamer Capture Element > > + */ > > + > > +#include <gst/gst.h> > > + > > +#ifndef __GST_LIBCAMERA_PAD_H__ > > +#define __GST_LIBCAMERA_PAD_H__ > > + > > +#define GST_TYPE_LIBCAMERA_PAD gst_libcamera_pad_get_type() > > +G_DECLARE_FINAL_TYPE(GstLibcameraPad, gst_libcamera_pad, > > + GST_LIBCAMERA, PAD, GstPad) > > + > > + > > +#endif /* __GST_LIBCAMERA_PAD_H__ */ > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp > > b/src/gstreamer/gstlibcamerasrc.cpp > > index 39a06a4..a8bcede 100644 > > --- a/src/gstreamer/gstlibcamerasrc.cpp > > +++ b/src/gstreamer/gstlibcamerasrc.cpp > > @@ -7,6 +7,7 @@ > > */ > > > > #include "gstlibcamerasrc.h" > > +#include "gstlibcamerapad.h" > > Alphabetical order here too (I'll stop saying it now :-)). > > > > > struct _GstLibcameraSrc { > > GstElement parent; > > @@ -14,6 +15,18 @@ struct _GstLibcameraSrc { > > > > G_DEFINE_TYPE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT); > > > > +#define TEMPLATE_CAPS GST_STATIC_CAPS("video/x-raw;image/jpeg") > > JPEG is only supported by UVC in libcamera. Should we default to a YUV > format ? It uses video/x-raw first followed by jpeg, which include all video formats that are not compressed. This could benefit from a space after ";" in the caps string. It's a bit hard to read this way. > > > + > > +/* For the simple case, we have a src pad that is always present. */ > > +GstStaticPadTemplate src_template = { > > + "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS > > +}; > > + > > +/* More pads can be requested in state < PAUSED */ > > +GstStaticPadTemplate request_src_template = { > > + "src_%s", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS > > +}; > > + > > static void > > gst_libcamera_src_init(GstLibcameraSrc *self) > > { > > @@ -28,4 +41,10 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) > > "LibCamera Source", "Source/Video", > > "Linux Camera source using libcamera", > > "Nicolas Dufresne < > > nicolas.dufresne@collabora.com"); > > + gst_element_class_add_static_pad_template_with_gtype(element_class, > > + &src_template, > > + GST_TYPE_LIBCAMERA_ > > PAD); > > + gst_element_class_add_static_pad_template_with_gtype(element_class, > > + &request_src_templa > > te, > > + GST_TYPE_LIBCAMERA_ > > PAD); > > } > > diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build > > index 7769b78..e497bf4 100644 > > --- a/src/gstreamer/meson.build > > +++ b/src/gstreamer/meson.build > > @@ -3,6 +3,7 @@ libcamera_gst_sources = [ > > 'gstlibcamera-utils.cpp', > > 'gstlibcamerasrc.cpp', > > 'gstlibcameraprovider.cpp', > > + 'gstlibcamerapad.cpp', > > ] > > > > libcamera_gst_c_args = [
diff --git a/src/gstreamer/gstlibcamerapad.cpp b/src/gstreamer/gstlibcamerapad.cpp new file mode 100644 index 0000000..c6c22e4 --- /dev/null +++ b/src/gstreamer/gstlibcamerapad.cpp @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Collabora Ltd. + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> + * + * gstlibcamerapad.cpp - GStreamer Capture Pad + */ + +#include "gstlibcamerapad.h" +#include "gstlibcamera-utils.h" + +#include <libcamera/stream.h> + +using namespace libcamera; + +struct _GstLibcameraPad { + GstPad parent; + StreamRole role; +}; + +enum { + PROP_0, + PROP_STREAM_ROLE +}; + +G_DEFINE_TYPE(GstLibcameraPad, gst_libcamera_pad, GST_TYPE_PAD); + +static void +gst_libcamera_pad_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + auto *self = GST_LIBCAMERA_PAD(object); + GST_OBJECT_LOCKER(self); + + switch (prop_id) { + case PROP_STREAM_ROLE: + self->role = (StreamRole)g_value_get_enum(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_libcamera_pad_get_property(GObject *object, guint prop_id, GValue *value, + GParamSpec *pspec) +{ + auto *self = GST_LIBCAMERA_PAD(object); + GST_OBJECT_LOCKER(self); + + switch (prop_id) { + case PROP_STREAM_ROLE: + g_value_set_enum(value, self->role); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +gst_libcamera_pad_init(GstLibcameraPad *self) +{ +} + +static GType +gst_libcamera_stream_role_get_type(void) +{ + static GType type = 0; + static const GEnumValue values[] = { + { StillCapture, "libcamera::StillCapture", "still-capture" }, + { VideoRecording, "libcamera::VideoRecording", "video-recording" }, + { Viewfinder, "libcamera::Viewfinder", "view-finder" }, + { 0, NULL, NULL } + }; + + if (!type) + type = g_enum_register_static("GstLibcameraStreamRole", values); + + return type; +} + +static void +gst_libcamera_pad_class_init(GstLibcameraPadClass *klass) +{ + auto *object_class = G_OBJECT_CLASS(klass); + + object_class->set_property = gst_libcamera_pad_set_property; + object_class->get_property = gst_libcamera_pad_get_property; + + auto *spec = g_param_spec_enum("stream-role", "Stream Role", + "The selected stream role", + gst_libcamera_stream_role_get_type(), + VideoRecording, + (GParamFlags)(GST_PARAM_MUTABLE_READY + | G_PARAM_CONSTRUCT + | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(object_class, PROP_STREAM_ROLE, spec); +} diff --git a/src/gstreamer/gstlibcamerapad.h b/src/gstreamer/gstlibcamerapad.h new file mode 100644 index 0000000..2e745f1 --- /dev/null +++ b/src/gstreamer/gstlibcamerapad.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Collabora Ltd. + * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com> + * + * gstlibcamerapad.h - GStreamer Capture Element + */ + +#include <gst/gst.h> + +#ifndef __GST_LIBCAMERA_PAD_H__ +#define __GST_LIBCAMERA_PAD_H__ + +#define GST_TYPE_LIBCAMERA_PAD gst_libcamera_pad_get_type() +G_DECLARE_FINAL_TYPE(GstLibcameraPad, gst_libcamera_pad, + GST_LIBCAMERA, PAD, GstPad) + + +#endif /* __GST_LIBCAMERA_PAD_H__ */ diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 39a06a4..a8bcede 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -7,6 +7,7 @@ */ #include "gstlibcamerasrc.h" +#include "gstlibcamerapad.h" struct _GstLibcameraSrc { GstElement parent; @@ -14,6 +15,18 @@ struct _GstLibcameraSrc { G_DEFINE_TYPE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT); +#define TEMPLATE_CAPS GST_STATIC_CAPS("video/x-raw;image/jpeg") + +/* For the simple case, we have a src pad that is always present. */ +GstStaticPadTemplate src_template = { + "src", GST_PAD_SRC, GST_PAD_ALWAYS, TEMPLATE_CAPS +}; + +/* More pads can be requested in state < PAUSED */ +GstStaticPadTemplate request_src_template = { + "src_%s", GST_PAD_SRC, GST_PAD_REQUEST, TEMPLATE_CAPS +}; + static void gst_libcamera_src_init(GstLibcameraSrc *self) { @@ -28,4 +41,10 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) "LibCamera Source", "Source/Video", "Linux Camera source using libcamera", "Nicolas Dufresne <nicolas.dufresne@collabora.com"); + gst_element_class_add_static_pad_template_with_gtype(element_class, + &src_template, + GST_TYPE_LIBCAMERA_PAD); + gst_element_class_add_static_pad_template_with_gtype(element_class, + &request_src_template, + GST_TYPE_LIBCAMERA_PAD); } diff --git a/src/gstreamer/meson.build b/src/gstreamer/meson.build index 7769b78..e497bf4 100644 --- a/src/gstreamer/meson.build +++ b/src/gstreamer/meson.build @@ -3,6 +3,7 @@ libcamera_gst_sources = [ 'gstlibcamera-utils.cpp', 'gstlibcamerasrc.cpp', 'gstlibcameraprovider.cpp', + 'gstlibcamerapad.cpp', ] libcamera_gst_c_args = [