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句柄转换为对应的文件描述符,并通过参数返回供使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/159893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【无标题】dp80采集机和机器人通信相关框架总结

采血机器人通信解析相关框架总结: 类似于dp80,将整个过程进行了分解如下: 类似于dp80,将整个过程进行了分解如下: 上位机界面在进行点击操作的时候,先是通信协议的解析,解析后改变采血的控制状态如下: Dp80主要框架解析࿱

4

【任务 1】容器云平台搭建[5 分] 【题目 1】平台部署–部署容器云平台[1.5 分] 【题目 2】平台部署–部署 Istio 服务网格[0.5 分] 【题目 3】平台部署–部署 KubeVirt 虚拟化[1 分] 【题目 4】平台部署–部署 Harbor 仓库及Helm 包管理工具[1 分] 【题目 5】集群管理–备份 ET…

华为obs上传下载-Java版 2023-11-23

弄了半天&#xff0c;老师帮弄成功了&#xff0c;经过同意&#xff0c;分享到网上&#xff0c;希望能帮助更多人&#xff0c;至于怎么弄的&#xff0c;我也不知道。 创建idea项目后&#xff0c;项目结构&#xff0c;对应文件没有的创一个 pom.xm 注意改Java版本&#xff0c;我…

dvwa-command injection 代码审计(超详细逐行审计)

dvwa-command injection 代码审计 low <?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ];// Determine OS and execute the ping command.if( stristr( php_uname( s ), Windows NT ) ) {// Windows$cmd shell_exec( ping . $target );}…

华为-算法---测试开发工程师----摘要牛客网

