在嵌入式下,在移植软件时经常会碰到这样的问题,就是显示分辩率的变化.一般软件往往针对桌面机的环境编译没有太多问题,但是在嵌入式环境下,受限的LCD显示有着很大的问题.
这种情况下,一种方法是修改代码,让其在嵌入式的LCD上显示.另外一种是使用软件进行显示缩放. 这两个方法只在部分条件有效,而且修改的工作量极大,更多情况是无法修改,比如SDL下的Dosbox是针对 640*480,修改源码的分辩率成 480*272 后,基本屏幕显示完全错位.软件无法正常运行.
这里有一种思路是使用s3c6410的post process.它是一个硬件进行图像和视频缩放的的模块.用POST后,只需要简单调整frame buffer显示库代码,即可以让原来无法移植的软件在嵌入式环境下自由缩放.
一.Post Process 说明
s3c6410的Post Process支持图像和视频缩放和格式转换,因为是硬件操作,所以速度非常之快.
这是DataSheet 对其功能说明.
• Dedicated DMA with offset address
• 3 Channel scaling pipelines for video/graphic scaling up/down or zooming in/out
• Video input format: 420, 422 format
• Graphic input format: 16-bit (565format) or 24-bit
• Graphics Output format to Memory: 16-bit (565 format) / 24-bit graphic data (progressive only)
• Video Output format to Memory: YCbCr420, YCbCr422
• Output format to external FIFO: YCbCr444 / RGB (30-bit) for interlace and progressive
• FreeRun Mode Operation
• Programmable source image size up to 4096 × 4096 resolution
• Programmable destination image size up to 2048 × 2048 resolution
• Programmable scaling ratio
• Format conversion for video signals
• Color space conversion from YCbCr to RGB
• Color Space conversion from RGB to YCbCr
它的主要处理流程是在系一种统内存中开辟一个PP的帧内存.其中数据被PP处理后,有两个流向,一个是通过DMA直接传到例如显存当中,这样可以直接显示,另外一种是传到硬件队列当中,然后可以发送到LCD,TV等设备当中.
二.官方的Linux PP测试程序.
官方有一个Linux下的测试程序,是演示的如果使用Post Process的驱动 s3c-pp的演示代码.它是用双缓冲的把两幅640*480的原始图像,在任意分辩率下进行缩放后,交替在屏幕上显示.
这里有两个版本,我选择是 Multimedia_DDPP_V2.5v3.xxpp_app 的测试程序.
我是在4.3'的s3c6410开发板上运行.fb的信息是 480*272 bpp采用16.
这样需要对原有的代码post_test.c进行简单修改.
1.23行,设备结点修改为 #define PP_DEVICE_FILE_NAME '/dev/s3c-pp'
2. 25,26行,分辩率修改为4.3'的配置
#define LCD_WIDTH 480
#define LCD_HEIGHT 272
Makefile 的修改,将CC=....的值调整为 CC=arm-linux-gcc
编译成功后,可以选择如下两种方式运行.
./post_test 0 10000
其中第一个参数是PP的输出方式,0是采用DMA输出,1是采用FIFO,两种情况测试均成功.
第二个参数是两幅图像交错显示时,每次显示的时间.单位是微秒.
这是在我的开发板显示效果,结果是比较令人满意.
三.封装后的S3C PP 库代码
分析后的PP处理流程.官方只给一个简单中测试程序.简单分析其处理机制,大体按如下流程进行处理.
1.打开/dev/s3c-pp结点进行操作
2.对PP的设备使用ioctl命令 ioctl(pp_dev->pp_fd, S3C_PP_SET_PARAMS, &pp_param)来设置缩放前后的分辩率,bpp和格式.其结构定义在 s3c_pp_params_t 之中.
3. 对pp设备使用ioctl命令ioctl(pp_dev->pp_fd, S3C_PP_ALLOC_KMEM, &alloc_info[0]),分配转换前的在内存.如果输出是LCD的,输出缓冲直接采用显存.
4.将转换前数据拷贝到转换前内存之中
5,对于PP调用 ioctl(pp_dev->pp_fd, S3C_PP_START); 进行转换.
如果是显存,则直接显示在LCD之上.
6.退出时,调用ioctl(pp_dev->pp_fd, S3C_PP_FREE_KMEM, &alloc_info[0]) 释放转换前的内存.
7.关闭pp的设备设点
#ifndef __S3C_PP_LIB_H__
#define __S3C_PP_LIB_H__
/*
Author: Andrew Huang
descrition S3C6410 Post Process library
*/
#ifdef __cplusplus
extern 'C' {
#endif
typedef enum {
DMA_ONESHOT,
FIFO_FREERUN
} s3c_pp_out_path_t;
typedef enum {
PAL1, PAL2, PAL4, PAL8,
RGB8, ARGB8, RGB16, ARGB16, RGB18, RGB24, RGB30, ARGB24,
YC420, YC422, // Non-interleave
CRYCBY, CBYCRY, YCRYCB, YCBYCR, YUV444 // Interleave
} s3c_color_space_t;
typedef enum {
INTERLACE_MODE,
PROGRESSIVE_MODE
} s3c_pp_scan_mode_t;
// Structure type for IOCTL commands S3C_PP_SET_PARAMS, S3C_PP_SET_INPUT_BUF_START_ADDR_PHY,
// S3C_PP_SET_INPUT_BUF_NEXT_START_ADDR_PHY, S3C_PP_SET_OUTPUT_BUF_START_ADDR_PHY.
typedef struct {
unsigned int src_full_width; // Source Image Full Width (Virtual screen size)
unsigned int src_full_height; // Source Image Full Height (Virtual screen size)
unsigned int src_start_x; // Source Image Start width offset
unsigned int src_start_y; // Source Image Start height offset
unsigned int src_width; // Source Image Width
unsigned int src_height; // Source Image Height
unsigned int src_buf_addr_phy; // Base Address of the Source Image : Physical Address
unsigned int src_next_buf_addr_phy; // Base Address of Source Image to be displayed next time in FIFO_FREERUN Mode
s3c_color_space_t src_color_space; // Color Space of the Source Image
unsigned int dst_full_width; // Destination Image Full Width (Virtual screen size)
unsigned int dst_full_height; // Destination Image Full Height (Virtual screen size)
unsigned int dst_start_x; // Destination Image Start width offset
unsigned int dst_start_y; // Destination Image Start height offset
unsigned int dst_width; // Destination Image Width
unsigned int dst_height; // Destination Image Height
unsigned int dst_buf_addr_phy; // Base Address of the Destination Image : Physical Address
s3c_color_space_t dst_color_space; // Color Space of the Destination Image
s3c_pp_out_path_t out_path; // output and run mode (DMA_ONESHOT or FIFO_FREERUN)
s3c_pp_scan_mode_t scan_mode; // INTERLACE_MODE, PROGRESSIVE_MODE
} s3c_pp_params_t;
// Structure type for IOCTL commands S3C_PP_ALLOC_KMEM, S3C_PP_FREE_KMEM.
typedef struct {
int size;
unsigned int vir_addr;
unsigned int phy_addr;
} s3c_pp_mem_alloc_t;
#define PP_IOCTL_MAGIC 'P'
#define S3C_PP_SET_PARAMS _IO(PP_IOCTL_MAGIC, 0)
#define S3C_PP_START _IO(PP_IOCTL_MAGIC, 1)
#define S3C_PP_GET_SRC_BUF_SIZE _IO(PP_IOCTL_MAGIC, 2)
#define S3C_PP_SET_SRC_BUF_ADDR_PHY _IO(PP_IOCTL_MAGIC, 3)
#define S3C_PP_SET_SRC_BUF_NEXT_ADDR_PHY _IO(PP_IOCTL_MAGIC, 4)
#define S3C_PP_GET_DST_BUF_SIZE _IO(PP_IOCTL_MAGIC, 5)
#define S3C_PP_SET_DST_BUF_ADDR_PHY _IO(PP_IOCTL_MAGIC, 6)
#define S3C_PP_ALLOC_KMEM _IO(PP_IOCTL_MAGIC, 7)
#define S3C_PP_FREE_KMEM _IO(PP_IOCTL_MAGIC, 8)
#define S3C_PP_GET_RESERVED_MEM_SIZE _IO(PP_IOCTL_MAGIC, 9)
#define S3C_PP_GET_RESERVED_MEM_ADDR_PHY _IO(PP_IOCTL_MAGIC, 10)
struct video_view {
int x;
int y;
int w;
int h;
int bpp;
int format;
char * buf;
int size;
char * phy_addr;
};
struct fb_pp {
struct video_view fb_view;
struct video_view src_view;
int fb_fd;
int pp_fd;
int out_path;
int scan_mode;
s3c_pp_params_t pp_param;
};
typedef struct
{
unsigned int map_dma_f1;
unsigned int map_dma_f2;
} s3c_fb_dma_info_t;
extern int s3c_pp_setup(struct fb_pp * pp_dev,struct video_view * src,int out_path);
extern int s3c_pp_open(struct fb_pp * pp_dev,int bpp);
extern int s3c_pp_write(struct fb_pp * pp_dev,char * buf,int buf_len);
extern int s3c_pp_write_file(struct fb_pp * pp_dev,char * filename);
extern int s3c_pp_apply(struct fb_pp * pp_dev);
#ifdef __cplusplus
}
#endif
#endif /* __S3C_PP_LIB_H__ */
上一篇:s3c6410 完全由SD卡启动Linux流程
下一篇:s3c6410 TVout 测试
推荐阅读最新更新时间:2024-11-12 18:14
设计资源 培训 开发板 精华推荐
- [装逼神器]又一款个性名片V1.0
- CAN 总线应用中的 iCoupler 隔离
- 使用 MaxLinear, Inc 的 SPX2808 的参考设计
- 使用 STMicroelectronics 的 L7912C 的参考设计
- 用于简单 400 mW 唱机放大器的 NCV431A 可编程精密基准的典型应用
- DC1753A-B,基于 LTC3880EUJ 双相单输出的演示板 (DCR SENSE),PMBus 降压,6.5V = VIN = 24V,VOUT = 0.5V 至 3.3V @ 40A
- DK-100G-5SGXEA7NES、Stratix V GX 100G开发板提供硬件平台
- 用于 STK6000 入门套件的 ATSTK600-SC14、STK600-TQFP64-2 插座卡
- 使用 Microchip Technology 的 LM285BEZB-2.5 的参考设计
- 具有 5V 和 15V 输出升压稳压器的 LT3095IUDD 5V Vin 的典型应用电路
- 报名抽取京东卡|2021慕尼黑华南电子展观众注册进行中
- 【EEWORLD第三十八届】2012年05月社区明星人物揭晓!
- 《看一个TI老工程师如何驯服精密放大器》点评有礼!
- Microchip 安全解决方案系列在线研讨会第1-26场
- 直播已结束【ADI 低噪声 Buck 稳压器如何减小电源噪声】
- ADI有奖下载活动之22:针对电子测试和测量的RF和微波解决方案
- 有奖直播|TI DLP® 技术如何推动AR HUD和汽车大灯的发展
- 有奖直播|Nexperia针对车联网应用的高效ESD解决方案
- 【有奖直播】 聚焦语音识别核心技术,走进Microchip Timberwolf™音频处理器研讨会
- TE Connectivity 提供更懂你的连接解决方案