hc
2023-02-14 0cc9b7c44253c93447ddf73e206fbdbb3d9f16b1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
From 98f949385c555b72e68db867969bf7bd3e642355 Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Mon, 29 Nov 2021 14:49:25 +0800
Subject: [PATCH 2/2] HACK: gstpad: Add 1 sec timeout for activation
 
When using ghost pad, changing the activation mode might cause
recursive waiting and hang the pipeline.
 
It's hard to fix it without bring in new issues, let's just add a
timeout as a workaround.
 
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
 gst/gstpad.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 
diff --git a/gst/gstpad.c b/gst/gstpad.c
index bccba4e..1c43e1e 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -964,6 +964,18 @@ gst_pad_mode_get_name (GstPadMode mode)
   return "unknown";
 }
 
+static inline void
+wait_activation_locked (GstPad * pad)
+{
+  /* HACK: 1 sec timeout for activation */
+  for (gint i = 0; i < 1000; i++) {
+    if (G_LIKELY (!pad->priv->in_activation))
+      break;
+
+    g_usleep(1000);
+  }
+}
+
 /* Returns TRUE if pad wasn't already in the new_mode */
 static gboolean
 pre_activate (GstPad * pad, GstPadMode new_mode)
@@ -971,8 +983,13 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
   switch (new_mode) {
     case GST_PAD_MODE_NONE:
       GST_OBJECT_LOCK (pad);
+#if 0
       while (G_UNLIKELY (pad->priv->in_activation))
         g_cond_wait (&pad->priv->activation_cond, GST_OBJECT_GET_LOCK (pad));
+#else
+      if (G_UNLIKELY (pad->priv->in_activation))
+        wait_activation_locked (pad);
+#endif
       if (new_mode == GST_PAD_MODE (pad)) {
         GST_WARNING_OBJECT (pad,
             "Pad is already in the process of being deactivated");
@@ -991,8 +1008,13 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
     case GST_PAD_MODE_PUSH:
     case GST_PAD_MODE_PULL:
       GST_OBJECT_LOCK (pad);
+#if 0
       while (G_UNLIKELY (pad->priv->in_activation))
         g_cond_wait (&pad->priv->activation_cond, GST_OBJECT_GET_LOCK (pad));
+#else
+      if (G_UNLIKELY (pad->priv->in_activation))
+        wait_activation_locked (pad);
+#endif
       if (new_mode == GST_PAD_MODE (pad)) {
         GST_WARNING_OBJECT (pad,
             "Pad is already in the process of being activated");
-- 
2.20.1