Beispiel #1
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  Priv       *p = (Priv*)o->chant_data;
  guchar     *capbuf;
  static gboolean inited = FALSE;

    if (!inited && o->fps != 0)
      {
        inited= TRUE;
        g_timeout_add (1000/o->fps, update, operation);
      }

  if (!p->active)
    return FALSE;

  v4lgrabf (p->vd);
  capbuf = v4lgetaddress (p->vd);
  v4lsyncf (p->vd);

  if (!capbuf)
    {
      g_warning ("no capbuf found");
      return FALSE;
    }

  if (p->decode)
    {
      guchar foobuf[o->width*o->height*3];
          /* XXX: foobuf is unneeded the conversions resets for every
           * scanline and could thus have been done in a line by line
           * manner an fed into the output buffer
           */
      gint y;
      for (y = 0; y < p->h; y++)
        {
          gint       x;

          guchar *dst = &foobuf[y*p->w*3];
          guchar *ysrc = (guchar *) (capbuf + (y) * (p->w) * 1);
          guchar *usrc = (guchar *) (capbuf + (p->w) * (p->h) + (y) / 2 * (p->w) / 2);
          guchar *vsrc = (guchar *) (capbuf + (p->w) * (p->h) + ((p->w) * (p->h)) / 4 + (y) / 2 * (p->w) / 2);

          for (x = 0; x < p->w; x++)
            {

              gint       R, G, B;

#ifndef byteclamp
#define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0)
#endif

#define YUV82RGB8(Y,U,V,R,G,B)do{\
                  R= ((Y<<15)                 + 37355*(V-128))>>15;\
                  G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\
                  B= ((Y<<15) +66454* (U-128)                )>>15;\
                  byteclamp(R);\
                  byteclamp(G);\
                  byteclamp(B);\
              }while(0)

      /* the format support for this code is not very good, but it
       * works for the devices I have tested with, conversion even
       * for chroma subsampled images is something we should let
       * babl handle.
       */
              YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B);
              dst[0] = B;
              dst[1] = G;
              dst[2] = R;

              dst += 3;
              ysrc++;
              if (x % 2)
                {
                  usrc++;
                  vsrc++;
                }
            }
        }
      gegl_buffer_set (output, NULL, NULL, foobuf, GEGL_AUTO_ROWSTRIDE);
    }
  else
    {
      gegl_buffer_set (output, NULL, NULL, capbuf, GEGL_AUTO_ROWSTRIDE);
    }
  return  TRUE;
}
Beispiel #2
0
static int read_frame(GeglOperation *operation, GeglBuffer *output)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  Priv *p= (Priv*)o->user_data;

	struct v4l2_buffer buf;
	unsigned int i;

	switch (p->io) {
	case IO_METHOD_READ:
		if (-1 == read(p->fd, p->buffers[0].start, p->buffers[0].length)) {
			switch (errno) {
			case EAGAIN:
				return 0;

			case EIO:
				/* Could ignore EIO, see spec. */

				/* fall through */

			default:
				errno_exit("read");
			}
		}

		//process_image(priv, p->buffers[0].start, p->buffers[0].length);
    gegl_buffer_set (output, NULL, 0, NULL, p->buffers[0].start, GEGL_AUTO_ROWSTRIDE);
		break;

	case IO_METHOD_MMAP:
		CLEAR(buf);

		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_MMAP;

		if (-1 == xioctl(p->fd, VIDIOC_DQBUF, &buf)) {
			switch (errno) {
			case EAGAIN:
				return 0;

			case EIO:
				/* Could ignore EIO, see spec. */

				/* fall through */

			default:
				errno_exit("VIDIOC_DQBUF");
			}
		}

		assert(buf.index < p->n_buffers);

		//process_image(priv, p->buffers[buf.index].start, buf.bytesused);
    //
    //
    {
      guchar *capbuf = p->buffers[buf.index].start;
      guchar foobuf[o->width*o->height*4];
          /* XXX: foobuf is unneeded the conversions resets for every
           * scanline and could thus have been done in a line by line
           * manner an fed into the output buffer
           */
      gint y;
      for (y = 0; y < p->h; y++)
        {
          gint       x;

          guchar *dst = &foobuf[y*p->w*4];
          guchar *ysrc = (guchar *) (capbuf + (y) * (p->w) * 2);

          guchar *usrc = ysrc + 3;
          guchar *vsrc = ysrc + 1;



          for (x = 0; x < p->w; x++)
            {

              gint       R, G, B;

#ifndef byteclamp
#define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0)
#endif

#define YUV82RGB8(Y,U,V,R,G,B)do{\
                  R= ((Y<<15)                 + 37355*(V-128))>>15;\
                  G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\
                  B= ((Y<<15) +66454* (U-128)                )>>15;\
                  byteclamp(R);\
                  byteclamp(G);\
                  byteclamp(B);\
              }while(0)

      /* the format support for this code is not very good, but it
       * works for the devices I have tested with, conversion even
       * for chroma subsampled images is something we should let
       * babl handle.
       */
              YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B);
#if 0
              dst[0] = *ysrc;
              dst[1] = *ysrc;
              dst[2] = *ysrc;
#else
              dst[0] = B;
              dst[1] = G;
              dst[2] = R;
              dst[3] = 255;
#endif

              dst  += 4;
              ysrc += 2;

              if (x % 2)
                {
                  usrc += 4;
                  vsrc += 4;
                }
            }
        }
    
    gegl_buffer_set (output, NULL, 0, NULL, foobuf,
        GEGL_AUTO_ROWSTRIDE);
    }

		if (-1 == xioctl(p->fd, VIDIOC_QBUF, &buf))
			errno_exit("VIDIOC_QBUF");
		break;

	case IO_METHOD_USERPTR:
		CLEAR(buf);

		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_USERPTR;

		if (-1 == xioctl(p->fd, VIDIOC_DQBUF, &buf)) {
			switch (errno) {
			case EAGAIN:
				return 0;

			case EIO:
				/* Could ignore EIO, see spec. */

				/* fall through */

			default:
				errno_exit("VIDIOC_DQBUF");
			}
		}

		for (i = 0; i < p->n_buffers; ++i)
			if (buf.m.userptr == (unsigned long)p->buffers[i].start
			    && buf.length == p->buffers[i].length)
				break;

		assert(i < p->n_buffers);

		//process_image(priv, (void *)buf.m.userptr, buf.bytesused);
    gegl_buffer_set (output, NULL, 0, NULL, (void*)buf.m.userptr, GEGL_AUTO_ROWSTRIDE);

		if (-1 == xioctl(p->fd, VIDIOC_QBUF, &buf))
			errno_exit("VIDIOC_QBUF");
		break;
	}

	return 1;
}