当前位置: 首页 > news >正文

Linux Media 子系统 V4l2

一 创建 V4l2 的 entity

在Linux内核的Media Controller框架中,V4L2设备作为实体(entity)的注册过程涉及以下步骤:

1. 初始化Media Controller结构

  • 驱动首先创建一个media_device实例,并与V4L2设备(如v4l2_device)关联。例如:
    struct media_device *mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL);
    media_device_init(mdev);
    mdev->dev = dev; // 关联到父设备
    v4l2_dev->mdev = mdev; // 将media_device绑定到V4L2设备
    

2. 创建V4L2子设备(Subdev)并注册为Entity

  • 每个硬件组件(如传感器、ISP)通过v4l2_subdev表示,并初始化其media_entity
    struct v4l2_subdev *sd = &sensor->sd;
    v4l2_subdev_init(sd, &sensor_ops); // 初始化子设备
    sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; // 设置实体类型
    media_entity_pads_init(&sd->entity, num_pads, pads); // 初始化pads
    

3. 注册Entities到Media Controller

  • 将子设备的实体添加到media_device中:
    int ret = media_device_register_entity(mdev, &sd->entity);
    

4. 建立实体间的连接(Links)

  • 使用media_create_pad_link()在源和目标的pad之间创建链接:
    media_create_pad_link(&sensor_sd->entity, SENSOR_PAD_SRC,&isp_sd->entity, ISP_PAD_SINK, 0);
    

5. 注册Media Controller到内核

  • 最后,注册整个media_device,用户空间可通过/dev/mediaX访问:
    int ret = media_device_register(mdev);
    

关键点

  • Entity类型:V4L2子设备(如传感器、ISP)通过media_entity表示,其类型由function字段标识(如MEDIA_ENT_F_CAM_SENSOR)。
  • 自动关联:当V4L2子设备注册时,其media_entity会自动加入media_device,无需手动添加。
  • 用户空间交互:用户可通过media-ctl工具查看拓扑结构,例如:
    media-ctl -p -d /dev/media0
    

示例驱动代码片段

// 初始化media_device
mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL);
media_device_init(mdev);
mdev->dev = dev;
strscpy(mdev->model, "My Camera", sizeof(mdev->model));// 初始化传感器子设备
v4l2_subdev_init(&sensor_sd, &sensor_ops);
sensor_sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
sensor_pads[0].flags = MEDIA_PAD_FL_SOURCE;
media_entity_pads_init(&sensor_sd.entity, 1, sensor_pads);
media_device_register_entity(mdev, &sensor_sd.entity);// 注册media_device
media_device_register(mdev);

通过上述步骤,V4L2子设备被注册为Media Controller框架中的实体,用户空间可管理复杂的数据流拓扑。

二 构建 pipeline

在 Linux 的 Media Controller 框架中,构建一个 **Pipeline(数据流管道)**需要明确设备中各个硬件组件(Entity)的拓扑关系,并通过 PadsLinks 将它们连接起来。以下是完整的构建流程和关键步骤:

1. 理解基本概念

在构建 Pipeline 前,需明确以下核心概念:

  • Entity(实体):表示硬件组件(如摄像头传感器、ISP、DMA引擎等)。
  • Pad(端点):Entity 的输入/输出端点,分为 Source Pad(源)Sink Pad(汇)
  • Link(链路):连接两个 Entity 的 Pad,定义数据流方向(如传感器 → ISP → DMA)。
  • Format(格式):数据格式(如分辨率、像素格式)需要在连接的 Pad 之间协商。

2. 构建 Pipeline 的步骤

(1) 识别设备中的 Entities

每个硬件组件在驱动中注册为一个 media_entity,例如:

  • 传感器MEDIA_ENT_F_CAM_SENSOR
  • ISP(图像处理器)MEDIA_ENT_F_PROC_VIDEO_ISP
  • DMA 引擎MEDIA_ENT_F_IO_V4L

通过 media-ctl 工具查看设备拓扑:

media-ctl -p -d /dev/media0

输出示例:

