--- moonlight-orig/cmake/FindRockchip.cmake 2022-05-26 15:41:01.746182723 -0700 +++ areascout-moonlight/cmake/FindRockchip.cmake 2022-05-26 15:39:28.741230073 -0700 @@ -8,7 +8,13 @@ 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 @@ 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}) --- moonlight-orig/src/video/rk.c 2022-05-26 15:41:01.750182764 -0700 +++ areascout-moonlight/src/video/rk.c 2022-05-26 15:39:28.749230155 -0700 @@ -37,9 +37,11 @@ #include #include +#include #define READ_BUF_SIZE 0x00100000 #define MAX_FRAMES 16 +#define MAX_DEST_BUFFERS 3 #define RK_H264 7 #define RK_H265 16777220 @@ -50,6 +52,8 @@ 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; @@ -82,6 +86,7 @@ void *display_thread(void *param) { + static int index = 0; int ret; while (!frm_eos) { @@ -98,8 +103,9 @@ 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); @@ -114,10 +120,13 @@ 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) { @@ -141,7 +150,15 @@ 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; @@ -157,6 +174,47 @@ 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); @@ -224,6 +282,15 @@ // 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); @@ -363,6 +430,10 @@ // 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); @@ -446,6 +517,8 @@ mpp_destroy(mpi_ctx); free(pkt_buf); + c_RkRgaDeInit(); + drmModeFreePlane(ovr); drmModeFreePlaneResources(plane_resources); drmModeFreeEncoder(encoder);