rk3568之mpp开发笔记记录之摄像头实时码流获取的神秘面纱

news2025/4/17 19:22:37

前言:

大家好,在上一篇文章里面,我给大家解读了怎么获取imx415-sensor的实时码流的细节,今天开始会解析里面到底是怎么实现的?

提前透露一点,整个摄像头驱动框架和上层调用,都会涉及到v4l2的开发使用,所以对于v4l2的掌握非常重要。

mpp编码器框架执行流程:

整个mpp单路码流测试源码,我们从下面这个接口mpi_enc_test开始解读,一步一步来学习里面的原理和实现:

3768a7222cb187ac0dc3c5337393af23.png

下面是整个代码的执行流程图:

ee4935d96ab7795c30bc83db5c8ba6ad.png

我们今天的重点在接口test_ctx_init接口,里面涉及到大量的v4l2和mpp缓冲池的操作,而这个接口里面最为重要的是下面划线这个接口,这个接口里面会涉及摄像头码流的开启和停止:

69b195b89037bcba8725324cd56adae2.png

接下来我们就开始进入到这个接口里面,看一下他里面的代码执行流程框架,然后再开始详细解读,里面也会讲解基础的v4l2的知识点,照顾一些朋友没有接触过v4l2的朋友:

a50e92499c9dd97219c752c31713e2ca.png

v4l2几个关键结构体和ioctl指令解读:

首先ioctl指令操作代码在Linux内核源码头文件videodev2.h汇总如下:

a5696302944ae082e7d7576930e7e446.png45e7dd9f13b3203e7667f385c3403888.pngcbfe0d0da8da70f7055a3605ebccb363.pnga8a1375fcde03568a0bfdcf176d21d71.png

下面我们来看源码里面的结构体结构体解析:

87e89dfbcdbe3740447d3eabb9612514.png

1、struct v4l2_capability结构体:

5a3bfdd517add6be412a855cac3ce85c.png
/**
 * struct v4l2_capability - 用于描述 V4L2 设备能力的信息结构体
 *
 * VIDIOC_QUERYCAP 是一个 V4L2 IOCTL 命令,用于查询视频设备的基本能力信息。
 * 用户程序可以通过调用此命令,填充此结构体以获取以下信息:
 * - 驱动程序的名称
 * - 设备的硬件名称
 * - 设备连接的总线信息
 * - 驱动程序的版本
 * - 设备的整体功能以及当前设备节点的功能
 *
 * 结构体成员说明:
 *
 * @driver:       驱动模块的名称(如 "bttv")。
 *                表示设备所使用的驱动程序。
 *
 * @card:         硬件卡的名称(如 "Hauppauge WinTV")。
 *                表示具体的硬件设备名称,用于标识设备型号或品牌。
 *
 * @bus_info:     设备连接总线的信息(如 "PCI:0000:00:1f.2")。
 *                表示设备连接的总线类型及其标识信息,例如 PCI、USB 等。
 *
 * @version:      驱动程序的版本号,通常以 KERNEL_VERSION 宏生成。
 *                格式为主版本号、次版本号和补丁版本号。
 *
 * @capabilities: 设备整体功能标志位,描述设备支持的功能。
 *                例如,支持视频捕获(V4L2_CAP_VIDEO_CAPTURE)、
 *                视频输出(V4L2_CAP_VIDEO_OUTPUT)等。
 *
 * @device_caps:  当前设备节点(如 /dev/video0)提供的功能标志位。
 *                可能是 `capabilities` 的子集,具体描述此节点的功能。
 *
 * @reserved:     保留字段,为将来扩展预留空间。
 */
struct v4l2_capability {
    __u8    driver[16];     /* 驱动程序的名称 */
    __u8    card[32];       /* 硬件卡的名称 */
    __u8    bus_info[32];   /* 总线信息 */
    __u32   version;        /* 驱动程序版本号 */
    __u32   capabilities;   /* 设备整体功能 */
    __u32   device_caps;    /* 当前设备节点功能 */
    __u32   reserved[3];    /* 保留字段 */
};

常见功能标志位有:

