1*4882a593SmuzhiyunFrom 02517deddcd968b332eb6d996d00609b4784a980 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Fri, 8 Nov 2019 17:36:20 +0800 4*4882a593SmuzhiyunSubject: [PATCH 05/12] video-flip: Support rockchip RGA 2D accel 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunDisabled by default, set env GST_VIDEO_FLIP_USE_RGA=1 to enable. 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 9*4882a593Smuzhiyun--- 10*4882a593Smuzhiyun gst/videofilter/gstvideoflip.c | 216 ++++++++++++++++++++++++++++++++- 11*4882a593Smuzhiyun gst/videofilter/meson.build | 2 +- 12*4882a593Smuzhiyun meson.build | 3 + 13*4882a593Smuzhiyun 3 files changed, 218 insertions(+), 3 deletions(-) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyundiff --git a/gst/videofilter/gstvideoflip.c b/gst/videofilter/gstvideoflip.c 16*4882a593Smuzhiyunindex 07db899..9ea405b 100644 17*4882a593Smuzhiyun--- a/gst/videofilter/gstvideoflip.c 18*4882a593Smuzhiyun+++ b/gst/videofilter/gstvideoflip.c 19*4882a593Smuzhiyun@@ -48,6 +48,11 @@ 20*4882a593Smuzhiyun #include <gst/gst.h> 21*4882a593Smuzhiyun #include <gst/video/video.h> 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun+#ifdef HAVE_RGA 24*4882a593Smuzhiyun+#include <rga/rga.h> 25*4882a593Smuzhiyun+#include <rga/RgaApi.h> 26*4882a593Smuzhiyun+#endif 27*4882a593Smuzhiyun+ 28*4882a593Smuzhiyun /* GstVideoFlip properties */ 29*4882a593Smuzhiyun enum 30*4882a593Smuzhiyun { 31*4882a593Smuzhiyun@@ -68,7 +73,7 @@ GST_STATIC_PAD_TEMPLATE ("src", 32*4882a593Smuzhiyun GST_PAD_ALWAYS, 33*4882a593Smuzhiyun GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, " 34*4882a593Smuzhiyun "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, " 35*4882a593Smuzhiyun- "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21," 36*4882a593Smuzhiyun+ "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, NV12_10LE40, " 37*4882a593Smuzhiyun "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, " 38*4882a593Smuzhiyun "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }")) 39*4882a593Smuzhiyun ); 40*4882a593Smuzhiyun@@ -79,7 +84,7 @@ GST_STATIC_PAD_TEMPLATE ("sink", 41*4882a593Smuzhiyun GST_PAD_ALWAYS, 42*4882a593Smuzhiyun GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, " 43*4882a593Smuzhiyun "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, " 44*4882a593Smuzhiyun- "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21," 45*4882a593Smuzhiyun+ "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, NV12_10LE40, " 46*4882a593Smuzhiyun "GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, " 47*4882a593Smuzhiyun "I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }")) 48*4882a593Smuzhiyun ); 49*4882a593Smuzhiyun@@ -1454,6 +1459,193 @@ gst_video_flip_y422 (GstVideoFlip * videoflip, GstVideoFrame * dest, 50*4882a593Smuzhiyun } 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun+#ifdef HAVE_RGA 54*4882a593Smuzhiyun+static RgaSURF_FORMAT 55*4882a593Smuzhiyun+get_rga_format (GstVideoFormat format) 56*4882a593Smuzhiyun+{ 57*4882a593Smuzhiyun+ switch (format) { 58*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_BGRA: 59*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_BGRx: 60*4882a593Smuzhiyun+ return RK_FORMAT_BGRA_8888; 61*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_RGBA: 62*4882a593Smuzhiyun+ return RK_FORMAT_RGBA_8888; 63*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_RGBx: 64*4882a593Smuzhiyun+ return RK_FORMAT_RGBX_8888; 65*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_BGR: 66*4882a593Smuzhiyun+ return RK_FORMAT_BGR_888; 67*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_RGB: 68*4882a593Smuzhiyun+ return RK_FORMAT_RGB_888; 69*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_RGB16: 70*4882a593Smuzhiyun+ return RK_FORMAT_RGB_565; 71*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV12: 72*4882a593Smuzhiyun+ return RK_FORMAT_YCbCr_420_SP; 73*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV21: 74*4882a593Smuzhiyun+ return RK_FORMAT_YCrCb_420_SP; 75*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_I420: 76*4882a593Smuzhiyun+ return RK_FORMAT_YCbCr_420_P; 77*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_YV12: 78*4882a593Smuzhiyun+ return RK_FORMAT_YCrCb_420_P; 79*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV16: 80*4882a593Smuzhiyun+ return RK_FORMAT_YCbCr_422_SP; 81*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV61: 82*4882a593Smuzhiyun+ return RK_FORMAT_YCrCb_422_SP; 83*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_Y42B: 84*4882a593Smuzhiyun+ return RK_FORMAT_YCbCr_422_P; 85*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV12_10LE40: 86*4882a593Smuzhiyun+ return RK_FORMAT_YCbCr_420_SP_10B; 87*4882a593Smuzhiyun+ default: 88*4882a593Smuzhiyun+ return RK_FORMAT_UNKNOWN; 89*4882a593Smuzhiyun+ } 90*4882a593Smuzhiyun+} 91*4882a593Smuzhiyun+ 92*4882a593Smuzhiyun+static gboolean 93*4882a593Smuzhiyun+get_rga_info (const GstVideoFrame * frame, rga_info_t * info, 94*4882a593Smuzhiyun+ int x, int y, int w, int h) 95*4882a593Smuzhiyun+{ 96*4882a593Smuzhiyun+ GstVideoMeta *meta = gst_buffer_get_video_meta (frame->buffer); 97*4882a593Smuzhiyun+ const GstVideoInfo *vinfo = &frame->info; 98*4882a593Smuzhiyun+ RgaSURF_FORMAT format; 99*4882a593Smuzhiyun+ gint hstride, vstride0, i; 100*4882a593Smuzhiyun+ guint8 *ptr; 101*4882a593Smuzhiyun+ 102*4882a593Smuzhiyun+ memset (info, 0, sizeof (rga_info_t)); 103*4882a593Smuzhiyun+ 104*4882a593Smuzhiyun+ if (!meta) 105*4882a593Smuzhiyun+ return FALSE; 106*4882a593Smuzhiyun+ 107*4882a593Smuzhiyun+ hstride = meta->stride[0]; 108*4882a593Smuzhiyun+ vstride0 = meta->n_planes == 1 ? meta->height : meta->offset[1] / hstride; 109*4882a593Smuzhiyun+ 110*4882a593Smuzhiyun+ /* RGA requires contig buffer */ 111*4882a593Smuzhiyun+ ptr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); 112*4882a593Smuzhiyun+ for (i = 1; i < GST_VIDEO_FRAME_N_PLANES (frame); i++) { 113*4882a593Smuzhiyun+ gint size = GST_VIDEO_FRAME_PLANE_OFFSET (frame, i) - 114*4882a593Smuzhiyun+ GST_VIDEO_FRAME_PLANE_OFFSET (frame, i - 1); 115*4882a593Smuzhiyun+ gint vstride = size / meta->stride[i - 1]; 116*4882a593Smuzhiyun+ 117*4882a593Smuzhiyun+ ptr += size; 118*4882a593Smuzhiyun+ if (ptr != GST_VIDEO_FRAME_PLANE_DATA (frame, i)) 119*4882a593Smuzhiyun+ return FALSE; 120*4882a593Smuzhiyun+ 121*4882a593Smuzhiyun+ if ((meta->stride[i] != hstride && meta->stride[i] != hstride / 2) || 122*4882a593Smuzhiyun+ (vstride != vstride0 && vstride != vstride0 / 2)) 123*4882a593Smuzhiyun+ return FALSE; 124*4882a593Smuzhiyun+ } 125*4882a593Smuzhiyun+ 126*4882a593Smuzhiyun+ format = get_rga_format (GST_VIDEO_INFO_FORMAT (vinfo)); 127*4882a593Smuzhiyun+ switch (format) { 128*4882a593Smuzhiyun+ case RK_FORMAT_RGBX_8888: 129*4882a593Smuzhiyun+ case RK_FORMAT_RGBA_8888: 130*4882a593Smuzhiyun+ case RK_FORMAT_BGRA_8888: 131*4882a593Smuzhiyun+ hstride /= 4; 132*4882a593Smuzhiyun+ break; 133*4882a593Smuzhiyun+ case RK_FORMAT_RGB_888: 134*4882a593Smuzhiyun+ case RK_FORMAT_BGR_888: 135*4882a593Smuzhiyun+ hstride /= 3; 136*4882a593Smuzhiyun+ break; 137*4882a593Smuzhiyun+ case RK_FORMAT_RGB_565: 138*4882a593Smuzhiyun+ hstride /= 2; 139*4882a593Smuzhiyun+ break; 140*4882a593Smuzhiyun+ case RK_FORMAT_YCbCr_420_SP_10B: 141*4882a593Smuzhiyun+ case RK_FORMAT_YCbCr_422_SP: 142*4882a593Smuzhiyun+ case RK_FORMAT_YCrCb_422_SP: 143*4882a593Smuzhiyun+ case RK_FORMAT_YCbCr_422_P: 144*4882a593Smuzhiyun+ case RK_FORMAT_YCrCb_422_P: 145*4882a593Smuzhiyun+ case RK_FORMAT_YCbCr_420_SP: 146*4882a593Smuzhiyun+ case RK_FORMAT_YCrCb_420_SP: 147*4882a593Smuzhiyun+ case RK_FORMAT_YCbCr_420_P: 148*4882a593Smuzhiyun+ case RK_FORMAT_YCrCb_420_P: 149*4882a593Smuzhiyun+ /* RGA requires yuv image rect align to 2 */ 150*4882a593Smuzhiyun+ x = (x + 1) & ~1; 151*4882a593Smuzhiyun+ y = (y + 1) & ~1; 152*4882a593Smuzhiyun+ w &= ~1; 153*4882a593Smuzhiyun+ h &= ~1; 154*4882a593Smuzhiyun+ 155*4882a593Smuzhiyun+ if (vstride0 % 2) 156*4882a593Smuzhiyun+ return FALSE; 157*4882a593Smuzhiyun+ break; 158*4882a593Smuzhiyun+ default: 159*4882a593Smuzhiyun+ return FALSE; 160*4882a593Smuzhiyun+ } 161*4882a593Smuzhiyun+ 162*4882a593Smuzhiyun+ info->virAddr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); 163*4882a593Smuzhiyun+ info->mmuFlag = 1; 164*4882a593Smuzhiyun+ 165*4882a593Smuzhiyun+ rga_set_rect (&info->rect, x, y, w, h, hstride, vstride0, format); 166*4882a593Smuzhiyun+ return TRUE; 167*4882a593Smuzhiyun+} 168*4882a593Smuzhiyun+ 169*4882a593Smuzhiyun+static gboolean 170*4882a593Smuzhiyun+video_flip_try_rga (GstVideoFlip * videoflip, 171*4882a593Smuzhiyun+ GstVideoFrame * out_frame, GstVideoFrame * in_frame) 172*4882a593Smuzhiyun+{ 173*4882a593Smuzhiyun+ gint sw = GST_VIDEO_FRAME_WIDTH (in_frame); 174*4882a593Smuzhiyun+ gint sh = GST_VIDEO_FRAME_HEIGHT (in_frame); 175*4882a593Smuzhiyun+ gint dw = GST_VIDEO_FRAME_WIDTH (out_frame); 176*4882a593Smuzhiyun+ gint dh = GST_VIDEO_FRAME_HEIGHT (out_frame); 177*4882a593Smuzhiyun+ 178*4882a593Smuzhiyun+ rga_info_t src_info = { 0 }; 179*4882a593Smuzhiyun+ rga_info_t dst_info = { 0 }; 180*4882a593Smuzhiyun+ static int rga_supported = 1; 181*4882a593Smuzhiyun+ static int rga_inited = 0; 182*4882a593Smuzhiyun+ const char *buf; 183*4882a593Smuzhiyun+ 184*4882a593Smuzhiyun+ buf = g_getenv ("GST_VIDEO_FLIP_USE_RGA"); 185*4882a593Smuzhiyun+ if (!buf || strcmp (buf, "1")) 186*4882a593Smuzhiyun+ return FALSE; 187*4882a593Smuzhiyun+ 188*4882a593Smuzhiyun+ if (!rga_supported) 189*4882a593Smuzhiyun+ return FALSE; 190*4882a593Smuzhiyun+ 191*4882a593Smuzhiyun+ if (!rga_inited) { 192*4882a593Smuzhiyun+ if (c_RkRgaInit () < 0) { 193*4882a593Smuzhiyun+ rga_supported = 0; 194*4882a593Smuzhiyun+ return FALSE; 195*4882a593Smuzhiyun+ } 196*4882a593Smuzhiyun+ rga_inited = 1; 197*4882a593Smuzhiyun+ } 198*4882a593Smuzhiyun+ 199*4882a593Smuzhiyun+ if (!get_rga_info (in_frame, &src_info, 0, 0, sw, sh)) { 200*4882a593Smuzhiyun+ GST_DEBUG ("unsupported src info for RGA"); 201*4882a593Smuzhiyun+ return FALSE; 202*4882a593Smuzhiyun+ } 203*4882a593Smuzhiyun+ 204*4882a593Smuzhiyun+ if (!get_rga_info (out_frame, &dst_info, 0, 0, dw, dh)) { 205*4882a593Smuzhiyun+ GST_DEBUG ("unsupported dst info for RGA"); 206*4882a593Smuzhiyun+ return FALSE; 207*4882a593Smuzhiyun+ } 208*4882a593Smuzhiyun+ 209*4882a593Smuzhiyun+ switch (videoflip->active_method) { 210*4882a593Smuzhiyun+ case GST_VIDEO_ORIENTATION_90R: 211*4882a593Smuzhiyun+ src_info.rotation = HAL_TRANSFORM_ROT_90; 212*4882a593Smuzhiyun+ break; 213*4882a593Smuzhiyun+ case GST_VIDEO_ORIENTATION_180: 214*4882a593Smuzhiyun+ src_info.rotation = HAL_TRANSFORM_ROT_180; 215*4882a593Smuzhiyun+ break; 216*4882a593Smuzhiyun+ case GST_VIDEO_ORIENTATION_90L: 217*4882a593Smuzhiyun+ src_info.rotation = HAL_TRANSFORM_ROT_270; 218*4882a593Smuzhiyun+ break; 219*4882a593Smuzhiyun+ case GST_VIDEO_ORIENTATION_HORIZ: 220*4882a593Smuzhiyun+ src_info.rotation = HAL_TRANSFORM_FLIP_H; 221*4882a593Smuzhiyun+ break; 222*4882a593Smuzhiyun+ case GST_VIDEO_ORIENTATION_VERT: 223*4882a593Smuzhiyun+ src_info.rotation = HAL_TRANSFORM_FLIP_V; 224*4882a593Smuzhiyun+ break; 225*4882a593Smuzhiyun+ default: 226*4882a593Smuzhiyun+ GST_DEBUG ("unsupported rotation for RGA"); 227*4882a593Smuzhiyun+ return FALSE; 228*4882a593Smuzhiyun+ } 229*4882a593Smuzhiyun+ 230*4882a593Smuzhiyun+ if (c_RkRgaBlit (&src_info, &dst_info, NULL) < 0) { 231*4882a593Smuzhiyun+ GST_DEBUG ("failed to blit with RGA"); 232*4882a593Smuzhiyun+ return FALSE; 233*4882a593Smuzhiyun+ } 234*4882a593Smuzhiyun+ 235*4882a593Smuzhiyun+ GST_DEBUG ("flipped with RGA"); 236*4882a593Smuzhiyun+ return TRUE; 237*4882a593Smuzhiyun+} 238*4882a593Smuzhiyun+#endif 239*4882a593Smuzhiyun+ 240*4882a593Smuzhiyun static void 241*4882a593Smuzhiyun gst_video_flip_configure_process (GstVideoFlip * vf) 242*4882a593Smuzhiyun { 243*4882a593Smuzhiyun@@ -1504,6 +1696,12 @@ gst_video_flip_configure_process (GstVideoFlip * vf) 244*4882a593Smuzhiyun case GST_VIDEO_FORMAT_NV21: 245*4882a593Smuzhiyun vf->process = gst_video_flip_semi_planar_yuv; 246*4882a593Smuzhiyun break; 247*4882a593Smuzhiyun+#ifdef HAVE_RGA 248*4882a593Smuzhiyun+ case GST_VIDEO_FORMAT_NV12_10LE40: 249*4882a593Smuzhiyun+ /* Not supported by the official videoflip */ 250*4882a593Smuzhiyun+ vf->process = video_flip_try_rga; 251*4882a593Smuzhiyun+ break; 252*4882a593Smuzhiyun+#endif 253*4882a593Smuzhiyun default: 254*4882a593Smuzhiyun break; 255*4882a593Smuzhiyun } 256*4882a593Smuzhiyun@@ -1684,6 +1882,20 @@ gst_video_flip_transform_frame (GstVideoFilter * vfilter, 257*4882a593Smuzhiyun GST_VIDEO_FRAME_WIDTH (out_frame), GST_VIDEO_FRAME_HEIGHT (out_frame)); 258*4882a593Smuzhiyun g_type_class_unref (enum_class); 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun+#ifdef HAVE_RGA 261*4882a593Smuzhiyun+ /* Accel flip with rockchip RGA */ 262*4882a593Smuzhiyun+ if (video_flip_try_rga (videoflip, out_frame, in_frame)) { 263*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (videoflip); 264*4882a593Smuzhiyun+ return GST_FLOW_OK; 265*4882a593Smuzhiyun+ } 266*4882a593Smuzhiyun+ 267*4882a593Smuzhiyun+ /* Not supported by the official videoflip */ 268*4882a593Smuzhiyun+ if (G_UNLIKELY (videoflip->process == video_flip_try_rga)) { 269*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (videoflip); 270*4882a593Smuzhiyun+ goto not_negotiated; 271*4882a593Smuzhiyun+ } 272*4882a593Smuzhiyun+#endif 273*4882a593Smuzhiyun+ 274*4882a593Smuzhiyun videoflip->process (videoflip, out_frame, in_frame); 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun proposed = videoflip->proposed_method; 277*4882a593Smuzhiyundiff --git a/gst/videofilter/meson.build b/gst/videofilter/meson.build 278*4882a593Smuzhiyunindex d7b6788..1a594c6 100644 279*4882a593Smuzhiyun--- a/gst/videofilter/meson.build 280*4882a593Smuzhiyun+++ b/gst/videofilter/meson.build 281*4882a593Smuzhiyun@@ -10,7 +10,7 @@ gstvideofilter = library('gstvideofilter', 282*4882a593Smuzhiyun vfilter_sources, 283*4882a593Smuzhiyun c_args : gst_plugins_good_args, 284*4882a593Smuzhiyun include_directories : [configinc], 285*4882a593Smuzhiyun- dependencies : [gstbase_dep, gstvideo_dep, libm], 286*4882a593Smuzhiyun+ dependencies : [gstbase_dep, gstvideo_dep, libm, rga_dep], 287*4882a593Smuzhiyun install : true, 288*4882a593Smuzhiyun install_dir : plugins_install_dir, 289*4882a593Smuzhiyun ) 290*4882a593Smuzhiyundiff --git a/meson.build b/meson.build 291*4882a593Smuzhiyunindex c21a5ad..0f3f2f2 100644 292*4882a593Smuzhiyun--- a/meson.build 293*4882a593Smuzhiyun+++ b/meson.build 294*4882a593Smuzhiyun@@ -382,6 +382,9 @@ gst_plugins_good_args = ['-DHAVE_CONFIG_H'] 295*4882a593Smuzhiyun configinc = include_directories('.') 296*4882a593Smuzhiyun libsinc = include_directories('gst-libs') 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun+rga_dep = dependency('librga', required: false) 299*4882a593Smuzhiyun+cdata.set('HAVE_RGA', rga_dep.found()) 300*4882a593Smuzhiyun+ 301*4882a593Smuzhiyun have_orcc = false 302*4882a593Smuzhiyun orcc_args = [] 303*4882a593Smuzhiyun orc_targets = [] 304*4882a593Smuzhiyun-- 305*4882a593Smuzhiyun2.20.1 306*4882a593Smuzhiyun 307