I have a working V4L2 implementation that captures images from a connected video device. Until now this worked well with all cameras I tried:
bidx=read_frame(data);
if (bidx>-1)
{
if (data->pixelformat==V4L2_PIX_FMT_YUYV) yuv422_to_rgb24(data,(unsigned char*)data->buffers[bidx].start);
else if (data->pixelformat==V4L2_PIX_FMT_YUV422P) yuv422p_to_rgb24(data,(unsigned char*)data->buffers[bidx].start);
else
{
printf("Error: unsupported pixel format 0x%X\n",data->pixelformat);
assert(0);
V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_YUV422P signalise the data in the buffer are single images which can be processed each separately just by using the contents of the returned buffer. This is exactly what I want to do.
Now I found that one device returns the data as MJPG (may be this has happened by a update of the Linux kernel?) and therefore jumps into the error-branch of the code above.
Now my question is: how can I get single images out of these MJPG-data?
To clarify that: I want to do that fully programmatically, calls to the command line to use some external applications are NOT a solution for me.
Thanks!
Update: the V4L-stuff can be found in the read_frame()-function:
int read_frame(struct instData *data)
{
struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl (data->fd, VIDIOC_DQBUF, &buf))
{
switch (errno)
{
case EAGAIN:
return -1;
case EIO:
/* Could ignore EIO, see spec. */
/* fall through */
default:
return -1;
}
}
xioctl (data->fd, VIDIOC_QBUF, &buf);
return buf.index;
}
Finally I found the answer: MJPEG can be decoded by using libjpeg, the code itself can be found at How to decode an MJPEG to raw RGB (or YUV) data