菜鸟修炼笔记-音视频开发基础知识-drm简介

article/2025/10/25 3:54:42

音视频开发基础知识-drm简介

  • 前言
  • 一。DRM的基础概念
    • 1. DRM是什么?
    • 2. DRM的组成
      • 2.1 libdrm
      • 2.2 GEM
      • 2.3 KMS
  • 二。KMS各个元素详解
    • 1. plane
      • 1.1 定义:
      • 1.2 类型
      • 1.3 功能
      • 1.4 使用:
      • 1.5 注意:
    • 2. property
      • 2.1 定义和作用:
      • 2.2 常用的property及含义
  • 三。drm应用程序调用流程
    • 1. 初始化:
      • 1.1 打开设备
      • 1.2 设置drm的flag:
      • 1.3 获取crtc,encoder,connector,plane
    • 2. 创建dumb空间并通过mmap映射到应用层
      • 2.1 创建dumb buffer
      • 2.2 通过mmap映射到应用层
    • 3. 将相机数据传入前面mmap映射的地址中
    • 4. 提交数据
    • 5. 资源释放
    • 总结:
  • 参考资料

前言

最近工作上有些需求需要使用到drm中的plane,作为一名小菜鸟,在面对这个需求的时候,一堆问号又不由自主地从我的小脑瓜里面冒了出来。drm是什么?plane是什么?它们有什么用?它们有什么关系?它们要怎么用?所幸,万能的互联网存在各种知识,只需要我们花时间去寻找和学习,就能把各种各样的问题解决。
本文将会结合网上的资料和我自己的理解,来尝试回答以上的问题。

特别声明

本文很大部分信息来自其他博文,具体的博文网址见文末的参考资料。

一。DRM的基础概念

1. DRM是什么?

DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等,而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护。

2. DRM的组成

DRM从模块上划分,可以简单分为3部分:libdrm、KMS、GEM。

其中KMS还包括:CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property。
而GEM还包括:DUMB、PRIME、fence。

由于我目前需要了解的是plane属于KMS模块,我们将着重了解的是KMS。

2.1 libdrm

libdrm对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。应用层可以直接使用libdrm中的接口来达到图像显示和图像处理等功能。

2.2 GEM

Graphic Execution Manager,主要负责显示buffer的分配和释放,也是GPU唯一用到DRM的地方。

属于GEM模块的几个专有名词的意义如下:

元素说明
DUMB只支持连续物理内存,基于kernel中通用CMA API实现,多用于小分辨率简单场景
PRIME连续、非连续物理内存都支持,基于DMA-BUF机制,可以实现buffer共享,多用于大内存复杂场景
fencebuffer同步机制,基于内核dma_fence机制实现,用于防止显示内容出现异步问题

2.3 KMS

Kernel Mode Setting,所谓Mode setting,其实说白了就两件事:更新画面和设置显示参数
更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。
设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。

属于KMS的几个专有名词的意义如下:

元素说明
CRTC对显示buffer进行扫描,并产生时序信号的硬件模块,通常指Display Controller
ENCODER负责将CRTC输出的timing时序转换成外部设备所需要的信号的模块,如HDMI转换器或DSI Controller
CONNECTOR连接物理显示设备的连接器,如HDMI、DisplayPort、DSI总线,通常和Encoder驱动绑定在一起
PLANE硬件图层,有的Display硬件支持多层合成显示,但所有的Display Controller至少要有1个plane
FBFramebuffer,单个图层的显示内容,唯一一个和硬件无关的基本元素
VBLANK软件和硬件的同步机制,RGB时序中的垂直消影区,软件通常使用硬件VSYNC来实现
propertybuffer同步机制,基于内核dma_fence机制实现,用于防止显示内容出现异步问题

它们之间的关系和作用如下图所示,值得注意的是与显示屏连接的是connector,而plane可以存在多个也可以同时使用多个plane来进行图像显示。
在这里插入图片描述(图片来源:The DRM/KMS subsystem from a newbie’s point of view)

二。KMS各个元素详解

本文主要整理plane和property的内容,其余内容详见原博文。(文末有链接)

1. plane

1.1 定义:

Plane指的是Display Controller中用于多层合成的单个硬件图层模块。
Plane是连接FB与CRTC的纽带,是内存的搬运工。意思就是说,plane的作用是将帧缓存搬到CRTC中。