e4a7a1d32b2ad5e6410c9ab54f007c38.png
/* 'capabilities' 字段的值定义 */
#define V4L2_CAP_VIDEO_CAPTURE          0x00000001  /* 是视频捕获设备 */
#define V4L2_CAP_VIDEO_OUTPUT           0x00000002  /* 是视频输出设备 */
#define V4L2_CAP_VIDEO_OVERLAY          0x00000004  /* 支持视频叠加功能 */
#define V4L2_CAP_VBI_CAPTURE            0x00000010  /* 是原始 VBI 捕获设备 */
#define V4L2_CAP_VBI_OUTPUT             0x00000020  /* 是原始 VBI 输出设备 */
#define V4L2_CAP_SLICED_VBI_CAPTURE     0x00000040  /* 是分片 VBI 捕获设备 */
#define V4L2_CAP_SLICED_VBI_OUTPUT      0x00000080  /* 是分片 VBI 输出设备 */
#define V4L2_CAP_RDS_CAPTURE            0x00000100  /* 支持 RDS 数据捕获 */
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY   0x00000200  /* 支持视频输出叠加 */
#define V4L2_CAP_HW_FREQ_SEEK           0x00000400  /* 支持硬件频率搜索 */
#define V4L2_CAP_RDS_OUTPUT             0x00000800  /* 是一个 RDS 编码器 */

/* 是支持多平面格式的视频捕获设备 */
#define V4L2_CAP_VIDEO_CAPTURE_MPLANE   0x00001000
/* 是支持多平面格式的视频输出设备 */
#define V4L2_CAP_VIDEO_OUTPUT_MPLANE    0x00002000
/* 是支持多平面格式的视频内存到内存设备 */
#define V4L2_CAP_VIDEO_M2M_MPLANE       0x00004000
/* 是视频内存到内存设备 */
#define V4L2_CAP_VIDEO_M2M              0x00008000

#define V4L2_CAP_TUNER                  0x00010000  /* 具有调谐器功能 */
#define V4L2_CAP_AUDIO                  0x00020000  /* 支持音频功能 */
#define V4L2_CAP_RADIO                  0x00040000  /* 是一个无线电设备 */
#define V4L2_CAP_MODULATOR              0x00080000  /* 支持调制器功能 */

#define V4L2_CAP_SDR_CAPTURE            0x00100000  /* 是一个 SDR 捕获设备 */
#define V4L2_CAP_EXT_PIX_FORMAT         0x00200000  /* 支持扩展像素格式 */
#define V4L2_CAP_SDR_OUTPUT             0x00400000  /* 是一个 SDR 输出设备 */
#define V4L2_CAP_META_CAPTURE           0x00800000  /* 是一个元数据捕获设备 */

#define V4L2_CAP_READWRITE              0x01000000  /* 支持 read/write 系统调用 */
#define V4L2_CAP_ASYNCIO                0x02000000  /* 支持异步 I/O */
#define V4L2_CAP_STREAMING              0x04000000  /* 支持流式 I/O ioctls */

#define V4L2_CAP_TOUCH                  0x10000000  /* 是一个触控设备 */

#define V4L2_CAP_DEVICE_CAPS            0x80000000  /* 设置设备能力字段 */

2、struct v4l2_format结构体:

783539bf3a2b351993af3945fad327b3.png
/**
 * struct v4l2_format - 流数据格式描述结构体
 * 
 * 此结构体用于定义 V4L2 的数据流格式,可以通过 IOCTL 命令
 (如 VIDIOC_G_FMT、VIDIOC_S_FMT)进行获取或设置。
 * 根据数据流的类型,不同的字段会被使用。
 *
 * @type: 枚举类型 `enum v4l2_buf_type`,表示数据流的类型。
 *              常见的值包括:
 *              - V4L2_BUF_TYPE_VIDEO_CAPTURE:视频捕获
 *              - V4L2_BUF_TYPE_VIDEO_OUTPUT:视频输出
 *              - V4L2_BUF_TYPE_VIDEO_OVERLAY:视频叠加
 *              - V4L2_BUF_TYPE_VBI_CAPTURE:VBI 捕获
 *              - V4L2_BUF_TYPE_SDR_CAPTURE:SDR 捕获
 *
 * @pix: 表示单平面图像格式的定义(用于 V4L2_BUF_TYPE_VIDEO_CAPTURE)。
 *              结构体 `v4l2_pix_format` 包含图像分辨率、像素格式等信息。
 *
 * @pix_mp: 表示多平面图像格式的定义(用于 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)。
 *              结构体 `v4l2_pix_format_mplane` 用于描述支持多平面格式的设备,
 例如 YUV420 格式的不同平面。
 *
 * @win: 表示视频叠加窗口的定义(用于 V4L2_BUF_TYPE_VIDEO_OVERLAY)。
 *              结构体 `v4l2_window` 定义了叠加窗口的位置和尺寸。
 *
 * @vbi: 表示原始 VBI(垂直消隐间隔)捕获或输出的参数(用于 V4L2_BUF_TYPE_VBI_CAPTURE 或 V4L2_BUF_TYPE_VBI_OUTPUT)。
 *              结构体 `v4l2_vbi_format` 定义了 VBI 的格式和相关属性。
 *
 * @sliced: 表示分片 VBI(垂直消隐间隔)捕获或输出的参数(用于 V4L2_BUF_TYPE_SLICED_VBI_CAPTURE 或 V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)。
 *              结构体 `v4l2_sliced_vbi_format` 定义了分片 VBI 的格式。
 *
 * @sdr: 表示 SDR(软件定义无线电)捕获设备的格式(用于 V4L2_BUF_TYPE_SDR_CAPTURE)。
 *              结构体 `v4l2_sdr_format` 描述 SDR 的采样率、格式等信息。
 *
 * @meta: 表示元数据捕获设备的格式(用于 V4L2_BUF_TYPE_META_CAPTURE)。
 *              结构体 `v4l2_meta_format` 定义元数据的格式及相关属性。
 *
 * @raw_data: 用户自定义数据的占位符(保留扩展字段,长度为 200 字节)。
 *              该字段用于未来扩展或自定义格式。
 */
