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