Java面试题---摘要牛客网-CSDN博客package extendNiuKeWang;import java.util.Scanner;public class GoodHuaWei {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int money = sc.nextInt();System.out.println("n值总金额:"+money)…

遥控器红外解码数码管显示

/*----------------------------------------------- 内容&#xff1a;按配套遥控器上1-9会在数码管上对应显示 ------------------------------------------------*/ #include<reg52.h> //包含头文件&#xff0c;一般情况不需要改动&#xff0c;头文件包含特殊功能…

AMESim|Make failed:Unable to create an excutable for the system

最近在AMESIM与MATLAB进行联合仿真的时候遇到如下问题&#xff1a; Make failed:Unable to create an excutable for the system. 看了网上的解决办法如下 配置环境变量重装AMESIM&#xff0c;有顺序要求&#xff0c;首先是VS&#xff0c;然后是AMESIM与MATLAB。在AMESIM安装…

csdn最新最全pytest系列——pluggy插件源码解读(一)HookspecMarker类和HookimplMarker类分析

简介 pluggy是一个非常优秀的插件系统&#xff0c;它是理解pytest的核心&#xff0c;只有理解了pluggy的原理&#xff0c;才能更好的理解和使用pytest&#xff0c;否则见到了pytest的很多应用都会感觉很难理解 pluggy插件总共的代码量不足一千行&#xff0c;而实现的功能却是…

IDEA 配置maven结合案例使用篇

1. 项目需求和结构分析 需求案例&#xff1a;搭建一个电商平台项目&#xff0c;该平台包括用户服务、订单服务、通用工具模块等。 项目架构&#xff1a; 用户服务&#xff1a;负责处理用户相关的逻辑&#xff0c;例如用户信息的管理、用户注册、登录等。 spring-context 6.0.…

5-2计算pi

#include<stdio.h> #include<math.h>int main(){int sign1;//数值的符号int count0;//累计计算循环的次数double pi0.0;double n1;//分母double term1.0;//当前项的数while(fabs(term)>1e-6){//fabs(trem)|term|pipiterm;nn2;sign-sign;termsign/n;count;}pipi*…

基于Vue3的低代码开发平台——JNPF

目录 一、什么是Vue.js &#xff1f; 二、Jnpf-Web-Vue3 的技术栈介绍 &#xff08;1&#xff09;Vue3.x &#xff08;2&#xff09;Vue-router4.x &#xff08;3&#xff09;Vite4.x &#xff08;4&#xff09;Ant-Design-Vue3.x &#xff08;5&#xff09;TypeScript &#x…

【Java】实现阻塞队列-生产者/消费者模型

上文中我们讲了Java库中自带的阻塞队列&#xff0c;并且讲了如何用阻塞队列来实现生产者消费者模型 【Java】用Java库中自带的阻塞队列以及用阻塞队列实现生产者-消费者模型 下面我们来讲如何用代码实现一个阻塞队列 1、实现一个阻塞队列 阻塞队列 普通队列 线程安全 阻…

机器学习实战第1天:鸢尾花分类任务

专栏介绍 欢迎订阅专栏——机器学习实战 机器学习实战_Nowl的博客-CSDN博客 纸上得来终觉浅 本专栏项目将着重于解决各类实际机器学习问题&#xff0c;带你上手各种场景的实际问题 数据集可以在我的资源中找到&#xff0c;也可以自行搜索 文中导入数据集的路径要改成自己的…

java 事务提交(批量处理数据,单个批次执行完成后直接提交事务)

方法一&#xff1a;接口REQUIRES_NEW 实现单个事务提交 方式1: for (TIrBuPBom buPBom : batchList) {// 查询待处理的批次数据List<TIrBuPBom> pBomList pBomMapperBase.list(new LambdaQueryWrapper<TIrBuPBom>().eq(TIrBuPBom::getBatchNo, buPBom.getBatchNo…

C++学习笔记——C++ deque和vector的区别

C中的std::deque&#xff08;双端队列&#xff09;和std::vector&#xff08;向量&#xff09;是两种不同的容器类型&#xff0c;它们有以下区别&#xff1a; 内部实现方式不同&#xff1a;std::deque使用了一种双端队列的数据结构&#xff0c;它由多个块&#xff08;chunks&am…

【Python】用 dict 实现一个简单的 json 数据库

废话不看&#xff1a; 最近写了一个小项目&#xff0c;基本逻辑是通过定时任务轮询 API&#xff0c;检测 API 状态变化并执行对应的操作。该 API 一共有 3 种状态&#xff0c;假设每种状态的值分别为 1、2、3&#xff0c;在状态 2 的时候需要调用一次处理方法。 这里的问题是状…

JavaScript面试经,offer拿到手软

文章来源于公众号&#xff1a;猴哥说前端 作者&#xff1a;monkeysoft 本文给大家分享一些 JavaScript 面试经验&#xff0c;在这金九银十的招聘季&#xff0c;希望大家都能找到满意的工作。 JavaScript的数据类型都有什么&#xff1f; 基本数据类型&#xff1a;String,Boolea…

word2vec的算法原理(不用开源包,python实现)

看了很多关于word2vec的算法原理的介绍文章&#xff0c;看明白了&#xff0c;但依然有点不深刻。 以下是python直接实现的word2vec的算法&#xff0c;简单明了&#xff0c;读完就懂了 import numpy as npdef tokenize(text):return text.lower().split()def generate_word_pa…

【操作系统】文件系统的实现

文章目录 文件系统的层次结构文件系统的实现目录实现线性列表哈希表 文件的实现连续分配链接分配索引分配 文件存储空间管理空闲表法与空闲链表法成组链接法位示图法 文件系统的层次结构 文件系统从上往下分为了五层&#xff0c;分别是用户调用接口、文件目录系统、存取控制模…

SWT/Jface(1): 表格的创建和渲染

前言 使用JFace创建表格还是比较方便的, 如果仅仅是创建空表格的话, 以下2步即可完成: 创建TableViewer对象, 指定样式, 比如是否支持多行选择, 有无边框, 是否支持滚动条等创建TableColumn对象: 包括列展示名称, 宽度和样式等, 最终绑定到table对象 实例 创建表格 //注意…