# sample_gpu_2d 使用说明

sample_gpu_2d 通过调用 [2D GPU 接口 ](../multimedia_development/12-2DGPU_API_zh_CN.html) 实现如下功能：
1. 旋转
2. 矩形填充
3. 透明度混合
4. 颜色空间转换
5. 位块拷贝
6. 裁剪
7. 拼接
8. 放大和缩放
9. 多源透明度混合
10. 外部内存转换成 gpu 内存

接下来，针对每个功能，进行详细描述

注意：每个 sample 中增加了性能测试的代码，其中 `performance_test.sh` 可以测试出所有 sample 中对应接口的性能数据 ,
可以在 `performance_test.sh` 中修改自己感兴趣的分辨率再进行测试。
```
[Case copy                          ] [Input 1*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 344412    us] [AverageConsume 3444   us] [FPS   290.3]
[Case format_convert                ] [Input 1*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 313243    us] [AverageConsume 3132   us] [FPS   319.2]
[Case multi_source_alphablend       ] [Input 4*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 541909    us] [AverageConsume 5419   us] [FPS   184.5]
[Case resize                        ] [Input 1*1920*1080] [Output 3840*2160] [TestTimes   100] [TotalConsume 1287105   us] [AverageConsume 12871  us] [FPS    77.7]
[Case resize                        ] [Input 1*1920*1080] [Output  960*540 ] [TestTimes   100] [TotalConsume 81144     us] [AverageConsume 811    us] [FPS  1232.4]
[Case stitch                        ] [Input 4*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 351719    us] [AverageConsume 3517   us] [FPS   284.3]
[Case stitch                        ] [Input 2*1920*1080] [Output 1920*540 ] [TestTimes   100] [TotalConsume 176619    us] [AverageConsume 1766   us] [FPS   566.2]
[Case alphablend                    ] [Input 1*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 412188    us] [AverageConsume 4121   us] [FPS   242.6]
[Case crop                          ] [Input 1*3840*2160] [Output 1920*1080] [TestTimes   100] [TotalConsume 314460    us] [AverageConsume 3144   us] [FPS   318.0]
[Case rectangle_fill                ] [Input 1*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 298156    us] [AverageConsume 2981   us] [FPS   335.4]
[Case rotation                      ] [Input 1*1920*1080] [Output 1920*1080] [TestTimes   100] [TotalConsume 609109    us] [AverageConsume 6091   us] [FPS   164.2]
```

## sample_rotation
### 功能概述
功能描述：`sample_rotation` 完成对图像进行顺时针旋转 90 度的功能

#### 软件架构说明


![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)


#### 代码位置及目录结构

- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_rotation
    ├── Makefile
    └── rotation.c
