v4l2_drm Python api说明#
概述#
k230_v4l2_drm 是嘉楠堪智 K230 平台上 V4L2 视频采集与 DRM 显示的 Python 绑定库。它将 Linux V4L2 (Video4Linux2) 摄像头采集和 DRM (Direct Rendering Manager) 显示输出整合为统一的流水线,支持:
多路摄像头采集:通过多个 context 同时采集多路视频
零拷贝 DRM 显示:V4L2 buffer 直接送 DRM 显示,无需额外拷贝
OSD 叠加:在视频画面上叠加 ARGB8888/RGB888 图层(如检测框、文字)
旋转/翻转:硬件级旋转 (0°/90°/180°/270°) 和镜像翻转
裁剪/偏移:设置显示偏移和裁剪区域
后台显示线程:
display_start()在后台线程持续刷新显示
完整 API 速查表#
方法/属性 |
签名 |
说明 |
|---|---|---|
构造 |
|
创建实例 |
DRM初始化 |
|
初始化显示, 返回分辨率 |
配置 |
|
配置摄像头参数 |
|
设置显示偏移 |
|
|
设置裁剪区域 |
|
|
设置旋转 |
|
|
设置翻转 |
|
|
设置缓冲区数量 |
|
流水线 |
|
初始化流水线 |
|
启动后台显示线程 |
|
|
停止显示线程 |
|
|
启动采集 |
|
|
停止采集 |
|
|
采集一帧 |
|
|
释放帧缓冲区 |
|
数据 |
|
获取帧原始数据 |
|
获取帧数组 (带形状) |
|
属性 |
|
上下文数量 |
|
采集宽度 |
|
|
采集高度 |
|
|
V4L2设备号 |
|
|
格式FourCC |
|
|
格式字符串 |
|
|
X偏移 |
|
|
Y偏移 |
|
|
旋转值 |
|
|
水平翻转 |
|
|
垂直翻转 |
|
|
帧计数 |
|
|
设置帧计数 |
|
|
V4L2文件描述符 |
|
|
显示帧计数 (可读写) |
|
OSD |
|
设置OSD格式 |
|
更新OSD图像 |
模块常量#
旋转枚举 (Rotation)#
常量 |
值 |
说明 |
|---|---|---|
|
0 |
不旋转 |
|
1 |
顺时针旋转 90° |
|
2 |
旋转 180° |
|
3 |
顺时针旋转 270° |
|
4 |
水平镜像 (沿 X 轴翻转) |
|
5 |
垂直镜像 (沿 Y 轴翻转) |
像素格式 (FourCC 字符串)#
用于 set_context() 的 format 参数:
常量 |
值 |
说明 |
|---|---|---|
|
|
YUV 4:2:0 半平面格式 (Y + 交错UV) |
|
|
YUV 4:2:0 半平面格式 (Y + 交错VU) |
|
|
YUV 4:2:2 半平面格式 |
|
|
YUV 4:2:2 半平面格式 |
|
|
BGR 24位格式 |
|
|
RGB 24位格式 |
|
|
YUYV 4:2:2 打包格式 |
注意:
format参数接受字符串 (如"NV12"),内部会自动转换为 FourCC。K230 还支持"BG3P"格式 (BGR 平面格式,用于 AI 推理输入)。
V4L2 像素格式常量 (整数)#
常量 |
说明 |
|---|---|
|
V4L2 NV12 格式四字符码 |
|
V4L2 NV21 格式四字符码 |
|
V4L2 NV16 格式四字符码 |
|
V4L2 NV61 格式四字符码 |
|
V4L2 BGR24 格式四字符码 |
|
V4L2 RGB24 格式四字符码 |
|
V4L2 YUYV 格式四字符码 |
DRM 格式常量 (整数)#
常量 |
说明 |
|---|---|
|
DRM NV12 格式 |
|
DRM NV21 格式 |
|
DRM NV16 格式 |
|
DRM NV61 格式 |
|
DRM BGR888 格式 |
|
DRM RGB888 格式 |
|
DRM YUYV 格式 |
|
DRM ARGB8888 格式 (用于 OSD) |
|
DRM XRGB8888 格式 (用于 OSD, 无透明通道) |
类: V4l2Drm#
构造函数#
V4l2Drm(context_num=1, osd=False)
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
视频采集上下文数量 (对应摄像头路数) |
|
|
|
是否启用 OSD 叠加图层 |
示例:
# 单路摄像头, 无OSD
v4l2 = V4l2Drm(context_num=1)
# 双路摄像头 (如: 一路显示 + 一路AI推理), 启用OSD
v4l2 = V4l2Drm(context_num=2, osd=True)
初始化与配置#
drm_init(drm_id=0)#
初始化 DRM 显示设备。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
DRM 设备编号 (对应 |
返回值: tuple(int, int) — 成功返回 (width, height) 屏幕分辨率;失败返回 (-1, -1)
width, height = v4l2.drm_init(drm_id=0)
if width == -1:
raise RuntimeError("DRM init failed")
set_context(index, device, width, height, format, display)#
配置指定上下文的摄像头参数。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 (0 ~ context_num-1) |
|
|
|
V4L2 设备编号 (对应 |
|
|
|
采集分辨率宽度 |
|
|
|
采集分辨率高度 |
|
|
|
像素格式 (如 |
|
|
|
是否将该路视频输出到屏幕显示 |
# Context 0: 摄像头1, 1080p, NV12格式, 用于显示
v4l2.set_context(index=0, device=1, width=1920, height=1080, format="NV12", display=True)
# Context 1: 摄像头2, 720p, BG3P格式, 仅用于AI推理, 不显示
v4l2.set_context(index=1, device=2, width=1280, height=720, format="BG3P", display=False)
set_offset(index, x, y)#
设置指定上下文在屏幕上的显示偏移。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
X 偏移 (像素) |
|
|
|
Y 偏移 (像素) |
# 将context 0的画面偏移到 (100, 50) 位置
v4l2.set_offset(index=0, x=100, y=50)
set_crop(index, w, h, ox, oy)#
设置指定上下文的裁剪区域。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
裁剪宽度 (0 = 不裁剪) |
|
|
|
裁剪高度 (0 = 不裁剪) |
|
|
|
裁剪区域 X 偏移 |
|
|
|
裁剪区域 Y 偏移 |
# 裁剪出 640x480 区域, 起始偏移 (100, 100)
v4l2.set_crop(index=0, w=640, h=480, ox=100, oy=100)
set_rotation(index, rotation)#
设置指定上下文的旋转模式。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
旋转值, 使用 |
from k230_v4l2_drm import V4l2Drm, ROTATION_90, ROTATION_0
# 根据屏幕方向自动选择旋转
if width > height:
v4l2.set_rotation(0, ROTATION_0) # 横屏, 不旋转
else:
v4l2.set_rotation(0, ROTATION_90) # 竖屏, 旋转90度
set_flip(index, hflip, vflip)#
设置指定上下文的镜像翻转。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
水平翻转 (0=关闭, 1=开启) |
|
|
|
垂直翻转 (0=关闭, 1=开启) |
# 水平镜像 (左右翻转)
v4l2.set_flip(index=0, hflip=1, vflip=0)
set_buffer_num(index, num)#
设置指定上下文的 V4L2 缓冲区数量。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
缓冲区数量 (最少 3, 推荐 4) |
v4l2.set_buffer_num(index=0, num=4)
流水线控制#
setup()#
初始化并启动 V4L2-DRM 流水线。在所有 set_context / set_rotation 等配置完成后调用。
返回值: bool — 成功返回 True,失败返回 False
if not v4l2.setup():
raise RuntimeError("V4L2-DRM setup failed!")
display_start()#
在后台线程启动显示刷新循环。调用后显示线程持续运行,将 V4L2 buffer 提交到 DRM 显示。
v4l2.display_start()
display_stop()#
停止显示刷新循环并等待后台线程结束。
v4l2.display_stop()
dump_start(index)#
启动指定上下文的视频采集 (开始 V4L2 流式采集)。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
返回值: bool
v4l2.dump_start(index=0)
dump_stop(index)#
停止指定上下文的视频采集。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
返回值: bool
v4l2.dump_stop(index=0)
dump_frame(index, timeout_ms)#
从指定上下文采集一帧。阻塞等待直到有帧可用或超时。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
|
|
|
超时时间 (毫秒) |
返回值: bool — 成功采集返回 True,超时或失败返回 False
if v4l2.dump_frame(index=0, timeout_ms=1000):
# 成功获取一帧
frame_data = v4l2.get_buffer_data(index=0)
# ... 处理帧数据 ...
v4l2.dump_release(index=0) # 必须释放!
else:
print("Frame capture timeout")
重要:
dump_frame成功后必须调用dump_release释放缓冲区,否则后续帧无法入队。
dump_release(index)#
释放指定上下文已采集的帧缓冲区,使其可被 V4L2 重新使用。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
返回值: bool
数据访问#
get_buffer_data(index)#
获取指定上下文当前帧的原始数据,返回 numpy 数组。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
返回值: numpy.ndarray — 一维 uint8 数组,包含帧的原始像素数据
raw_data = v4l2.get_buffer_data(index=0)
# raw_data.shape = (frame_size,), dtype = uint8
get_buffer_array(index)#
获取指定上下文当前帧数据,返回具有形状信息的 numpy 数组。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
|
|
上下文编号 |
返回值: numpy.ndarray — 带形状的 numpy 数组
对于 NV12 格式: shape =
(height * 3 // 2, width)或类似对于 BG3P 格式 (BGR 平面): shape =
(3, height, width)即 NCHW 排列对于 YUYV 格式: shape =
(height, width, 2)
frame = v4l2.get_buffer_array(index=1)
# 对于BG3P格式: frame.shape = (3, 720, 1280), 可直接用于AI推理
属性查询#
方法 |
返回类型 |
说明 |
|---|---|---|
|
|
上下文总数 |
|
|
指定上下文的采集宽度 |
|
|
指定上下文的采集高度 |
|
|
指定上下文的 V4L2 设备编号 |
|
|
指定上下文的 V4L2 格式 (整数 FourCC) |
|
|
指定上下文的格式字符串 (如 |
|
|
指定上下文的 X 偏移 |
|
|
指定上下文的 Y 偏移 |
|
|
指定上下文的旋转值 |
|
|
指定上下文的水平翻转状态 |
|
|
指定上下文的垂直翻转状态 |
|
|
指定上下文的帧计数 |
|
|
设置指定上下文的帧计数 |
|
|
指定上下文的 V4L2 文件描述符 (可用于 |
显示帧计数属性#
display_frame_count (属性)#
当前显示帧计数器,可读写。
# 读取
count = v4l2.display_frame_count
# 写入
v4l2.display_frame_count = 0
OSD (On-Screen Display) 叠加#
OSD 功能允许在视频画面上叠加透明图层,常用于绘制 AI 检测框、文字等。
前提: 构造
V4l2Drm时必须设置osd=True
set_osd_format(fourcc)#
设置 OSD 图层格式。
参数 |
类型 |
说明 |
|---|---|---|
|
|
DRM 格式常量,通常为 |
from k230_v4l2_drm import V4l2Drm, DRM_FORMAT_ARGB8888
v4l2 = V4l2Drm(context_num=1, osd=True)
v4l2.drm_init()
# ...
v4l2.set_osd_format(DRM_FORMAT_ARGB8888)
osd_update(img)#
更新 OSD 图层内容。将 numpy 数组图像数据写入 OSD 平面。
参数 |
类型 |
说明 |
|---|---|---|
|
|
OSD 图像数据 |
图像要求:
格式为 ARGB8888 时: shape =
(height, width, 4), dtype =uint8格式为 RGB888 时: shape =
(height, width, 3), dtype =uint8尺寸应与显示分辨率匹配
Alpha 通道: 0 = 完全透明, 255 = 完全不透明
import numpy as np
# 创建全透明OSD图像 (与显示同尺寸)
osd_img = np.zeros((display_height, display_width, 4), dtype=np.uint8)
# 绘制红色矩形框 (ARGB格式: B, G, R, A)
osd_img[100:200, 100:300] = [0, 0, 255, 255] # 红色不透明
# 绘制绿色文字区域
osd_img[10:50, 10:200] = [0, 255, 0, 255] # 绿色不透明
# 更新OSD
v4l2.osd_update(osd_img)
注意:
osd_update每次调用会完整替换 OSD 图层内容。如需叠加多个元素,应先在 numpy 数组上绘制完成后一次性提交。