1.2 类型

类型说明
Cursor光标图层,一般用于PC系统,用于显示鼠标
Overlay叠加图层,通常用于YUV格式的视频图层
Primary主要图层,通常用于仅支持RGB格式的简单图层

其实随着现代半导体技术的飞速发展,Overlay PlanePrimary Plane之间已经没有明显的界限了,许多芯片的图层处理能力已经非常强大,不仅仅可以处理简单的RGB格式,也可以处理YUV视频格式,甚至FBC压缩格式。针对这类硬件图层,它既可以是Overlay Plane,也可以是Primary Plane,至于驱动如何定义,就要看工程师的喜好了。
而对于一些早期处理能力比较弱的硬件,为了节约成本,每个图层支持的格式并不一样,比如将平常使用格式最多的RGB图层作为Primary Plane,而将平时用不多的YUV视频图层作为Overlay Plane,那么这个时候上层应用程序在使用这两种plane的时候就需要区别对待了。

1.3 功能

一个高级的Plane,通常具有如下功能:

功能说明
Crop裁剪,如上图
Scaling缩放,放大或缩小
Rotation旋转,90° 180° 270° X/Y镜像
Z-OrderZ-顺序,调整当前层在总图层中的Z轴顺序
Blending合成,pixel alpha / global alpha
Format颜色格式,ARGB888 XRGB888 YUV420 等

1.4 使用:

伪代码:

int main(void)
{...drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);drmModeGetPlaneResources(fd);drmModeSetPlane(plane_id, crtc_id, fb_id, 0,crtc_x, crtc_y, crtc_w, crtc_h,src_x << 16, src_y << 16, src_w << 16, src_h << 16);...
}

(1)设置DRM_CLIENT_CAP_UNIVERSAL_PLANES:

drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
//fd为前面打开的文字描述符

因为如果不设置DRM_CLIENT_CAP_UNIVERSAL_PLANES,drmModeGetPlaneResources()就只会返回Overlay Plane,其他Plane都不会返回。而如果设置了,DRM驱动则会返回所有支持的Plane资源,包括cursor、overlay和primary。

(2)获取plane资源(主要需要获取所需的plane_id):

drmModePlaneRes *plane_res;
uint32_t plane_id;
plane_res = drmModeGetPlaneResources(fd);
plane_id = plane_res->planes[0];

(3)实现裁剪、平移和放大的效果:drmModeSetPlane()drmModeSetPlane的详细定义

	drmModeSetPlane(plane_id, crtc_id, fb_id, 0,crtc_x, crtc_y, crtc_w, crtc_h,src_x << 16, src_y << 16, src_w << 16, src_h << 16);

这个函数的参数含义如下:
在这里插入图片描述

1.5 注意:

(1)要与YUV/YCbCr图形格式中的plane区分开来:

DRM中的Plane和我们常说的YUV/YCbCr图形格式中的plane完全是两个不同的概念。YUV图形格式中的plane指的是图像数据在内存中的排列形式,一般Y通道占一段连续的内存块,UV通道占另一段连续的内存块,我们称之为YUV-2plane
(也叫YUV 2平面),属于软件层面。而DRM中的Plane指的是Display
Controller中用于多层合成的单个硬件图层模块,属于硬件层面。二者概念上不要混淆。

(2)并不是所有的Display Controller都支持Plane,即使没有plane_id,屏幕也能正常显示。比如s3c2440这种骨灰级ARM9 SoC,它的LCDC就没有Plane的概念。但是DRM框架规定,任何一个CRTC,必须要有1个Primary Plane。 即使像S3C2440这种不带真实Plane硬件的Display Controller,我们也认为它的Primary Plane就是LCDC本身,因为它实现了从Framebuffer到CRTC的数据搬运工作,而这正是一个Plane最基本的功能。

2. property

2.1 定义和作用:

用来控制drm各个环节参数的全局属性,Property的结构简单概括主要由3部分组成:nameidvalue,不同的property控制不同的环节,也有不同的nameidvalue。通过获取不同的property并进行相应的设置,便可以控制drm各个环节。

2.2 常用的property及含义

DRM应用程序进阶 (Property)