struct v4l2_format {
 __u32  type;  /* 数据流的类型 */
 union {
  struct v4l2_pix_format  pix;     /* 单平面视频捕获 */
  struct v4l2_pix_format_mplane pix_mp;  /* 多平面视频捕获 */
  struct v4l2_window  win;     /* 视频叠加 */
  struct v4l2_vbi_format  vbi;     /* 原始 VBI 捕获或输出 */
  struct v4l2_sliced_vbi_format sliced;  /* 分片 VBI 捕获或输出 */
  struct v4l2_sdr_format  sdr;     /* SDR 捕获 */
  struct v4l2_meta_format  meta;    /* 元数据捕获 */
  __u8 raw_data[200];                   /* 自定义数据 */
 } fmt;  /* 数据流格式的联合体 */
};

/*
 * V I D E O   I M A G E   F O R M A T
 */
struct v4l2_pix_format {
 __u32   width;
 __u32   height;
 __u32   pixelformat;
 __u32   field;  /* enum v4l2_field */
 __u32   bytesperline; /* for padding, zero if unused */
 __u32   sizeimage;
 __u32   colorspace; /* enum v4l2_colorspace */
 __u32   priv;  /* private data, depends on pixelformat */
 __u32   flags;  /* format flags (V4L2_PIX_FMT_FLAG_*) */
 union {
  /* enum v4l2_ycbcr_encoding */
  __u32   ycbcr_enc;
  /* enum v4l2_hsv_encoding */
  __u32   hsv_enc;
 };
 __u32   quantization; /* enum v4l2_quantization */
 __u32   xfer_func; /* enum v4l2_xfer_func */
};

上面的成员:filed:b898587425f9044a7739283cf4f2ab6e.png

/*
 * E N U M S
 * 
 * enum v4l2_field - 场(Field)模式枚举
 *
 * 此枚举定义了视频缓冲区中场模式的类型。场(Field)是视频的扫描方式,
 * 常见于隔行扫描(Interlaced)的视频帧中。不同的场模式适用于不同的视频格式和设备。
 *
 * @V4L2_FIELD_ANY:         设备驱动可以自行选择场模式,具体可能是无场(NONE)、顶场(TOP)、底场(BOTTOM)
 *                          或隔行(INTERLACED),由驱动根据实际情况决定。
 * @V4L2_FIELD_NONE:        视频帧没有场信息,通常用于逐行扫描(Progressive Scan)。
 * @V4L2_FIELD_TOP:         仅包含顶场(Top Field)。
 * @V4L2_FIELD_BOTTOM:      仅包含底场(Bottom Field)。
 * @V4L2_FIELD_INTERLACED:  隔行扫描模式,包含顶场和底场,交替显示。
 * @V4L2_FIELD_SEQ_TB:      顺序扫描模式,顶场和底场按顺序存储在一个缓冲区中,顺序为顶-底(Top-Bottom)。
 * @V4L2_FIELD_SEQ_BT:      顺序扫描模式,顶场和底场按顺序存储在一个缓冲区中,顺序为底-顶(Bottom-Top)。
 * @V4L2_FIELD_ALTERNATE:   顶场和底场交替存储在不同的缓冲区中。
 * @V4L2_FIELD_INTERLACED_TB: 隔行扫描模式,顶场优先,且顶场先传输。
 * @V4L2_FIELD_INTERLACED_BT: 隔行扫描模式,顶场优先,但底场先传输。
 */
