# 系统概述

## 文档使用方法
### 文档组成
- 第 1 小节 : 整体描述多媒体系统
- 第 2 小节 : 多媒体系统的核心软件框架 HBN ( 目前多媒体系统有部分模块，没有包含在 HBN 框架中，后面会详细描述 )
- 第 3 小节 : 多媒体系统的调试手段
- 第 4-14 小节 : 详细介绍各个独立模块 , 包括基本信息、使用方法、注意事项等
- 第 15 小节 : 图像质量的调试方法

### 如何使用文档
1. 掌握多媒体系统的整体和核心框架
	- 详细阅读多媒体章节的第 1 小节，掌握多媒体系统的组成部分（包含多媒体章节的第 4-12 小节）以及各个部分之间的关系
	- 详细阅读多媒体章节的第 2 小节，掌握多媒体系统的核心软件框架 HBN
	- 浏览多媒体章节的第 3 小节，了解多媒体系统有哪些调试手段，在后面使用过程中遇到问题时，知道有哪些手段可以调试
2. 结合 [ 示例代码 ](../samples/index.html) 章节的 demo, 逐个了解多媒体章节的第 4-14 小章节的模块，至此可以实现摄像头采集和处理链路的搭建
3. 按照多媒体章节的第 15 小节调试图像质量

## 整体概述

多媒体系统集成了多种硬件加速单元，使 CPU 专注于其优势任务：运行操作系统和处理业务逻辑。<br>
同时，系统提供了简洁灵活的 API，用于高效连接和协调各模块的工作。以下将从硬件与软件两个方面进行介绍：

1. 硬件方面：详述硬件模块的组成结构及各硬件单元之间的数据交互机制。
2. 软件方面：解析软件 API 的设计与功能，并说明如何利用 API 实现不同硬件单元间的高效数据协作

## 硬件方面
### 组成

| 模块   | 全称                                | 解释                                                         |
| ------ | ----------------------------------- | ------------------------------------------------------------ |
| VIN    | Video Input                         | 软件概念，包含 MIPI、 SIF，接收单路或多路 Camera sensor 数据，直接送给下游 ISP 或写到 DDR |
| SIF    | Sensor Interface                    | 衔接 MIPI 口，把 MIPI 接口收到的数据帧送给下游 ISP 或直接写到 DDR              |
| ISP    | Image Signal Processor              | 图像信号处理器                           |
| VSE    | Video Scaler                        | 图像的裁剪、缩放、颜色空间转换           |
| OSD    | On Screen Display                   | 视频图像叠层显示                                             |
| GDC    | Geometrical Distortion Correction   | 几何畸变矫正                                                 |
| VPU    | Video Processing Unit               | 视频处理单元，完成视频的编解码功能，支持 H.264/H.265                          |
| JPU    | JPEG Processing Unit                | JPEG 图片处理单元，完成 JPEG、 MJPEG 的编解码功能               |
| 2DGPU  | 2D Graphics Processing Unit        | 2D 图像的加速单元，提供位块传输、矩形填充和清除、 Alpha 融合、旋转、裁剪、颜色空间转换等功能               |
| 3DGPU  | 3D Graphics Processing Unit        | 3D 图像渲染的加速单元               |
| Display | Video Display Unit                 | 视频显示模块，提供图层、旋转等功能，支持 BT1120 、 HDMI、 MIPI DSI 接口    |

### 数据交互
X5 芯片内置了专用数据通道，可直接连接 VIN、 ISP 和 VSE 模块，实现视频数据的高速直传，不需要读写 DDR ，从而节省 DDR 带宽，大幅提升性能。<br>
然而，由于 ISP 和 VSE 的硬件资源是单一的，当接入多路 Camera Sensor 时，必须通过分时复用的方式进行处理，视频数据必须通过 DDR 进行缓存。<br>
基于数据传输是否依赖 DDR 缓存，硬件加速单元之间的数据交互方式可以分为以下两种模式：

1. Offline 模式 ( 图中 **绿色箭头**)：数据通过 DDR 完成传输，上游模块将数据写入 DDR，下游模块从 DDR 读取。此模式支持多路 Camera Sensor 的接入的场景。
2. Online 模式 ( 图中 **红色箭头**)：数据直接从上游模块传递至下游模块，无需读写 DDR，显著提升性能。然而，该模式仅适用于单路 Camera Sensor 的场景。