```

#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序
##### 整体流程

![app_common_complex](./_static/_images/sample_gpu_2d/dataflow/app_common_complex.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程
![sample_simple](./_static/_images/sample_gpu_2d/dataflow/sample_simple.png)



### 编译部署
#### 编译
- 进入 sample_rotation 目录，执行 `make` 编译
- 输出成果物是 sample_rotation 源码目录下的 `rotation`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节

#### 程序部署
1. 把目录 `sample_rotation` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_rotation` 运行 `chmod +x rotation` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./rotation`
程序从 `resource` 目录中读取文件 `R5G6B5_640x640.bmp` 进行翻转后
保存到当前目录：`R5G6B5_640x640_rotated.bmp`

#### 程序参数选项说明
```sh
Usage: rotation [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./rotation -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./rotation (not need input param)
```

举例说明：
- `./rotation -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./rotation`: 对输入图像进行顺时针旋转 90 度


#### 运行效果
执行命令：
```sh
./rotation
```
运行日志：
```
./rotation
Start !!!
Save file to [./R5G6B5_640x640_rotated.bmp].
Stop !!!
```
效果说明：<br>
程序读取输入文件后，顺时针旋转 90 度，并将翻转后结果保存文件输出， 效果如下：

输入文件：

![rotation-input](./_static/_images/sample_gpu_2d/R5G6B5_640x640.png)

输出文件：

![rotation-output](./_static/_images/sample_gpu_2d/R5G6B5_640x640_rotated.png)



## sample_rectangle_fill
### 功能概述
功能描述：`sample_rectangle_fill` 完成对图像进行矩形填充的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)


#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_rectangle_fill
    ├── Makefile
    └── rectangle_fill.c
```

#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程

![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程

![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程

![rectangle_fill_sample](./_static/_images/sample_gpu_2d/dataflow/rectangle_fill_sample.png)

### 编译部署
#### 编译
- 进入 sample_rectangle_fill 目录，执行 `make` 编译
- 输出成果物是 sample_rectangle_fill 源码目录下的 `rectangle_fill`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节

#### 程序部署
1. 把目录 `sample_rectangle_fill` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_rectangle_fill` 运行 `chmod +x rectangle_fill` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./rectangle_fill`， 程序从 `resource` 目录中读取文件 `R5G6B5_640x640.bmp` 进行填充矩形框后，
保存到当前目录：`R5G6B5_640x640_rectangle_fill.bmp`
#### 程序参数选项说明
```sh
Usage: rectangle_fill [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./rectangle_fill -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./rectangle_fill (not need input param)
```

举例说明：
- `./rectangle_fill -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./rectangle_fill`: 对输入图像进行矩形填充


#### 运行效果
执行命令：
`./rectangle_fill`
运行日志：
```
./rectangle_fill
Start !!!
Save file to [./R5G6B5_640x640_rectangle_fill.bmp].
Stop !!!
```
效果说明：<br>
程序读取输入文件后，分别进行如下操作：

1. 左上角添加蓝色不透明的矩形框
2. 右上角添加绿色半透明的矩形框
3. 左下角添加绿色透明的矩形框
4. 右小角添加绿色不透明的矩形框

输入文件：

![rectangle_fill-input](./_static/_images/sample_gpu_2d/R5G6B5_640x640.png)

输出文件：

![rectangle_fill-output](./_static/_images/sample_gpu_2d/R5G6B5_640x640_rectangle_fill.png)



## sample_alphablend
### 功能概述
功能描述：`sample_alphablend` 完成对图像进行 alphablend 的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)


#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_alphablend
    ├── alphablend.c
    └── Makefile
```

#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程

![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程
![alpha_sample](./_static/_images/sample_gpu_2d/dataflow/alpha_sample.png)

### 编译部署
#### 编译
- 进入 sample_alphablend 目录，执行 `make` 编译
- 输出成果物是 sample_alphablend 源码目录下的 `alphablend`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节

#### 程序部署
1. 把目录 `sample_alphablend` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_alphablend` 运行 `chmod +x alphablend` 命令给程序赋予可执行权限
### 运行
#### 程序运行方法
执行程序：`./alphablend`
#### 程序参数选项说明
```sh
Usage: alphablend [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./alphablend -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./alphablend (not need input param)
```

举例说明：
- `./alphablend -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./alphablend`: 执行 alpha 融合功能的示例

#### 运行效果
执行命令：

`./alphablend`

运行日志：
```
./alphablend
Start !!!
Stop !!!
```
效果说明：<br>

1. 首先构造两个 `640*480`、`N2D_BGRA8888` 格式的 buffer
2. 其中一个 buffer 画蓝色矩形框，另外一个 buffer 画红色矩形框，两个矩形框有交集（查看融合效果）
3. 遍历所有的融合模式，每个融合模式下，改变不同的透明度
4. 将不同融合模式和不同透明度的各种组合的融合效果，保存到文件中（文件名由融合模式和透明度参数拼接）

#### `src_over` 模式
![src_over-0](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_0_128-128.png)
![src_over-1](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_1_144-112.png)
![src_over-2](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_2_160-96.png)
![src_over-3](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_3_176-80.png)

![src_over-4](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_4_192-64.png)
![src_over-5](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_5_208-48.png)
![src_over-6](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_6_224-32.png)
![src_over-7](./_static/_images/sample_gpu_2d/alphablend/src_over_mode_index_7_240-16.png)


#### `src_in` 模式
![src_in-0](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_0_128-128.png)
![src_in-1](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_1_144-112.png)
![src_in-2](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_2_160-96.png)
![src_in-3](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_3_176-80.png)

![src_in-4](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_4_192-64.png)
![src_in-5](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_5_208-48.png)
![src_in-6](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_6_224-32.png)
![src_in-7](./_static/_images/sample_gpu_2d/alphablend/src_in_mode_index_7_240-16.png)


#### `dst_over` 模式
![dst_over-0](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_0_128-128.png)
![dst_over-1](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_1_144-112.png)
![dst_over-2](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_2_160-96.png)
![dst_over-3](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_3_176-80.png)

![dst_over-4](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_4_192-64.png)
![dst_over-5](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_5_208-48.png)
![dst_over-6](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_6_224-32.png)
![dst_over-7](./_static/_images/sample_gpu_2d/alphablend/dst_over_mode_index_7_240-16.png)


#### `dst_in` 模式
![dst_in-0](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_0_128-128.png)
![dst_in-1](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_1_144-112.png)
![dst_in-2](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_2_160-96.png)
![dst_in-3](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_3_176-80.png)

![dst_in-4](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_4_192-64.png)
![dst_in-5](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_5_208-48.png)
![dst_in-6](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_6_224-32.png)
![dst_in-7](./_static/_images/sample_gpu_2d/alphablend/dst_in_mode_index_7_240-16.png)


#### `subtract` 模式
![subtract-0](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_0_128-128.png)
![subtract-1](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_1_144-112.png)
![subtract-2](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_2_160-96.png)
![subtract-3](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_3_176-80.png)

![subtract-4](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_4_192-64.png)
![subtract-5](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_5_208-48.png)
![subtract-6](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_6_224-32.png)
![subtract-7](./_static/_images/sample_gpu_2d/alphablend/subtract_mode_index_7_240-16.png)


#### `additive` 模式
![additive-0](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_0_128-128.png)
![additive-1](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_1_144-112.png)
![additive-2](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_2_160-96.png)
![additive-3](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_3_176-80.png)

![additive-4](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_4_192-64.png)
![additive-5](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_5_208-48.png)
![additive-6](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_6_224-32.png)
![additive-7](./_static/_images/sample_gpu_2d/alphablend/additive_mode_index_7_240-16.png)

## sample_format_convert
### 功能概述
功能描述：`sample_format_convert` 完成对图像进行颜色空间转换的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_format_convert
    ├── format_convert.c
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程

![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程
![format_convert_sample](./_static/_images/sample_gpu_2d/dataflow/format_convert_sample.png)
### 编译部署
#### 编译
#### 程序部署
1. 把目录 `sample_format_convert` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_format_convert` 运行 `chmod +x format_convert` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./format_convert`
#### 程序参数选项说明
```sh
Usage: format_convert [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./format_convert -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./format_convert (not need input param)
```

举例说明：
- `./format_convert -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./format_convert`: 执行 颜色空间转换功能的示例

#### 运行效果
执行命令：
```c
./format_convert
```

运行日志：
```
./format_convert
Start !!!
Stop !!!
```

效果说明：

1. 程序从 `resource` 目录中读取文件 `RGBA8888_640x480.bmp` 进行不同种类的颜色空间转换
2. 首先将输入图片转换成 如下格式中的一种
3. 再转换成输入文件的格式（`RGBA8888`），并保存成文件
```
n2d_buffer_format_t yuv_format[] =
{
    N2D_YUYV,
    N2D_UYVY,
    N2D_YV12,
    N2D_I420,
    N2D_NV12,
    N2D_NV21,
    N2D_NV16,
    N2D_NV61,
    N2D_P010_MSB,
    N2D_P010_LSB,
    N2D_I010
};
```

注意：由于程序的功能是将输入文件的颜色空间转换成 `yuv_format[i]`，
再转换回输入文件对应的颜色空间，所以 输出文件和输入文件是没有区别的。


输入文件：

![format-input](./_static/_images/sample_gpu_2d/RGBA8888_640x480.png)

输出文件：

![format-input](./_static/_images/sample_gpu_2d/RGBA8888_640x480.png)



## sample_copy
### 功能概述

功能描述：`sample_copy` 完成对图像进行内存拷贝的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_copy
    ├── copy.c
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程

![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程
![sample_normal](./_static/_images/sample_gpu_2d/dataflow/sample_normal.png)

### 编译部署
#### 编译
#### 程序部署
1. 把目录 `sample_copy` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_copy` 运行 `chmod +x copy` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./copy`
#### 程序参数选项说明
```sh
Usage: copy [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./copy -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./copy (not need input param)
```

举例说明：
- `./copy -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./copy`: 执行 内存拷贝功能的示例
#### 运行效果
执行命令：
`./copy`
运行日志：
```
Run Sample[copy](sample mode ignore input param).

Start !!!
copy input file ../resource/RGBA8888_640x480.bmp [640*480] ==> output file ./copy_sample_640_480.bmp [640*480]
Stop !!!
```
效果说明：

1. 程序从 `resource` 目录中读取文件 `RGBA8888_640x480.bmp` 进行拷贝
2. 将拷贝后的图像保存到文件：`copy_sample_640_480.bmp`

输入文件：

![format-input](./_static/_images/sample_gpu_2d/RGBA8888_640x480.png)

输出文件：

![format-input](./_static/_images/sample_gpu_2d/RGBA8888_640x480.png)


## sample_crop
### 功能概述

功能描述：`sample_crop` 完成图像裁剪的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_crop
    ├── crop.c
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程
![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例流程
![sample_normal](./_static/_images/sample_gpu_2d/dataflow/sample_normal.png)

### 编译部署
#### 编译
- 进入 sample_crop 目录，执行 `make` 编译
- 输出成果物是 sample_crop 源码目录下的 `crop`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节
#### 程序部署
1. 把目录 `sample_crop` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_crop` 运行 `chmod +x crop` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./crop`
#### 程序参数选项说明
```sh
Usage: crop [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./crop -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./crop (not need input param)
```

举例说明：
- `./crop -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./crop`: 执行图像裁剪功能的示例

#### 运行效果

执行命令：
`./crop`
运行日志：

```

Run Sample[crop](sample mode ignore input param).

Start !!!
crop input file ../resource/RGBA8888_640x480.bmp [640*480] ==> output file ./crop_sample_160_120.bmp [160*120]
Stop !!!
```

效果说明：
1. 程序从 `resource` 目录中读取文件 `RGBA8888_640x480.bmp`
2. 根据矩形框 (0,0,160,120) 对输入的文件进行裁剪
3. 将裁剪的结果保存到 `crop_sample_160_120.bmp`


输入文件：

![format-input](./_static/_images/sample_gpu_2d/RGBA8888_640x480.png)

输出文件：

![format-input](./_static/_images/sample_gpu_2d/crop_sample_160_120.png)


## sample_multi_source_alphablend
### 功能概述
功能描述：`sample_multi_source_alphablend` 完成对多个输入图像同时进行融合
#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_multi_source_alphablend
    ├── multi_source_alphablend.c
    └── Makefile
```

#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程

![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![multi_source_blend_performance](./_static/_images/sample_gpu_2d/dataflow/multi_source_blend_performance.png)

##### 示例程序流程
![multi_source_blend](./_static/_images/sample_gpu_2d/dataflow/multi_source_blend.png)

### 编译部署
#### 编译
- 进入 sample_multi_source_alphablend 目录，执行 `make` 编译
- 输出成果物是 sample_multi_source_alphablend 源码目录下的 `multi_source_alphablend`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节
#### 程序部署
1. 把目录 `sample_multi_source_alphablend` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_multi_source_alphablend` 运行 `chmod +x multi_source_alphablend` 命令给程序赋予可执行权限
### 运行
#### 程序运行方法
执行程序：`./multi_source_alphablend`
#### 程序参数选项说明
```sh
Usage: multi_source_alphablend [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./multi_source_alphablend -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./multi_source_alphablend (not need input param)
```

举例说明：
- `./multi_source_alphablend -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./multi_source_alphablend`: 执行对多个输入图像同时进行融合功能的示例

#### 运行效果
执行命令：
`./multi_source_alphablend`
运行日志：
```

Run Sample[multi_source_alphablend](sample mode ignore input param).

Start !!!
multi_source_alphablend input file scenery0x [640*480] ==> output file ./multi_source_alphablend_sample_640_480.bmp [640*480]
Stop !!!
```
效果说明：

1. 程序从 `resource` 目录中读取文件 `scenery01.bmp`、`scenery02.bmp`、`scenery03.bmp`、`scenery04.bmp`
2. 将 4 张图片分别从不同的位置进行裁剪后，按照 `N2D_BLEND_SRC_OVER` 的融合模式进行透明度融合操作
3. 将融合的结果保存到文件 `multi_source_alphablend_sample_640_480.bmp`


输入文件 :

![format-input](./_static/_images/sample_gpu_2d/scenery01.png)

![format-input](./_static/_images/sample_gpu_2d/scenery02.png)

![format-input](./_static/_images/sample_gpu_2d/scenery03.png)

![format-input](./_static/_images/sample_gpu_2d/scenery04.png)

输出文件：

![format-input](./_static/_images/sample_gpu_2d/multi_source_alphablend_sample_640_480.png)



## sample_resize
### 功能概述
功能描述：`sample_resize ` 完成对图像的放大功能, 可以指定不同的滤波器类型

|  滤波器类型                       | 含义                      |典型用途|
|---------------------------------|------------------------------|------------------------------|
|N2D_FILTER_SYNC | 同步滤波器，多指 Sinc Filter 或同步插值滤波，理论上可以保持图像频域特性，减少混叠。计算量较大。| 高质量缩放、对清晰度要求极高的图像处理。|
|N2D_FILTER_BLUR | 模糊滤波器，进行平滑或低通处理，使图像柔化，细节减少，噪点降低。|降噪、背景虚化、缩略图生成。|
|N2D_FILTER_BILINEAR | 双线性插值滤波，最常用的插值算法之一，速度快，质量中等。|实时缩放、视频播放、GUI渲染。|
|N2D_FILTER_BICUBIC | 双三次插值滤波，比双线性更平滑、细节更好，但计算量大。|高质量图像缩放、照片处理。|


#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── bit_filter_1920_1080.bmp
│   ├── nv12_1920x1080.yuv
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_resize
    ├── resize.c
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程
![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![performance](./_static/_images/sample_gpu_2d/dataflow/performance.png)

##### 示例程序流程
![sample_normal](./_static/_images/sample_gpu_2d/dataflow/resize_sample.png)
### 编译部署
#### 编译
- 进入 sample_resize 目录，执行 `make` 编译
- 输出成果物是 sample_resize 源码目录下的 `resize`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节
#### 程序部署
1. 把目录 `sample_resize ` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_resize ` 运行 `chmod +x resize` 命令给程序赋予可执行权限
### 运行
#### 程序运行方法
执行程序：`./resize`
#### 程序参数选项说明
```sh
Usage: resize [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./resize -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./resize (not need input param)
```

举例说明：
- `./resize -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./resize`: 执行图像放大功能的示例

#### 运行效果
执行命令：
`./resize`
运行日志：
```
Run Sample[resize](sample mode ignore input param).

Start !!!
Resize input file ../resource/bit_filter_1920_1080.bmp [1920*1080] ==> output file ./resize_sample_3840_2160_sync.bmp [3840*2160]
Resize input file ../resource/bit_filter_1920_1080.bmp [1920*1080] ==> output file ./resize_sample_3840_2160_blur.bmp [3840*2160]
Resize input file ../resource/bit_filter_1920_1080.bmp [1920*1080] ==> output file ./resize_sample_3840_2160_bilinear.bmp [3840*2160]
Resize input file ../resource/bit_filter_1920_1080.bmp [1920*1080] ==> output file ./resize_sample_3840_2160_bicubic.bmp [3840*2160]
Stop !!!
```
效果说明：
1. 程序从 `resource` 目录中读取文件 `bit_filter_1920_1080.bmp`
2. 分别使用 4 种过滤器算法，将图像横向和纵向各放大两倍
3. 将放大的图像保存到文件 `resize_sample_3840_2160_sync.bmp`、`resize_sample_3840_2160_blur.bmp`、`resize_sample_3840_2160_bilinear.bmp`、`resize_sample_3840_2160_bicubic.bmp`、

输入文件：

![format-input](./_static/_images/sample_gpu_2d/filter_blit.png)


## sample_stitch
### 功能概述
功能描述：`sample_stitch ` 完成对 4 个输入的图像进行拼接成 1 个图像的功能

#### 软件架构说明
![framework_all](./_static/_images/sample_gpu_2d/dataflow/framework_all.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构

```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   └── scenery04.bmp
└── sample_stitch
    ├── stitch.c
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序

##### 整体流程
![app_common_simple](./_static/_images/sample_gpu_2d/dataflow/app_common_simple.png)

##### 性能测试流程
![stitch_performance](./_static/_images/sample_gpu_2d/dataflow/stitch_performance.png)

##### 示例程序流程
![stitch_sample](./_static/_images/sample_gpu_2d/dataflow/stitch_sample.png)



### 编译部署
#### 编译
- 进入 sample_stitch 目录，执行 `make` 编译
- 输出成果物是 sample_stitch 源码目录下的 `stitch`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节
#### 程序部署
1. 把目录 `sample_stitch ` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_stitch ` 运行 `chmod +x stitch` 命令给程序赋予可执行权限
### 运行
#### 程序运行方法
 执行程序：`./stitch`
#### 程序参数选项说明
```sh
Usage: stitch [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./stitch -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./stitch (not need input param)
```

举例说明：
- `./stitch -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./stitch`: 执行对 4 个输入的图像进行拼接成 1 个图像功能的示例

#### 运行效果
执行命令：
运行日志：
```
Run Sample[stitch](sample mode ignore input param).

Start !!!
stitch input file pip0x [640*480] ==> output file ./stitch_sample_1280_960.bmp [1280*960]
Stop !!!
```

效果说明：

1. 程序从 `resource` 目录中读取文件 `scenery01.bmp`、`scenery02.bmp`、`scenery03.bmp`、`scenery04.bmp`
2. 将 4 张输入的图片按照 4 宫格的方式拼接成 1 张图片
3. 将拼接后的图片保存到 `stitch_sample_1280_960.bmp`


输入文件 :

![format-input](./_static/_images/sample_gpu_2d/scenery01.png)

![format-input](./_static/_images/sample_gpu_2d/scenery02.png)

![format-input](./_static/_images/sample_gpu_2d/scenery03.png)

![format-input](./_static/_images/sample_gpu_2d/scenery04.png)

输出文件：

![format-input](./_static/_images/sample_gpu_2d/stitch_sample_1280_960.png)



## sample_create_n2d_buffer
### 功能概述
功能描述：`sample_create_n2d_buffer` 实现将如下两种方式申请的内存转换成 2D GPU API 接口使用的图像缓存结构体 `n2d_buffer_t`
1. 物理地址不连续：`malloc` 函数申请的内存
2. 物理地址连续：[Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 接口申请的内存

#### 软件架构说明

![framework_create_n2d_buffer](./_static/_images/sample_gpu_2d/dataflow/framework_create_n2d_buffer.png)

#### 代码位置及目录结构
- 代码位置 `app/samples/platform_samples/sample_gpu_2d`
- 目录结构
```
sample_gpu_2d/
├── resource
│   ├── R5G6B5_640x640.bmp
│   ├── RGBA8888_640x480.bmp
│   ├── scenery01.bmp
│   ├── scenery02.bmp
│   ├── scenery03.bmp
│   ├── scenery04.bmp
|   └── nv12_1920x1080.yuv
└── sample_create_n2d_buffer
    ├── create_n2d_buffer.c
    ├── create_n2d_buffer_wraper.c
    ├── create_n2d_buffer_wraper.h
    └── Makefile
```
#### API 流程说明
GPU 2D API 使用的核心步骤是：
1. 准备源缓冲区和目标缓冲区 , 源缓冲区和目标缓冲区结构使用 [n2d_buffer_t ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-buffer-t)  结构定义
2. 执行 blit 操作：将执行命令送入指令缓存区
   - [n2d_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-blit)
   - [n2d_filterblit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-filterblit)
   - [n2d_multisource_blit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-multisource-blit)
3. 执行 commit 操作：将指令缓存区中待执行的指令送入 GPU 硬件并阻塞等待 GPU 硬件处理完成
   - [n2d_commit ](../multimedia_development/12-2DGPU_API_zh_CN.html#n2d-commit)


示例程序主要有两个分支：
1. 性能测试
2. 示例程序，其中提供了如下 3 种示例
   - `create_n2d_buffer_and_copy_sample`: 将 hbmem 申请的内存转换为 2D GPU API 接口使用的图像缓存结构体 `n2d_buffer_t`
     -  hbmem 申请的内存转换为 `n2d_buffer_t` 的本质：对内存描述结构体另一种形式的封装，不会涉及内存拷贝
   - `create_n2d_buffer_from_normal_memory_sample`: 将 malloc 申请的内存转换为 2D GPU API 接口使用的图像缓存结构体 `n2d_buffer_t`，转换的步骤如下：
     - 通过 [Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 接口申请物理地址连续的内存
     - 把 malloc 申请的内存拷贝到 [Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 接口申请的内存
     - 把 [Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 接口申请的内存转换成 `n2d_buffer_t`
   - `create_n2d_buffer_stitch`: 将 hbmem 申请的内存转换为 2D GPU API 接口使用的图像缓存结构体 `n2d_buffer_t` 并且完成拼接的操作

**注意**：
示例程序中会调用 cache 相关操作的接口，如下，详细请参考：[Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html#cache)
1. `hb_mem_flush_buf`
2. `hb_mem_invalidate_buf`


##### 示例程序整体流程
![create_n2d_buffer_sample](./_static/_images/sample_gpu_2d/dataflow/create_n2d_buffer_sample.png)

##### 性能测试流程
![create_n2d_buffer_performance](./_static/_images/sample_gpu_2d/dataflow/create_n2d_buffer_performance.png)

##### create_n2d_buffer_and_copy_sample 示例流程
![create_n2d_buffer_copy](./_static/_images/sample_gpu_2d/dataflow/create_n2d_buffer_copy.png)

##### create_n2d_buffer_from_normal_memory_sample 示例流程
![create_n2d_buffer_normal](./_static/_images/sample_gpu_2d/dataflow/create_n2d_buffer_normal.png)

##### create_n2d_buffer_stitch 示例流程

![create_n2d_buffer_stitch](./_static/_images/sample_gpu_2d/dataflow/create_n2d_buffer_stitch.png)

### 编译部署
#### 编译
- 进入 sample_create_n2d_buffer 目录，执行 `make` 编译
- 输出成果物是 sample_create_n2d_buffer 源码目录下的 `create_n2d_buffer`
- 详细程序编译方式请查阅 [ 编译方法 ](overview.html#span-id-sample-build) 章节
#### 程序部署
1. 把目录 `sample_create_n2d_buffer ` 和 `resource` 上传到开发板 `/userdata` 目录下
2. 进入 `sample_create_n2d_buffer ` 运行 `chmod +x create_n2d_buffer` 命令给程序赋予可执行权限

### 运行
#### 程序运行方法
执行程序：`./create_n2d_buffer`
#### 程序参数选项说明
```sh
Usage: create_n2d_buffer [OPTIONS]
Options:
  -m <mode>              Specify running mode(0:sample, 1:performance test)
  -c <image_width>       Specify image width(column)
  -r <image_height>      Specify image height(row)
  -i <iteration_number>  Specify frames per second
  -h <help>              Show this help message
     For Example, performance test: ./create_n2d_buffer -m 1 -c 1920 -r 1080 -i 1000
     For Example, sample          : ./create_n2d_buffer (not need input param)
```

举例说明：
- `./create_n2d_buffer -m 1 -c 1920 -r 1080 -i 1000`：性能测试模式，指定 分辨率是 1920*1080 ，运行 1000 次，最终打印平均耗时和帧率
- `./create_n2d_buffer`: 执行把外部内存转换成 2D GPU API 接口支持的 `n2d_buffer_t` 功能的示例

#### 运行效果
执行命令：
`./create_n2d_buffer`
运行日志：
```

Run Sample[create_n2d_buffer](sample mode ignore input param).

Start !!!
Dump image to file(./create_n2d_buffer_copy_sample_hbn_1920_1080.yuv), size(3110400) succeeded
Dump image to file(./create_n2d_buffer_stitch_sample_hbn_1920_2160.yuv), size(6220800) succeeded
Dump image to file(./create_n2d_buffer_normal_memory_sample_hbn_1920_1080.yuv), size(3110400) succeeded
Stop !!!
```
效果说明：

1. 程序从 `resource` 目录中读取文件 `nv12_1920x1080.yuv`
2. 对输入图片做三种操作：

	a. 使用 [Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 接口申请物理地址连续的内存，转换成 `n2d_buffer_t`，使用 2D GPU 的接口完成图片的复制，结果保存到文件 `create_n2d_buffer_copy_sample_hbn_1920_1080.yuv`

	b. 使用 [Hbmem](../multimedia_development/3-Hbmem_index_zh_CN.html) 在操作 a 的基础上增加使用 2D GPU 的接口完成上下拼接的功能，结果保存到文件
	`create_n2d_buffer_stitch_sample_hbn_1920_2160.yuv`

	c. 使用 `malloc` 申请物理地址不连续的内存，转换成 `n2d_buffer_t`，使用 2D GPU 的接口完成图片的复制，结果保存到文件 `create_n2d_buffer_normal_memory_sample_hbn_1920_1080.yuv`
