From 8adcf79acecd3592ac6ff969b00d7cbf805ff941 Mon Sep 17 00:00:00 2001 From: Ashok Sidipotu Date: Fri, 10 Nov 2023 01:27:59 +0100 Subject: pipewire: Fix GST hang for unavailable cameras - GST pipeline or camera-gstreamer app hangs for a unavailable target. - To fix the issue gstpipewiresrc element in pipewire is enhanced to handle the pw_stream error in a better manner. Bug-AGL: SPEC-4881 Change-Id: Id67095b1ecf5e59d00f9c79e15c7464f27a43eb4 Signed-off-by: Ashok Sidipotu Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/29397 Tested-by: Jan-Simon Moeller Reviewed-by: Jan-Simon Moeller Reviewed-by: Marius Vlad --- .../0002-gst-avoid-reporting-error-twice.patch | 62 ++++++++++++++++++++++ ...src-break-out-of-wait_started-also-on-STA.patch | 38 +++++++++++++ .../pipewire/pipewire_0.3.83.bbappend | 2 + 3 files changed, 102 insertions(+) create mode 100644 meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-gst-avoid-reporting-error-twice.patch create mode 100644 meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gstpipewiresrc-break-out-of-wait_started-also-on-STA.patch diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-gst-avoid-reporting-error-twice.patch b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-gst-avoid-reporting-error-twice.patch new file mode 100644 index 000000000..fa123a07f --- /dev/null +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-gst-avoid-reporting-error-twice.patch @@ -0,0 +1,62 @@ +From cbb12450c2f258ef3ac8239889784e1a97dfeaa8 Mon Sep 17 00:00:00 2001 +From: George Kiagiadakis +Date: Wed, 8 Nov 2023 18:12:59 +0200 +Subject: [PATCH 1/2] gst: avoid reporting error twice + +First, make the error permanent by calling pw_stream_set_error() +and when this emits an error state again, report that to GStreamer. + +Do the same in pipewiresink, which didn't even have the +pw_stream_set_error() call before, so the stream wasn't really going +into an error state at all. + +Upstream-Status: Pipewire MR1763 merged +--- + src/gst/gstpipewiresink.c | 9 +++++++-- + src/gst/gstpipewiresrc.c | 10 +++++++--- + 2 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c +index 36d158095..001ede9d5 100644 +--- a/src/gst/gstpipewiresink.c ++++ b/src/gst/gstpipewiresink.c +@@ -532,8 +532,13 @@ on_state_changed (void *data, enum pw_stream_state old, enum pw_stream_state sta + pw_stream_trigger_process (pwsink->stream); + break; + case PW_STREAM_STATE_ERROR: +- GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, +- ("stream error: %s", error), (NULL)); ++ /* make the error permanent, if it is not already; ++ pw_stream_set_error() will recursively call us again */ ++ if (pw_stream_get_state (pwsink->stream, NULL) != PW_STREAM_STATE_ERROR) ++ pw_stream_set_error (pwsink->stream, -EPIPE, "%s", error); ++ else ++ GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, ++ ("stream error: %s", error), (NULL)); + break; + } + pw_thread_loop_signal (pwsink->core->loop, FALSE); +diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c +index 0514e4caa..e473338ba 100644 +--- a/src/gst/gstpipewiresrc.c ++++ b/src/gst/gstpipewiresrc.c +@@ -681,9 +681,13 @@ on_state_changed (void *data, + case PW_STREAM_STATE_STREAMING: + break; + case PW_STREAM_STATE_ERROR: +- pw_stream_set_error (pwsrc->stream, -EPIPE, "%s", error); +- GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, +- ("stream error: %s", error), (NULL)); ++ /* make the error permanent, if it is not already; ++ pw_stream_set_error() will recursively call us again */ ++ if (pw_stream_get_state (pwsrc->stream, NULL) != PW_STREAM_STATE_ERROR) ++ pw_stream_set_error (pwsrc->stream, -EPIPE, "%s", error); ++ else ++ GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ++ ("stream error: %s", error), (NULL)); + break; + } + pw_thread_loop_signal (pwsrc->core->loop, FALSE); +-- +2.41.0 + diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gstpipewiresrc-break-out-of-wait_started-also-on-STA.patch b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gstpipewiresrc-break-out-of-wait_started-also-on-STA.patch new file mode 100644 index 000000000..29bc50472 --- /dev/null +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gstpipewiresrc-break-out-of-wait_started-also-on-STA.patch @@ -0,0 +1,38 @@ +From 4fb8417b201033ae2de20032b44d52cae1394ff8 Mon Sep 17 00:00:00 2001 +From: George Kiagiadakis +Date: Wed, 8 Nov 2023 18:23:02 +0200 +Subject: [PATCH 2/2] gstpipewiresrc: break out of wait_started() also on + STATE_UNCONNECTED + +When the session manager sends an error to the client, it typically +also destroys the node after the error, which causes the stream to go +to STATE_UNCONNECTED via proxy_removed(). In that case, make sure +we exit the loop early, otherwise it will take 30 seconds to unblock +gst_element_set_state() + +Upstream-Status: Pipewire MR1763 merged +--- + src/gst/gstpipewiresrc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c +index e473338ba..e3b86b373 100644 +--- a/src/gst/gstpipewiresrc.c ++++ b/src/gst/gstpipewiresrc.c +@@ -783,10 +783,9 @@ wait_started (GstPipeWireSrc *this) + GST_DEBUG_OBJECT (this, "waiting for started signal, state now %s", + pw_stream_state_as_string (state)); + +- if (state == PW_STREAM_STATE_ERROR) +- break; +- +- if (this->flushing) { ++ if (state == PW_STREAM_STATE_ERROR || ++ state == PW_STREAM_STATE_UNCONNECTED || ++ this->flushing) { + state = PW_STREAM_STATE_ERROR; + break; + } +-- +2.41.0 + diff --git a/meta-pipewire/recipes-multimedia/pipewire/pipewire_0.3.83.bbappend b/meta-pipewire/recipes-multimedia/pipewire/pipewire_0.3.83.bbappend index beb7c0817..6b920abd3 100644 --- a/meta-pipewire/recipes-multimedia/pipewire/pipewire_0.3.83.bbappend +++ b/meta-pipewire/recipes-multimedia/pipewire/pipewire_0.3.83.bbappend @@ -1,5 +1,7 @@ SRC_URI += "\ file://0001-systemd-Do-not-override-rootprefix.patch \ + file://0002-gst-avoid-reporting-error-twice.patch \ + file://0003-gstpipewiresrc-break-out-of-wait_started-also-on-STA.patch \ " PACKAGECONFIG = "\ -- cgit 1.2.3-korg