Entity 1: Camera Sensor (type 0x0000, function CAM_SENSOR)Pad 0: Source [fmt:SRGGB10/1920x1080]
Entity 2: ISP (type 0x0000, function PROC_VIDEO_ISP)Pad 0: Sink [fmt:SRGGB10/1920x1080]Pad 1: Source [fmt:YUYV/1920x1080]
Entity 3: DMA Engine (type 0x0000, function IO_V4L)Pad 0: Sink [fmt:YUYV/1920x1080]
(2) 建立 Links(连接 Pads)

通过 media-ctl 或驱动代码创建连接,确保数据流方向正确:

# 连接传感器(Entity 1)的 Source Pad 0 → ISP(Entity 2)的 Sink Pad 0
media-ctl -d /dev/media0 -l "'Camera Sensor':0 -> 'ISP':0 [1]"# 连接 ISP(Entity 2)的 Source Pad 1 → DMA Engine(Entity 3)的 Sink Pad 0
media-ctl -d /dev/media0 -l "'ISP':1 -> 'DMA Engine':0 [1]"
  • [1] 表示启用 Link,[0] 表示禁用。
(3) 协商格式(Format Negotiation)

每个 Pad 需要设置一致的数据格式(如分辨率、像素格式)。例如,在用户空间通过 media-ctl 设置:

# 设置传感器(Entity 1)的 Source Pad 0 格式为 SRGGB10_1920x1080
media-ctl -d /dev/media0 -V "'Camera Sensor':0 [fmt:SRGGB10/1920x1080]"# 设置 ISP(Entity 2)的 Sink Pad 0 格式为 SRGGB10_1920x1080(与传感器匹配)
media-ctl -d /dev/media0 -V "'ISP':0 [fmt:SRGGB10/1920x1080]"# 设置 ISP(Entity 2)的 Source Pad 1 格式为 YUYV_1920x1080
media-ctl -d /dev/media0 -V "'ISP':1 [fmt:YUYV/1920x1080]"# 设置 DMA Engine(Entity 3)的 Sink Pad 0 格式为 YUYV_1920x1080(与 ISP 匹配)
media-ctl -d /dev/media0 -V "'DMA Engine':0 [fmt:YUYV/1920x1080]"
(4) 激活 Pipeline

通过 V4L2 API 启动数据流:

# 使用 v4l2-ctl 捕获数据(假设 DMA Engine 对应 /dev/video0)
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=YUYV
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=10 --stream-to=output.raw

3. 内核驱动中的关键操作

驱动需要实现以下功能以支持 Pipeline 构建:

(1) 注册 Entities 和 Pads

在驱动中初始化 media_entitymedia_pad

// 示例:摄像头传感器驱动
struct v4l2_subdev *sensor_sd = &sensor->sd;// 初始化子设备
v4l2_subdev_init(sensor_sd, &sensor_ops);// 设置 Entity 类型
sensor_sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;// 初始化 Pads(假设传感器只有一个 Source Pad)
struct media_pad *sensor_pads = &sensor->pads[0];
sensor_pads[0].flags = MEDIA_PAD_FL_SOURCE; // Source Pad
media_entity_pads_init(&sensor_sd->entity, 1, sensor_pads);// 注册到 Media Controller
media_device_register_entity(mdev, &sensor_sd->entity);
(2) 创建 Links

在驱动中动态创建 Links:

// 连接传感器(Source Pad 0)→ ISP(Sink Pad 0)
media_create_pad_link(&sensor_sd->entity, 0, // Source Pad 0&isp_sd->entity, 0,    // Sink Pad 0MEDIA_LNK_FL_ENABLED   // 启用 Link
);

4. 验证 Pipeline