下图描述 **多路 Camera Sensor 和单路 Camera Sensor** 两种使用场景：

![ 框图 ](./media/multi_media_data_flow_common.png)

ISP 模块比较特殊，有 4 路输入，并且内部有 MCM 模块（`Multi channel context management`）所以在 VIN 与 ISP 连接时，支持最多 4 路 online 连接，<br>
由于 ISP 的数据处理单元（图中的 Pipeline）只有一个，所以 ISP 的数据处理单元处理前，仍然需要把视频帧先存储到 DDR 中，驱动程序会分时复用 ISP 模块。<br>
因为 VIN 模块输出的 RAW 数据按照 16 字节对齐 , MCM 模块将 VIN 输出的数据转换成不需要按照 16 字节对齐的数据，可以减少内存的占用和 DDR 带宽占用，<br>
因此这种模式比纯粹的 Offline 模式有优势，这种模式的流程如下：
1. VIN 和 ISP 使用 online 的模式连接（最多支持 ４ 路）
2. ISP 内部的 MCM 模块将 VIN 传过来的数据，先转换成连续存储的格式（转换前是 16 字节对齐的），然后存储到 DDR 中
3. ISP 内部的数据处理单元（图中的 Pipeline）使用 RDMA 从 DDR 中读取视频帧，进行处理，处理的结果仍然存储到 DDR 中

下图描述 **多路 Camera Sensor** 场景下， VIN 到 ISP 使用 online 模式连接，同时 ISP 内部使用 MCM 模式，

![ 框图 ](./media/multi_media_data_flow_isp_mcm.png)


总结如下：
- `VIN`：包含 4 个 MIPI RX 和 4 个 SIF
	- MIPI RX：连接 1 个 MIPI 接口的 Camera Sensor
	- SIF：与 MIPI 接口一一对应，把 MIPI 接口收到的数据帧送给下游 ISP 或直接写到 DDR；
- `ISP`：有 4 个输入 port，支持与 4 路 SIF 连接。由于 ISP 硬件 Pipeline 只有一个，接入多路 camera Sensor 时， ISP 会把数据写到 DDR，然后分时复用 Pipeline
	- 单路 Camera Sensor 场景下， VIN 到 ISP 的连接方式：优先选用 Online 模式，支持 Offline 模式
	- 多路 Camera Sensor 场景下， VIN 到 ISP 的连接方式：优先选用 offline 模式， MCM 模式目前还在优化中（对应图中的特殊模式）
- `VSE`：只有 1 个输入 port, 硬件只有 1 个，支持 6 个输出通道，每个通道可支持不同尺寸的缩放和裁剪，支持 OSD 功能，可在图像中叠加文字或色块
	- 单路 Camera Sensor 场景下， ISP 到 VSE 的连接方式优先选用 Online，支持 Offline 模式
	- 多路 Camera Sensor 场景下， ISP 到 VSE 的连接方式只能使用 offline 模式
- `其他模块`：只支持 offline 模式：
	- `Display`：从 DDR 读数据，然后通过 MIPI DSI/BT1120 输出到显示设备，或通过 MIPI Tx 输出给另一个 MIPI Host 设备；
	- `GDC`、`2DGPU`、`3DGPU`，`VPU`、`JPU`：从 DDR 读数据，处理完再写到 DDR；



## 软件方面
### 框架

![ 框图 ](./media/multi_media_soft_framework.png)

