This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

dm6446: previewer - segmentation fault


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(&params, 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, &params);

    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, &params);
        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

  • Hello Everybody,

    i could store the dark frame data in the mmap'd buffer without any segmentation fault (the input parameters were improper by mistake which was creating this segmentation fault).

    Now I could store the dark frame data into the buffer and the address is also updated properly in DSDR_ADDR register, but the dark frame correction is not happening properly.

    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?

    I would also like to check DARK_FAIL bit in PCR register to check whether there is no read error (as reported in section 4.5 of vpfe user guide) but its bit position is not mentioned in the PCR register description (section 6.2.2). what is the bit position of DARK_FAIL in the PCR register?

    Any suggestions to resolve this issue are greatly appreciated.

    --

    Best Regards

    S Arun