V4L2: grab single images out of a MJPEG stream?

80 Views Asked by At

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;
}
1

There are 1 best solutions below

0
Elmi On

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