HYL_OK3568_LINUX/buildroot/package/gstreamer1/gst1-plugins-good/0005-video-flip-Support-rockchip-RGA-2D-accel.patch
2025-05-10 21:49:39 +08:00

307 lines
9.1 KiB
Diff

From 02517deddcd968b332eb6d996d00609b4784a980 Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Fri, 8 Nov 2019 17:36:20 +0800
Subject: [PATCH 05/12] video-flip: Support rockchip RGA 2D accel
Disabled by default, set env GST_VIDEO_FLIP_USE_RGA=1 to enable.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
gst/videofilter/gstvideoflip.c | 216 ++++++++++++++++++++++++++++++++-
gst/videofilter/meson.build | 2 +-
meson.build | 3 +
3 files changed, 218 insertions(+), 3 deletions(-)
diff --git a/gst/videofilter/gstvideoflip.c b/gst/videofilter/gstvideoflip.c
index 07db899..9ea405b 100644
--- a/gst/videofilter/gstvideoflip.c
+++ b/gst/videofilter/gstvideoflip.c
@@ -48,6 +48,11 @@
#include <gst/gst.h>
#include <gst/video/video.h>
+#ifdef HAVE_RGA
+#include <rga/rga.h>
+#include <rga/RgaApi.h>
+#endif
+
/* GstVideoFlip properties */
enum
{
@@ -68,7 +73,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
"ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
- "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21,"
+ "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, NV12_10LE40, "
"GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, "
"I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }"))
);
@@ -79,7 +84,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
"ARGB, BGRA, ABGR, RGBA, Y444, xRGB, RGBx, xBGR, BGRx, "
- "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21,"
+ "RGB, BGR, I420, YV12, IYUV, YUY2, UYVY, YVYU, NV12, NV21, NV12_10LE40, "
"GRAY8, GRAY16_BE, GRAY16_LE, I420_10LE, I420_10BE, I420_12LE, I420_12BE, "
"I422_10LE, I422_10BE, I422_12LE, I422_12BE, Y444_10LE, Y444_10BE, Y444_12LE, Y444_12BE }"))
);
@@ -1454,6 +1459,193 @@ gst_video_flip_y422 (GstVideoFlip * videoflip, GstVideoFrame * dest,
}
}
+#ifdef HAVE_RGA
+static RgaSURF_FORMAT
+get_rga_format (GstVideoFormat format)
+{
+ switch (format) {
+ case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_BGRx:
+ return RK_FORMAT_BGRA_8888;
+ case GST_VIDEO_FORMAT_RGBA:
+ return RK_FORMAT_RGBA_8888;
+ case GST_VIDEO_FORMAT_RGBx:
+ return RK_FORMAT_RGBX_8888;
+ case GST_VIDEO_FORMAT_BGR:
+ return RK_FORMAT_BGR_888;
+ case GST_VIDEO_FORMAT_RGB:
+ return RK_FORMAT_RGB_888;
+ case GST_VIDEO_FORMAT_RGB16:
+ return RK_FORMAT_RGB_565;
+ case GST_VIDEO_FORMAT_NV12:
+ return RK_FORMAT_YCbCr_420_SP;
+ case GST_VIDEO_FORMAT_NV21:
+ return RK_FORMAT_YCrCb_420_SP;
+ case GST_VIDEO_FORMAT_I420:
+ return RK_FORMAT_YCbCr_420_P;
+ case GST_VIDEO_FORMAT_YV12:
+ return RK_FORMAT_YCrCb_420_P;
+ case GST_VIDEO_FORMAT_NV16:
+ return RK_FORMAT_YCbCr_422_SP;
+ case GST_VIDEO_FORMAT_NV61:
+ return RK_FORMAT_YCrCb_422_SP;
+ case GST_VIDEO_FORMAT_Y42B:
+ return RK_FORMAT_YCbCr_422_P;
+ case GST_VIDEO_FORMAT_NV12_10LE40:
+ return RK_FORMAT_YCbCr_420_SP_10B;
+ default:
+ return RK_FORMAT_UNKNOWN;
+ }
+}
+
+static gboolean
+get_rga_info (const GstVideoFrame * frame, rga_info_t * info,
+ int x, int y, int w, int h)
+{
+ GstVideoMeta *meta = gst_buffer_get_video_meta (frame->buffer);
+ const GstVideoInfo *vinfo = &frame->info;
+ RgaSURF_FORMAT format;
+ gint hstride, vstride0, i;
+ guint8 *ptr;
+
+ memset (info, 0, sizeof (rga_info_t));
+
+ if (!meta)
+ return FALSE;
+
+ hstride = meta->stride[0];
+ vstride0 = meta->n_planes == 1 ? meta->height : meta->offset[1] / hstride;
+
+ /* RGA requires contig buffer */
+ ptr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
+ for (i = 1; i < GST_VIDEO_FRAME_N_PLANES (frame); i++) {
+ gint size = GST_VIDEO_FRAME_PLANE_OFFSET (frame, i) -
+ GST_VIDEO_FRAME_PLANE_OFFSET (frame, i - 1);
+ gint vstride = size / meta->stride[i - 1];
+
+ ptr += size;
+ if (ptr != GST_VIDEO_FRAME_PLANE_DATA (frame, i))
+ return FALSE;
+
+ if ((meta->stride[i] != hstride && meta->stride[i] != hstride / 2) ||
+ (vstride != vstride0 && vstride != vstride0 / 2))
+ return FALSE;
+ }
+
+ format = get_rga_format (GST_VIDEO_INFO_FORMAT (vinfo));
+ switch (format) {
+ case RK_FORMAT_RGBX_8888:
+ case RK_FORMAT_RGBA_8888:
+ case RK_FORMAT_BGRA_8888:
+ hstride /= 4;
+ break;
+ case RK_FORMAT_RGB_888:
+ case RK_FORMAT_BGR_888:
+ hstride /= 3;
+ break;
+ case RK_FORMAT_RGB_565:
+ hstride /= 2;
+ break;
+ case RK_FORMAT_YCbCr_420_SP_10B:
+ case RK_FORMAT_YCbCr_422_SP:
+ case RK_FORMAT_YCrCb_422_SP:
+ case RK_FORMAT_YCbCr_422_P:
+ case RK_FORMAT_YCrCb_422_P:
+ case RK_FORMAT_YCbCr_420_SP:
+ case RK_FORMAT_YCrCb_420_SP:
+ case RK_FORMAT_YCbCr_420_P:
+ case RK_FORMAT_YCrCb_420_P:
+ /* RGA requires yuv image rect align to 2 */
+ x = (x + 1) & ~1;
+ y = (y + 1) & ~1;
+ w &= ~1;
+ h &= ~1;
+
+ if (vstride0 % 2)
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+
+ info->virAddr = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
+ info->mmuFlag = 1;
+
+ rga_set_rect (&info->rect, x, y, w, h, hstride, vstride0, format);
+ return TRUE;
+}
+
+static gboolean
+video_flip_try_rga (GstVideoFlip * videoflip,
+ GstVideoFrame * out_frame, GstVideoFrame * in_frame)
+{
+ gint sw = GST_VIDEO_FRAME_WIDTH (in_frame);
+ gint sh = GST_VIDEO_FRAME_HEIGHT (in_frame);
+ gint dw = GST_VIDEO_FRAME_WIDTH (out_frame);
+ gint dh = GST_VIDEO_FRAME_HEIGHT (out_frame);
+
+ rga_info_t src_info = { 0 };
+ rga_info_t dst_info = { 0 };
+ static int rga_supported = 1;
+ static int rga_inited = 0;
+ const char *buf;
+
+ buf = g_getenv ("GST_VIDEO_FLIP_USE_RGA");
+ if (!buf || strcmp (buf, "1"))
+ return FALSE;
+
+ if (!rga_supported)
+ return FALSE;
+
+ if (!rga_inited) {
+ if (c_RkRgaInit () < 0) {
+ rga_supported = 0;
+ return FALSE;
+ }
+ rga_inited = 1;
+ }
+
+ if (!get_rga_info (in_frame, &src_info, 0, 0, sw, sh)) {
+ GST_DEBUG ("unsupported src info for RGA");
+ return FALSE;
+ }
+
+ if (!get_rga_info (out_frame, &dst_info, 0, 0, dw, dh)) {
+ GST_DEBUG ("unsupported dst info for RGA");
+ return FALSE;
+ }
+
+ switch (videoflip->active_method) {
+ case GST_VIDEO_ORIENTATION_90R:
+ src_info.rotation = HAL_TRANSFORM_ROT_90;
+ break;
+ case GST_VIDEO_ORIENTATION_180:
+ src_info.rotation = HAL_TRANSFORM_ROT_180;
+ break;
+ case GST_VIDEO_ORIENTATION_90L:
+ src_info.rotation = HAL_TRANSFORM_ROT_270;
+ break;
+ case GST_VIDEO_ORIENTATION_HORIZ:
+ src_info.rotation = HAL_TRANSFORM_FLIP_H;
+ break;
+ case GST_VIDEO_ORIENTATION_VERT:
+ src_info.rotation = HAL_TRANSFORM_FLIP_V;
+ break;
+ default:
+ GST_DEBUG ("unsupported rotation for RGA");
+ return FALSE;
+ }
+
+ if (c_RkRgaBlit (&src_info, &dst_info, NULL) < 0) {
+ GST_DEBUG ("failed to blit with RGA");
+ return FALSE;
+ }
+
+ GST_DEBUG ("flipped with RGA");
+ return TRUE;
+}
+#endif
+
static void
gst_video_flip_configure_process (GstVideoFlip * vf)
{
@@ -1504,6 +1696,12 @@ gst_video_flip_configure_process (GstVideoFlip * vf)
case GST_VIDEO_FORMAT_NV21:
vf->process = gst_video_flip_semi_planar_yuv;
break;
+#ifdef HAVE_RGA
+ case GST_VIDEO_FORMAT_NV12_10LE40:
+ /* Not supported by the official videoflip */
+ vf->process = video_flip_try_rga;
+ break;
+#endif
default:
break;
}
@@ -1684,6 +1882,20 @@ gst_video_flip_transform_frame (GstVideoFilter * vfilter,
GST_VIDEO_FRAME_WIDTH (out_frame), GST_VIDEO_FRAME_HEIGHT (out_frame));
g_type_class_unref (enum_class);
+#ifdef HAVE_RGA
+ /* Accel flip with rockchip RGA */
+ if (video_flip_try_rga (videoflip, out_frame, in_frame)) {
+ GST_OBJECT_UNLOCK (videoflip);
+ return GST_FLOW_OK;
+ }
+
+ /* Not supported by the official videoflip */
+ if (G_UNLIKELY (videoflip->process == video_flip_try_rga)) {
+ GST_OBJECT_UNLOCK (videoflip);
+ goto not_negotiated;
+ }
+#endif
+
videoflip->process (videoflip, out_frame, in_frame);
proposed = videoflip->proposed_method;
diff --git a/gst/videofilter/meson.build b/gst/videofilter/meson.build
index d7b6788..1a594c6 100644
--- a/gst/videofilter/meson.build
+++ b/gst/videofilter/meson.build
@@ -10,7 +10,7 @@ gstvideofilter = library('gstvideofilter',
vfilter_sources,
c_args : gst_plugins_good_args,
include_directories : [configinc],
- dependencies : [gstbase_dep, gstvideo_dep, libm],
+ dependencies : [gstbase_dep, gstvideo_dep, libm, rga_dep],
install : true,
install_dir : plugins_install_dir,
)
diff --git a/meson.build b/meson.build
index c21a5ad..0f3f2f2 100644
--- a/meson.build
+++ b/meson.build
@@ -382,6 +382,9 @@ gst_plugins_good_args = ['-DHAVE_CONFIG_H']
configinc = include_directories('.')
libsinc = include_directories('gst-libs')
+rga_dep = dependency('librga', required: false)
+cdata.set('HAVE_RGA', rga_dep.found())
+
have_orcc = false
orcc_args = []
orc_targets = []
--
2.20.1