223 lines
7.5 KiB
Diff
223 lines
7.5 KiB
Diff
|
From fd0cff622860903d4146a15062cfb0ecce300b28 Mon Sep 17 00:00:00 2001
|
||
|
From: krishenriksen <info@krishenriksen.dk>
|
||
|
Date: Mon, 1 Feb 2021 09:21:07 +0700
|
||
|
Subject: [PATCH 1/2] Rotation and tearing fix on Rockchip video backend for
|
||
|
rg351p
|
||
|
|
||
|
---
|
||
|
cmake/FindRockchip.cmake | 10 ++++--
|
||
|
src/video/rk.c | 77 ++++++++++++++++++++++++++++++++++++++--
|
||
|
2 files changed, 83 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/cmake/FindRockchip.cmake b/cmake/FindRockchip.cmake
|
||
|
index 83764dd2..1ad3f938 100644
|
||
|
--- a/cmake/FindRockchip.cmake
|
||
|
+++ b/cmake/FindRockchip.cmake
|
||
|
@@ -8,7 +8,13 @@ find_library(DRM_LIBRARY
|
||
|
NAMES libdrm.so
|
||
|
DOC "Path to libdrm Library"
|
||
|
PATHS /usr/local/lib /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/arm-linux-gnueabihf)
|
||
|
-mark_as_advanced(DRM_INCLUDE_DIR)
|
||
|
+mark_as_advanced(DRM_LIBRARY)
|
||
|
+
|
||
|
+find_library(RGA_LIBRARY
|
||
|
+ NAMES librga.so
|
||
|
+ DOC "Path to librga Library"
|
||
|
+ PATHS /usr/local/lib /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/arm-linux-gnueabihf)
|
||
|
+mark_as_advanced(RGA_LIBRARY)
|
||
|
|
||
|
find_path(ROCKCHIP_INCLUDE_DIR
|
||
|
NAMES rk_mpi.h
|
||
|
@@ -26,4 +32,4 @@ include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Rockchip DEFAULT_MSG ROCKCHIP_INCLUDE_DIR ROCKCHIP_LIBRARY)
|
||
|
|
||
|
set(ROCKCHIP_INCLUDE_DIRS ${ROCKCHIP_INCLUDE_DIR} ${DRM_INCLUDE_DIR})
|
||
|
-set(ROCKCHIP_LIBRARIES ${ROCKCHIP_LIBRARY} ${DRM_LIBRARY})
|
||
|
+set(ROCKCHIP_LIBRARIES ${ROCKCHIP_LIBRARY} ${DRM_LIBRARY} ${RGA_LIBRARY})
|
||
|
diff --git a/src/video/rk.c b/src/video/rk.c
|
||
|
index 44526443..af9451d7 100644
|
||
|
--- a/src/video/rk.c
|
||
|
+++ b/src/video/rk.c
|
||
|
@@ -37,15 +37,19 @@
|
||
|
#include <libdrm/drm_fourcc.h>
|
||
|
|
||
|
#include <rockchip/rk_mpi.h>
|
||
|
+#include <rga/RgaApi.h>
|
||
|
|
||
|
#define READ_BUF_SIZE 0x00100000
|
||
|
#define MAX_FRAMES 16
|
||
|
+#define MAX_DEST_BUFFERS 3
|
||
|
#define RK_H264 7
|
||
|
#define RK_H265 16777220
|
||
|
|
||
|
void *pkt_buf = NULL;
|
||
|
int fd;
|
||
|
int fb_id;
|
||
|
+int fb_id_rot[MAX_DEST_BUFFERS];
|
||
|
+int prime_fd_rot[MAX_DEST_BUFFERS];
|
||
|
uint32_t plane_id, crtc_id;
|
||
|
int frm_eos;
|
||
|
int crtc_width;
|
||
|
@@ -78,6 +82,7 @@ struct {
|
||
|
|
||
|
void *display_thread(void *param) {
|
||
|
|
||
|
+ static int index = 0;
|
||
|
int ret;
|
||
|
|
||
|
while (!frm_eos) {
|
||
|
@@ -94,8 +99,9 @@ void *display_thread(void *param) {
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
- _fb_id = fb_id;
|
||
|
|
||
|
+ _fb_id = fb_id_rot[index];
|
||
|
+ index = (index + 1) % MAX_DEST_BUFFERS;
|
||
|
fb_id = 0;
|
||
|
ret = pthread_mutex_unlock(&mutex);
|
||
|
assert(!ret);
|
||
|
@@ -110,10 +116,13 @@ void *display_thread(void *param) {
|
||
|
|
||
|
void *frame_thread(void *param) {
|
||
|
|
||
|
+ static int index = 0;
|
||
|
int count = 0;
|
||
|
int ret;
|
||
|
int i;
|
||
|
MppFrame frame = NULL;
|
||
|
+ rga_info_t src_info = {0};
|
||
|
+ rga_info_t dst_info = {0};
|
||
|
|
||
|
while (!frm_eos) {
|
||
|
|
||
|
@@ -137,7 +146,15 @@ void *frame_thread(void *param) {
|
||
|
RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
|
||
|
MppFrameFormat fmt = mpp_frame_get_fmt(frame);
|
||
|
assert((fmt == MPP_FMT_YUV420SP) || (fmt == MPP_FMT_YUV420SP_10BIT));
|
||
|
-
|
||
|
+ printf("Frame WxH=%dx%d WSxHs=%dx%d\n", frm_width, frm_height, hor_stride, ver_stride);
|
||
|
+
|
||
|
+#if 1
|
||
|
+ // position overlay, expand to full screen
|
||
|
+ fb_x = 0;
|
||
|
+ fb_y = 0;
|
||
|
+ fb_width = crtc_width;
|
||
|
+ fb_height = crtc_height;
|
||
|
+#else
|
||
|
// position overlay, scale to ratio
|
||
|
float crt_ratio = (float)crtc_width/crtc_height;
|
||
|
float frame_ratio = (float)frm_width/frm_height;
|
||
|
@@ -153,6 +170,47 @@ void *frame_thread(void *param) {
|
||
|
fb_x = 0;
|
||
|
fb_y = (crtc_height-fb_height)/2;
|
||
|
}
|
||
|
+#endif
|
||
|
+ for (int i = 0; i < MAX_DEST_BUFFERS; i++) {
|
||
|
+ // new DRM buffer for rotated screen
|
||
|
+ struct drm_mode_create_dumb dmcd2 = {0};
|
||
|
+ dmcd2.bpp = fmt==MPP_FMT_YUV420SP?8:10;
|
||
|
+ dmcd2.width = hor_stride;
|
||
|
+ dmcd2.height = ver_stride*2; // documentation say not v*2/3 but v*2 (additional info included)
|
||
|
+ do {
|
||
|
+ ret = ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dmcd2);
|
||
|
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
|
||
|
+
|
||
|
+ struct drm_prime_handle dph2 = {0};
|
||
|
+ dph2.handle = dmcd2.handle;
|
||
|
+ dph2.fd = -1;
|
||
|
+ do {
|
||
|
+ ret = ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &dph2);
|
||
|
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
|
||
|
+ assert(!ret);
|
||
|
+
|
||
|
+ prime_fd_rot[i] = dph2.fd;
|
||
|
+
|
||
|
+ uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
|
||
|
+ handles[0] = dmcd2.handle;
|
||
|
+ offsets[0] = 0;
|
||
|
+ pitches[0] = hor_stride;
|
||
|
+ handles[1] = dmcd2.handle;
|
||
|
+ offsets[1] = hor_stride * ver_stride;
|
||
|
+ pitches[1] = hor_stride;
|
||
|
+ ret = drmModeAddFB2(fd, frm_width, frm_height, fmt==MPP_FMT_YUV420SP?DRM_FORMAT_NV12:DRM_FORMAT_NV12_10, handles, pitches, offsets, &fb_id_rot[i], 0);
|
||
|
+ assert(!ret);
|
||
|
+ }
|
||
|
+ // setup rotation
|
||
|
+ src_info.mmuFlag = 1;
|
||
|
+ src_info.rotation = HAL_TRANSFORM_ROT_270;
|
||
|
+
|
||
|
+ rga_set_rect(&src_info.rect, 0, 0, frm_width, frm_height, mpp_frame_get_hor_stride(frame), mpp_frame_get_ver_stride(frame), RK_FORMAT_YCbCr_420_SP);
|
||
|
+
|
||
|
+ dst_info.fd = prime_fd_rot[index];
|
||
|
+ dst_info.mmuFlag = 1;
|
||
|
+
|
||
|
+ rga_set_rect(&dst_info.rect, 0, 0, frm_width, frm_height, mpp_frame_get_hor_stride(frame), mpp_frame_get_ver_stride(frame), RK_FORMAT_YCbCr_420_SP);
|
||
|
|
||
|
// create new external frame group and allocate (commit flow) new DRM buffers and DRM FB
|
||
|
assert(!mpi_frm_grp);
|
||
|
@@ -220,6 +278,15 @@ void *frame_thread(void *param) {
|
||
|
// send DRM FB to display thread
|
||
|
ret = pthread_mutex_lock(&mutex);
|
||
|
assert(!ret);
|
||
|
+
|
||
|
+ src_info.fd = frame_to_drm[i].prime_fd;
|
||
|
+ dst_info.fd = prime_fd_rot[index];
|
||
|
+ index = (index + 1) % MAX_DEST_BUFFERS;
|
||
|
+
|
||
|
+ if (c_RkRgaBlit(&src_info, &dst_info, NULL) < 0) {
|
||
|
+ fprintf(stderr, "Failed to do rga blit\n");
|
||
|
+ }
|
||
|
+
|
||
|
fb_id = frame_to_drm[i].fb_id;
|
||
|
ret = pthread_cond_signal(&cond);
|
||
|
assert(!ret);
|
||
|
@@ -359,6 +426,10 @@ int rk_setup(int videoFormat, int width, int height, int redrawRate, void* conte
|
||
|
// hide cursor by move in left lower corner
|
||
|
drmModeMoveCursor(fd, crtc_id, 0, crtc_height);
|
||
|
|
||
|
+ // RGA Setup
|
||
|
+
|
||
|
+ c_RkRgaInit();
|
||
|
+
|
||
|
// MPI SETUP
|
||
|
|
||
|
pkt_buf = malloc(READ_BUF_SIZE);
|
||
|
@@ -442,6 +513,8 @@ void rk_cleanup() {
|
||
|
mpp_destroy(mpi_ctx);
|
||
|
free(pkt_buf);
|
||
|
|
||
|
+ c_RkRgaDeInit();
|
||
|
+
|
||
|
drmModeFreePlane(ovr);
|
||
|
drmModeFreePlaneResources(plane_resources);
|
||
|
drmModeFreeEncoder(encoder);
|
||
|
|
||
|
From a812c83ea9946e08854443e4c1ace8a5cb78eb3a Mon Sep 17 00:00:00 2001
|
||
|
From: Kris Henriksen <github@krishenriksen>
|
||
|
Date: Mon, 1 Feb 2021 02:47:54 +0000
|
||
|
Subject: [PATCH 2/2] added required mode for rockchip
|
||
|
|
||
|
---
|
||
|
src/video/rk.c | 7 +++++++
|
||
|
1 file changed, 7 insertions(+)
|
||
|
|
||
|
diff --git a/src/video/rk.c b/src/video/rk.c
|
||
|
index af9451d7..e40f2c60 100644
|
||
|
--- a/src/video/rk.c
|
||
|
+++ b/src/video/rk.c
|
||
|
@@ -36,6 +36,13 @@
|
||
|
#include <xf86drmMode.h>
|
||
|
#include <libdrm/drm_fourcc.h>
|
||
|
|
||
|
+#define DRM_FORMAT_NV12_10 fourcc_code('N', 'A', '1', '2') /* 2x2 subsampled Cr:Cb plane */
|
||
|
+#define DRM_FORMAT_NV21_10 fourcc_code('N', 'A', '2', '1') /* 2x2 subsampled Cb:Cr plane */
|
||
|
+#define DRM_FORMAT_NV16_10 fourcc_code('N', 'A', '1', '6') /* 2x1 subsampled Cr:Cb plane */
|
||
|
+#define DRM_FORMAT_NV61_10 fourcc_code('N', 'A', '6', '1') /* 2x1 subsampled Cb:Cr plane */
|
||
|
+#define DRM_FORMAT_NV24_10 fourcc_code('N', 'A', '2', '4') /* non-subsampled Cr:Cb plane */
|
||
|
+#define DRM_FORMAT_NV42_10 fourcc_code('N', 'A', '4', '2') /* non-subsampled Cb:Cr plane */
|
||
|
+
|
||
|
#include <rockchip/rk_mpi.h>
|
||
|
#include <rga/RgaApi.h>
|
||
|
|