⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videobook.tmpl

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 TMPL
📖 第 1 页 / 共 5 页
字号:
  </para>  <para>        Our depth is 24, as this is in bits. We will be returning RGB24 format. This        has one byte of red, then one of green, then one of blue. This then repeats        for every other pixel in the image. The other common formats the interface         defines are  </para>   <table frame=all><title>Framebuffer Encodings</title>   <tgroup cols=2 align=left>   <tbody>   <row>   <entry>GREY</><entry>Linear greyscale. This is for simple cameras and the                        like</>   </row><row>   <entry>RGB565</><entry>The top 5 bits hold 32 red levels, the next six bits                         hold green and the low 5 bits hold blue. </>   </row><row>   <entry>RGB555</><entry>The top bit is clear. The red green and blue levels                        each occupy five bits.</>    </row>    </tbody>    </tgroup>    </table>  <para>        Additional modes are support for YUV capture formats. These are common for        TV and video conferencing applications.  </para>  <para>        The VIDIOCSPICT ioctl allows a user to set some of the picture parameters.        Exactly which ones are supported depends heavily on the card itself. It is        possible to support many modes and effects in software. In general doing        this in the kernel is a bad idea. Video capture is a performance-sensitive        application and the programs can often do better if they aren't being        'helped' by an overkeen driver writer. Thus for our device we will report        RGB24 only and refuse to allow a change.  </para>  <programlisting>                case VIDIOCSPICT:                {                        struct video_picture v;                        if(copy_from_user(&amp;v, arg, sizeof(v)))                                return -EFAULT;                        if(v.depth!=24 ||                            v.palette != VIDEO_PALETTE_RGB24)                                return -EINVAL;                        set_hardware_brightness(v.brightness);                        set_hardware_hue(v.hue);                        set_hardware_saturation(v.colour);                        set_hardware_brightness(v.contrast);                        return 0;                }  </programlisting>  <para>        We check the user has not tried to change the palette or the depth. We do        not want to carry out some of the changes and then return an error. This may        confuse the application which will be assuming no change occurred.  </para>  <para>        In much the same way as you need to be able to set the picture controls to        get the right capture images, many cards need to know what they are        displaying onto when generating overlay output. In some cases getting this        wrong even makes a nasty mess or may crash the computer. For that reason        the VIDIOCSBUF ioctl used to set up the frame buffer information may well        only be usable by root.  </para>  <para>        We will assume our card is one of the old ISA devices with feature connector        and only supports a couple of standard video modes. Very common for older        cards although the PCI devices are way smarter than this.  </para>  <programlisting>static struct video_buffer capture_fb;                case VIDIOCGFBUF:                {                        if(copy_to_user(arg, &amp;capture_fb,                              sizeof(capture_fb)))                                return -EFAULT;                        return 0;                                        }  </programlisting>  <para>        We keep the frame buffer information in the format the ioctl uses. This        makes it nice and easy to work with in the ioctl calls.  </para>  <programlisting>                case VIDIOCSFBUF:                {                        struct video_buffer v;                        if(!capable(CAP_SYS_ADMIN))                                return -EPERM;                        if(copy_from_user(&amp;v, arg, sizeof(v)))                                return -EFAULT;                        if(v.width!=320 &amp;&amp; v.width!=640)                                return -EINVAL;                        if(v.height!=200 &amp;&amp; v.height!=240                                 &amp;&amp; v.height!=400                                &amp;&amp; v.height !=480)                                return -EINVAL;                        memcpy(&amp;capture_fb, &amp;v, sizeof(v));                        hardware_set_fb(&amp;v);                        return 0;                }  </programlisting>  <para>        The capable() function checks a user has the required capability. The Linux        operating system has a set of about 30 capabilities indicating privileged        access to services. The default set up gives the superuser (uid 0) all of        them and nobody else has any.  </para>  <para>        We check that the user has the SYS_ADMIN capability, that is they are        allowed to operate as the machine administrator. We don't want anyone but        the administrator making a mess of the display.  </para>  <para>        Next we check for standard PC video modes (320 or 640 wide with either        EGA or VGA depths). If the mode is not a standard video mode we reject it as        not supported by our card. If the mode is acceptable we save it so that        VIDIOCFBUF will give the right answer next time it is called.  The        hardware_set_fb() function is some undescribed card specific function to        program the card for the desired mode.  </para>  <para>        Before the driver can display an overlay window it needs to know where the        window should be placed, and also how large it should be. If the card        supports clipping it needs to know which rectangles to omit from the        display. The video_window structure is used to describe the way the image         should be displayed.    </para>   <table frame=all><title>struct video_window fields</title>   <tgroup cols=2 align=left>   <tbody>   <row>        <entry>width</><entry>The width in pixels of the desired image. The card                        may use a smaller size if this size is not available</>	</row><row>        <entry>height</><entry>The height of the image. The card may use a smaller                        size if this size is not available.</>	</row><row>        <entry>x</><entry>   The X position of the top left of the window. This                        is in pixels relative to the left hand edge of the                        picture. Not all cards can display images aligned on                        any pixel boundary. If the position is unsuitable                        the card adjusts the image right and reduces the                        width.</>	</row><row>        <entry>y</><entry>   The Y position of the top left of the window. This                        is counted in pixels relative to the top edge of the                        picture. As with the width if the card cannot                        display  starting on this line it will adjust the                        values.</>	</row><row>        <entry>chromakey</><entry>The colour (expressed in RGB32 format) for the                        chromakey colour if chroma keying is being used. </>	</row><row>        <entry>clips</><entry>An array of rectangles that must not be drawn			over.</>	</row><row>        <entry>clipcount</><entry>The number of clips in this array.</>    </row>    </tbody>    </tgroup>    </table>    <para>        Each clip is a struct video_clip which has the following fields   </para>   <table frame=all><title>video_clip fields</title>   <tgroup cols=2 align=left>   <tbody>   <row>        <entry>x, y</><entry>Co-ordinates relative to the display</>	</row><row>        <entry>width, height</><entry>Width and height in pixels</>	</row><row>        <entry>next</><entry>A spare field for the application to use</>    </row>    </tbody>    </tgroup>    </table>    <para>        The driver is required to ensure it always draws in the area requested or a        smaller area, and that it never draws in any of the areas that are clipped.        This may well mean it has to leave alone. small areas the application wished to be        drawn.  </para>  <para>        Our example card uses chromakey so does not have to address most of the        clipping.  We will add a video_window structure to our global variables to        remember our parameters, as we did with the frame buffer.  </para>  <programlisting>                case VIDIOCGWIN:                {                        if(copy_to_user(arg, &amp;capture_win,                             sizeof(capture_win)))                                return -EFAULT;                        return 0;                }                case VIDIOCSWIN:                {                        struct video_window v;                        if(copy_from_user(&amp;v, arg, sizeof(v)))                                return -EFAULT;                        if(v.width > 640 || v.height > 480)                                return -EINVAL;                        if(v.width < 16 || v.height < 16)                                return -EINVAL;                        hardware_set_key(v.chromakey);                        hardware_set_window(v);                        memcpy(&amp;capture_win, &amp;v, sizeof(v));                        capture_w = v.width;                        capture_h = v.height;                        return 0;                }  </programlisting>  <para>        Because we are using Chromakey our setup is fairly simple. Mostly we have to        check the values are sane and load them into the capture card.  </para>  <para>        With all the setup done we can now turn on the actual capture/overlay. This        is done with the VIDIOCCAPTURE ioctl. This takes a single integer argument        where 0 is on and 1 is off.  </para>  <programlisting>                case VIDIOCCAPTURE:                {                        int v;                        if(get_user(v, (int *)arg))                                return -EFAULT;                        if(v==0)                                hardware_capture_off();                        else                        {                                if(capture_fb.width == 0                                     || capture_w == 0)                                        return -EINVAL;                                hardware_capture_on();                        }                        return 0;                }  </programlisting>  <para>        We grab the flag from user space and either enable or disable according to        its value. There is one small corner case we have to consider here. Suppose        that the capture was requested before the video window or the frame buffer        had been set up. In those cases there will be unconfigured fields in our        card data, as well as unconfigured hardware settings. We check for this case and        return an error if the frame buffer or the capture window width is zero.  </para>  <programlisting>                default:                        return -ENOIOCTLCMD;        }}  </programlisting>  <para>        We don't need to support any other ioctls, so if we get this far, it is time        to tell the video layer that we don't now what the user is talking about.  </para>  </sect1>  <sect1 id="endvid">  <title>Other Functionality</title>  <para>        The Video4Linux layer supports additional features, including a high        performance mmap() based capture mode and capturing part of the image.         These features are out of the scope of the book.  You should however have enough         example code to implement most simple video4linux devices for radio and TV        cards.  </para>  </sect1>  </chapter>  <chapter id="bugs">     <title>Known Bugs And Assumptions</title>  <para>  <variablelist>    <varlistentry><term>Multiple Opens</term>    <listitem>    <para>        The driver assumes multiple opens should not be allowed. A driver        can work around this but not cleanly.    </para>    </listitem></varlistentry>    <varlistentry><term>API Deficiencies</term>    <listitem>    <para>        The existing API poorly reflects compression capable devices. There        are plans afoot to merge V4L, V4L2 and some other ideas into a        better interface.    </para>    </listitem></varlistentry>  </variablelist>  </para>  </chapter>  <chapter id="pubfunctions">     <title>Public Functions Provided</title>!Edrivers/media/video/videodev.c  </chapter></book>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -