打印

整理了一个STM32H7的寄存器方式YCbCr转RGB函数并DMA2D到显示屏,支持采样比4:4:4,4:2:2和4:2:0

[复制链接]
220|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
卡拉瓦乔|  楼主 | 2018-8-4 16:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用时注意第62行的g_LcdWidth是表示显示屏的宽度
以及输出是RGB565格式还是ARGB8888格式。




/*
*********************************************************************************************************
*        函 数 名: DMA2D_Copy_YCbCr_To_RGB
*        功能说明: YCbCr转RGB输出
*        形    参: pSrc:    数据源地址
*                  pDst:    数据目的地址
*                  x:       X轴首地址
*                  y:       Y轴首地址
*                  xsize:   目的区域的X轴大小,即每行像素数
*                  ysize:   目的区域的Y轴大小,即行数
*                  PixelFormat:   目标区颜色格式
*                  ChromaSampling : YCbCr Chroma sampling : 4:2:0, 4:2:2 or 4:4:4  
*        返 回 值: 无
*********************************************************************************************************
*/
static void DMA2D_Copy_YCbCr_To_RGB(uint32_t *pSrc,
                                    uint32_t *pDst,
                                    uint16_t x,
                                    uint16_t y,
                                    uint16_t xsize,
                                    uint16_t ysize,
                                    uint32_t PixelFormat,
                                    uint32_t ChromaSampling)
{   
        uint32_t cssMode = DMA2D_CSS_420;
        uint32_t inputLineOffset = 0;  
        uint32_t destination = 0;
        
        /* 处理输入行偏移 */
        if(ChromaSampling == JPEG_420_SUBSAMPLING)
        {
                cssMode = DMA2D_CSS_420;

                inputLineOffset = xsize % 16;
                if(inputLineOffset != 0)
                {
                        inputLineOffset = 16 - inputLineOffset;
                }   
        }
        else if(ChromaSampling == JPEG_444_SUBSAMPLING)
        {
                cssMode = DMA2D_NO_CSS;

                inputLineOffset = xsize % 8;
                if(inputLineOffset != 0)
                {
                        inputLineOffset = 8 - inputLineOffset;
                }   
        }
        else if(ChromaSampling == JPEG_422_SUBSAMPLING)
        {
                cssMode = DMA2D_CSS_422;

                inputLineOffset = xsize % 16;
                if(inputLineOffset != 0)
                {
                        inputLineOffset = 16 - inputLineOffset;
                }      
        }  
  
        /* 输出地址,特别注意末尾乘以2的对RGB565,如果输出格式是ARGB8888,需要乘以4 */
        destination = (uint32_t)pDst + ((y * g_LcdWidth) + x) * 2;
         
  
        /* DMA2D采用存储器到存储器模式,并且执行FPC颜色格式转换, 这种模式是前景层作为DMA2D输入 */  
        DMA2D->CR      = 0x00010000UL | (1 << 9);
        DMA2D->OOR     = g_LcdWidth - xsize;
        
        /* 输出格式 */
        DMA2D->OPFCCR  = PixelFormat
                         | (DMA2D_REGULAR_ALPHA << 20)
                         | (DMA2D_RB_REGULAR << 21);  
        
        /* 前景层输入格式 */        
        DMA2D->FGPFCCR = DMA2D_INPUT_YCBCR
                         | (DMA2D_REPLACE_ALPHA << 16)
                         | (DMA2D_REGULAR_ALPHA << 20)
                         | (DMA2D_RB_REGULAR << 21)   
                         | (0xFFU << 24)              
                         | (cssMode << 18);               

        DMA2D->FGOR    = inputLineOffset;
        DMA2D->NLR     = (uint32_t)(xsize << 16) | (uint16_t)ysize;      
        DMA2D->OMAR    = (uint32_t)destination;
        DMA2D->FGMAR   = (uint32_t)pSrc;  

        /* 启动传输 */
        DMA2D->CR   |= DMA2D_CR_START;   

        /* 等待DMA2D传输完成 */
        while (DMA2D->CR & DMA2D_CR_START) {}
}
复制代码

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

438

主题

438

帖子

0

粉丝