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.

Allocate buffer for VPIF capture/display driver in CMEM region

Hi..

I wonder whether it could allocate buffer for VPIF capture/display driver(/dev/video0, /dev/video2...) in CMEM region.

Do you happen to know this problem??

Thank you..

=================================================================================
  Demo source :  $DVSDK/PSP_01_30_00_082/example/dm646x/Source/saMmapLoopback.c +
                               $DSPLINK/gpp/src/samples/readwrite/readwrite.c + 
                               cmem source(cmem_1_10)
=================================================================================

 

 

  • The answer may depend on two parts

    1) Capture can be done with V4L2 linux driver which allows user space application to pass in buffers to be used.  Display side can be done with V4L2 or FBDev; in the FBDev case, drivers are pre-allocated during boot process normally from a special area near the beginning of Linux memory space.  Therefore, if FBDev is used, you could not use a CMEM buffer.

    2) If V4L2 is used, this may still be not be possible, as there is likely a virtual to physical memory translation when user space application passes buffers to V4L2 drivers; keep in mind that in the Linux model, user space does not have direct access to physical memory.  What complicates things further is that in order for CMEM buffer to have a virtual address, it needs to reside in Linux memory space (this is my understanding anyway).  From this point of view it would seem difficult or impossible to do, but maybe someone more familiar with CMEM and its capabilities can comment.

  • Hi.. I modified the loopback source($DVSDK/PSP_01_30_00_082/example/dm646x/Source/saMmapLoopback.c) for using CMEM region. But, I wonder whether it could allocate buffer for VPIF capture/display driver(/dev/video0, /dev/video2...) in CMEM region. Error is happened when I mapped memory(mmap) VPIF buffer in CMEM region.

    This is my example.

    =====================================

    [ video.c ]

    ........

    for(i = 0; i < 3; i++)
        captureBuf[i] = (Uint8 *)CMEM_alloc(SRC_WIDTH * SRC_HEIGHT * 2, NULL);

    // CMEM physical memory
    for(i = 0 ; i < 3; i++)
        dspAddr1[i] = CMEM_getPhys(captureBuf[i]);

    // open capture channel 0
    ret = initCapture(&capture_fd, &capture_numbuffers, outputname, stdname, &capture_fmt, dspAddr1);

    ........

     ------------------------------------------------------------------
    [ capture.c ]

     int initCapture(int *capture_fd, int *numbuffers, char *outputname, char *stdname, struct v4l2_format *fmt, int *cmem_addr) {
    .....
    for (i = 0; i < reqbuf.count; i++) {
      /* Query physical address of the buffers */
      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
      buf.index = i;
      buf.memory = V4L2_MEMORY_MMAP;
      ret = ioctl(*capture_fd, VIDIOC_QUERYBUF, &buf);
      if (ret < 0) {
        perror("VIDIOC_QUERYCAP\n");
        return -1;
       } 
       /* Mmap the buffers in application space */
      capture_buff_info[i].length = buf.length;
      capture_buff_info[i].index = i;
      capture_buff_info[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
                                                          //MAP_SHARED, *capture_fd, buf.m.offset);
                                                          MAP_SHARED, *capture_fd, cmem_addr[i]);  // I modified
      if (capture_buff_info[i].start == MAP_FAILED) {
        printf("Cannot mmap = %d buffer\n", i);
      return -1;
    }
    /* It is better to zero buffers */
    memset(capture_buff_info[i].start, 0x80, capture_buff_info[i].length);
    }

    ===================================================================================

    error message :

    Cannot mmap = 0 buffer
    Error in opening capture device for channel 0

    Execute phase failed. Status: [0xffffffff]

    ====================================================================================

  • My guess is that CMEM may be returning pointer to physical memory and initCapture may be expecting virtual memory.   I believe you can use CMEM_Register call to convert from physical to virtual according to http://wiki.davincidsp.com/index.php/CMEM_Overview

  • Juan Gonzales said:

    My guess is that CMEM may be returning pointer to physical memory and initCapture may be expecting virtual memory.   I believe you can use CMEM_Register call to convert from physical to virtual according to http://wiki.davincidsp.com/index.php/CMEM_Overview

    CMEM_alloc() returns a virtual address, and CMEM_getPhys() obtains the corresponding physical address, suitable to be used by a DSP or DMA or HW accelerator that doesn't go through an MMU.

    CMEM_registerAlloc() takes the physical address of an already-allocated buffer, registers its use with the CMEM kernel module, and creates a new virtual mapping.  It is intended to be used by a thread or process *other* than the one that did the original CMEM_alloc(), but could also be used by the same thread or process that did the original alloc.

    Regards,

    - Rob