From dc4c019c62abefc09e4903abea44bc36f3427452 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Fri, 1 Sep 2023 17:37:22 +0200 Subject: [PATCH] Video Capture PipeWire: Implement camera rotation support Support the Pipewire videotransform meta via the already existing shared infrastructure. This is needed for mobile devices which often have a 90 degree rotated camera - which is likely the reason there is already support in the shared code paths. Bug: webrtc:15464 Change-Id: I15223055d8675502ae326d270ebd2debbcfbfa50 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/318641 Reviewed-by: Ilya Nikolaevskiy Reviewed-by: Per Kjellander Commit-Queue: Ilya Nikolaevskiy Cr-Commit-Position: refs/heads/main@{#40708} --- .../linux/video_capture_pipewire.cc | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc index 46cfe9bc15..7b79f15a6c 100644 --- a/modules/video_capture/linux/video_capture_pipewire.cc +++ b/modules/video_capture/linux/video_capture_pipewire.cc @@ -301,6 +301,10 @@ void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) { &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))))); + params.push_back(reinterpret_cast(spa_pod_builder_add_object( + &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, + SPA_POD_Id(SPA_META_VideoTransform), SPA_PARAM_META_size, + SPA_POD_Int(sizeof(struct spa_meta_videotransform))))); pw_stream_update_params(stream_, params.data(), params.size()); } @@ -341,6 +345,19 @@ void VideoCaptureModulePipeWire::OnStreamProcess(void* data) { that->ProcessBuffers(); } +static VideoRotation VideorotationFromPipeWireTransform(uint32_t transform) { + switch (transform) { + case SPA_META_TRANSFORMATION_90: + return kVideoRotation_90; + case SPA_META_TRANSFORMATION_180: + return kVideoRotation_180; + case SPA_META_TRANSFORMATION_270: + return kVideoRotation_270; + default: + return kVideoRotation_0; + } +} + void VideoCaptureModulePipeWire::ProcessBuffers() { RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); @@ -349,6 +366,17 @@ void VideoCaptureModulePipeWire::ProcessBuffers() { h = static_cast( spa_buffer_find_meta_data(buffer->buffer, SPA_META_Header, sizeof(*h))); + struct spa_meta_videotransform* videotransform; + videotransform = + static_cast(spa_buffer_find_meta_data( + buffer->buffer, SPA_META_VideoTransform, sizeof(*videotransform))); + if (videotransform) { + VideoRotation rotation = + VideorotationFromPipeWireTransform(videotransform->transform); + SetCaptureRotation(rotation); + SetApplyRotation(rotation != kVideoRotation_0); + } + if (h->flags & SPA_META_HEADER_FLAG_CORRUPTED) { RTC_LOG(LS_INFO) << "Dropping corruped frame."; } else {