Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 98e91bc877e03cf3582cd163550eb7e3 > files > 1095

kernel-doc-html-2.4.19-16mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>Reading The Video Image</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Video4Linux Programming"
HREF="book1.html"><LINK
REL="UP"
TITLE="Video Capture Devices"
HREF="c261.html"><LINK
REL="PREVIOUS"
TITLE="Interrupt Handling"
HREF="x316.html"><LINK
REL="NEXT"
TITLE="Video Ioctl Handling"
HREF="x334.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Video4Linux Programming</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x316.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Video Capture Devices</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x334.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="RDVID"
></A
>Reading The Video Image</H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#13;
static long camera_read(struct video_device *dev, char *buf,
                                unsigned long count)
{
        struct wait_queue wait = { current, NULL };
        u8 *ptr;
        int len;
        int i;

        add_wait_queue(&#38;capture_wait, &#38;wait);

        while(!capture_ready)
        {
                if(file-&#62;flags&#38;O_NDELAY)
                {
                        remove_wait_queue(&#38;capture_wait, &#38;wait);
                        current-&#62;state = TASK_RUNNING;
                        return -EWOULDBLOCK;
                }
                if(signal_pending(current))
                {
                        remove_wait_queue(&#38;capture_wait, &#38;wait);
                        current-&#62;state = TASK_RUNNING;
                        return -ERESTARTSYS;
                }
                schedule();
                current-&#62;state = TASK_INTERRUPTIBLE;
        }
        remove_wait_queue(&#38;capture_wait, &#38;wait);
        current-&#62;state = TASK_RUNNING;

  </PRE
></TD
></TR
></TABLE
><P
>        The first thing we have to do is to ensure that the application waits until
        the next frame is ready. The code here is almost identical to the mouse code
        we used earlier in this chapter. It is one of the common building blocks of
        Linux device driver code and probably one which you will find occurs in any
        drivers you write.
  </P
><P
>        We wait for a frame to be ready, or for a signal to interrupt our waiting. If a
        signal occurs we need to return from the system call so that the signal can
        be sent to the application itself. We also check to see if the user actually
        wanted to avoid waiting - ie  if they are using non-blocking I/O and have other things 
        to get on with.
  </P
><P
>        Next we copy the data from the card to the user application. This is rarely
        as easy as our example makes out. We will add capture_w, and capture_h here
        to hold the width and height of the captured image. We assume the card only
        supports 24bit RGB for now.
  </P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#13;

        capture_ready = 0;

        ptr=(u8 *)buf;
        len = capture_w * 3 * capture_h; /* 24bit RGB */

        if(len&#62;count)
                len=count;  /* Doesn't all fit */

        for(i=0; i&#60;len; i++)
        {
                put_user(inb(io+IMAGE_DATA), ptr);
                ptr++;
        }

        hardware_restart_capture();
                
        return i;
}

  </PRE
></TD
></TR
></TABLE
><P
>        For a real hardware device you would try to avoid the loop with put_user().
        Each call to put_user() has a time overhead checking whether the accesses to user
        space are allowed. It would be better to read a line into a temporary buffer
        then copy this to user space in one go.
  </P
><P
>        Having captured the image and put it into user space we can kick the card to
        get the next frame acquired.
  </P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x316.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="x334.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Interrupt Handling</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c261.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Video Ioctl Handling</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>