enum v4l2_field {
 V4L2_FIELD_ANY           = 0, /* 驱动可以根据需要选择适当的场模式 */
 V4L2_FIELD_NONE          = 1, /* 无场模式(逐行扫描) */
 V4L2_FIELD_TOP           = 2, /* 仅顶场 */
 V4L2_FIELD_BOTTOM        = 3, /* 仅底场 */
 V4L2_FIELD_INTERLACED    = 4, /* 隔行扫描(顶场+底场) */
 V4L2_FIELD_SEQ_TB        = 5, /* 顺序扫描(顶场-底场) */
 V4L2_FIELD_SEQ_BT        = 6, /* 顺序扫描(底场-顶场) */
 V4L2_FIELD_ALTERNATE     = 7, /* 顶场和底场交替存储 */
 V4L2_FIELD_INTERLACED_TB = 8, /* 隔行扫描(顶场优先,顶场先传输) */
 V4L2_FIELD_INTERLACED_BT = 9, /* 隔行扫描(顶场优先,底场先传输) */
};

还有上面的 pixelformat:

a18f9e673612c5f54a24e06bed9218e4.jpeg7b24421941fb91b2767a540bf7e6b1d6.jpeg

3、struct v4l2_requestbuffers结构体:

88fcdf4f8b6c07a5b27d01f6dbe2448f.png
/*
 * M E M O R Y - M A P P I N G   B U F F E R S
 * 
 * struct v4l2_requestbuffers - 请求缓冲区的结构体
 * 
 * 此结构体用于视频捕获设备通过内存映射(mmap)或用户指针(user pointer)方式分配缓冲区。
 * 应用程序通过调用 IOCTL 命令(如 VIDIOC_REQBUFS)请求驱动程序分配指定数量的缓冲区,
 * 这些缓冲区可以用来存储捕获的图像或视频帧。
 * 
 * @count:        缓冲区的数量,应用程序请求分配的缓冲区数量。
 *                驱动程序会尝试满足该请求,但可能会分配更少的缓冲区。
 *
 * @type:         缓冲区的类型,使用枚举 `enum v4l2_buf_type`。
 *                表示缓冲区用于何种数据流,例如:
 *                - V4L2_BUF_TYPE_VIDEO_CAPTURE:视频捕获缓冲区
 *                - V4L2_BUF_TYPE_VIDEO_OUTPUT:视频输出缓冲区
 *
 * @memory:       缓冲区的内存类型,使用枚举 `enum v4l2_memory`。
 *                描述缓冲区的使用方式,例如:
 *                - V4L2_MEMORY_MMAP:缓冲区通过内存映射访问
 *                - V4L2_MEMORY_USERPTR:缓冲区由用户空间提供指针
 *                - V4L2_MEMORY_DMABUF:缓冲区通过 DMA 缓冲区访问
 *
 * @capabilities: 缓冲区的能力标志,用于扩展支持功能。
 *                通常在应用程序中设置为 0 或忽略。
 *
 * @reserved:     保留字段,为未来扩展预留空间。
 */
struct v4l2_requestbuffers {
 __u32   count;          /* 缓冲区数量 */
 __u32   type;           /* 缓冲区类型 */
 __u32   memory;         /* 内存类型 */
 __u32   capabilities;   /* 缓冲区能力标志 */
 __u32   reserved[1];    /* 保留字段 */
};

