[libcamera-devel] [PATCH] gstreamer: src: Send image-orientation tag
Robert Mader
robert.mader at collabora.com
Wed Jun 14 18:21:53 CEST 2023
Matching the validated Transform of the configuration, if the transform
is not the Identity. As we currently always request a configuration with
`Identity` transform, this can be the case if camera has a rotation
property (90/180/270 degree) and the sensor can't do rotation in
question. Sending the orientation-tag allows downstream elements to
compensate accordingly.
This matches current pipewiresrc behavior and can be tested with e.g.:
gst-launch-1.0 libcamerasrc ! videoconvert ! videoflip video-direction=auto ! gtksink
Signed-off-by: Robert Mader <robert.mader at collabora.com>
---
src/gstreamer/gstlibcamera-utils.cpp | 24 ++++++++++++++++++++++++
src/gstreamer/gstlibcamera-utils.h | 3 +++
src/gstreamer/gstlibcamerasrc.cpp | 11 +++++++++++
3 files changed, 38 insertions(+)
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
index 750ec351..3bfbc354 100644
--- a/src/gstreamer/gstlibcamera-utils.cpp
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -553,3 +553,27 @@ gst_libcamera_get_camera_manager(int &ret)
return cm;
}
+
+const char *
+gst_libcamera_transform_to_tag_string(libcamera::Transform transform)
+{
+ switch (transform) {
+ case Transform::Rot90:
+ return "rotate-90";
+ case Transform::Rot180:
+ return "rotate-180";
+ case Transform::Rot270:
+ return "rotate-270";
+ case Transform::HFlip:
+ return "flip-rotate-0";
+ case Transform::VFlip:
+ return "flip-rotate-180";
+ case Transform::Transpose:
+ return "flip-rotate-270";
+ case Transform::Rot180Transpose:
+ return "flip-rotate-90";
+ case Transform::Identity:
+ default:
+ return "rotate-0";
+ }
+}
diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h
index fd304a8b..499533c4 100644
--- a/src/gstreamer/gstlibcamera-utils.h
+++ b/src/gstreamer/gstlibcamera-utils.h
@@ -11,6 +11,7 @@
#include <libcamera/camera_manager.h>
#include <libcamera/controls.h>
#include <libcamera/stream.h>
+#include <libcamera/transform.h>
#include <gst/gst.h>
#include <gst/video/video.h>
@@ -30,6 +31,8 @@ gboolean gst_task_resume(GstTask *task);
#endif
std::shared_ptr<libcamera::CameraManager> gst_libcamera_get_camera_manager(int &ret);
+const char *gst_libcamera_transform_to_tag_string(libcamera::Transform transform);
+
/**
* \class GLibLocker
* \brief A simple scoped mutex locker for GMutex
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index a10cbd4f..b41f52d7 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -461,6 +461,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
GLibRecLocker lock(&self->stream_lock);
GstLibcameraSrcState *state = self->state;
GstFlowReturn flow_ret = GST_FLOW_OK;
+ const char *transform_tag;
gint ret;
g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps");
@@ -519,6 +520,16 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
goto done;
}
+ transform_tag = gst_libcamera_transform_to_tag_string(state->config_->transform);
+ for (gsize i = 0; i < state->srcpads_.size(); i++) {
+ GstPad *srcpad = state->srcpads_[i];
+ GstEvent *tag_event;
+
+ tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION,
+ transform_tag, NULL));
+ gst_pad_push_event(srcpad, tag_event);
+ }
+
ret = state->cam_->configure(state->config_.get());
if (ret) {
GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
--
2.41.0
More information about the libcamera-devel
mailing list