1From 7c5f1171ff553accc588bd00500bf03b8a5de517 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Wed, 6 Nov 2019 15:07:44 +0800
4Subject: [PATCH 04/12] v4l2: Support preferred formats
5
6Set env "GST_V4L2_PREFERRED_FOURCC" to specify preferred formats, for
7example:
8export GST_V4L2SRC_PREFERRED_FOURCC=YU12:NV12
9
10Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
11---
12 sys/v4l2/gstv4l2object.c | 17 +++++++++++++++++
13 sys/v4l2/gstv4l2src.c    | 37 +++++++++++++++++++++++++++++++++++++
14 2 files changed, 54 insertions(+)
15
16diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
17index 032fd69..19ae751 100644
18--- a/sys/v4l2/gstv4l2object.c
19+++ b/sys/v4l2/gstv4l2object.c
20@@ -25,6 +25,7 @@
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <errno.h>
24+#include <stdlib.h>
25 #include <string.h>
26 #include <sys/mman.h>
27 #include <sys/ioctl.h>
28@@ -1142,6 +1143,22 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
29       break;
30   }
31
32+  {
33+    const char *buf = g_getenv ("GST_V4L2_PREFERRED_FOURCC");
34+    int max_rank = YUV_BASE_RANK * 2;
35+
36+    while (buf) {
37+      if (buf[0] == ':')
38+        buf++;
39+
40+      if (!strncmp (buf, (char *) &fourcc, 4))
41+        rank = max_rank;
42+
43+      buf = strchr (buf, ':');
44+      max_rank--;
45+    }
46+  }
47+
48   /* All ranks are below 1<<15 so a shift by 15
49    * will a) make all non-emulated formats larger
50    * than emulated and b) will not overflow
51diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
52index e33b71e..4cc4cdf 100644
53--- a/sys/v4l2/gstv4l2src.c
54+++ b/sys/v4l2/gstv4l2src.c
55@@ -438,6 +438,38 @@ gst_v4l2_src_parse_fixed_struct (GstStructure * s,
56     gst_structure_get_fraction (s, "framerate", fps_n, fps_d);
57 }
58
59+static gint
60+gst_v4l2src_get_format_loss (GstStructure * s)
61+{
62+  GstVideoFormat format;
63+  const gchar *buf = g_getenv ("GST_V4L2_PREFERRED_FOURCC");
64+  guint32 fourcc, loss;
65+
66+  if (!buf)
67+    return 0;
68+
69+  format =
70+      gst_video_format_from_string (gst_structure_get_string (s, "format"));
71+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
72+    return 0;
73+
74+  fourcc = gst_video_format_to_fourcc (format);
75+
76+  loss = 0;
77+  while (buf) {
78+    if (buf[0] == ':')
79+      buf++;
80+
81+    if (!strncmp (buf, (char *) &fourcc, 4))
82+      return loss;
83+
84+    buf = strchr (buf, ':');
85+    loss++;
86+  }
87+
88+  return loss;
89+}
90+
91 /* TODO Consider framerate */
92 static gint
93 gst_v4l2src_fixed_caps_compare (GstCaps * caps_a, GstCaps * caps_b,
94@@ -490,6 +522,11 @@ gst_v4l2src_fixed_caps_compare (GstCaps * caps_a, GstCaps * caps_b,
95   if (bh == pref->height)
96     bd -= 1;
97
98+  if (ad == bd) {
99+    ad = gst_v4l2src_get_format_loss (a);
100+    bd = gst_v4l2src_get_format_loss (b);
101+  }
102+
103   /* If the choices are equivalent, maintain the order */
104   if (ad == bd)
105     ret = 1;
106--
1072.20.1
108
109