/* capabilities 字段的标志位定义,用于描述缓冲区支持的功能 */
#define V4L2_BUF_CAP_SUPPORTS_MMAP      (1 << 0)  /* 支持通过内存映射 (mmap) 访问缓冲区 
这种方式允许用户进程直接访问内核分配的缓冲区数据,减少数据拷贝,适用于高效的数据传输。
使用场景:视频捕获设备或高效数据流处理*/
#define V4L2_BUF_CAP_SUPPORTS_USERPTR   (1 << 1)  /* 支持通过用户指针 (user pointer) 
访问缓冲区;用户进程可以提供缓冲区地址给驱动,驱动直接使用用户空间缓冲区进行数据存储或传输。
使用场景:用户希望管理缓冲区内存的分配和生命周期。*/
#define V4L2_BUF_CAP_SUPPORTS_DMABUF    (1 << 2)  /* 支持通过 DMA 缓冲区 (DMA buffer) 
访问缓冲区;设备之间可以直接通过共享 DMA 缓冲区传递数据,避免数据复制。
使用场景:硬件加速视频处理或跨设备数据传输*/
#define V4L2_BUF_CAP_SUPPORTS_REQUESTS  (1 << 3)  /* 支持缓冲区请求 API,用于媒体请求
(media requests);该标志表明缓冲区支持基于请求的 API,可以与其他媒体设备同步,
例如用于复杂的视频流处理。使用场景媒体框架中需要更复杂的请求-响应机制,例如视频解码场景 */

4、struct v4l2_buffer结构体:

33869ab5fc414ced505a055ac7d98011.png
/**
 * struct v4l2_buffer - 视频缓冲区信息
 *
 * 此结构体用于描述缓冲区的信息,并在应用程序和驱动之间交换数据。
 * 可用于单平面缓冲区和多平面缓冲区,根据 `type` 的值区分。
 *
 * @index:          缓冲区的索引(从 0 开始)。
 * @type:           缓冲区类型,使用枚举 `enum v4l2_buf_type`,如:
 *                  - V4L2_BUF_TYPE_VIDEO_CAPTURE:单平面视频捕获缓冲区
 *                  - V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:多平面视频捕获缓冲区
 * @bytesused:      缓冲区中已用的字节数(有效载荷大小),
 *                  对于多平面缓冲区,此字段设置为 0。
 * @flags:          缓冲区标志信息,指示缓冲区的状态(如是否已填充)。
 * @field:          图像的场顺序,使用枚举 `enum v4l2_field`。
 * @timestamp:      帧的时间戳,表示捕获或输出的时间。
 * @timecode:       帧的时间码信息。
 * @sequence:       帧的序列号,用于标识帧的顺序。
 * @memory:         缓冲区的内存类型,使用枚举 `enum v4l2_memory`。
 * @offset:         当缓冲区为单平面,且内存类型为 V4L2_MEMORY_MMAP 时,
 *                  表示设备内存的偏移量。
 * @userptr:        当缓冲区为单平面,且内存类型为 V4L2_MEMORY_USERPTR 时,
 *                  表示用户空间指针。
 * @fd:             当缓冲区为单平面,且内存类型为 V4L2_MEMORY_DMABUF 时,
 *                  表示 DMA 缓冲区的文件描述符。
 * @planes:         当缓冲区为多平面时,指向包含平面信息的数组。
 * @length:         单平面缓冲区的总大小(字节);对于多平面缓冲区,表示平面数组的元素数量。
 * @request_fd:     缓冲区关联的请求文件描述符,用于请求 API。
 * @reserved2:      保留字段,用于未来扩展。
 */
struct v4l2_buffer {
 __u32   index;        /* 缓冲区索引 */
 __u32   type;         /* 缓冲区类型 */
 __u32   bytesused;    /* 有效载荷大小 */
 __u32   flags;        /* 缓冲区标志 */
 __u32   field;        /* 图像场顺序 */
 struct timeval  timestamp;    /* 时间戳 */
 struct v4l2_timecode timecode;    /* 时间码 */
 __u32   sequence;     /* 帧序列号 */

 /* 内存位置 */
 __u32   memory;       /* 内存类型 */
 union {
  __u32           offset;     /* 单平面映射偏移量 */
  unsigned long   userptr;    /* 单平面用户指针 */
  struct v4l2_plane *planes;  /* 多平面信息指针 */
  __s32  fd;          /* 单平面 DMA 缓冲区文件描述符 */
 } m;
 __u32   length;       /* 缓冲区大小或平面数组元素数量 */
 __u32   reserved2;    /* 保留字段 */
 union {
  __s32  request_fd;  /* 请求文件描述符 */
  __u32  reserved;    /* 保留字段 */
 };
};

flags的标识如下:

bdbddeab5b65c7962fe6c2545a46f74b.png
/* 'flags' 字段的标志位定义 */

/* 缓冲区已映射到用户空间(内存映射) */
#define V4L2_BUF_FLAG_MAPPED               0x00000001  

