Ignore:
Timestamp:
10/02/19 16:06:31 (5 years ago)
Author:
Sanahuja Guillaume
Message:

use V4L2_MEMORY_USERPTR

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/sanscv/lib/FlairSensorActuator/src/V4LCamera.cpp

    r328 r335  
    6262        Thread::Err("device is unable to capture video memory.\n");
    6363    }
    64   /* 
    65    * unnecessary?
    66     struct video_capability capability;
    67     memset(&capability, 0, sizeof (video_capability));
    68     capability.type = cap.capabilities;
    69      
    70     // Query channels number
    71     if (xioctl(device, VIDIOC_G_INPUT, &capability.channels)==-1) {
    72         Thread::Err("VIDIOC_G_INPUT xioctl\n");
    73     }
    74     */
     64
    7565    //get v4l2_format
    7666    struct v4l2_format form;
     
    10595        QueueBuffer(bufferIndex);
    10696    }
    107    
    108     //alloc img buf
    109     Printf("TODO: alloc bufs in cmem and uses it for v4l\n");
    110     output->buffer=AllocFunction(width*height*2);
    11197   
    11298    // enable the streaming
     
    138124
    139125V4LCamera::~V4LCamera() {
    140     FreeFunction(output->buffer);
     126    for (int n_buffers = 0; n_buffers < nbBuffers; n_buffers++) {
     127       FreeFunction((char*)buffers[n_buffers].start);
     128   }
    141129    SafeStop();
    142130    Join();
     
    220208      hasProblems=true;
    221209    }
    222 //Printf("todo allocate 1 frame and copy here\n");
     210
    223211    output->GetMutex();
    224     memcpy(output->buffer,buffers[bufferIndex].start,buffers[bufferIndex].length);
     212    output->buffer=(char*)buffers[bufferIndex].start;
    225213    output->ReleaseMutex();
    226214
     
    239227        memset(&buf, 0, sizeof (v4l2_buffer));
    240228        buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    241         buf.memory      = V4L2_MEMORY_MMAP;
     229        buf.memory      = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
    242230        buf.index       = (unsigned long)index;
    243 
    244         if (xioctl (device, VIDIOC_QBUF, &buf)==-1) {
    245             Thread::Err("VIDIOC_QBUF xioctl\n");
     231        buf.m.userptr=(unsigned long)(buffers[index].start);
     232        buf.length=buffers[index].length;
     233       
     234        int ret=xioctl (device, VIDIOC_QBUF, &buf);
     235        if (ret==-1) {
     236            Thread::Err("VIDIOC_QBUF xioctl %s\n",strerror(-ret));
    246237            return -1;
    247238        }
     
    261252    tv.tv_sec = 0;
    262253    tv.tv_usec = 100000;
    263 //Printf("%lld\n",GetTimeMS());
     254
    264255    int r = select (device+1, &fds, NULL, NULL, &tv);
    265 //Printf("%lld select ok\n",GetTimeMS());
     256
    266257    if (-1 == r) {
    267258        char errorMsg[256];
     
    278269    memset(&buf, 0, sizeof (v4l2_buffer));
    279270    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    280     buf.memory = V4L2_MEMORY_MMAP;
     271    buf.memory = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
    281272
    282273    //get last captured image
    283274    int prevDQbuf=-1;
    284275    for(int i=0;i<4;i++) {
    285         //Printf("%lld ioctl\n",GetTimeMS());
    286276        if (xioctl (device, VIDIOC_DQBUF, &buf)==-1) {
    287             //Printf("iter %i err %i\n",i,errno);
    288277            if (errno==EAGAIN) {
    289                 //Printf("exit buf %i\n",buf.index);
    290278                break;
    291279            } else {
     
    294282            }
    295283       } else {
    296            //Printf("buf %i\n",buf.index);
    297284           if(prevDQbuf!=-1) {
    298285               QueueBuffer(prevDQbuf);
    299                //Printf("queued %i\n",prevDQbuf);
    300286           }
    301            prevDQbuf=buf.index;
     287           for (int n_buffers = 0; n_buffers < nbBuffers; n_buffers++) {
     288               if((void*)(buf.m.userptr)==buffers[n_buffers].start) {
     289                   prevDQbuf=n_buffers;
     290                   bufferIndex=n_buffers;
     291                   break;
     292               }
     293           }
    302294       }
    303        //Printf("%lld ioctl ok\n",GetTimeMS());
    304     }
    305 
    306    if(buf.index >= nbBuffers) {
    307      Thread::Err("buf.index >= nbBuffers\n");
    308      return -1;
    309    }
     295    }
    310296   
    311     bufferIndex=buf.index;
    312  
    313297   return 1;
    314298}
     
    324308   requestbuffers.count = buffer_number;
    325309   requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    326    requestbuffers.memory = V4L2_MEMORY_MMAP;
     310   requestbuffers.memory = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
    327311
    328312   if (xioctl (device, VIDIOC_REQBUFS, &requestbuffers)==-1) {
    329        if (EINVAL == errno) {
    330          Thread::Err("memory mapping not supported\n");
     313       if (errno==EINVAL) {
     314         Thread::Err("VIDIOC_REQBUFS user memory not supported\n");
    331315       } else {
    332316         Thread::Err ("VIDIOC_REQBUFS xioctl\n");
     
    334318       return -1;
    335319   }
    336 
    337    if (requestbuffers.count < buffer_number) {
    338        if (buffer_number == 1) {
    339         Thread::Err("Insufficient buffer memory\n");
    340         return -1;
    341        } else {
    342         buffer_number--;
    343         Thread::Warn ("Insufficient buffer memory, decreasing buffers\n");
    344         goto try_again;
    345        }
     320   
     321   nbBuffers=DEFAULT_V4L_BUFFERS;
     322   for (int n_buffers = 0; n_buffers < nbBuffers; n_buffers++) {
     323       buffers[n_buffers].length = output->GetDataType().GetSize();
     324       buffers[n_buffers].start =AllocFunction(output->GetDataType().GetSize());
    346325   }
    347326
    348    for (int n_buffers = 0; n_buffers < requestbuffers.count; ++n_buffers) {
    349        struct v4l2_buffer buf;
    350 
    351        memset(&buf, 0, sizeof (v4l2_buffer));
    352 
    353        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    354        buf.memory = V4L2_MEMORY_MMAP;
    355        buf.index = n_buffers;
    356 
    357        if (xioctl (device, VIDIOC_QUERYBUF, &buf)==-1) {
    358            Thread::Err("VIDIOC_QUERYBUF xioctl\n");
    359            return -1;
    360        }
    361 
    362        buffers[n_buffers].length = buf.length;
    363        buffers[n_buffers].start =
    364          mmap (NULL /* start anywhere */,
    365                buf.length,
    366                PROT_READ | PROT_WRITE /* required */,
    367                MAP_SHARED /* recommended */,
    368                device, buf.m.offset);
    369 //Printf("buffer %i start %x length %i\n",n_buffers,buffers[n_buffers].start,buffers[n_buffers].length);
    370        if (MAP_FAILED == buffers[n_buffers].start) {
    371            Thread::Err("mmap\n");
    372            return -1;
    373        }
    374    }
    375    nbBuffers=requestbuffers.count;
    376 //Printf("allocated %i buffers\n",nbBuffers);
    377327   return 1;
    378328};
Note: See TracChangeset for help on using the changeset viewer.