|
我使用ARM9 S3C2440平台,SENSOR用OV9650,OS用LINUX2.4.18,LCD为320*240
现在能实现在LCD上正常PREVIEW模式,和保存640*480的图片.但是OV的配置参数是30W的.
我现在想保存较大分辨率的图片,比如960*1000,或者1024*768,或1280*1024的.于是遇到了一些问题:
1.我想在驱动中想为YUV分配130W像素的缓冲,即我将
//#define YUV_TUPLE_SIZE (1024*768*2) // maximum
改为//#define YUV_TUPLE_SIZE (1280*1024*2) // maximum
然后提示无法分配这么大的内存,我做了实验,最大可定义为
//#define YUV_TUPLE_SIZE (1080*960*2) // maximum
我想问除了用consistent_alloc这个函数分配外,还有其它什么函数能代替?怎么才能保证内存分配成功,我的内存我现在用的版本是2.4.18
2.如1所述,如果我分配1080*960的YUV空间,
而定义
#define FIXED_SOURCE_WIDTH1 960
#define FIXED_SOURCE_HEIGHT1 1000
即保存的图片大小为960*1000.
在LCD上只能显示一部分.
我看提供的DEMO程序来看,也只能显示那么多,也就是LCD本来是240*320的,但是显示出来是240*250的.
还是因为分配的YUV空间太小,假如扩大到1280*1024就没问题.但目前因为内存分配失败无法实现.
这是show_cam_image函数即图片显示函数中的一部分代码.fb_buf为LCD Framebuffer
for(i=0; i<4; i++) { //0,1,2,3
if((image_width2>>i)<=fb_xres) {
f = 0;
w = min(image_width2>>i, fb_xres);
h = min(image_height2>>i, fb_yres);
break;
}
if((image_height2>>i)<=fb_yres) {
f = 1;
w = min(image_width2>>i, fb_yres);
h = min(image_height2>>i, fb_xres);
break;
}
}
for(y=0; y<H; y++) {
for(x=0; x<W; 2 calculate { x+="2)" times
if(i) {
fb_buf[x] = Conv_YCbCr_Rgb(y_buf[x<<I],
y_buf[(x<<I)+1],
cb_buf[(x<<I)>>1],
cr_buf[(x<<I)>>1]);
fb_buf[x+1] = Conv_YCbCr_Rgb(y_buf[(x<<I)+YUV_INTERVAL[I]],
y_buf[(x<<I)+1+YUV_INTERVAL[I]],
cb_buf[((x<<I)+YUV_INTERVAL[I])>>1],
cr_buf[((x<<I)+YUV_INTERVAL[I])>>1]);
} else {
rgb_data = Conv_YCbCr_Rgb(y_buf[x<<I],
y_buf[(x<<I)+1],
cb_buf[(x<<I)>>1],
cr_buf[(x<<I)>>1]);
fb_buf[x] = rgb_data;
fb_buf[x+1] = rgb_data>>16;
}
}
fb_buf += fb_xres;
y_buf += image_width<<I;
cb_buf += (image_width<<I)>>1;
cr_buf += (image_width<<I)>>1;
}
这段代码的意思是否只抽取YUV缓冲中的部分数据放到LCD的Framebuffer中?
3.假如我按960*1000来保存图片.
保存的图片质量很差,还出现了三个排开的同样的图片,
因为我向OV的厂家要了130W的寄存器参数对OV SENSOR重新进行了配置,那么YUV缓冲中应该是至少100W左右的数据,即使不能捕获130W的数据,那么正常保存的图片不应该这样呀.我把YUV_BUFFER中的的数据完全打印出来,好像也没看见重复的数据.
我想问问如果从原来输出30W象素的设置改变为配置OV为130W的像素输出,除了配置I2C的100多个寄存器外,其它还需要配置什么吗?
另外当我配置捕获的图片为960*1000的时候,LCD上虽只显示240*250的图片,但是显示效果还是可以的.并且原来当OV SENSOR配置为30W输出的时候,也能正常保存640*480的图片,并且图片质量也不错.以下是保存图片的程序,请帮忙分析下,难道不适合保存960*1000的图片,好像没看见这个限制呀.
static void save_picture(unsigned char *src)
{
int y, x;
char name[64];
unsigned long rgb_data;
unsigned short w = image_width1;
unsigned short h = image_height1;
unsigned char *src_y = src;
unsigned char *src_cb = src_y+image_width1*image_height1;
unsigned char *src_cr = src_cb+image_width1*image_height1/2;
int palette = optional_image_format[image_format].palette;
image_buffer = malloc(w*h*3); //RGB24
if(image_buffer==NULL) {
printf("allocate memory fail in saving picture!\n");
return;
}
if(palette==VIDEO_PALETTE_RGB565)
for(y=0; y<H; y++)
for(x=0; x<W; x++) {
image_buffer[(y*w+x)*3] = (((__u16 *)src)[y*w+x]&0xf800)>>8;
image_buffer[(y*w+x)*3+1] = (((__u16 *)src)[y*w+x]&0x07e0)>>3;
image_buffer[(y*w+x)*3+2] = (((__u16 *)src)[y*w+x]&0x001f)<<3;
}
else if(palette==VIDEO_PALETTE_YUV422P)
for(y=0; y<H; y++)
for(x=0; x<W x++) 3; {
rgb_data = Conv_YCbCr_Rgb(src_y[y*w+x], src_y[y*w+x+1],
src_cb[(y*w+x)>>1], src_cr[(y*w+x)>>1]);
image_buffer[(y*w+x)*3] = (rgb_data&0xf800)>>8;
image_buffer[(y*w+x)*3+1] = (rgb_data&0x07e0)>>3;
image_buffer[(y*w+x)*3+2] = (rgb_data&0x001f)<<3;
x++;
image_buffer[(y*w+x)*3] = (rgb_data&0xf8000000)>>24;
image_buffer[(y*w+x)*3+1] = (rgb_data&0x07e00000)>>19;
image_buffer[(y*w+x)*3+2] = (rgb_data&0x001f0000)>>13;
}
else {
printf("unsupported input image format for saving jpeg file\n");
free(image_buffer);
return;
}
printf("h=%d,w=%d",h,w);
for(y=0;y<H;Y++)
for(x=0;x<W;X++)
{
if(x%10==0)
printf("\n");
printf("0x%2x ",src[y*w+x]);
}
memset(name, 0, sizeof(name));
sprintf(name, "%s%04d.jpg", image_file, file_index++);
write_JPEG_file(name, optimization);
free(image_buffer);
} |
|