通过以下方法验证 Pipeline 是否正常工作:

  1. 查看拓扑
    media-ctl -p -d /dev/media0
    
  2. 检查格式协商
    media-ctl -V -d /dev/media0
    
  3. 捕获数据
    v4l2-ctl --stream-mmap --stream-to=frame.raw
    ```## 标题

5. 常见问题

  • Link 未启用:检查 media-ctl 命令中的 [1] 标志。
  • 格式不匹配:确保相邻 Pads 的格式(如像素格式、分辨率)一致。
  • 权限问题:确保用户有权限访问 /dev/mediaX/dev/videoX

总结

构建 Media Controller Pipeline 的核心步骤为:

  1. 识别 Entities 和 Pads(通过驱动或 media-ctl)。
  2. 建立 Links 定义数据流方向。
  3. 协商 Formats 确保相邻 Pads 格式一致。
  4. 激活数据流(通过 V4L2 API)。

通过这一流程,复杂的硬件拓扑(如摄像头 → ISP → 编码器 → 显示)可以在用户空间和内核中高效管理。

三 pipeline 传输数据

在 Linux 的 Media Controller 框架中,启动一个 Pipeline 的数据传输需要结合用户空间的 V4L2 API 和内核驱动的协作。以下是完整的流程和步骤:

1. Pipeline 数据传输的启动条件

在开始传输前,需确保以下条件已满足:

  1. Pipeline 已正确构建

    • Entities(实体,如传感器、ISP、DMA)已注册到 Media Controller。
    • Pads(端点)之间的 Links(链路)已建立并启用。
    • 所有相邻 Pads 的格式(分辨率、像素格式)已协商一致。
  2. 用户空间与内核的通信准备

    • V4L2 设备节点(如 /dev/video0)已打开。
    • 内存缓冲区(DMA Buffer)已分配并映射到用户空间。

2. 用户空间启动 Pipeline 的步骤

通过 V4L2 API 启动数据传输的核心步骤如下:

(1) 打开 V4L2 设备节点
int fd = open("/dev/video0", O_RDWR);
if (fd < 0) {perror("Failed to open device");exit(EXIT_FAILURE);
}
(2) 设置数据格式

设置视频流的格式(需与 Pipeline 中 DMA Sink Pad 的格式一致):

struct v4l2_format fmt = {0};
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 1920;
fmt.fmt.pix.height = 1080;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; // 与 DMA Sink Pad 的格式一致
fmt.fmt.pix.field = V4L2_FIELD_NONE;if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {perror("Failed to set format");exit(EXIT_FAILURE);
}
(3) 申请缓冲区(Request Buffers)

请求内核分配一定数量的 DMA 缓冲区:

struct v4l2_requestbuffers req = {0};
req.count = 4;                // 缓冲区数量
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP; // 使用内存映射模式if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {perror("Failed to request buffers");exit(EXIT_FAILURE);
}
(4) 内存映射(MMAP)缓冲区

将内核分配的缓冲区映射到用户空间:

struct buffer *buffers = calloc(req.count, sizeof(*buffers));
for (int i = 0; i < req.count; i++) {struct v4l2_buffer buf = {0};buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {perror("Failed to query buffer");exit(EXIT_FAILURE);}// 映射到用户空间buffers[i].length = buf.length;buffers[i].start = mmap(NULL, buf.length,PROT_READ | PROT_WRITE,MAP_SHARED, fd, buf.m.offset);
}
(5) 将缓冲区入队(Queue Buffers)

将缓冲区放入内核的输入队列,等待填充数据:

for (int i = 0; i < req.count; i++) {struct v4l2_buffer buf = {0};buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {perror("Failed to queue buffer");exit(EXIT_FAILURE);}
}
(6) 启动流传输(Start Streaming)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) {perror("Failed to start streaming");exit(EXIT_FAILURE);
}
(7) 捕获数据(Dequeue Buffers)

循环从内核队列中取出已填充数据的缓冲区:

while (1) {struct v4l2_buffer buf = {0};buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) {perror("Failed to dequeue buffer");break;}// 处理数据(例如保存到文件)process_image(buffers[buf.index].start, buf.bytesused);// 重新将缓冲区入队if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {perror("Failed to re-queue buffer");break;}
}

3. 内核驱动的职责

内核驱动需要实现以下关键回调函数以支持数据传输:

(1) 启动流(Start Streaming)

当用户空间调用 VIDIOC_STREAMON 时,驱动需启动硬件的数据流:

static int my_driver_start_streaming(struct vb2_queue *vq, unsigned int count) {struct my_device *dev = vb2_get_drv_priv(vq);// 1. 配置硬件寄存器,启动传感器、ISP、DMA 等start_hardware(dev);// 2. 通知下游 Entities(如 ISP)开始工作v4l2_subdev_call(dev->isp_sd, video, s_stream, 1);return 0;
}
(2) 停止流(Stop Streaming)

当用户空间调用 VIDIOC_STREAMOFF 时,驱动需停止硬件:

static void my_driver_stop_streaming(struct vb2_queue *vq) {struct my_device *dev = vb2_get_drv_priv(vq);// 1. 停止传感器、ISP、DMA 等stop_hardware(dev);// 2. 通知下游 Entities 停止工作v4l2_subdev_call(dev->isp_sd, video, s_stream, 0);
}
(3) 缓冲区处理

驱动需要将硬件填充的 DMA 缓冲区返回给用户空间:

static void my_driver_dma_callback(struct my_device *dev) {struct vb2_buffer *vb = dev->current_vb;// 标记缓冲区已填充数据vb2_buffer_done(vb, VB2_BUF_STATE_DONE);dev->current_vb = NULL;
}

4. 调试与验证

(1) 检查 Pipeline 状态
# 查看所有 Entities 和 Links
media-ctl -p -d /dev/media0# 查看格式协商结果
media-ctl -V -d /dev/media0
(2) 验证数据传输

使用 v4l2-ctl 捕获数据:

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=10 --stream-to=output.raw
(3) 常见问题
  • 无数据流
    • 检查 Links 是否启用(media-ctl -l)。
    • 确保所有 Pads 的格式一致。
  • 权限问题
    sudo chmod 666 /dev/media0 /dev/video0
    
  • 驱动未实现回调
    • 确认 vb2_ops 中的 start_streamingstop_streaming 已注册。

总结

启动 Pipeline 数据传输的完整流程:

  1. 用户空间
    • 打开设备 → 设置格式 → 申请缓冲区 → 启动流 → 循环捕获数据。
  2. 内核驱动
    • 实现 start_streamingstop_streaming 回调,协调硬件和下游 Entities。
  3. 调试工具
    • 使用 media-ctlv4l2-ctl 验证 Pipeline 状态和数据流。

通过这一流程,复杂硬件(如摄像头 → ISP → 编码器)的实时数据流可以在 Linux 系统中高效运行。

相关文章:

Linux Media 子系统 V4l2

一 创建 V4l2 的 entity 在Linux内核的Media Controller框架中&#xff0c;V4L2设备作为实体&#xff08;entity&#xff09;的注册过程涉及以下步骤&#xff1a; 1. 初始化Media Controller结构 驱动首先创建一个media_device实例&#xff0c;并与V4L2设备&#xff08;如v4…...

民兵装备管理系统DW-S300|支持国产化、自主研发

民兵装备器材管理系统&#xff08;智装备DW-S301&#xff09;是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 装备接收与登记 民兵装备抵达仓库时&#…...

Pro Git --(Windows)总结

Pro Git --Windows 文章目录 Pro Git --Windows知识来源Git入门与进阶 知识来源 廖雪峰的官方网站 Git教程 Git入门与进阶 # 初步学习Git #个人建议先大致过一遍&#xff0c;对Git有个大致的理解&#xff0c;然后在实操项目# 创建一个空目录 $ mkdir learngit $ cd learngit …...

加油口,电梯门的对称性对 TCP/IP 传输协议的启示

春节期间河南穷游屡次加油站排队加油之启示。 不考虑有意的设计因素&#xff0c;汽车加油口概率性分布在车身的左边或者右边&#xff0c;这个偶然的小细节让加油机同时为两辆车加油而无需额外的加油管。 如果所有车辆加油口都在同一侧&#xff0c;加油站的加油机就只能给一边的…...

【进阶】JVM篇

为什么学习jvm 1、面试的需要 学过java的程序员对jvm应该不陌生&#xff0c;程序员为什么要学习jvm呢&#xff1f;其实不懂jvm也可以照样写出优质的代码&#xff0c;但是不懂jvm会被大厂的面试官虐的体无完肤。 2、高级程序员需要了解 jvm作用 jvm负责把编译后的字节码转换…...

【安全靶场】信息收集靶场

靶场&#xff1a;https://app.hackinghub.io/hubs/prison-hack 信息收集 子域名收集 1.subfinder files.jabprisons.com staging.jabprisons.com cobrowse.jabprisons.com a1.top.jabprisons.com cf1.jabprisons.com va.cobrowse.jabprisons.com vs.jabprisons.com c…...

新数据结构(4)——Java继承

基本概念 继承的本质&#xff1a;重复使用已经定义好的方法和域&#xff0c;实现代码的重复利用。 使用继承之后&#xff0c;创建的子类可以方便地调用父类中已经定义的方法。 一个继承的例子&#xff1a; 重载和重写 重载 重载&#xff1a;发生在同一个类里&#xff0c;指…...

大数据学习之SparkStreaming、PB级百战出行网约车项目一

一.SparkStreaming 163.SparkStreaming概述 Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. Spark Streaming 是核心 Spark API 的扩展&#xff0c;支持实时数据…...

介绍两个个电池充电管理芯片(TP4057、ME4069)

第一个是TP4057。 输入电压是4~6.5V TP4056&#xff0c;它们之间最大的区别就是TP4056最高是1A的充电电流&#xff0c;而TP4057是500ma&#xff0c;适用于更小一点的电池。 TP4057停机模式的静态电流也更小&#xff08;上图列的是待机模式&#xff0c;但查看后面的表格发现实际…...

Debezium日常分享系列之:解码逻辑解码消息内容

Debezium日常分享系列之&#xff1a;解码逻辑解码消息内容 示例配置选项 DecodeLogicalDecodingMessageContent SMT将PostgreSQL逻辑解码消息的二进制内容转换为结构化形式。当Debezium PostgreSQL连接器捕获逻辑解码消息时&#xff0c;它会将消息事件记录发送到Kafka。默认情况…...

【Linux】smp_mb__after_atomic

文章目录 背景知识smp_mb__after_atomic 的作用具体应用场景为什么需要 smp_mb__after_atomic相关宏总结 背景知识 在现代多核处理器和并发编程中&#xff0c;编译器优化和CPU乱序执行可能导致程序指令的实际执行顺序与源代码中的顺序不一致。这种现象可能会破坏多线程或进程间…...

关于conda换镜像源,pip换源

目录 1. 查看当前下载源2. 添加镜像源2.1清华大学开源软件镜像站2.2上海交通大学开源镜像站2.3中国科学技术大学 3.删除镜像源4.删除所有镜像源&#xff0c;恢复默认5.什么是conda-forge6.pip换源 1. 查看当前下载源 conda config --show channels 如果发现多个 可以只保留1个…...

【JavaEE进阶】依赖注入 DI详解

目录 &#x1f334;什么是依赖注入 &#x1f384;依赖注入的三种方法 &#x1f6a9;属性注⼊(Field Injection) &#x1f6a9;Setter注入 &#x1f6a9;构造方法注入 &#x1f6a9;三种注⼊的优缺点 &#x1f333;Autowired存在的问题 &#x1f332;解决Autowired存在的…...

鸿蒙HarmonyOS NEXT开发:横竖屏切换开发实践

文章目录 一、概述二、窗口旋转说明1、配置module.json5的orientation字段2、调用窗口的setPreferredOrientation方法 四、性能优化1、使用自定义组件冻结2、对图片使用autoResize3、排查一些耗时操作 四、常见场景示例1、视频类应用横竖屏开发2、游戏类应用横屏开发 五、其他常…...

自己部署 DeepSeek 助力 Vue 开发:打造丝滑的折叠面板(Accordion)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 自己…...

程序员升级进阶之路

熟悉业务、项目代码、工作流程&#xff0c;积极吸取技术资料接需求&#xff0c;画流程图&#xff0c;&#xff08;伪代码&#xff09;&#xff0c;详细设计明确职业发展方向【很重要】求精&#xff1a;写代码前的技术方案设计 写代码并不难&#xff0c;关键是要明确为什么要写…...

C/C++后端开发面经

字节跳动 客户端开发 实习 一面(50min) 自我介绍是否愿意转语言,是否只愿意搞后端选一个项目来详细谈谈HTTP和HTTPS有什么区别?谈一下HTTPS加密的具体过程&#xff1a; 非对称加密 对称加密 证书认证的方式 非对称加密是为了保证对称密钥的安全性。 对称…...

【C++】策略模式

使用场景 主要目的是定义一系列可互换的算法或行为&#xff0c;并使它们在运行时可以根据不同的情况动态地替换。它侧重于算法的封装和替换&#xff0c;让客户端可以灵活地选择不同的策略来完成特定的任务。 例如&#xff0c;在一个游戏角色的行为系统中&#xff0c;角色的攻击…...

Baklib剖析企业内容管理与内容中台的主要区别解析

内容概要 在当今数字化转型的浪潮中&#xff0c;企业内容管理和内容中台这两种系统日益受到关注。两者虽均旨在提升企业的内容管理效率与协同能力&#xff0c;但却存在明显差异。企业内容管理&#xff08;ECM&#xff09;主要聚焦于文档的创建、存储、检索和管理&#xff0c;旨…...

深入了解 MySQL:从基础到高级特性

引言 在当今数字化时代&#xff0c;数据的存储和管理至关重要。MySQL 作为一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;凭借其高性能、可靠性和易用性&#xff0c;成为众多开发者和企业的首选。本文将详细介绍 MySQL 的基础概念、安装启…...

从零到一:基于Rook构建云原生Ceph存储的全面指南(上)

文章目录 一.Rook简介二.Rook与Ceph架构2.1 Rook结构体系2.2 Rook包含组件1&#xff09;Rook Operator2&#xff09;Rook Discover3&#xff09;Rook Agent 2.3 Rook与kubernetes结合的架构图如下2.4 ceph特点2.5 ceph架构2.6 ceph组件 三.Rook部署Ceph集群3.1 部署条件3.3 获取…...

嵌入式经常用到串口,如何判断串口数据接收完成?

说起通信&#xff0c;首先想到的肯定是串口&#xff0c;日常中232和485的使用比比皆是&#xff0c;数据的发送、接收是串口通信最基础的内容。这篇文章主要讨论串口接收数据的断帧操作。 空闲中断断帧 一些mcu&#xff08;如&#xff1a;stm32f103&#xff09;在出厂时就已经在…...

OpenGL-基础知识(更新中)

本文基于The Cherno在Youtube上的OpenGL系列视频总结出的笔记&#xff0c;等这个系列视频学习完后&#xff0c;将更加系统详细的学习《计算机图形学编程&#xff08;使用OpenGL和C 第二版&#xff09;》这本书。个人认为看cherno的视频上手速度更快&#xff0c;而且他对基本概念…...

【多模态大模型】系列2:Transformer Encoder-Decoder——BLIP、CoCa、BEITv3

目录 1 BLIP2 CoCa3 BEITv3 1 BLIP BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation BLIP是 ALBEF 原班人马做的&#xff0c;基本可以看做吸收了 VLMo 思想的 ALBEF。训练的 loss 和技巧都与 ALBEF一致&#xff…...

基于CanMV IDE 开发软件对K210图像识别模块的开发

简介 CanMV IDE 是一款专为 K210 芯片设计的图形识别 Python 软件&#xff0c;它提供了强大的功能&#xff0c;帮助开发者轻松实现基于 K210 芯片的图形识别应用。无论你是初学者还是经验丰富的开发者&#xff0c;CanMV IDE 都能为你提供便捷的开发环境和丰富的资源。 硬件资…...

如何准备软考高级系统分析师考试

以下是针对软考高级系统分析师考试的详细备考方案&#xff0c;结合学习周期、阶段任务、习题选择和通过概率分析&#xff0c;帮助考生高效备考。 一、备考周期建议&#xff08;4-6个月&#xff09; 建议分为 基础阶段&#xff08;2个月&#xff09;→ 强化阶段&#xff08;2个…...

解析RK3588无线边缘盒子为工业自动化边缘推理带来的 AI 突破

在工业自动化领域&#xff0c;边缘推理的高效性和准确性对于提升生产效率和质量至关重要。RK3588 凭借强大的 AI 算力&#xff0c;为工业自动化边缘推理带来了显著的赋能效果。 RK3588 拥有出色的多核架构和高性能的 GPU &#xff0c;能够快速处理大量的数据。在工业生产线上&…...

初一说明文:我的护眼灯

本文转自&#xff1a;AI范文助手网 原文链接&#xff1a;https://www.aazhushou.com/czzw/5023.html 自爱迪生发明了灯以来&#xff0c;各种各样的灯相继问世了&#xff0c;给人一种新景象&#xff0c;其中护眼灯也问世了。 我有一盏台灯叫麦迪格护眼灯。那天我和母亲去商场&…...

归并排序(C# C++)

目录 1 归并排序的基本概念 2 算法步骤 2-1 分解阶段 2-2 合并阶段 3 代码实现 3-1 C#代码示例&#xff08;该代码在unity环境下&#xff09; 3-2 C代码示例 1 归并排序的基本概念 归并排序&#xff08;Merge Sort&#xff09;是一种经典的分治算法&#xff0c;由约翰…...

【Linux】Ubuntu Linux 系统 ——PHP开发环境

ℹ️大家好&#xff0c;我是练小杰&#xff0c;元宵节到了&#xff0c;在此祝大家元宵节快乐&#x1f606; 新的一年里&#xff0c;愿你步步高升&#xff0c;事事如意&#xff0c;心想事成&#xff01;! 本文是关于Linux 操作系统中部署PHP开发环境这部分基础内容&#xff0c;后…...

TDengine 性能测试工具 taosBenchmark

简介工具获取运行 无参数模式命令行模式配置文件模式 命令行参数配置文件参数 通用配置参数写入配置参数 数据库相关超级表相关标签列与数据列写入行为相关 查询配置参数 执行指定查询语句查询超级表 订阅配置参数数据类型对照表 配置文件示例 写入 JSON 示例查询 JSON 示例订阅…...

校园网绕过认证上网很简单

校园网绕过认证就是不用通过校园WiFi的WEB页面登录&#xff0c;这个WEB登录页面就是认证页面. 所谓绕过认证&#xff0c;就是不通过校园WiFi WEB登录页面直接上网&#xff0c;校园WiFi没有密码&#xff0c;直接就能连接上&#xff0c;我们连上这个WiFi的时候&#xff0c;它会给…...

C++ Primer 迭代语句

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…...

World of Warcraft [CLASSIC][Grandel] FOR THE HORDE

《World of Warcraft [CLASSIC][80猎人][Grandel]维克尼拉斯大型纪录片2025年元宵节击杀联盟主城4BOSS[为了部落&#xff01;]》 World of Warcraft [CLASSIC][80猎人][Grandel]维克尼拉斯大型纪录片2025年元宵节击杀联盟主城4BOSS[为了部落&#xff01;]_魔兽...

【ESP32指向鼠标】——icm20948与esp32通信

【ESP32指向鼠标】——icm20948与esp32通信 ICM-20948介绍 ICM-20948 是一款由 InvenSense&#xff08;现为 TDK 的一部分&#xff09;生产的 9 轴传感器集成电路。它结合了 陀螺仪、加速度计和磁力计。 内置了 DMP&#xff08;Digital Motion Processor&#xff09;即负责执…...

随手记:小程序setData 数据传输长度为 XXXKB,存在有性能问题!小程序长列表性能优化,uni.createIntersectionObserver

在一些小程序列表的页面&#xff0c;总是会看到小程序控制台的黄色警告&#xff1a; 这是由于data 数据过大&#xff0c;导致的问题 方法&#xff1a; 1.避免setData的数据过大&#xff0c;小于1024kb。 2.避免调用频繁&#xff0c;保证数据实时性。 3.避免未绑定在WXML的…...

双ESP8266-01S通讯UDP配置

第一台ESP8266(发送命令需要勾---发送新行) ATCWMODE3 ATCWSAP_DEF"CAR_wifi_Master","12345678",5,3 //设置本地wifi名称以及密码 ATCIPSTA_DEF"192.168.4.1" //设置本地IP ATCIFSR …...

记忆模块概述

文章目录 记忆模块概述记忆组件的定义记忆组件、链组件和Agent组件的关系设置第一个记忆组件内置记忆组件自定义记忆组件 本文将LangChain框架内所有与记忆功能有关的组件统一称为“记忆模块”。简而言之&#xff0c;记忆模块是一个集合体&#xff0c;由多个不同的记忆组件构成…...

计算机网络结课设计:通过思科Cisco进行中小型校园网搭建

上学期计算机网络课程的结课设计是使用思科模拟器搭建一个中小型校园网&#xff0c;当时花了几天时间查阅相关博客总算是做出来了&#xff0c;在验收后一直没管&#xff0c;在寒假想起来了简单分享一下&#xff0c;希望可以给有需求的小伙伴一些帮助 目录 一、设计要求 二、…...

算法之 数论

文章目录 质数判断质数3115.质数的最大距离 质数筛选204.计数质数2761.和等于目标值的质数对 2521.数组乘积中的不同质因数数目 质数 质数的定义&#xff1a;除了本身和1&#xff0c;不能被其他小于它的数整除&#xff0c;最小的质数是 2 求解质数的几种方法 法1&#xff0c;根…...

【论文阅读】Revisiting the Assumption of Latent Separability for Backdoor Defenses

https://github.com/Unispac/Circumventing-Backdoor-Defenses 摘要和介绍 在各种后门毒化攻击中&#xff0c;来自目标类别的毒化样本和干净样本通常在潜在空间中形成两个分离的簇。 这种潜在的分离性非常普遍&#xff0c;甚至在防御研究中成为了一种默认假设&#xff0c;我…...

【深入探讨 ResNet:解决深度神经网络训练问题的革命性架构】

深入探讨 ResNet&#xff1a;解决深度神经网络训练问题的革命性架构 随着深度学习的快速发展&#xff0c;卷积神经网络&#xff08;CNN&#xff09;已经成为图像识别、目标检测等计算机视觉任务的主力军。然而&#xff0c;随着网络层数的增加&#xff0c;训练深层网络变得愈加…...

【C】链表算法题7 -- 环形链表||

leetcode链接https://leetcode.cn/problems/linked-list-cycle-ii/description/ 问题描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到…...

设备智能化无线通信,ESP32-C2物联网方案,小尺寸芯片实现大功能

在科技飞速发展的当下&#xff0c;我们的生活正被各类智能设备悄然改变&#xff0c;它们如同一位位无声的助手&#xff0c;渗透到我们生活的每一个角落&#xff0c;让生活变得更加便捷和丰富多彩。 智能插座、智能照明和简单家电设备在家居领域的应用&#xff0c;为我们的生活…...

【嵌入式Linux应用开发基础】read函数与write函数

目录 一、read 函数 1.1. 函数原型 1.2. 参数说明 1.3. 返回值 1.4. 示例代码 二、write 函数 2.1. 函数原型 2.2. 参数说明 2.3. 返回值 2.4. 示例代码 三、关键注意事项 3.1 部分读写 3.2 错误处理 3.3 阻塞与非阻塞模式 3.4 数据持久化 3.5 线程安全 四、嵌…...

从 X86 到 ARM :工控机迁移中的核心问题剖析

在工业控制领域&#xff0c;技术的不断演进促使着工控机从 X86 架构向 ARM 架构迁移。然而&#xff0c;这一过程并非一帆风顺&#xff0c;面临着诸多关键挑战。 首先&#xff0c;软件兼容性是一个重要问题。许多基于 X86 架构开发的工业控制软件可能无法直接在 ARM 架构上运行…...

【数据结构】(7) 栈和队列

一、栈 Stack 1、什么是栈 栈是一种特殊的线性表&#xff0c;它只能在固定的一端&#xff08;栈顶&#xff09;进行出栈、压栈操作&#xff0c;具有后进先出的特点。 2、栈概念的例题 答案为 C&#xff0c;以C为例进行讲解&#xff1a; 第一个出栈的是3&#xff0c;那么 1、…...

android设置添加设备QR码信息

摘要&#xff1a;客户衍生需求&#xff0c;通过扫QR码快速获取设备基础信息&#xff0c;并且基于POS SDK进行打印。 1. 定位至device info的xml添加相关perference Index: vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/my_device_info.xml--- vendor/medi…...

进程状态

目录 1.进程排队 硬件的队列 进程排队 2.进程的三大状态 什么是状态 运行状态 阻塞状态 挂起状态 3.Linux系统中的进程状态 4.僵尸状态 5.孤儿进程 1.进程排队 硬件的队列 计算机是由很多硬件组成的&#xff0c;操作系统为了管理这些硬件&#xff0c;通常需要为这…...

【linux学习指南】模拟线程封装与智能指针shared_ptr

文章目录 &#x1f4dd;线程封装&#x1f309; Thread.hpp&#x1f309; Makefile &#x1f320;线程封装第一版&#x1f309; Makefile:&#x1f309;Main.cc&#x1f309; Thread.hpp: &#x1f320;线程封装第二版&#x1f309; Thread.hpp:&#x1f309; Main.cc &#x1f…...