洋洋喜洋洋 2024-08-15 15:26 采纳率: 42.9%
浏览 2
已结题

libdrm使用流程

在RK3568板卡上,已经使用mpp硬解码,请问各位如何使用drm来显示视频帧数据呢?如何能设置图像的显示位置贺大小?怎么将图像数据送进去显示?

  • 写回答

3条回答 默认 最新

  • GISer Liu 2024-08-15 15:29
    关注

    该回答引用自GPT-deepseek, 由博主 GISer Liu 编写:

    问题分析

    用户在RK3568板卡上使用mpp硬解码后,希望了解如何使用libdrm来显示视频帧数据,并希望知道如何设置图像的显示位置和大小,以及如何将图像数据送进去显示。

    解决方案

    1. 使用libdrm显示视频帧数据的基本流程

    1. 初始化DRM设备:打开DRM设备并获取DRM句柄。
    2. 创建DRM资源:创建CRTC、Encoder、Connector等DRM资源。
    3. 分配帧缓冲区:为视频帧数据分配DRM帧缓冲区。
    4. 设置显示位置和大小:配置CRTC的显示位置和大小。
    5. 提交帧数据:将视频帧数据提交到DRM帧缓冲区并显示。

    2. 详细步骤和代码示例

    2.1 初始化DRM设备
    #include <xf86drm.h>
    #include <xf86drmMode.h>
    
    int fd;
    fd = drmOpen("rockchip", NULL);
    if (fd < 0) {
        perror("drmOpen");
        return -1;
    }
    
    2.2 创建DRM资源
    drmModeRes *res;
    drmModeConnector *conn;
    drmModeEncoder *enc;
    drmModeCrtc *crtc;
    
    res = drmModeGetResources(fd);
    if (!res) {
        perror("drmModeGetResources");
        return -1;
    }
    
    conn = drmModeGetConnector(fd, res->connectors[0]);
    if (!conn) {
        perror("drmModeGetConnector");
        return -1;
    }
    
    enc = drmModeGetEncoder(fd, conn->encoder_id);
    if (!enc) {
        perror("drmModeGetEncoder");
        return -1;
    }
    
    crtc = drmModeGetCrtc(fd, enc->crtc_id);
    if (!crtc) {
        perror("drmModeGetCrtc");
        return -1;
    }
    
    2.3 分配帧缓冲区
    drmModeFB *fb;
    uint32_t width = conn->modes[0].hdisplay;
    uint32_t height = conn->modes[0].vdisplay;
    uint32_t stride = width * 4; // 假设是32位RGB
    uint32_t size = stride * height;
    uint32_t handle;
    
    int ret = drmPrimeFDToHandle(fd, mpp_buffer_get_fd(mpp_buffer), &handle);
    if (ret < 0) {
        perror("drmPrimeFDToHandle");
        return -1;
    }
    
    ret = drmModeAddFB(fd, width, height, 24, 32, stride, handle, &fb_id);
    if (ret < 0) {
        perror("drmModeAddFB");
        return -1;
    }
    
    2.4 设置显示位置和大小
    uint32_t x = 0;
    uint32_t y = 0;
    
    ret = drmModeSetCrtc(fd, crtc->crtc_id, fb_id, x, y, &conn->connector_id, 1, &conn->modes[0]);
    if (ret < 0) {
        perror("drmModeSetCrtc");
        return -1;
    }
    
    2.5 提交帧数据
    // 假设mpp_buffer是mpp解码后的帧缓冲区
    void *mpp_buffer;
    // 将mpp_buffer中的数据拷贝到DRM帧缓冲区
    // 这里假设mpp_buffer和DRM帧缓冲区的格式和大小一致
    memcpy(drm_buffer, mpp_buffer, size);
    

    总结

    通过以上步骤,您可以在RK3568板卡上使用libdrm来显示视频帧数据,并设置图像的显示位置和大小。具体的代码示例展示了如何初始化DRM设备、创建DRM资源、分配帧缓冲区、设置显示位置和大小,以及如何将视频帧数据提交到DRM帧缓冲区并显示。希望这些内容能帮助您解决问题。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月5日
  • 已采纳回答 8月28日
  • 创建了问题 8月15日

悬赏问题

  • ¥15 android 集成sentry上报时报错。
  • ¥50 win10链接MySQL
  • ¥35 跳过我的世界插件ip验证
  • ¥15 抖音看过的视频,缓存在哪个文件
  • ¥15 自定义损失函数报输入参数的数目不足
  • ¥15 如果我想学习C大家有是的的资料吗
  • ¥15 根据文件名称对文件进行排序
  • ¥15 deploylinux的ubuntu系统无法成功安装使用MySQL❓
  • ¥15 有人会用py或者r画这种图吗
  • ¥15 MOD04_3K图像预处理