本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。
本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。
MYC-YT113i核心板及开发板
真正的国产核心板,100%国产物料认证
-
国产T113-i处理器配备2*Cortex-A7@1.2GHz ,RISC-V
-
外置DDR3接口、支持视频编解码器、HiFi4 DSP
-
接口丰富:视频采集接口、显示器接口、USB2.0 接口、CAN 接口、千兆以太网接口
-
工业级:-40℃~+85℃、尺寸37mm*39mm
-
邮票孔+LGA,140+50PIN
全志 T113-i 2D图形加速硬件支持情况
-
Supports layer size up to 2048 x 2048 pixels
-
Supports pre-multiply alpha image data
-
Supports color key
-
Supports two pipes Porter-Duff alpha blending
-
Supports multiple video formats 4:2:0, 4:2:2, 4:1:1 and multiple pixel formats (8/16/24/32 bits graphics layer)
-
Supports memory scan order option
-
Supports any format convert function
-
Supports 1/16× to 32× resize ratio
-
Supports 32-phase 8-tap horizontal anti-alias filter and 32-phase 4-tap vertical anti-alias filter
-
Supports window clip
-
Supports FillRectangle, BitBlit, StretchBlit and MaskBlit
-
Supports horizontal and vertical flip, clockwise 0/90/180/270 degree rotate for normal buffer
-
Supports horizontal flip, clockwise 0/90/270 degree rotate for LBC buffer
可以看到 g2d 硬件支持相当多的2D图像处理,包括颜色空间转换,分辨率缩放,图层叠加,旋转等
开发环境配置
基础开发环境搭建参考上上上一篇
【米尔-全志T113-i开发板试用】基础开发环境配置和opencv-mobile移植测试 - 米尔电子 - 电子技术论坛 - 广受欢迎的专业电子论坛!
除了工具链外,我们使用 opencv-mobile 加载输入图片和保存结果,用来查看颜色转换是否正常
g2d硬件直接采用标准的 Linux ioctl 操纵,只需要引入相关结构体定义即可,无需链接so
此外,g2d的输入和输出数据必须在dmaion buffer上,因此还需要dmaion.h头文件,用来分配和释放dmaion buffer
基于C语言实现的YUV转RGB
这里复用之前T113-i JPG解码的函数
void yuv420sp2rgb(const unsigned char* yuv420sp, int w, int h, unsigned char* rgb)
{
const unsigned char* yptr = yuv420sp;
const unsigned char* vuptr = yuv420sp + w * h;
for (int y = 0; y < h; y += 2)
{
const unsigned char* yptr0 = yptr;
const unsigned char* yptr1 = yptr + w;
unsigned char* rgb0 = rgb;
unsigned char* rgb1 = rgb + w * 3;
int remain = w;
#define SATURATE_CAST_UCHAR(X) (unsigned char)::std::min(::std::max((int)(X), 0), 255);
for (; remain > 0; remain -= 2)
{
// R = 1.164 * yy + 1.596 * vv
// G = 1.164 * yy - 0.813 * vv - 0.391 * uu
// B = 1.164 * yy + 2.018 * uu
// R = Y + (1.370705 * (V-128))
// G = Y - (0.698001 * (V-128)) - (0.337633 * (U-128))
// B = Y + (1.732446 * (U-128))
// R = ((Y << 6) + 87.72512 * (V-128)) >> 6
// G = ((Y << 6) - 44.672064 * (V-128) - 21.608512 * (U-128)) >> 6
// B = ((Y << 6) + 110.876544 * (U-128)) >> 6
// R = ((Y << 6) + 90 * (V-128)) >> 6
// G = ((Y << 6) - 46 * (V-128) - 22 * (U-128)) >> 6
// B = ((Y << 6) + 113 * (U-128)) >> 6
// R = (yy + 90 * vv) >> 6
// G = (yy - 46 * vv - 22 * uu) >> 6
// B = (yy + 113 * uu) >> 6
int v = vuptr[0] - 128;
int u = vuptr[1] - 128;
int ruv = 90 * v;
int guv = -46 * v + -22 * u;
int buv = 113 * u;
int y00 = yptr0[0] << 6;
rgb0[0] = SATURATE_CAST_UCHAR((y00 + ruv) >> 6);
rgb0[1] = SATURATE_CAST_UCHAR((y00 + guv) >> 6);
rgb0[2] = SATURATE_CAST_UCHAR((y00 + buv) >> 6);
int y01 =