uvc_app里面自定义的drm

2023-11-23 04:20
文章标签 自定义 app 里面 drm uvc

本文主要是介绍uvc_app里面自定义的drm,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

直接上代码:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>#include <libdrm/drm.h>
#include <libdrm/drm_mode.h>
#include "drm.h"
#include "uvc_log.h"#define DRM_DEVICE "/dev/dri/card0"int drm_open(void)  //打开DRM设备文件
{int fd;fd = open(DRM_DEVICE, O_RDWR);if (fd < 0){LOG_ERROR("open %s failed!\n", DRM_DEVICE);return -1;}return fd;
}void drm_close(int fd)
{if (fd >= 0)close(fd);
}static int drm_ioctl(int fd, int req, void *arg)    //用于封装ioctl系统调用,用于向DRM设备发送控制命令
{int ret;do{ret = ioctl(fd, req, arg);}while (ret == -1 && (errno == EINTR || errno == EAGAIN));return ret;
}int drm_alloc(int fd, size_t len, size_t align, unsigned int *handle, unsigned int flags)   //分配显存
{int ret;struct drm_mode_create_dumb dmcb;memset(&dmcb, 0, sizeof(struct drm_mode_create_dumb));dmcb.bpp = 8;dmcb.width = (len + align - 1) & (~(align - 1));dmcb.height = 1;dmcb.flags = flags;if (handle == NULL)return -EINVAL;ret = drm_ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dmcb);if (ret < 0)return ret;*handle = dmcb.handle;return ret;
}int drm_free(int fd, unsigned int handle)   //释放通过drm_alloc函数分配的显存
{struct drm_mode_destroy_dumb data ={.handle = handle,};return drm_ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &data);
}void *drm_map_buffer(int fd, unsigned int handle, size_t len)   //映射显存到用户空间
{struct drm_mode_map_dumb dmmd;void *buf = NULL;int ret;memset(&dmmd, 0, sizeof(dmmd));dmmd.handle = handle;ret = drm_ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &dmmd);if (ret){LOG_ERROR("map_dumb failed: %s\n", strerror(ret));return NULL;}buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, dmmd.offset);if (buf == MAP_FAILED){LOG_ERROR("mmap failed: %s\n", strerror(errno));return NULL;}return buf;
}void drm_unmap_buffer(void *buf, size_t len)    //取消之前由drm_map_buffer函数映射到用户空间的缓冲区
{if (buf)munmap(buf, len);
}int drm_handle_to_fd(int fd, unsigned int handle, int *map_fd, unsigned int flags)  //将给定的DRM句柄(handle)转换为对应的文件描述符(file descriptor)
{int ret;struct drm_prime_handle dph;memset(&dph, 0, sizeof(struct drm_prime_handle));dph.handle = handle;dph.fd = -1;dph.flags = flags;if (map_fd == NULL)return -EINVAL;ret = drm_ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &dph);if (ret < 0)return ret;*map_fd = dph.fd;if (*map_fd < 0){LOG_ERROR("map ioctl returned negative fd\n");return -EINVAL;}return ret;
}int drm_get_info_from_name(int   fd,unsigned int   name,unsigned int  *handle,int  *size) //通过名称获取DRM信息
{int  ret = 0;struct drm_gem_open req;req.name = name;ret = drm_ioctl(fd, DRM_IOCTL_GEM_OPEN, &req);if (ret < 0){return ret;}*handle = req.handle;*size   = (int)req.size;return ret;
}

这段代码是一个使用DRM(Direct Rendering Manager)库的示例代码,用于在Linux系统中进行图形渲染和显示控制。DRM是一个内核模块,提供了用户空间程序与硬件之间的接口,用于管理显示设备和图形加速硬件。

该代码中包含了一些函数,如drm_open用于打开DRM设备文件,drm_alloc用于分配显存,drm_map_buffer用于映射显存到用户空间等。

drm_ioctl

在这段代码中,drm_ioctl是一个自定义的函数,用于封装ioctl系统调用,用于向DRM设备发送控制命令。在Linux中,ioctl系统调用通常用于设备的控制和配置。

具体来说,该函数的作用是向打开的DRM设备文件描述符fd发送req所指定的控制命令,arg是控制命令的参数,函数会一直尝试ioctl直到成功为止。

需要注意的是,ioctl系统调用在Linux中是一个相对底层的操作,使用时需要对设备的控制命令有一定的了解,并且需要小心处理各种错误情况。

在这段代码中,drm_ioctl函数封装了ioctl调用,处理了一些常见的错误情况,并提供了更友好的接口给上层调用,使得代码更易于使用和维护。

drm_alloc

这段代码是一个用于在DRM设备上分配显存的函数实现。

