Hello Everybody,
This is regarding the previewer (dark frame subtraction) of dm6446.
As per VPFE user guide we need to store dark frame data into the sdram first, then if the address is supplied to previewer it fetches the dark frame data and performs dark frame subtraction.
To store this data into the sdram, i am requesting a input buffer from previewer, mmap it to application and then trying to store the dark frame data, but I receive a "Segmentation fault" while storing the dark data in the mmap'd buffer.
the previewer initialization and DoPreview functions are shown below (taken from the examples/ directory and modified):
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define MAX_WIDTH (1280 + HCROP)
#define WIDTH 640
#define HEIGHT 480
struct prev_params params;
struct prev_buffer t_buff;
static int prevfd = -1;
void InitPreviewer(int width, int height, struct buffer* prevbuffer, struct buffer* darkbuffer)
{
struct prev_reqbufs reqbufs;
int ret,i,j;
int prev_width;
prev_width = width > MAX_WIDTH ? MAX_WIDTH : width;
/* open the Preview Engine driver */
prevfd = open("/dev/davinci_previewer", O_RDWR);
if(prevfd < 0)
{
printf("\nError opening device");
exit(0);
}
memset(¶ms, 0 , sizeof(params));
params.features = PREV_CFA | PREV_GAMMA | PREV_DARK_FRAME_SUBTRACT;
/* set the input size, pitch and output pitch */
params.size_params.hsize = prev_width;
params.size_params.hstart = 0;
params.size_params.vstart = 0;
params.size_params.vsize = height;
params.size_params.pixsize = PREV_INWIDTH_10BIT;
params.size_params.in_pitch = (width * 2 + 31) & (~31);
params.size_params.out_pitch = ((width - HCROP) * 2 + 31) & (~31);
params.brightness = 0x0;
params.contrast = 0x10;
/* no down sampling */
params.sample_rate = 1;
/* pixel order */
params.pix_fmt = PREV_PIXORDER_CBYCRY;
/* remaining parameters, tables initialization code is removed for simplicity */
/* this section requests a buffer and loads dark frame data from dark.raw into the buffer */
#if 1
/* request one input buffer to store dark frame data */
reqbufs.buf_type= PREV_BUF_IN;
reqbufs.size = height * ((width + 31) & (~31)) * 2;
reqbufs.count = 1;
ret = ioctl(prevfd, PREV_REQBUF, &reqbufs);
if(ret < 0) {
printf("\ncannot get the requested buffer for dark frame data\n");
//goto out;
exit(0);
}
t_buff.index = 0; // buffer allocated by previewer
t_buff.buf_type = PREV_BUF_IN;
/* get the physical address of the buffer */
ret =ioctl(prevfd, PREV_QUERYBUF, &t_buff);
if(ret < 0 )
{
printf("\ncannot get out buffer address");
//goto out;
exit(0);
}
darkbuffer->length = t_buff.size;
darkbuffer->start = mmap(NULL, t_buff.size, PROT_READ|PROT_WRITE, MAP_SHARED, prevfd, t_buff.offset);
darkbuffer->offset = t_buff.offset;
if(darkbuffer->start == MAP_FAILED)
{
printf("\ncannot mmap buffer");
//goto out;
exit(0);
}
FILE *fdark = NULL;
fdark = fopen("dark.raw", "rb");
if (!fdark)
{
printf("Dark frame not available, exiting...");
exit(0);
}
/* populate the buffer with dark frame data */
unsigned short val = 0;
unsigned int width_offset = 0;
for (i=0; i<HEIGHT; ++i)
{
width_offset = i*WIDTH;
for (j=0; j<WIDTH; ++j)
{
fread(&val,sizeof(short int), 1, fdark);
val = val >> 6; /* because only the higher 10-bits corresponds to dark image data */
*((unsigned short int *)darkbuffer->start + width_offset + j)
= (unsigned char)val; /* when darkbuffer->start is dereferenced, it gives Segmentation fault */
}
}
/* update address from where dark frame data need to be fetched */
params.dark_frame_addr = (int *)darkbuffer->offset;
#endif
ret = ioctl(prevfd, PREV_SET_PARAM, ¶ms);
int exp = 0x100;
ret = ioctl(prevfd, PREV_SET_EXP, &exp);
if(ret < 0)
{
printf("\n error in setting parameters");
exit(0);
}
reqbufs.buf_type= PREV_BUF_OUT;
reqbufs.size = height * ((width + 31) & (~31)) * 2;
reqbufs.count = 1;
ret = ioctl(prevfd, PREV_REQBUF, &reqbufs);
if(ret < 0)
{
printf("\ncannot get the requested buffer");
//goto out;
exit(0);
}
t_buff.index = 0;
t_buff.buf_type = PREV_BUF_OUT;
ret =ioctl(prevfd, PREV_QUERYBUF, &t_buff);
if(ret < 0 )
{
printf("\ncannot get out buffer address");
//goto out;
exit(0);
}
prevbuffer->length = t_buff.size;
prevbuffer->start = mmap(NULL, t_buff.size, PROT_READ|PROT_WRITE, MAP_SHARED, prevfd, t_buff.offset);
prevbuffer->offset = t_buff.offset;
if(prevbuffer->start == MAP_FAILED)
{
printf("\ncannot mmap buffer");
//goto out;
exit(0);
}
}
void DoPreview(int width, int height, int offset)
{
struct prev_convert convert;
int ret;
/* Pass capture buffer directly to previewer */
convert.in_buff.index = -1;
convert.in_buff.offset = offset;
convert.in_buff.size = width * height * 2;
convert.out_buff.index = -1;
convert.out_buff.offset = t_buff.offset;
convert.out_buff.size = width * height * 2;
do{
/* Start previewing */
params.size_params.hsize = width > MAX_WIDTH ? MAX_WIDTH : width;
ret = ioctl(prevfd, PREV_SET_PARAM, ¶ms);
ret = ioctl(prevfd, PREV_PREVIEW, &convert);
if (ret < 0) {
printf("DoPreview: Cannot convert -------\n");
exit(0);
}
convert.in_buff.offset += (MAX_WIDTH - HCROP) * 2;
convert.out_buff.offset += (MAX_WIDTH - HCROP) * 2;
width -= (MAX_WIDTH - HCROP);
}while(width > HCROP);
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
what could be the reason for getting the 'Segmentation fault' when pointer returned by mmap() is deferenced? any ideas on how to resolve this?
Is this the correct way of providing the dark frame data to the previewer? if not what is the correct procedure? please suggest the changes required.
Has anyone successfully performed dark frame subtraction on dm6446? how to get it work properly?
--
Best Regards
S Arun