初级会员

- 积分
- 142
- 金钱
- 142
- 注册时间
- 2015-6-23
- 在线时间
- 17 小时
|
利用STM32H743-DMA2D将YUV422数据流转换成RGB888数据花屏:
原始热成像数据:192x256分辨率,颜色格式YUV422,以UYVY排列
YUV422数据已经通过SPI_DMA方式获取到,软件解码显示正常;软件解码如下:
void YUV422_RGB888(const u8* uyvy, u8* rgb, int frameSize)
{
int cnt = 0;
for (int i = 0; i<frameSize; i += 2)
{
// 获取UYVY数据
u8 U = uyvy[i * 2]; // U分量
u8 Y0 = uyvy[i * 2 + 1]; // Y分量0
u8 V = uyvy[i * 2 + 2]; // V分量
u8 Y1 = uyvy[i * 2 + 3]; // Y分量1
// 转换Y0
int C0 = Y0 - 16;
int D = U - 128;
int E = V - 128;
int R0 = (298 * C0 + 409 * E + 128) >> 8;
int G0 = (298 * C0 - 100 * D - 208 * E + 128) >> 8;
int B0 = (298 * C0 + 516 * D + 128) >> 8;
// 转换Y1
int C1 = Y1 - 16;
int R1 = (298 * C1 + 409 * E + 128) >> 8;
int G1 = (298 * C1 - 100 * D - 208 * E + 128) >> 8;
int B1 = (298 * C1 + 516 * D + 128) >> 8;
// 限制RGB值在0-255之间
rgb[cnt] =(u8) (R0< 0 ? 0 : (R0 > 255 ? 255 : R0));
cnt++;
rgb[cnt] = (u8)(G0< 0 ? 0 : (G0 > 255 ? 255 : G0));
cnt++;
rgb[cnt] = (u8)(B0< 0 ? 0 : (B0 > 255 ? 255 : B0));
cnt++;
rgb[cnt] = (u8)(R1< 0 ? 0 : (R1 > 255 ? 255 : R1));
cnt++;
rgb[cnt] = (u8)(G1< 0 ? 0 : (G1 > 255 ? 255 : G1));
cnt++;
rgb[cnt] = (u8)(B1< 0 ? 0 : (B1 > 255 ? 255 : B1));
cnt++;
}
}
软件解码显示图像如图片一
为了加快解算速度配置DMA2D解算数据,参考原子哥JPEG硬件解码DMA2D配置代码如下:
u8 JPEG_DMA2D_YUV2RGB_Conversion(u8 *YUV422,u8 *RGB888)
{
u32 regval=0;
u32 timeout=0;
RCC->AHB3ENR|=1<<4; //使能DMA2D时钟
RCC->AHB3RSTR|=1<<4; //复位DMA2D
RCC->AHB3RSTR&=~(1<<4); //结束复位
DMA2D->CR&=~(1<<0); //先停止DMA2D
DMA2D->CR=1<<16; //MODE[1:0]=01,存储器到存储???,带PFC模式
DMA2D->OPFCCR=1<<0; //CM[2:0]=001,输出为RGB888格式
DMA2D->IFCR|=1<<1; //清除传输完成标志
regval=11<<0; //CM[3:0]=1011,输入数据为YCbCr格式
regval|=1<<18; //CSS[1:0]=cm,Chroma Sub-Sampling:0,4:4:4;1,4:2:2;2,4:2:0
DMA2D->FGPFCCR=regval; //设置FGPCCR寄存???
DMA2D->NLR=192+(256<<16); //设定行数寄存???
DMA2D->OMAR=(u32)RGB888; //输出存储器地址
DMA2D->OOR=0; //设置输出行偏移为0
DMA2D->FGMAR=(u32)YUV422; //输入数据源地址
DMA2D->FGOR=0; //前景层行偏移
DMA2D->CR|=1<<0; //启动DMA2D
while((DMA2D->ISR&(1<<1))==0) //等待传输完成
{
timeout++;
if(timeout>0X1FFFFF)break; //超时??????
}
//YUV2RGB转码结束后,在复位一次DMA2D
RCC->AHB3RSTR|=1<<4; //复位DMA2D
RCC->AHB3RSTR&=~(1<<4); //结束复位
if(timeout>0X1FFFFF)return 1;
return 0;
}
解算出来的数据是花,如图片二
是我哪里配置不对,还是原始YUV422数据排列的方式与DMA2D的数据为YCbCr格式不对应?
|
-
图片1软件解码
-
图片2DMA2D解码
|