1From c703437f71ac74a184c3730b8f6ca1cc54c07374 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Tue, 19 Jul 2022 18:19:48 +0800
4Subject: [PATCH 3/4] HACK: caps: Consider dmabuf subset of system memory
5
6Note, this is only true when the dmabuf is mmapable.
7
8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9---
10 gst/gstcaps.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
11 1 file changed, 87 insertions(+)
12
13diff --git a/gst/gstcaps.c b/gst/gstcaps.c
14index bbb9211..5e726fe 100644
15--- a/gst/gstcaps.c
16+++ b/gst/gstcaps.c
17@@ -125,6 +125,23 @@ typedef struct _GstCapsImpl
18 /* lock to protect multiple invocations of static caps to caps conversion */
19 G_LOCK_DEFINE_STATIC (static_caps_lock);
20
21+#ifndef GST_CAPS_FEATURE_MEMORY_DMABUF
22+#define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
23+#endif
24+
25+/* HACK: dma memory would likely provide system memory through mmap */
26+static gboolean
27+gst_caps_features_drop_dma (GstCapsFeatures * features)
28+{
29+  if (gst_caps_features_is_any (features) ||
30+      !gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF))
31+    return FALSE;
32+
33+  gst_caps_features_remove (features, GST_CAPS_FEATURE_MEMORY_DMABUF);
34+  gst_caps_features_add (features, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
35+  return TRUE;
36+}
37+
38 static void gst_caps_transform_to_string (const GValue * src_value,
39     GValue * dest_value);
40 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
41@@ -1330,6 +1347,8 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
42     if (!f1)
43       f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
44
45+    f1 = gst_caps_features_copy (f1);
46+retry:
47     for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
48       s2 = gst_caps_get_structure_unchecked (superset, j);
49       f2 = gst_caps_get_features_unchecked (superset, j);
50@@ -1344,6 +1363,11 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
51       }
52     }
53
54+    if (j == -1 && gst_caps_features_drop_dma (f1))
55+      goto retry;
56+
57+    gst_caps_features_free (f1);
58+
59     /* If we found no superset for this subset structure
60      * we return FALSE immediately */
61     if (j == -1) {
62@@ -1586,10 +1610,26 @@ gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
63       features2 = gst_caps_get_features_unchecked (caps2, k);
64       if (!features2)
65         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
66+
67+      features1 = gst_caps_features_copy (features1);
68+      features2 = gst_caps_features_copy (features2);
69+retry:
70       if (gst_caps_features_is_equal (features1, features2) &&
71           gst_structure_can_intersect (struct1, struct2)) {
72+        gst_caps_features_free (features1);
73+        gst_caps_features_free (features2);
74         return TRUE;
75+      } else {
76+        if (gst_caps_features_drop_dma (features1))
77+          goto retry;
78+
79+        if (gst_caps_features_drop_dma (features2))
80+          goto retry;
81       }
82+
83+      gst_caps_features_free (features1);
84+      gst_caps_features_free (features2);
85+
86       /* move down left */
87       k++;
88       if (G_UNLIKELY (j == 0))
89@@ -1612,6 +1652,7 @@ gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
90   GstCapsFeatures *features2;
91   GstCaps *dest;
92   GstStructure *istruct;
93+  gboolean drop_dma = FALSE;
94
95   dest = gst_caps_new_empty ();
96   /* run zigzag on top line then right line, this preserves the caps order
97@@ -1632,6 +1673,8 @@ gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
98    */
99   len1 = GST_CAPS_LEN (caps1);
100   len2 = GST_CAPS_LEN (caps2);
101+
102+retry:
103   for (i = 0; i < len1 + len2 - 1; i++) {
104     /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
105     j = MIN (i, len1 - 1);
106@@ -1649,6 +1692,15 @@ gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
107       features2 = gst_caps_get_features_unchecked (caps2, k);
108       if (!features2)
109         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
110+
111+      features1 = gst_caps_features_copy (features1);
112+      features2 = gst_caps_features_copy (features2);
113+
114+      if (drop_dma) {
115+        gst_caps_features_drop_dma (features1);
116+        gst_caps_features_drop_dma (features2);
117+      }
118+
119       if (gst_caps_features_is_equal (features1, features2)) {
120         istruct = gst_structure_intersect (struct1, struct2);
121         if (istruct) {
122@@ -1662,6 +1714,10 @@ gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
123                 gst_caps_features_copy_conditional (features1));
124         }
125       }
126+
127+      gst_caps_features_free (features1);
128+      gst_caps_features_free (features2);
129+
130       /* move down left */
131       k++;
132       if (G_UNLIKELY (j == 0))
133@@ -1669,6 +1725,13 @@ gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
134       j--;
135     }
136   }
137+
138+  /* try without DMA */
139+  if (CAPS_IS_EMPTY (dest) && !drop_dma) {
140+    drop_dma = TRUE;
141+    goto retry;
142+  }
143+
144   return dest;
145 }
146
147@@ -1696,20 +1759,34 @@ gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
148   GstCapsFeatures *features2;
149   GstCaps *dest;
150   GstStructure *istruct;
151+  gboolean drop_dma = FALSE;
152
153   dest = gst_caps_new_empty ();
154   len1 = GST_CAPS_LEN (caps1);
155   len2 = GST_CAPS_LEN (caps2);
156+
157+retry:
158   for (i = 0; i < len1; i++) {
159     struct1 = gst_caps_get_structure_unchecked (caps1, i);
160     features1 = gst_caps_get_features_unchecked (caps1, i);
161     if (!features1)
162       features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
163+
164+    features1 = gst_caps_features_copy (features1);
165+
166     for (j = 0; j < len2; j++) {
167       struct2 = gst_caps_get_structure_unchecked (caps2, j);
168       features2 = gst_caps_get_features_unchecked (caps2, j);
169       if (!features2)
170         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
171+
172+      features2 = gst_caps_features_copy (features2);
173+
174+      if (drop_dma) {
175+        gst_caps_features_drop_dma (features1);
176+        gst_caps_features_drop_dma (features2);
177+      }
178+
179       if (gst_caps_features_is_equal (features1, features2)) {
180         istruct = gst_structure_intersect (struct1, struct2);
181         if (istruct) {
182@@ -1723,7 +1800,17 @@ gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
183                 gst_caps_features_copy_conditional (features1));
184         }
185       }
186+
187+      gst_caps_features_free (features2);
188     }
189+
190+    gst_caps_features_free (features1);
191+  }
192+
193+  /* try without DMA */
194+  if (CAPS_IS_EMPTY (dest) && !drop_dma) {
195+    drop_dma = TRUE;
196+    goto retry;
197   }
198
199   return dest;
200--
2012.20.1
202
203