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