/* 缓冲区已加入队列,等待处理 */
#define V4L2_BUF_FLAG_QUEUED               0x00000002  

/* 缓冲区已处理完成,数据准备好 */
#define V4L2_BUF_FLAG_DONE                 0x00000004  

/* 图像是关键帧(I 帧) */
#define V4L2_BUF_FLAG_KEYFRAME             0x00000008  

/* 图像是预测帧(P 帧) */
#define V4L2_BUF_FLAG_PFRAME               0x00000010  

/* 图像是双向预测帧(B 帧) */
#define V4L2_BUF_FLAG_BFRAME               0x00000020  

/* 缓冲区准备好,但数据存在损坏 */
#define V4L2_BUF_FLAG_ERROR                0x00000040  

/* 缓冲区已添加到未排队的请求中 */
#define V4L2_BUF_FLAG_IN_REQUEST           0x00000080  

/* timecode 字段有效 */
#define V4L2_BUF_FLAG_TIMECODE             0x00000100  

/* 缓冲区已准备好入队 */
#define V4L2_BUF_FLAG_PREPARED             0x00000400  

/* 缓存处理标志 */
/* 禁止无效缓存 */
#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x00000800  
/* 禁止清理缓存 */
#define V4L2_BUF_FLAG_NO_CACHE_CLEAN       0x00001000  

/* 时间戳类型标志 */
/* 时间戳掩码 */
#define V4L2_BUF_FLAG_TIMESTAMP_MASK       0x0000e000  
/* 时间戳未知 */
#define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN    0x00000000  
/* 使用单调时间戳 */
#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC  0x00002000  
/* 复制的时间戳 */
#define V4L2_BUF_FLAG_TIMESTAMP_COPY       0x00004000  

/* 时间戳来源标志 */
/* 时间戳来源掩码 */
#define V4L2_BUF_FLAG_TSTAMP_SRC_MASK      0x00070000  
/* 时间戳来源于帧结束 (EOF) */
#define V4L2_BUF_FLAG_TSTAMP_SRC_EOF       0x00000000  
/* 时间戳来源于帧开始 (SOE) */
#define V4L2_BUF_FLAG_TSTAMP_SRC_SOE       0x00010000  

/* 内存到内存编码器/解码器 */
/* 表示最后一个缓冲区 */
#define V4L2_BUF_FLAG_LAST                 0x00100000  

/* request_fd 字段有效 */
#define V4L2_BUF_FLAG_REQUEST_FD           0x00800000

5、v4l2_buf_type枚举:

41e6e57fd6656598d35b713a15c6044b.png
c


复制代码
/**
 * enum v4l2_buf_type - 缓冲区类型枚举
 *
 * 该枚举定义了 V4L2 中缓冲区的数据流类型,用于指定设备支持的数据传输类型。
 * 不同类型表示设备处理的视频、音频或元数据流方式,应用程序在使用缓冲区时需要根据实际用途设置该字段。
 *
 * @V4L2_BUF_TYPE_VIDEO_CAPTURE:         视频捕获类型,设备从输入源(如摄像头)捕获视频帧。
 * @V4L2_BUF_TYPE_VIDEO_OUTPUT:          视频输出类型,设备将视频帧发送到输出端(如显示器)。
 * @V4L2_BUF_TYPE_VIDEO_OVERLAY:         视频叠加类型,用于处理叠加在输出视频上的额外图像。
 * @V4L2_BUF_TYPE_VBI_CAPTURE:           垂直消隐间隔(VBI)捕获,用于捕获原始 VBI 数据。
 * @V4L2_BUF_TYPE_VBI_OUTPUT:            垂直消隐间隔(VBI)输出,用于输出原始 VBI 数据。
 * @V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:    分片 VBI 捕获,捕获处理后的 VBI 数据片段。
 * @V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:     分片 VBI 输出,输出处理后的 VBI 数据片段。
 * @V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:  视频输出叠加,用于向输出流添加叠加图像。
 * @V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:  多平面视频捕获,支持多平面存储格式的视频捕获。
 * @V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:   多平面视频输出,支持多平面存储格式的视频输出。
 * @V4L2_BUF_TYPE_SDR_CAPTURE:           软件定义无线电(SDR)捕获,用于捕获 SDR 数据流。
 * @V4L2_BUF_TYPE_SDR_OUTPUT:            软件定义无线电(SDR)输出,用于输出 SDR 数据流。
 * @V4L2_BUF_TYPE_META_CAPTURE:          元数据捕获,用于捕获非视频/音频数据的元信息。
 * @V4L2_BUF_TYPE_PRIVATE:               **已废弃**,不要使用。
 */
