洋洋喜洋洋 2024-08-28 11:37 采纳率: 42.9%
浏览 14
已结题

drmModeAddFB2参数设置

将704*576大小的帧使用mpp硬解码,解出来的数据格式是NV12,想要使用DRM进行显示。使用libdrm的drmModeAddFB2()创建一个NV12的帧缓冲区并映射该数据,具体是怎么实现的?特别是drmModeAddFB2的bo_handles[4]、pitches[4]、offsets[4]这几个参数是怎么设置的?困扰我好久了,每次drmModeAddFB2的返回值都是-22!

  • 写回答

1条回答 默认 最新

  • 清水白石008 2024-08-29 05:51
    关注
    🕒上午好,题主!目前:🟢[在线]
    📢参考GPT-4o mini 模型、由清水白石008整理提供!
    📣今日金句:“生活中最重要的不是你所处的位置,而是你所朝的方向。” — 奥利弗·温德尔·霍姆斯
    

    要使用 libdrmdrmModeAddFB2() 函数创建一个 NV12 格式的帧缓冲区并映射数据,您需要正确设置 bo_handlespitchesoffsets 参数。以下是实现的详细步骤和解释。

    NV12 格式简介

    NV12 是一种 YUV 格式,其中 Y 分量存储在一个平面中,而 UV 分量交错存储在另一个平面中。具体来说:

    • Y 分量的大小为 width * height
    • UV 分量的大小为 (width / 2) * (height / 2) * 2,因为 U 和 V 分量是交错存储的。

    drmModeAddFB2 函数参数

    drmModeAddFB2() 的参数如下:

    • bo_handles[4]:用于存储每个缓冲区对象的句柄。
    • pitches[4]:每个缓冲区的行距(以字节为单位)。
    • offsets[4]:每个缓冲区的偏移量(以字节为单位)。

    设置参数

    1. 创建缓冲区对象
      您需要为 Y 和 UV 分量创建两个缓冲区对象。通常,您可以使用 drmPrimeHandleToFD()drmModeAddFB() 来创建这些缓冲区对象。

    2. **设置 bo_handles**:

      • bo_handles[0]:Y 分量的缓冲区对象句柄。
      • bo_handles[1]:UV 分量的缓冲区对象句柄。
      • bo_handles[2]bo_handles[3] 可以设置为 0,因为 NV12 只需要两个平面。
    3. **设置 pitches**:

      • pitches[0]:Y 分量的行距,通常为 width(以字节为单位)。
      • pitches[1]:UV 分量的行距,通常为 width(以字节为单位)。
      • pitches[2]pitches[3] 可以设置为 0。
    4. **设置 offsets**:

      • offsets[0]:Y 分量的偏移量,通常为 0。
      • offsets[1]:UV 分量的偏移量,通常为 width * height(Y 分量的大小)。
      • offsets[2]offsets[3] 可以设置为 0。

    示例代码

    以下是一个示例代码片段,展示如何使用 drmModeAddFB2() 创建 NV12 格式的帧缓冲区:

    #include <xf86drm.h>
    #include <xf86drmMode.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int create_nv12_fb(int fd, uint32_t *bo_handles, uint32_t *pitches, uint32_t *offsets, int width, int height, uint32_t *fb_id) {
        // 设置 Y 分量的缓冲区对象句柄
        bo_handles[0] = /* Y 分量的缓冲区对象句柄 */;
        // 设置 UV 分量的缓冲区对象句柄
        bo_handles[1] = /* UV 分量的缓冲区对象句柄 */;
        
        // 设置行距
        pitches[0] = width;  // Y 分量的行距
        pitches[1] = width;  // UV 分量的行距
        pitches[2] = 0;       // 不使用
        pitches[3] = 0;       // 不使用
    
        // 设置偏移量
        offsets[0] = 0;                          // Y 分量的偏移量
        offsets[1] = width * height;             // UV 分量的偏移量
        offsets[2] = 0;                           // 不使用
        offsets[3] = 0;                           // 不使用
    
        // 调用 drmModeAddFB2 创建帧缓冲区
        int ret = drmModeAddFB2(fd, width, height, DRM_FORMAT_NV12, bo_handles, pitches, offsets, fb_id, 0);
        if (ret < 0) {
            fprintf(stderr, "drmModeAddFB2 failed: %s\n", strerror(-ret));
            return ret;
        }
    
        return 0;  // 成功
    }
    

    错误处理

    如果 drmModeAddFB2() 返回 -22,通常表示参数无效。请检查以下几点:

    • 确保 bo_handles 中的句柄是有效的。
    • 确保 pitchesoffsets 的值是正确的。
    • 确保您已经正确初始化了 DRM 设备并打开了文件描述符。

    总结

    通过正确设置 bo_handlespitchesoffsets,您应该能够成功创建 NV12 格式的帧缓冲区。如果仍然遇到问题,请仔细检查每个参数的值,并确保它们符合 NV12 格式的要求。希望这些信息能帮助您解决问题!如果您有其他问题,请随时问我。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

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

悬赏问题

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