三。drm应用程序调用流程

 注意:以下都是伪代码,实际函数的参数并不如下面代码所示

1. 初始化:

1.1 打开设备

open(/dev/dri/card0) 

1.2 设置drm的flag:

drmSetClientCap(DRM_CLIENT_CAP_UNIVERSAL_PLANES) 
drmSetClientCap(DRM_CLIENT_CAP_ATOMIC)

(1)为什么要设置 DRM_CLIENT_CAP_ATOMIC

凡是被DRM_MODE_PROP_ATOMIC修饰过的property,只有在drm应用程序支持Atomic操作时才可见,否则该property对应用程序不可见。因此通过设置DRM_CLIENT_CAP_ATOMIC这个flag,来告知DRM驱动该应用程序支持Atomic操作。

(2)为什么要设置 DRM_CLIENT_CAP_UNIVERSAL_PLANES

因为如果不设置DRM_CLIENT_CAP_UNIVERSAL_PLANESdrmModeGetPlaneResources()就只会返回Overlay Plane,其他Plane都不会返回。而如果设置了,DRM驱动则会返回所有支持的Plane资源,包括cursor、overlay和primary。

1.3 获取crtc,encoder,connector,plane

drmModeGetResources()
drmModeGetConnector() //found connector DSI 
drmModeObjectGetProperties() //found connector dpms prop 
drmModeGetEncoder() //found encoder DSI
drmModeGetCrtc() //found crtc that connect to DSI 
drmGetPlaneByType(DRM_PLANE_TYPE_PRIMARY) //get PRIMARY/OVERLAY type drm plane info
drmModeObjectGetProperties(plane_id,DRM_MODE_OBJECT_PLANE) //get drm plane properties 
drmModeGetProperty() //get drm info like crtc_id,fb_id and so on,they be used for commit

获取crtc,encoder,connector,plane的先后顺序为connector,encoder,crtc,plane,每个前者的结构中都有后者的id号,发现connector后可以用过其结构下的encoder_id找到与自己连接的encoder模块,同理直到找到从plane到connector的连接通路。

2. 创建dumb空间并通过mmap映射到应用层

2.1 创建dumb buffer

【什么是dumb buffer:关于 DRM 中 DUMB 和 PRIME 名字的由来】

drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)

2.2 通过mmap映射到应用层

【什么是mmap:【深入浅出Linux】关于mmap的解析】

drmIoctl(DRM_IOCTL_MODE_MAP_DUMB) //获取dumb buffer的映射偏移值
mmap() //通过mmap映射内核空间到应用层

3. 将相机数据传入前面mmap映射的地址中

drmPrimeHandleToFD(fd,handle,0,&fd2) //handle已和fd绑定,在此将fd2与handle绑定,即fd2同fd相同
drmModeAddFB2() //添加framebuffer

可以将相机数据从相机buf拷贝到mmap空间,但该方式效率太低,对于高帧率的应用场景可以使用DMA_BUF机制将相机数据buf和mmap空间建立连接,使数据通过dma通道直达mmap空间。

4. 提交数据

drmModeAtomicAlloc() //申请Atomic结构
drmModeAtomicAddProperty() //将前面获取的crtc_id,fb_id等参数都传入申请的Atomic结构中
drmModeAtomicCommit() //提交数据到display

【 Atomic Commit具体的用法见:DRM应用程序进阶 (atomic-plane)】

5. 资源释放

drmModeRmFB(fb_id) //删除drmModeAddFB2()添加的framebuffer,不然会造成shmem泄露
munmap() //释放mmap映射的内存
close() //关闭打开的drm句柄

总结:

以上便为应用程序调用libdrm的流程,其中的3和4在循环中,1和2只需要调用一次,但在某些场景中需要释放2中申请的资源,但1中初始化的不能释放;
该场景为:单一plane,crtc等,需要多次打开和关闭display,且系统中有多个功能块在使用drm中的一个或多个模块(比如视频编码用到encoder模块),这样,若将1中初始化的资源释放掉,再次获取时可能会被其他进程占用导致无法获取,这种场景下就需要保留1中资源,但多次申请/是否2中资源。
但这样会引入一个问题:调用drmModeRmFB函数释放fb,但若释放了正在用于提交的fb,内核会将crtc关闭,导致vop数据传输通路断裂,而且没有framebuffer时Encoder也会被disable,此时再打开vop也无法获取Encoder,致使vop不通;虽然内核宏CONFIG_DRM_FBDEV_EMULATION使能时,在所有的drmfd关闭后fbdev会重新配置crtc,但由于其他进程也打开了drm,因此crtc不会再次被设置,除非重启程序。
解决这一问题的方法是:打开vop时调用drmModeSetCrtc函数手动设置crtc,即使无法找到Encoder,该函数也会使用一个默认的Encoder将crtc,encoder,connector三者建立连接,从而打通vop通路。
也就是说在以上的应用场景下即使内核默认使能了宏CONFIG_DRM_FBDEV_EMULATION,也需要调用到drmModeSetCrtc()函数,非以上场景可不用调用(对于Atomic模式来说)。

参考资料

  1. 特别推荐:DRM(Direct Rendering Manager)学习简介
  2. 特别推荐:linux drm原理及应用
  3. DRM应用程序进阶 (atomic-plane)

http://chatgpt.dhexx.cn/article/O5i1JOZd.shtml

相关文章

CSS字体的font-family属性和@font-face使用方法

CSS字体的font-family属性&#xff1a; font-family属性一共有5个字体系列&#xff0c;分别是&#xff1a; sans-serif&#xff1a; 包括没有衬线的字体&#xff0c;与serif相比&#xff0c;通常认为sans-serif在计算机屏幕上更容易识别。 serif&#xff1a; 包括有衬线的字…

前端漂亮的字体 font-family

今天在看UI图的时候看到这种字体&#xff0c;给大家分享分享&#xff0c;直接上图 图一 利用字体系列font-family div{font-size: .7rem;color: #ffeb7b;/* 黄色 */font-family: electronicFont; /* 这是重点&#xff01;&#xff01;&#xff01; */ }图二 利用文字阴影text-…

【CSS】font-family的相关字体设置

大家都知道&#xff0c;在不同操作系统、不同游览器里面默认显示的字体是不一样的&#xff0c;并且相同字体在不同操作系统里面渲染的效果也不尽相同&#xff0c;那么如何设置字体显示效果会比较好呢&#xff1f;下面我们逐步的分析一下&#xff1a; 一、字体基础知识 css 中…

Web 字体 font-family 浅谈

前言 最近研究各大网站的font-family字体设置&#xff0c;发现每个网站的默认值都不相同&#xff0c;甚至一些大网站也犯了很明显的错误&#xff0c;说明字体还是有很大学问的&#xff0c;值的我们好好研究。 不同的操作系统、不同浏览器下内嵌的默认字体是不同的&#xff0c;错…

font-faimly字体大全

清 font-size:100px 为例 font-family:“Arial”,“Microsoft YaHei”,“黑体”,“宋体”,sans-serif; font-family:Tahoma,Helvetica,Arial,‘宋体’,sans-serif; font-family: ‘Microsoft YaHei’,arial,tahoma,\5b8b\4f53,sans-serif; font-family:Tahoma,Helvetica,A…

html字体设置font-family

<div ><p style"font-family:STHeiti">1.华文黑体:STHeiti</p><p style"font-family:STKaiti">2.华文楷体&#xff1a;STKaiti</p><p style"font-family:STSong">3.华文宋体&#xff1a;STSong</p>&l…

html常用font-family设置字体样式

<table border"1" cellpadding"0" cellspacing"0" ><tr><td><h3 style"font-family: 黑体;">黑体&#xff1a;SimHei</h3></td><td><h3 style"font-family: 华文黑体;">华…

font-family、font-style、font-weight、font-variant的区别「In CSS」

学习 CSS&#xff0c;看文档的时候总是对 font 的属性搞不清楚或者总是搞混。 这里总结一下这四个经常搞混的&#xff08;特别是前面两个&#xff09;。 font-family 这个属性指的是字体&#xff0c;比如说汉字中常说的行书与草书。 这个属性的值可以有多个&#xff0c;因为…

FontFamily 看这里就够了

TextView中字体设置 typeface 一、配置设置 代码方式设置 fontFamily 文字如何实现加粗、斜体&#xff1f; 三者之间的关系 自定义字体 参考&#xff1a; TextView中字体设置 textView中有三个属性可以设置字体 textStyle&#xff1a;设置样式fontFamily&#xff1…