下面从左向右介绍每个 API 的作用：
1. `HBN API`: 包含了 `HBN Framework API`、`ISP API`、`OSD API`、`Camera API`，覆盖了摄像头采集链路的所有模块，<br>
	- `HBN Framework API`: 多媒体系统软件的核心框架 , <br>
	把每个模块作为一个节点（ vnode），然后把每个模块连接起来形成流水线 (vflow)，<br>
	目前涵盖了 VIN， ISP， VSE， GDC， 2DGPU, 详细见 [HBN 框架接口说明 ](./1-HBN_API_zh_CN.html)
	- `ISP API`: 用于动态配置和获取 ISP 模块参数，详细见 [ 图像质量 ISP](./5-ISP_Tune_API_zh_CN.html),  <br>
	ISP 模块的静态参数配置和数据流转在 `HBN Framework` 中实现
	- `OSD API`: 用于创建和配置 OSD 模块，没有被 `HBN Framework API` 覆盖，但是可以通过接口 attach 到 VSE 节点的通道上，<br>
	详细见 [ 区域处理 OSD](./7-OSD_API_zh_CN.html)
	- `Camera API`: 用于配置 Camera Sensor，没有被 `HBN Framework API` 覆盖，但是可以通过接口 attach 到 VIN 节点 , <br>
	详细见 [ 视频接入 Camera](4-Camera_API_zh_CN.html)
2. `MediaCodec API`: 用于控制 VPU 和 JPU 模块，实现 H264 、 H265 、 JPEG 编解码的功能 , 详细见 [ 视频编解码 Codec](./10-MediaCodec_API_zh_CN.html)
3. `OpenGL ES、EGL、OpenCL、Vulkan`: 3DGPU 的接口，通用的 3DGPU 框架 , 详细见 [3DGPU](./11-3DGPU_API_zh_CN.html)
4. `N2D API`： 2DGPU 的接口，详细见 [2DGPU](./12-2DGPU_API_zh_CN.html), 部分功能集成到 HBN 框架，推荐使用 `N2D API`
5. `DRM API`: 视频显示模块的接口，详细见 [ 视频输出 Display](./9-Display_zh_CN.html)
6. `HB_MEM API`: 实现在用户空间实现大块物理地址连续内存的管理，详细见 [ 内存管理 Hbmem](./3-Hbmem_index_zh_CN.html)
	- 实现视频帧数据缓存：所有的硬件加速单元和 DMA 模块使用的内存必须是物理地址连续的
	- 实现视频帧数据流转：底层基于 dmabuf，实现了图像数据在内核态的不同驱动之间以及内核态和用户态之间传递
### 数据交互
在处理视频帧数据时，硬件加速单元要求使用物理地址连续的 DDR 缓存。为满足这一需求，多媒体系统软件提供了 `HB_MEM API`，具备以下特点 :

- **用户态内存分配** ：支持在用户态分配大块物理地址连续的内存，满足视频处理需求。
- **专用内存区域**：分配的内存来源于 `ION` 区域（设备树中预留的内存区域， Linux 系统的标准分配器不会使用该区域）。详细见 [ION 系统调试指南 ](../linux_development/system_component_development/39-ION_Debug_Guide.html)
- **零拷贝数据传输**：基于底层的 dmabuf 框架，实现不同驱动间以及内核态与用户态之间数据的直接传递，避免内存拷贝操作。
- **高效内存管理**：通过内存池（ mempool）避免频繁的内存申请和释放，从而减少用户态与内核态间的频繁切换，提升内存分配效率。
- **视频帧结构体支持**：提供结构体 hb_mem_graphic_buf_t，用于描述视频帧的数据内容和格式信息。

因此多媒体系统软件中基于结构体 `hb_mem_graphic_buf_t` 完成不同硬件加速单元之间数据交换，对于不支持 `hb_mem_graphic_buf_t` 的 API，<br>
可以通过各种方式完成转换，如下描述

1. `HBN API` 与 `MediaCodec API` 使用的视频帧的数据结构是 `hb_mem_graphic_buf_t`
2. `N2D API` 视频帧的数据结构是 `n2d_buffer_t`, 可以从 `hb_mem_graphic_buf_t` 中获取物理地址和视频参数后转换成 `n2d_buffer_t`，详细见 [sample_gpu_2d 使用说明 ](../samples/sample_gpu_2d.html#sample-create-n2d-buffer)
4. `DRM API` 底层也是基于 dmabuf 实现，可以从 `hb_mem_graphic_buf_t` 中获取 dmabuf 的文件描述符后转换成 `dma_buf_map_t`, 详细见 [sample_vot 使用说明 ](../samples/sample_vot.md)
5. `OpenGL ES、EGL、OpenCL、Vulkan`: 待补充