首先,它接受了五个参数:文件描述符fd、要分配的长度len、对齐方式align、用于接收句柄的指针handle以及标志flags

在函数内部,它先声明了一个struct drm_mode_create_dumb结构体dmcb,并将其清零初始化。

然后,它设置了dmcb结构体的一些字段,其中bpp表示每个像素占用的位数,width表示分配的空间大小(经过对齐处理),height为1,flags为传入的标志。

接着,它检查了handle的合法性,如果为NULL,则返回-EINVAL,表示参数错误。

接下来,它调用drm_ioctl函数,向DRM设备发送DRM_IOCTL_MODE_CREATE_DUMB命令,并传入dmcb结构体。如果返回值小于0,表示出现错误,直接将错误码返回。

最后,如果一切顺利,它将dmcb.handle的值赋给传入的*handle,并返回之前drm_ioctl的返回值。

总的来说,这个函数的作用是向DRM设备请求分配一块显存,返回分配成功与否的状态,并将分配的句柄通过参数返回供使用。

drm_free

在这段代码中,drm_free函数用于释放通过drm_alloc函数分配的显存。它接受一个文件描述符fd和一个handle参数,其中fd是已经打开的DRM设备文件描述符,handle是要释放的显存的句柄。

具体来说,drm_free函数会构造一个drm_mode_destroy_dumb结构体,并将handle赋值给结构体的handle字段。然后调用drm_ioctl函数,向fd发送DRM_IOCTL_MODE_DESTROY_DUMB命令,并将构造的结构体传递给ioctl系统调用。

该命令的作用是销毁通过DRM_IOCTL_MODE_CREATE_DUMB命令创建的显存资源,释放占用的系统资源。

需要注意的是,在调用drm_free函数之前,必须先通过drm_alloc函数成功地分配显存,并且确保handle参数的正确性。

drm_map_buffer

这段代码是一个用于将DRM设备的显存映射到用户空间的函数实现。

首先,它接受了三个参数:文件描述符fd、分配的显存句柄handle以及显存长度len

在函数内部,它声明了一个struct drm_mode_map_dumb结构体dmmd,并将其清零初始化。然后,它将传入的handle赋值给dmmd.handle字段。

接着,它调用drm_ioctl函数,向DRM设备发送DRM_IOCTL_MODE_MAP_DUMB命令,并传入dmmd结构体作为参数。如果返回值不为0,说明映射失败,直接返回NULL

如果映射成功,它将使用mmap函数将显存映射到用户空间,并将映射的地址赋值给buf

最后,如果一切顺利,它将返回buf指针,也就是映射到用户空间的显存地址。

总的来说,这个函数的作用就是将DRM设备的显存映射到用户空间,以便用户可以进行读写操作。

drm_handle_to_fd

这段代码是一个用于将给定的DRM句柄(handle)转换为对应的文件描述符(file descriptor)的函数实现。

这个函数接受了四个参数:文件描述符fd、要转换的句柄handle、用于接收文件描述符的指针map_fd以及标志flags

在函数内部,它首先声明了一个struct drm_prime_handle结构体dph,并将其清零初始化。然后,设置了dph结构体的handleflags字段,同时将dph.fd初始化为-1。

接着,它检查了map_fd的合法性,如果为NULL,则返回-EINVAL,表示参数错误。

然后,它调用drm_ioctl函数,向DRM设备发送DRM_IOCTL_PRIME_HANDLE_TO_FD命令,并传入dph结构体。如果返回值小于0,表示出现错误,直接将错误码返回。

如果一切顺利,它将dph.fd的值赋给传入的*map_fd,并进行进一步检查,如果*map_fd小于0,表示出现错误,返回-EINVAL

最后,它返回了之前drm_ioctl的返回值。

总的来说,这个函数的作用是将给定的DRM句柄转换为对应的文件描述符,并通过参数返回供使用。

这篇关于uvc_app里面自定义的drm的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/415310

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

鸿蒙开发中实现自定义弹窗 (CustomDialog)

效果图 #思路 创建带有 @CustomDialog 修饰的组件 ,并且在组件内部定义controller: CustomDialogController 实例化CustomDialogController,加载组件,open()-> 打开对话框 , close() -> 关闭对话框 #定义弹窗 (CustomDialog)是什么? CustomDialog是自定义弹窗,可用于广告、中

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

mybatis框架基础以及自定义插件开发

文章目录 框架概览框架预览MyBatis框架的核心组件MyBatis框架的工作原理MyBatis框架的配置MyBatis框架的最佳实践 自定义插件开发1. 添加依赖2. 创建插件类3. 配置插件4. 启动类中注册插件5. 测试插件 参考文献 框架概览 MyBatis是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射,为开发者提供了极大的灵活性和便利性。以下是关于M