LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 709|回复: 6

请大家看下下面的video4linux的代码

[复制链接]
发表于 2004-6-10 09:25:10 | 显示全部楼层 |阅读模式
[php]
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/poll.h>

#include <linux/videodev.h>

#define FILENAME "/dev/video"

#define IOCTL(fd, req, addr )   ((-1==ioctl(fd,req,addr))?(perror(#req),exit(EXIT_FAILURE)):0)

int main(void)
  {
    int fd;
    struct v4l2_input input;
    struct v4l2_standard standard;
    struct v4l2_format  format;
    struct v4l2_framebuffer fb;
    v4l2_std_id std;
    int index;
    int one=1,zero=0;
    fd=open(FILENAME,O_RDWR);
    //query input
    for (index=0;index<4;index++)
       {  input.index = index;
          IOCTL(fd,VIDIOC_ENUMINPUT,&input);
          printf("the input 0 name :%s ,status is %d ,standard is %d \n",input.name,input.status,input.std);
        }
    //query video standard
    IOCTL(fd,VIDIOC_G_STD,&std);
    standard.index = 0;
    while (0 == ioctl(fd,VIDIOC_ENUMSTD,&standard))
       {   if (standard.id & std)
            printf("the current video standard :%s\n",standard.name);
            standard.index++;
       }
     //list vid std of current input
     input.index = 1;
     IOCTL(fd,VIDIOC_G_INPUT,&input.index);
     input.index = 1;
     IOCTL(fd,VIDIOC_ENUMINPUT,&input);

     printf("the current input is %s ,it supports :",input.name);
     standard.index = 0;
     while (0 == ioctl(fd,VIDIOC_ENUMSTD,&standard))
       {   if (standard.id & input.std)
           printf(" %s ",standard.name);
           standard.index++;
       }
      //set up overlay param and start overlay
       format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
       IOCTL(fd,VIDIOC_G_FMT,&format);
       IOCTL(fd,VIDIOC_G_FBUF,&fb);
       fb.flags = V4L2_FBUF_FLAG_PRIMARY;
       fb.fmt.width = 800;
       fb.fmt.height = 600;
       IOCTL(fd,VIDIOC_S_FBUF,&fb);
       IOCTL(fd,VIDIOC_OVERLAY,&one);
    close(fd);
   }
[/php]

大家试一下,这段代码可以实现framebuffer下的overlay显示吗?
我用的是bt848的芯片,osprey的视频采集卡。
大家先把fb设为800x600,32位色。
 楼主| 发表于 2004-6-10 13:22:00 | 显示全部楼层
我作了一些改动,现在的程序可以成功的运行在framebuffer环境下了。
但是奇怪的是:
刚开始在控制台模式1024x768,32位色深,使用v4l-info无法获取FBUF信息。
之后,启动X,v4l-info仍无法获取FBUF信息。运行xawtv之后,再关闭之。v4l-info正常。
关闭X,在控制台模式下运行我的程序,一切正常了。
以下是我的程序代码,我自己的,随便大家改动、复制与使用,只希望大家可以互相交流经验,建议有视频采集卡的朋友试一下。
大家看看这是因为什么,讨论一下。
[php]
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/poll.h>

#include <linux/videodev.h>

#define FILENAME "/dev/video"

#define IOCTL(fd, req, addr )   ((-1==ioctl(fd,req,addr))?(perror(#req),exit(EXIT_FAILURE)):0)

int main(void)
  {
    int fd;
    struct v4l2_input input;
    struct v4l2_standard standard;
    struct v4l2_format  format;
    struct v4l2_framebuffer fb;
    v4l2_std_id std;
    int index;
    int one=1,zero=0;
    fd=open(FILENAME,O_RDWR);
    index = 1;
    IOCTL(fd,VIDIOC_S_INPUT,&index);
      
   //query video standard
    IOCTL(fd,VIDIOC_G_STD,&std);
    standard.index = 0;
    while (0 == ioctl(fd,VIDIOC_ENUMSTD,&standard))
       {   if (standard.id & std)
            printf("the current video standard :%s\n",standard.name);
            standard.index++;
       }
        
      //set up overlay param and start overlay
       format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
       IOCTL(fd,VIDIOC_G_FMT,&format);
       format.fmt.win.w.width = 768 ;
       format.fmt.win.w.height =576 ;
       format.fmt.win.w.top = 0;
       format.fmt.win.w.left = 0;
       format.fmt.win.field = V4L2_FIELD_INTERLACED;
       IOCTL(fd,VIDIOC_S_FMT,&format);
       IOCTL(fd,VIDIOC_G_FBUF,&fb);
       fb.flags = V4L2_FBUF_FLAG_PRIMARY;
       fb.fmt.width = 800;
       fb.fmt.height = 600;
       IOCTL(fd,VIDIOC_S_FBUF,&fb);
       IOCTL(fd,VIDIOC_OVERLAY,&one);
       while(1)
          {  }
       IOCTL(fd,VIDIOC_OVERLAY,&zero);
       close(fd);
       return(0);
   }
[/php]
发表于 2004-6-10 19:08:25 | 显示全部楼层
我的linux内核不支持framebuffer,没法试验你的程序,wuwu~~!
btw:请楼主下次发贴时注意保持缩进。
 楼主| 发表于 2004-6-11 09:05:31 | 显示全部楼层
版主想办法整一个fb吧,这玩意挺有意思的。
另外的一点说明:
我的framebuffer是matroxfb直接编译到内核中的。
lilo传递的参数是“video=matroxfb:vesa:0x118”
我的内核是2.6.5的。
bttv驱动是0.9.12。
采用video for linux 第二版的API。纯正的,不需要添加另外的库。
 楼主| 发表于 2004-6-11 09:06:51 | 显示全部楼层
版主把我的程序整理得很好看,多谢多谢。
发表于 2004-6-11 16:02:47 | 显示全部楼层
最初由 realtang 发表
版主想办法整一个fb吧,这玩意挺有意思的。
另外的一点说明:
我的framebuffer是matroxfb直接编译到内核中的。
lilo传递的参数是“video=matroxfb:vesa:0x118”
我的内核是2.6.5的。
bttv驱动是0.9.12。
采用video for linux 第二版的API。纯正的,不需要添加另外的库。

谢谢兄弟好意,我曾经折腾过内核的bootsplash,我知道这种在控制台下用的玩意儿很有意思,只是现在没有时间,什么时候有空了,在gentoo下再试验试验。
发表于 2004-7-18 20:46:24 | 显示全部楼层
怎么编译呀
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表