WPF—WrapPanel布局

WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列&#xff0c;当长度或高度不够是就会自动调整进行换行&#xff0c;后续排序按照从上至下或从右至左的顺序进行。 Orientation——根据内容自动换行。当 Horizontal选项看上去类似于Windows资源管理器的缩略图视图&…

WrapPanel

WrapPanel将子元素自左向右逐个地排列, 若一个水平行中放不下,就排在下一行。面板的方向可以是水平或垂直的 <Window x:Class"Panel布局.WrapPanelxaml"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.…

WPF中5种内建面板Canvas、StackPanel、WrapPanel、DockPanel、Grid分析

https://blog.csdn.net/weixin_43437202/article/details/88292620 Canvas、StackPanel、WrapPanel、DockPanel和Grid是WPF中主要的5种内建面板&#xff0c;这些面板类都位于System.Windows.Controls命名空间下。 主要布局特点简述 Grid 按行列排列内容&#xff0c;如果没有特…

WPF 改进 WrapPanel 右侧填充

WPF 改进 WrapPanel 右侧填充 本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。 WPF 改进 WrapPanel 右边缘填充 作者&#xff1a;陈-林-赵-魏|驚鏵 原文链接[1]&#xff1a;https://www.cnblogs.com/wandia/p/17084881.html 目的&#xff1a;改进下WrapPanel,…

WrapPanel 实现虚拟化

WrapPanel 实现虚拟化 控件名&#xff1a;VirtualizingWrapPanel 作者&#xff1a;WPFDevelopersOrg 原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers 框架使用大于等于.NET40&#xff1b;Visual Studio 2022;项目使用 MIT 开源许可协议&#xff1…

对wpf 的入门记录总结----面板控件Canvas、WrapPanel、StackPanel、DockPanel

面板是WPF裡其中一個很重要的控件。 面板扮演著裝載其他控件的容器的角色&#xff0c;同時也控制著頁面和視窗的佈局。 由於一個視窗只允許一個子控件&#xff0c;因此面板經常會被使用於分隔空間&#xff0c;這樣每個空間就會有一個控件或者面板。 wpf支持6种面板&#xff1…

listbox 表头自动换行_WPF让ListView或ListBox中的WrapPanel 自动换行

原文:WPF让ListView或ListBox中的WrapPanel 自动换行 在ListView或者ListBox中使用WrapPanel想让ItemTemplate中的内容像下图这样先横向平铺然后再纵向换行&#xff0c;默认设置是不能实现的。 图1. 横向平铺再纵向换行的效果示例 请注意最关键的在上面代码中第一行的“ScrollV…

WPF教程三:布局之WrapPanel面板(转 )

WPF教程三&#xff1a;布局之WrapPanel面板 WrapPanel&#xff1a;环绕面板 WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列&#xff0c;当长度或高度不够时就会自动调整进行换行&#xff0c;后续排序按照从上至下或从右至左的顺序进行。 Orientation——根据内容自…

WPF面板布局介绍Grid、StackPanel、DockPanel、WrapPanel

WPF面板布局介绍Grid、StackPanel、DockPanel、WrapPanel 回顾 上一篇&#xff0c;我们介绍了基本控件及控件的重要属性和用法&#xff0c;我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景&#xff0c;当 然这些都是本人在实际项目中的使用经验&#xff0c;可能…

2021-08-16 WPF控件专题 WrapPanel 控件详解

1.WrapPanel 控件介绍 流面板 子元素按顺序排列&#xff0c;如果按水平方向:从左到右&#xff0c;超出部分&#xff0c;自动换行到下一行 垂直 从上到下&#xff0c; 下一列 排列方向&#xff1a;Orientation ItemWidth ItemHeight 调整面板的尺寸时&#xff0c;内部子元素的…

.NET WPF(3)布局之WrapPanel面板

一.WPF&#xff08;3&#xff09;布局之WrapPane面板 1. WrapPanel&#xff1a;环绕面板 WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列&#xff0c;当长度或高度不够时就会自动调整进行换行&#xff0c;后续排序按照从上至下或从右至左的顺序进行。 Orie…