enum v4l2_buf_type {
 V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,  /* 视频捕获 */
 V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,  /* 视频输出 */
 V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,  /* 视频叠加 */
 V4L2_BUF_TYPE_VBI_CAPTURE          = 4,  /* VBI 捕获 */
 V4L2_BUF_TYPE_VBI_OUTPUT           = 5,  /* VBI 输出 */
 V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,  /* 分片 VBI 捕获 */
 V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,  /* 分片 VBI 输出 */
 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,  /* 视频输出叠加 */
 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,  /* 多平面视频捕获 */
 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10, /* 多平面视频输出 */
 V4L2_BUF_TYPE_SDR_CAPTURE          = 11, /* SDR 捕获 */
 V4L2_BUF_TYPE_SDR_OUTPUT           = 12, /* SDR 输出 */
 V4L2_BUF_TYPE_META_CAPTURE         = 13, /* 元数据捕获 */
 /* 已废弃,请勿使用 */
 V4L2_BUF_TYPE_PRIVATE              = 0x80,
};

还有一些结构体还没分析到,到时候我们在分析源码的时候遇到了,再进行解析。

总结

今天的内容就分享到这里,下期内容我们继续解读摄像头怎么获取实时码流实现原理,我们下期见!

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

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

相关文章

Mac电脑python多版本环境安装与切换

我当前是python3.9.6环境&#xff0c;需要使用3.9.8环境&#xff0c;通过brew安装3.9.8版本&#xff0c;然后通过pyenv切换环境 步骤 1: 安装 pyenv brew install pyenv brew install pyenv-virtualenv 步骤 2: 安装 Python 3.9.8&#xff08;使用 pyenv 安装指定版本的 Pyth…

小程序配置文件 —— 14 全局配置 - tabbar配置

全局配置 - tabBar配置 tabBar 字段&#xff1a;定义小程序顶部、底部 tab 栏&#xff0c;用以实现页面之间的快速切换&#xff1b;可以通过 tabBar 配置项指定 tab 栏的表现&#xff0c;以及 tab 切换时显示的对应页面&#xff1b; 在上面图中&#xff0c;标注了一些 tabBar …

Jupyter在运行上出现错误:ModuleNotFoundError: No module named ‘wordcloud‘

问题分析&#xff1a;显示Jupyter未安装这个模板 解决办法&#xff1a;在单元格内输入&#xff1a;!pip install wordcloud

github提交不上去,网络超时问题解决

问题出现的原因&#xff1a; DNS服务器数据不同步&#xff0c;github的服务器发送迁移&#xff0c;在本地缓存的ip地址现在无效了。 解决方案&#xff1a; 1&#xff09;点击这里&#xff0c;查询github.com最新的ip地址 2.0&#xff09;编辑linux系统地址缓存文件&#x…

Windows Subsystem for Linux (WSL)

目录 定义与功能 版本与特点 应用场景 启用 WSL 功能 更新WSL及其内核 下载Linux发行版本 WSL&#xff08;Windows Subsystem for Linux&#xff09;是微软在Windows 10和Windows 11中引入的一项功能&#xff0c;使用户能够在Windows上原生运行Linux的命令行工具和应用程…

图像处理-Ch5-图像复原与重建

Ch5 图像复原 文章目录 Ch5 图像复原图像退化与复原(Image Degradation and Restoration)噪声模型(Noise Models)i.i.d.空间随机噪声(Generating Spatial Random Noise with a Specified Distribution)周期噪声(Periodic Noise)估计噪声参数(Estimating Noise Parameters) 在仅…

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…

HTML——41有序列表

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>有序列表</title></head><body><!--有序列表&#xff1a;--><!--1.列表中各个元素在逻辑上有先后顺序&#xff0c;但不存在一定的级别关系-->…

详细教程:SQL2008数据库备份与还原全流程!

数据的安全性至关重要&#xff0c;无论是操作系统、重要文件、磁盘存储&#xff0c;还是企业数据库&#xff0c;备份都是保障其安全和完整性的关键手段。拥有备份意味着即使发生误删、系统崩溃或病毒攻击等问题&#xff0c;也能迅速通过恢复功能解决&#xff0c;避免数据丢失带…

IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具

