Chinaunix首页 | 论坛 | 博客
  • 博客访问: 547701
  • 博文数量: 119
  • 博客积分: 3391
  • 博客等级: 中校
  • 技术积分: 981
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-12 11:49
文章分类

全部博文(119)

文章存档

2014年(3)

2013年(1)

2011年(18)

2010年(27)

2009年(70)

我的朋友

分类: LINUX

2009-03-13 13:31:44

大家看下我写的实现streamio方式捕获视频桢的程序。
大家互相交流下经验。
有没有谁做过overlay和capture同时进行的程序呀?
希望可以抛砖引玉。
代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

#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_capability cap;
    v4l2_std_id std;
    struct v4l2_format format;
    struct v4l2_requestbuffers reqbuf;
    struct {
            void * start;
            size_t length;
    } * buffers;
    struct v4l2_buffer buffer;
    unsigned int i,x,y,index;
    unsigned char *data,*ptr;
    FILE *pgm ;
        //open device file
        fd = open(FILENAME,O_RDWR);
        //query the device's ability
        IOCTL(fd, VIDIOC_QUERYCAP, &cap);
        //if device can support capture and streamio
        if ( (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)&&(cap.capabilities & V4L2_CAP_STREAMING)) {
            //set the current input is composite 1
            index = 1;
            IOCTL(fd,VIDIOC_S_INPUT,&index);
            //query the current video std whether PAL
            IOCTL(fd,VIDIOC_G_STD,&std);
            //if the current video std is PAL
                if ( std & V4L2_STD_PAL)  {
                  //negotiate the image format
                  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                  IOCTL(fd,VIDIOC_G_FMT,&format);
                  //printf("the current pixelformat is %x \n",format.fmt.pix.pixelformat);
                  format.fmt.pix.width = 384;
                  format.fmt.pix.height = 288;
                  format.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
                  format.fmt.pix.field = V4L2_FIELD_TOP;
                  format.fmt.pix.bytesperline = 384*3;
                  format.fmt.pix.sizeimage = 384*288*3;
                  format.fmt.pix.colorspace =V4L2_COLORSPACE_SRGB;//SMPTE170M;
                  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                  IOCTL(fd,VIDIOC_S_FMT,&format);
                  printf("change the  current pixelformat is %c%c%c%c\n",(format.fmt.pix.pixelformat & 0x000000FF) ,((format.fmt.pix.pixelformat & 0x0000FF00)>>8),
                                                    ((format.fmt.pix.pixelformat & 0x00FF0000)>>16), ((format.fmt.pix.pixelformat & 0xFF000000)>>24) );
                  // negotiate the request buffer
                  reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                  reqbuf.memory = V4L2_MEMORY_MMAP;
                  reqbuf.count = 2;
                  //init the device memory
                  IOCTL(fd,VIDIOC_REQBUFS,&reqbuf );
                    //if init fails
                    if (reqbuf.count < 2) {
                        printf ("Not enough buffer memory\n");
                        exit (EXIT_FAILURE);
                    }
                  buffers = calloc (reqbuf.count,sizeof(*buffers));//later clean the buffers can use
                // assert(buffers != NULL);
                    //map the device memory to application memory
                    for (i=0;i
                        buffer.type = reqbuf.type;
                        buffer.index =i ;
                        //query the status of one buffer
                        IOCTL(fd,VIDIOC_QUERYBUF,&buffer);
                        buffers[i].length = buffer.length;
                        buffers[i].start = mmap (NULL,buffer.length,
                                              PROT_READ | PROT_WRITE,
                                              MAP_SHARED,
                                              fd,buffer.m.offset);
                        if (buffers[i].start == MAP_FAILED) {
                            perror ("mmap");
                            exit(EXIT_FAILURE);
                          }
                    }


              //begian streaming
                IOCTL(fd,VIDIOC_STREAMON,&reqbuf.type);
              //put one frame into the device incoming queue
                buffer.type = reqbuf.type;
                buffer.index = 0;
              // IOCTL( fd, VIDIOC_QUERYBUF, &buffer );
              //put another frame into the device incoming queue
                IOCTL(fd,VIDIOC_QBUF,&buffer);
                buffer.type =reqbuf.type;
                buffer.index =1 ;
              // IOCTL(fd,VIDIOC_QUERYBUF,&buffer);
                IOCTL(fd,VIDIOC_QBUF,&buffer);


              //get one frame out of the incoming queue and save as a pgm file
                buffer.type = reqbuf.type;
                buffer.index = 0;
                IOCTL( fd, VIDIOC_DQBUF, &buffer );
                data = buffers[0].start;
                pgm = fopen( "framea.pgm", "w" );
                fprintf( pgm, "P2\n%d %d 255\n",
                      format.fmt.pix.width, format.fmt.pix.height );
                ptr = data;
                for( y = 0; y < format.fmt.pix.height; y++ ) {
                for( x = 0; x < format.fmt.pix.width; x++ ) {
                  fprintf( pgm, "%03d ",
                                    (ptr[ 0] + ptr[1] + ptr[2] ) / 3 );
                  ptr += 3;
                    }
                  fprintf( pgm, "\n" );
                }
                fclose( pgm );
                //get another frame out of the incoming queue and save as a pgm file
                buffer.type = reqbuf.type;
                buffer.index = 1;
                IOCTL( fd, VIDIOC_DQBUF, &buffer );
                data = buffers[1].start;
                pgm = fopen( "frameb.pgm", "w" );
                fprintf( pgm, "P2\n%d %d 255\n",
                      format.fmt.pix.width, format.fmt.pix.height );
                ptr = data;
                for( y = 0; y < format.fmt.pix.height; y++ ) {
                for( x = 0; x < format.fmt.pix.width; x++ ) {
                  fprintf( pgm, "%03d ",
                                    (ptr[ 0] + ptr[1] + ptr[2] ) / 3 );
                  ptr += 3;
                    }
                  fprintf( pgm, "\n" );
                  }
                fclose( pgm );
                //stop the stream
                IOCTL( fd, VIDIOC_STREAMOFF, &reqbuf.type );
                //clean the allocated buffers
                for (i=0;i                        munmap (buffers[i].start,buffers[i].length);
              //close the device file and return
              close(fd);
              return 0;
              }
        }
}
阅读(2427) | 评论(6) | 转发(1) |
给主人留下些什么吧!~~

chinaunix网友2010-06-25 14:33:21

哇。好多年了,前辈啊,我刚学这个,看到此例,很是感慨,不错不错。

chinaunix网友2009-10-28 13:38:24

对,内里空洞无物的人才这么疯癫狂吠!

chinaunix网友2009-08-13 16:50:20

一看一楼,就想骂人,怎么程序员里面也有这种败类,人家都说了抛砖引玉,没说自己代码多么标准。靠,你张嘴就来,没教养,没教养的关键评定是,你骂了还不敢贴出来你的所谓代码风格不垃圾的代码。

chinaunix网友2009-06-02 08:54:17

几乎一个大函数把所有的处理完了。最好不要直接出现数据。 不过风格是可以培养的。关键在于对业务的理解。

chinaunix网友2009-04-21 12:28:56

愿闻高见~~