0

I'm currently trying to read video from a MJPEG UVC webcam using C++. Using this tutorial, I'm able to retrieve a JPEG image and to save it on disk. Now, I try to use the JPEG image data without writing it on disk ; I want to use a C++ vector to store it, but I can't find how to achieve that .

As far as I understand, the tutorial maps a memory segment that v4l2 uses to store webcam data in memory :

struct v4l2_buffer bufferinfo;
memset(&bufferinfo, 0, sizeof(bufferinfo));

bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo.memory = V4L2_MEMORY_MMAP;
bufferinfo.index = 0;

if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0){
    perror("VIDIOC_QUERYBUF");
    exit(1);
}

void* buffer_start = mmap(
    NULL,
    bufferinfo.length,
    PROT_READ | PROT_WRITE,
    MAP_SHARED,
    fd,
    bufferinfo.m.offset
);

This memory segment is populated by v4l2 when we send some command :

if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0){
    perror("VIDIOC_QBUF");
    exit(1);
}

// The buffer's waiting in the outgoing queue.
if(ioctl(fd, VIDIOC_DQBUF, &bufferinfo) < 0){
    perror("VIDIOC_QBUF");
    exit(1);
}

To finish, the memory is written to the disk using write function :

int jpgfile;
if((jpgfile = open("/tmp/myimage.jpeg", O_WRONLY | O_CREAT, 0660)) < 0){
    perror("open");
    exit(1);
}
write(jpgfile, buffer_start, bufferinfo.length);
close(jpgfile);

But how can I copy this memory segment into a vector ?

Thank you in advance.

Damien Picard
  • 381
  • 4
  • 12

1 Answers1

0

You can reinterpret the void * as a char * to obtain the raw data:

char *char_buffer = reinterpret_cast<char *>(buffer_start);

std::vector<char> jpegdata{char_buffer, char_buffer + bufferinfo.length};

(This uses the "iterator pair" overload of the vector constructor.)

You might consider using std::string instead:

std::string jpegdata{reinterpret_cast<char *>(buffer_start), bufferinfo.length};

(The std::string approach may wind up being faster; the constructor will likely memcpy() or use some other blitting technique to copy data more efficiently than the iterator-based vector template constructor.)

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • Thank you ! It works fine ! But I can't use the string version because I use jpeg data with OpenCV Mat structure, which only has a constructor from vector. – Damien Picard Apr 07 '17 at 18:39
  • Shame. I'm a bit surprised there isn't a template constructor that would work with any container that contains chars. – cdhowie Apr 08 '17 at 17:58