1*4882a593SmuzhiyunFrom f397165ca764cb6023e6efa88afb0df643789ea6 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Thu, 31 Oct 2019 18:45:19 +0800
4*4882a593SmuzhiyunSubject: [PATCH 08/14] video-converter: Support rockchip RGA 2D accel
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunDisabled by default, set env GST_VIDEO_CONVERT_USE_RGA=1 to enable.
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9*4882a593Smuzhiyun---
10*4882a593Smuzhiyun gst-libs/gst/video/meson.build       |   2 +-
11*4882a593Smuzhiyun gst-libs/gst/video/video-converter.c | 180 +++++++++++++++++++++++++++
12*4882a593Smuzhiyun meson.build                          |   3 +
13*4882a593Smuzhiyun 3 files changed, 184 insertions(+), 1 deletion(-)
14*4882a593Smuzhiyun
15*4882a593Smuzhiyundiff --git a/gst-libs/gst/video/meson.build b/gst-libs/gst/video/meson.build
16*4882a593Smuzhiyunindex cc5b241..615444d 100644
17*4882a593Smuzhiyun--- a/gst-libs/gst/video/meson.build
18*4882a593Smuzhiyun+++ b/gst-libs/gst/video/meson.build
19*4882a593Smuzhiyun@@ -113,7 +113,7 @@ gstvideo_h = video_enums[1]
20*4882a593Smuzhiyun video_gen_sources = [gstvideo_h]
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun orcsrc = 'video-orc'
23*4882a593Smuzhiyun-gstvideo_deps = [gst_base_dep, libm]
24*4882a593Smuzhiyun+gstvideo_deps = [gst_base_dep, libm, rga_dep]
25*4882a593Smuzhiyun if have_orcc
26*4882a593Smuzhiyun   gstvideo_deps += [orc_dep]
27*4882a593Smuzhiyun   orc_h = custom_target(orcsrc + '.h',
28*4882a593Smuzhiyundiff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c
29*4882a593Smuzhiyunindex 9b77eab..c49d9a0 100644
30*4882a593Smuzhiyun--- a/gst-libs/gst/video/video-converter.c
31*4882a593Smuzhiyun+++ b/gst-libs/gst/video/video-converter.c
32*4882a593Smuzhiyun@@ -38,6 +38,11 @@
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include "video-orc.h"
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun+#ifdef HAVE_RGA
37*4882a593Smuzhiyun+#include <rga/rga.h>
38*4882a593Smuzhiyun+#include <rga/RgaApi.h>
39*4882a593Smuzhiyun+#endif
40*4882a593Smuzhiyun+
41*4882a593Smuzhiyun /**
42*4882a593Smuzhiyun  * SECTION:videoconverter
43*4882a593Smuzhiyun  * @title: GstVideoConverter
44*4882a593Smuzhiyun@@ -2742,6 +2747,169 @@ gst_video_converter_get_config (GstVideoConverter * convert)
45*4882a593Smuzhiyun   return convert->config;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun+#ifdef HAVE_RGA
49*4882a593Smuzhiyun+static RgaSURF_FORMAT
50*4882a593Smuzhiyun+get_rga_format (GstVideoFormat format)
51*4882a593Smuzhiyun+{
52*4882a593Smuzhiyun+  switch (format) {
53*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_BGRA:
54*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_BGRx:
55*4882a593Smuzhiyun+      return RK_FORMAT_BGRA_8888;
56*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_RGBA:
57*4882a593Smuzhiyun+      return RK_FORMAT_RGBA_8888;
58*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_RGBx:
59*4882a593Smuzhiyun+      return RK_FORMAT_RGBX_8888;
60*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_BGR:
61*4882a593Smuzhiyun+      return RK_FORMAT_BGR_888;
62*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_RGB:
63*4882a593Smuzhiyun+      return RK_FORMAT_RGB_888;
64*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_BGR16:
65*4882a593Smuzhiyun+      return RK_FORMAT_RGB_565;
66*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_NV12:
67*4882a593Smuzhiyun+      return RK_FORMAT_YCbCr_420_SP;
68*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_NV21:
69*4882a593Smuzhiyun+      return RK_FORMAT_YCrCb_420_SP;
70*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_I420:
71*4882a593Smuzhiyun+      return RK_FORMAT_YCbCr_420_P;
72*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_YV12:
73*4882a593Smuzhiyun+      return RK_FORMAT_YCrCb_420_P;
74*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_NV16:
75*4882a593Smuzhiyun+      return RK_FORMAT_YCbCr_422_SP;
76*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_NV61:
77*4882a593Smuzhiyun+      return RK_FORMAT_YCrCb_422_SP;
78*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_Y42B:
79*4882a593Smuzhiyun+      return RK_FORMAT_YCbCr_422_P;
80*4882a593Smuzhiyun+    case GST_VIDEO_FORMAT_NV12_10LE40:
81*4882a593Smuzhiyun+      return RK_FORMAT_YCbCr_420_SP_10B;
82*4882a593Smuzhiyun+    default:
83*4882a593Smuzhiyun+      return RK_FORMAT_UNKNOWN;
84*4882a593Smuzhiyun+  }
85*4882a593Smuzhiyun+}
86*4882a593Smuzhiyun+
87*4882a593Smuzhiyun+static gboolean
88*4882a593Smuzhiyun+get_rga_info (const GstVideoFrame * frame, rga_info_t * info,
89*4882a593Smuzhiyun+    int x, int y, int w, int h)
90*4882a593Smuzhiyun+{
91*4882a593Smuzhiyun+  GstVideoMeta *meta = gst_buffer_get_video_meta (frame->buffer);
92*4882a593Smuzhiyun+  const GstVideoInfo *vinfo = &frame->info;
93*4882a593Smuzhiyun+  RgaSURF_FORMAT format;
94*4882a593Smuzhiyun+  gint hstride, vstride0, i;
95*4882a593Smuzhiyun+  guint8 *ptr;
96*4882a593Smuzhiyun+
97*4882a593Smuzhiyun+  memset (info, 0, sizeof (rga_info_t));
98*4882a593Smuzhiyun+
99*4882a593Smuzhiyun+  if (!meta)
100*4882a593Smuzhiyun+    return FALSE;
101*4882a593Smuzhiyun+
102*4882a593Smuzhiyun+  hstride = meta->stride[0];
103*4882a593Smuzhiyun+  vstride0 = meta->n_planes == 1 ? meta->height : meta->offset[1] / hstride;
104*4882a593Smuzhiyun+
105*4882a593Smuzhiyun+  /* RGA requires contig buffer */
106*4882a593Smuzhiyun+  ptr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
107*4882a593Smuzhiyun+  for (i = 1; i < GST_VIDEO_FRAME_N_PLANES (frame); i++) {
108*4882a593Smuzhiyun+    gint size = GST_VIDEO_FRAME_PLANE_OFFSET (frame, i) -
109*4882a593Smuzhiyun+        GST_VIDEO_FRAME_PLANE_OFFSET (frame, i - 1);
110*4882a593Smuzhiyun+    gint vstride = size / meta->stride[i - 1];
111*4882a593Smuzhiyun+
112*4882a593Smuzhiyun+    ptr += size;
113*4882a593Smuzhiyun+    if (ptr != GST_VIDEO_FRAME_PLANE_DATA (frame, i))
114*4882a593Smuzhiyun+      return FALSE;
115*4882a593Smuzhiyun+
116*4882a593Smuzhiyun+    if ((meta->stride[i] != hstride && meta->stride[i] != hstride / 2) ||
117*4882a593Smuzhiyun+        (vstride != vstride0 && vstride != vstride0 / 2))
118*4882a593Smuzhiyun+      return FALSE;
119*4882a593Smuzhiyun+  }
120*4882a593Smuzhiyun+
121*4882a593Smuzhiyun+  format = get_rga_format (GST_VIDEO_INFO_FORMAT (vinfo));
122*4882a593Smuzhiyun+  switch (format) {
123*4882a593Smuzhiyun+    case RK_FORMAT_RGBX_8888:
124*4882a593Smuzhiyun+    case RK_FORMAT_RGBA_8888:
125*4882a593Smuzhiyun+    case RK_FORMAT_BGRA_8888:
126*4882a593Smuzhiyun+      hstride /= 4;
127*4882a593Smuzhiyun+      break;
128*4882a593Smuzhiyun+    case RK_FORMAT_RGB_888:
129*4882a593Smuzhiyun+    case RK_FORMAT_BGR_888:
130*4882a593Smuzhiyun+      hstride /= 3;
131*4882a593Smuzhiyun+      break;
132*4882a593Smuzhiyun+    case RK_FORMAT_RGB_565:
133*4882a593Smuzhiyun+      hstride /= 2;
134*4882a593Smuzhiyun+      break;
135*4882a593Smuzhiyun+    case RK_FORMAT_YCbCr_420_SP_10B:
136*4882a593Smuzhiyun+    case RK_FORMAT_YCbCr_422_SP:
137*4882a593Smuzhiyun+    case RK_FORMAT_YCrCb_422_SP:
138*4882a593Smuzhiyun+    case RK_FORMAT_YCbCr_422_P:
139*4882a593Smuzhiyun+    case RK_FORMAT_YCrCb_422_P:
140*4882a593Smuzhiyun+    case RK_FORMAT_YCbCr_420_SP:
141*4882a593Smuzhiyun+    case RK_FORMAT_YCrCb_420_SP:
142*4882a593Smuzhiyun+    case RK_FORMAT_YCbCr_420_P:
143*4882a593Smuzhiyun+    case RK_FORMAT_YCrCb_420_P:
144*4882a593Smuzhiyun+      /* RGA requires yuv image rect align to 2 */
145*4882a593Smuzhiyun+      x = (x + 1) & ~1;
146*4882a593Smuzhiyun+      y = (y + 1) & ~1;
147*4882a593Smuzhiyun+      w &= ~1;
148*4882a593Smuzhiyun+      h &= ~1;
149*4882a593Smuzhiyun+
150*4882a593Smuzhiyun+      if (vstride0 % 2)
151*4882a593Smuzhiyun+        return FALSE;
152*4882a593Smuzhiyun+      break;
153*4882a593Smuzhiyun+    default:
154*4882a593Smuzhiyun+      return FALSE;
155*4882a593Smuzhiyun+  }
156*4882a593Smuzhiyun+
157*4882a593Smuzhiyun+  info->virAddr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
158*4882a593Smuzhiyun+  info->mmuFlag = 1;
159*4882a593Smuzhiyun+
160*4882a593Smuzhiyun+  rga_set_rect (&info->rect, x, y, w, h, hstride, vstride0, format);
161*4882a593Smuzhiyun+  return TRUE;
162*4882a593Smuzhiyun+}
163*4882a593Smuzhiyun+
164*4882a593Smuzhiyun+static gboolean
165*4882a593Smuzhiyun+video_converter_try_rga (GstVideoConverter * convert,
166*4882a593Smuzhiyun+    const GstVideoFrame * src, GstVideoFrame * dest)
167*4882a593Smuzhiyun+{
168*4882a593Smuzhiyun+  rga_info_t src_info = { 0 };
169*4882a593Smuzhiyun+  rga_info_t dst_info = { 0 };
170*4882a593Smuzhiyun+  static int rga_supported = 1;
171*4882a593Smuzhiyun+  static int rga_inited = 0;
172*4882a593Smuzhiyun+  const char *buf;
173*4882a593Smuzhiyun+
174*4882a593Smuzhiyun+  buf = g_getenv ("GST_VIDEO_CONVERT_USE_RGA");
175*4882a593Smuzhiyun+  if (!buf || strcmp (buf, "1"))
176*4882a593Smuzhiyun+    return FALSE;
177*4882a593Smuzhiyun+
178*4882a593Smuzhiyun+  if (!rga_supported)
179*4882a593Smuzhiyun+    return FALSE;
180*4882a593Smuzhiyun+
181*4882a593Smuzhiyun+  if (!rga_inited) {
182*4882a593Smuzhiyun+    if (c_RkRgaInit () < 0) {
183*4882a593Smuzhiyun+      rga_supported = 0;
184*4882a593Smuzhiyun+      return FALSE;
185*4882a593Smuzhiyun+    }
186*4882a593Smuzhiyun+    rga_inited = 1;
187*4882a593Smuzhiyun+  }
188*4882a593Smuzhiyun+
189*4882a593Smuzhiyun+  if (!get_rga_info (src, &src_info, convert->in_x, convert->in_y,
190*4882a593Smuzhiyun+          convert->in_width, convert->in_height)) {
191*4882a593Smuzhiyun+    GST_DEBUG ("unsupported src info for RGA");
192*4882a593Smuzhiyun+    return FALSE;
193*4882a593Smuzhiyun+  }
194*4882a593Smuzhiyun+
195*4882a593Smuzhiyun+  if (!get_rga_info (dest, &dst_info, convert->out_x, convert->out_y,
196*4882a593Smuzhiyun+          convert->out_width, convert->out_height)) {
197*4882a593Smuzhiyun+    GST_DEBUG ("unsupported dst info for RGA");
198*4882a593Smuzhiyun+    return FALSE;
199*4882a593Smuzhiyun+  }
200*4882a593Smuzhiyun+
201*4882a593Smuzhiyun+  if (c_RkRgaBlit (&src_info, &dst_info, NULL) < 0) {
202*4882a593Smuzhiyun+    GST_DEBUG ("failed to blit with RGA");
203*4882a593Smuzhiyun+    return FALSE;
204*4882a593Smuzhiyun+  }
205*4882a593Smuzhiyun+
206*4882a593Smuzhiyun+  GST_DEBUG ("converted with RGA");
207*4882a593Smuzhiyun+  return TRUE;
208*4882a593Smuzhiyun+}
209*4882a593Smuzhiyun+#endif
210*4882a593Smuzhiyun+
211*4882a593Smuzhiyun /**
212*4882a593Smuzhiyun  * gst_video_converter_frame:
213*4882a593Smuzhiyun  * @convert: a #GstVideoConverter
214*4882a593Smuzhiyun@@ -2789,6 +2957,12 @@ gst_video_converter_frame (GstVideoConverter * convert,
215*4882a593Smuzhiyun           convert->out_width == 0 || convert->out_height == 0))
216*4882a593Smuzhiyun     return;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun+#ifdef HAVE_RGA
219*4882a593Smuzhiyun+  /* Accel convert with rockchip RGA */
220*4882a593Smuzhiyun+  if (video_converter_try_rga (convert, src, dest))
221*4882a593Smuzhiyun+    return;
222*4882a593Smuzhiyun+#endif
223*4882a593Smuzhiyun+
224*4882a593Smuzhiyun   convert->convert (convert, src, dest);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun@@ -7218,6 +7392,12 @@ convert_scale_planes (GstVideoConverter * convert,
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun   int i, n_planes;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun+#ifdef HAVE_RGA
232*4882a593Smuzhiyun+  /* Accel convert with rockchip RGA */
233*4882a593Smuzhiyun+  if (video_converter_try_rga (convert, src, dest))
234*4882a593Smuzhiyun+    return;
235*4882a593Smuzhiyun+#endif
236*4882a593Smuzhiyun+
237*4882a593Smuzhiyun   n_planes = GST_VIDEO_FRAME_N_PLANES (dest);
238*4882a593Smuzhiyun   for (i = 0; i < n_planes; i++) {
239*4882a593Smuzhiyun     if (convert->fconvert[i])
240*4882a593Smuzhiyundiff --git a/meson.build b/meson.build
241*4882a593Smuzhiyunindex 19a8347..4341e8e 100644
242*4882a593Smuzhiyun--- a/meson.build
243*4882a593Smuzhiyun+++ b/meson.build
244*4882a593Smuzhiyun@@ -305,6 +305,9 @@ if get_option('default_library') == 'static'
245*4882a593Smuzhiyun   gst_plugins_base_args += ['-DGST_STATIC_COMPILATION']
246*4882a593Smuzhiyun endif
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun+rga_dep = dependency('librga', required: false)
249*4882a593Smuzhiyun+core_conf.set('HAVE_RGA', rga_dep.found())
250*4882a593Smuzhiyun+
251*4882a593Smuzhiyun # X11 checks are for sys/ and tests/
252*4882a593Smuzhiyun x11_dep = dependency('x11', required : get_option('x11'))
253*4882a593Smuzhiyun # GIO is used by the GIO plugin, and by the TCP, SDP, and RTSP plugins
254*4882a593Smuzhiyun--
255*4882a593Smuzhiyun2.20.1
256*4882a593Smuzhiyun
257