Message ID | 20200227200407.490616-15-nicolas.dufresne@collabora.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Nicolas, Thank you for the patch. On Thu, Feb 27, 2020 at 03:03:54PM -0500, Nicolas Dufresne wrote: > This add helpers to deal with the conversion from StreamConfiguration s/add/adds/ > to caps and vis-versa. This is needed to implement caps negotiation. s/vis/vice/ > > Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> > --- > src/gstreamer/gstlibcamera-utils.cpp | 64 ++++++++++++++++++++++++++++ > src/gstreamer/gstlibcamera-utils.h | 3 ++ > 2 files changed, 67 insertions(+) > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp > index dc129c3..231f3c5 100644 > --- a/src/gstreamer/gstlibcamera-utils.cpp > +++ b/src/gstreamer/gstlibcamera-utils.cpp > @@ -40,6 +40,18 @@ drm_to_gst_format(guint drm_fourcc) > return GST_VIDEO_FORMAT_UNKNOWN; > } > > +static inline guint Shouldn't we let the compiler decide whether to inline the function ? > +gst_format_to_drm(GstVideoFormat gst_format) > +{ > + if (gst_format == GST_VIDEO_FORMAT_ENCODED) > + return DRM_FORMAT_INVALID; > + > + for (const auto &item : format_map) for (const auto &item : format_map) { > + if (item.gst_format == gst_format) > + return item.drm_fourcc; } Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > + return DRM_FORMAT_INVALID; > +} > + > static GstStructure * > bare_structure_from_fourcc(guint fourcc) > { > @@ -96,3 +108,55 @@ 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, > + nullptr); > + 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); > + } > + > + /* Then 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)); > + } > + > + gint width, height; > + gst_structure_get_int(s, "width", &width); > + gst_structure_get_int(s, "height", &height); > + stream_cfg.size.width = width; > + stream_cfg.size.height = height; > +} > diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h > index 737ca63..51898a0 100644 > --- a/src/gstreamer/gstlibcamera-utils.h > +++ b/src/gstreamer/gstlibcamera-utils.h > @@ -14,6 +14,9 @@ > #include <libcamera/stream.h> > > 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); > > /** > * \class GLibLocker
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index dc129c3..231f3c5 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -40,6 +40,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 (const auto &item : format_map) + if (item.gst_format == gst_format) + return item.drm_fourcc; + return DRM_FORMAT_INVALID; +} + static GstStructure * bare_structure_from_fourcc(guint fourcc) { @@ -96,3 +108,55 @@ 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, + nullptr); + 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); + } + + /* Then 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)); + } + + gint width, height; + gst_structure_get_int(s, "width", &width); + gst_structure_get_int(s, "height", &height); + stream_cfg.size.width = width; + stream_cfg.size.height = height; +} diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index 737ca63..51898a0 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -14,6 +14,9 @@ #include <libcamera/stream.h> 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); /** * \class GLibLocker
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 <nicolas.dufresne@collabora.com> --- src/gstreamer/gstlibcamera-utils.cpp | 64 ++++++++++++++++++++++++++++ src/gstreamer/gstlibcamera-utils.h | 3 ++ 2 files changed, 67 insertions(+)