文章目录 一、IDEA二、建立第一个 Java 程序三、IDEA 常用设置四、IDEA 集成版本控制工具&#xff08;Git、GitHub&#xff09;4.1 IDEA 拉 GitHub/Git 项目4.2 IDEA 上传 项目到 Git4.3 更新提交命令 一、IDEA 1、什么是IDEA&#xff1f; IDEA&#xff0c;全称为 IntelliJ ID…

STM32 I2C通信协议

单片机学习&#xff01; 文章目录 目录 文章目录 前言 一、I2C通信 1.1 I2C总线 1.2 I2C通信线 1.3 同步半双工且数据应答 1.4 一主多从 二、硬件电路 2.1 I2C电路模型 2.2 I2C接线要求 2.3 I2C上拉电阻作用 三、I2C时序基本单元 3.1 起始终止条件 3.1.1 起始条件 3.1.2 终止条…

在线免费批量生成 Word 文档工具

为了方便的批量生成 Word 文档&#xff0c;写了个在线 Word 文档批量生成工具&#xff0c;可以根据 Excel 数据和 Word 模板批量生成大量个性化的 Word 文档。适用于需要批量生成格式统一但内容不同的文档场景。比如&#xff1a; 批量生成证书、奖状批量生成合同、协议批量生成…

再见了我的2024

目录 户外运动 阅读及影视剧欣赏 提升专业技能 外婆走了 消费分析 小妹家的二宝 2024 summary 2025年几个小目标 2024生活记录 2024年最后一天&#xff0c;就这样过去了。 总是来不及好好地告个别&#xff0c;就像我们的年老的亲人一样&#xff0c;见一面&#xff0c;少…

Java工程师实现视频文件上传minio文件系统存储及网页实现分批加载视频播放

Java工程师实现minio存储大型视频文件网页实现分批加载视频播放 一、需求说明 老板给我出个题目&#xff0c;让我把的电影文件上传到minio文件系统&#xff0c;再通过WEB端分配加载视频播放&#xff0c;类似于我们普通的电影网站。小编把Java代码共享出来。是真正的能拿过来直…

Three.js教程004:坐标辅助器与轨道控制器

文章目录 坐标辅助器与轨道控制器实现效果添加坐标辅助器添加轨道控制器完整代码完整代码下载坐标辅助器与轨道控制器 实现效果 添加坐标辅助器 创建坐标辅助器: const axesHelper = new Three.AxesHelper(5);添加到场景中: scene.

【优选算法 分治】深入理解分治算法:分治算法入门小专题详解

快速排序算法 (1) 快速排序法 (2) 快排前后指针 (3) 快排挖坑法 颜色分类 题目解析 算法原理 算法原理和移动零非常相似 简述移动零的算法原理 cur 在从前往后扫描的过程中&#xff0c;如果扫描的数符合 f 性质&#xff0c;就把这个数放到 dest 之…

Qt5 中 QGroupBox 标题下沉问题解决

我们设置了QGroupBox 样式之后,发现标题下沉了,那么如何解决呢? QGroupBox {font: 12pt "微软雅黑";color:white;border:1px solid white;border-radius:6px; } 解决后的效果 下面是解决方法: QGroupBox {font: 12pt "微软雅黑";color:white;bo…

sentinel-请求限流、线程隔离、本地回调、熔断

请求限流&#xff1a;控制QPS来达到限流的目的 线程隔离&#xff1a;控制线程数量来达到限流的目录 本地回调&#xff1a;当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 服务熔断&#xff1a;熔断也叫断路器&#xff0c;当失败、…

体验Cursor一段时间后的感受和技巧

用这种LLM辅助的IDE一段时间了&#xff0c;断断续续做了几个小项目了&#xff0c;总结一下整体的感受和自己的一些使用经验。 从Cursor开始又回到Cursor 第一个真正开始使用的LLM的辅助开发IDE就是Cursor&#xff0c;Github的Copilot支持尝试过&#xff0c;但是并没有真正的在…

【数据仓库】hadoop3.3.6 安装配置

文章目录 概述下载解压安装伪分布式模式配置hdfs配置hadoop-env.shssh免密登录模式设置初始化HDFS启动hdfs配置yarn启动yarn 概述 该文档是基于hadoop3.2.2版本升级到hadoop3.3.6版本&#xff0c;所以有些配置&#xff0c;是可以不用做的&#xff0c;下面仅记录新增操作&#…