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