1*4882a593SmuzhiyunFrom c91768dd2ab61594ea316a519b9bf9fe67f8cdb0 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/11] 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 c0abb22..3999a98 100644 17*4882a593Smuzhiyun--- a/gst-libs/gst/video/meson.build 18*4882a593Smuzhiyun+++ b/gst-libs/gst/video/meson.build 19*4882a593Smuzhiyun@@ -111,7 +111,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 50bb7d6..a40a5e3 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 d279db8..3aae21a 100644 242*4882a593Smuzhiyun--- a/meson.build 243*4882a593Smuzhiyun+++ b/meson.build 244*4882a593Smuzhiyun@@ -292,6 +292,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 # GLib checks are for the entire project 254*4882a593Smuzhiyun-- 255*4882a593Smuzhiyun2.20.1 256*4882a593Smuzhiyun 257