안녕하세요. 다행히 강좌 게시판에 프레임 버퍼와 카메라에 대한 내용이 있습니다.

카메라 영상을 촬영에서 TCP/IP로 전송까지 3단계로 설명한 글 중 첫번째입니다.

http://forum.falinux.com/zbxe/?document_srl=468601

프레임 버퍼에 대한 강좌는 프레임 버퍼에 대한 얘기에서부터 도형 출력까지 설명되어 있으니 참고하세요. ^^

http://forum.falinux.com/zbxe/?document_srl=406102

>안녕하세요 V4L를 가지고 머좀 만들어볼려는 학생입니다.
>이렇게 처음으로 질문을 드리네요 ^^
>
>EZ-X5보드와 로직텍 퀵캠 4000에 장비를 가지고
>V4L로 "file.bmp"란 파일을 생성하는 프로그램을 만들었습니다.
>그런데 사진이 이상하게 깨져서 나오더군요.(아마설정을 잘못해준거 같은데...)
>
>QT를 이용한 camstream을 이용하면 영상이 깨끗하게 나옵니다.
>밑에는 재가 코딩한 프로그램입니다.
>
>또 한가지만 더 물어볼께요
>프레임버퍼로 그림을 출력시키는 방법을 잘모르겠습니다.
>인터넷에서 많은 자료를 찻았는데
>저의 머리가 돌머리인지 이해가 잘 안되더라고요 -_ㅜ
>
>도와주세요ㅡㅜ
>
>#include <stdio.h>
>#include <stdlib.h>
>#include <unistd.h>
>#include <math.h>
>#include <string.h>
>#include <fcntl.h>
>#include <termios.h>
>#include <unistd.h>
>#include <getopt.h>
>#include <sys/ioctl.h>
>                                                                                
>#include <semaphore.h>
>#include <pthread.h>
>#include <stdlib.h>
>#include <getopt.h>
>
>#include <linux/types.h>
>#include <linux/fb.h>
>#include <sys/types.h>
>#include <sys/stat.h>
>#include <signal.h>
>#include <sys/mman.h>
>#include <linux/videodev.h>
>
>#define SERVO_LEFT        1
>#define SERVO_RIGHT        2
>#define SERVO_MIDDLE        3
>
>#define Dev_Name        "dev/Cam_Stream_Module"
>
>static int Timer = 0;
>static int Servo = 0;
>static int frames2 = 0;
>static int frame_number = 0;
>
>//extern int frame_number2;
>
>struct picbuf
>{
>        char *data;
>};
>
>typedef struct camera
>{
>        int dev;
>        int x;
>        int y;
>        int dither;
>        int contrast, brightness, colour, hug;
>        struct video_capability         vid_cap;
>        struct video_picture                vid_pic;
>        struct video_channel                vid_chnl;
>        struct video_window                vid_win;
>        struct video_mbuf                vid_buf;
>        struct video_mmap                vid_map[2];
>        char video_dev[256];
>        char *pic;
>        char *image;
>        char *ppmfile;
>        struct picbuf pic_buf[2];
>}cam;
>
>struct bgrpixel
>{
>        unsigned char b, g , r;
>};
>
>typedef struct lcd_frmae_buffer
>{
>        int dev;
>        char lcd_dev[256];
>        struct fb_var_screeninfo        fbvar;
>        struct bgrpixel                 pixel;
>        int x;
>        int y;
>        int bp;
>        int byte_total;
>        unsigned short *vbase;
>}lcd;
>
>int video_open(lcd *lcd)
>{
>        if(ioctl(lcd->dev, FBIOGET_VSCREENINFO, &lcd->fbvar) < 0)
>        {
>                printf("fbvar open failn");
>                return 0;
>        }
>        if(lcd -> fbvar.bits_per_pixel != 16)
>        {
>                printf("bpp is not 16n");
>                exit(0);
>        }
>        lcd -> x = lcd -> fbvar.xres;
>        lcd -> y = lcd -> fbvar.yres;
>        lcd -> bp = lcd -> fbvar.bits_per_pixel;
>        lcd -> byte_total = (lcd->x * lcd->y * (lcd->bp/8));
>        lcd -> vbase = (unsigned short *) mmap(0, lcd->byte_total, PROT_READ | PROT_WRITE, MAP_SHARED, lcd->dev, 0);
>        if((unsigned)lcd->vbase == (unsigned)-1)
>        {
>                printf("Lcd MMAP FAILn");
>                exit(0);
>        }
>
>        return 0;
>}
>
>static unsigned short makepixel(lcd *lcd, unsigned char r, unsigned char g, unsigned char b)
>{
>        unsigned short rnew, gnew, bnew;
>        
>        rnew = r >> (8 - (lcd->fbvar.red.length));
>        gnew = g >> (8 - (lcd->fbvar.green.length));
>        bnew = b >> (8 - (lcd->fbvar.blue.length));
>        
>        return (unsigned short) ((rnew << lcd->fbvar.red.offset)
>                | (gnew << lcd->fbvar.green.offset)
>                | (bnew << lcd->fbvar.blue.offset));
>}
>
>void screen(lcd *lcd,cam *cam)
>{
>        int x, y;
>        
>        for(x = 0; x <= cam->x ; x ++)
>        {
>                for(y = 0; y <= cam->y ; y++)
>                {
>                        lcd->pixel.r = 10;
>                        lcd->pixel.g = 10;
>                        lcd->pixel.b = 10;
>                        *(lcd->vbase + x *lcd->fbvar.xres+y) = makepixel(&lcd->fbvar, lcd->pixel.r, lcd->pixel.g, lcd->pixel.b);
>                }
>        }
>}
>
>void draw(int x, int y, unsigned short color,lcd *lcd)
>{
>        unsigned short *ptr;
>        ptr = lcd->vbase + ((y * lcd->x) + x);
>        *ptr = color;
>}
>
>int ppm_save(cam *cam)
>{
>        FILE *fp;
>        int fc;
>        
>        printf("Capturing...n");
>        fp = fopen(cam->ppmfile, "w");
>        if(fp == NULL)
>        {
>                printf("OPEN FAIL FOR WIRTING...n");
>                return -1;
>        }
>        fprintf(fp, "P6n%d %dn%dn",cam->x,cam->y,255);
>        fc = fwrite(cam->pic_buf[frame_number].data, 1, cam->vid_buf.size, fp);
>        fclose(fp);
>        return 0;
>}        
>
>void camera_cap(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCGCAP, &cam->vid_cap) == -1)
>        {
>                printf("Camera Capabilities OPEN FAIL, EXIT...n");
>                exit(0);
>        }
>        if(cam -> vid_cap.maxwidth < cam -> x)
>        {
>                cam->x = cam->vid_cap.maxwidth;
>        }
>        if(cam -> vid_cap.minwidth > cam -> x)
>        {
>                cam->x = cam->vid_cap.minwidth;
>        }
>        if(cam -> vid_cap.maxheight < cam -> y)
>        {
>                cam->y = cam->vid_cap.maxheight;
>        }
>        if(cam -> vid_cap.minheight > cam -> y)
>        {
>                cam->y = cam->vid_cap.minheight;
>        }
>}
>
>void set_pic_info(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
>        {
>                printf("VIDEO PICTURE OPEN FILE EXIT.....n");
>                exit(0);        
>        }
>}
>
>void get_pic_info(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCSPICT, &cam->vid_pic) == -1)
>        {
>                printf("VIDEO GET PICTURE OPEN FAIL EXIT.....n");
>                exit(0);
>        }
>}
>
>void get_win_info(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
>        {
>                printf("VIDEO GET WINDOW OPEN FAIL EXIT.....n");
>                exit(0);
>        }
>}
>
>void set_win_info(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCSWIN, &cam->vid_win) == -1)
>        {
>                printf("VIDEO SET WINDOW OPEN FAIL EXIT.....n");
>                exit(0);
>        }
>}
>
>void set_buffer(cam *cam)
>{
>        if(ioctl(cam->dev, VIDIOCGMBUF, &cam->vid_buf) == -1)
>        {
>                printf("BUFFER SET FAIL EXIT.....n");
>                exit(0);
>        }
>}
>
>
>void dev_open(void)
>{
>        Servo = open(Dev_Name, O_RDWR | O_NOCTTY);        
>        Timer = open("dev_timer", O_RDWR | O_NOCTTY);
>        
>        if(Servo < 0)
>        {
>                printf("%s OPEN FAIL.....n",Dev_Name);
>                exit(0);
>        }
>        printf("Servo OPEN SUCCESS.....n");
>        if(Timer < 0)
>        {
>                printf("Timer OPEN Fail [dev/timer]nn");
>                exit(1);
>        }
>        printf("Timer OPENn");
>}
>
>void init_cam(cam *cam)
>{
>        cam->pic = mmap(0,cam->vid_buf.size,PROT_READ | PROT_WRITE,MAP_SHARED, cam->dev,0);
>        cam->vid_map[0].height = cam->y;
>        cam->vid_map[0].width = cam->x;
>        cam->vid_map[0].frame = 0;
>        cam->vid_map[0].format = cam->vid_pic.palette;
>        cam->pic_buf[0].data = cam->pic;
>        cam->vid_map[1].height = cam->y;
>        cam->vid_map[1].width = cam->x;
>        cam->vid_map[1].frame = 1;
>        cam->vid_map[1].format = cam->vid_pic.palette;
>        cam->pic_buf[1].data = cam->pic + cam->vid_buf.offsets[1];
>        
>        if((unsigned char*) -1 == (unsigned char *) cam->pic)
>        {
>                printf("MMAP FAILEDn");
>                exit(-1);
>        }
>        if(ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map) == -1)
>        {
>                printf("100n");
>        }
>        if(ioctl(cam->dev, VIDIOCSYNC, cam->vid_map) == -1)
>        {
>                printf("1000n");
>        }
>}
>
>void frameloop(cam *cam)
>{
>        int ctl = 0;
>        ctl = ioctl(cam->dev, VIDIOCMCAPTURE, cam->vid_map + frame_number);
>
>        if(ctl == -1)
>        {
>                printf("CAPTURE FROM DEVICE OPEN FAIL.....n");
>                exit(-1);
>        }
>        frames2++;
>        ctl = ioctl(cam->dev, VIDIOCSYNC, cam->vid_map + frame_number);
>
>        if(ctl == -1)
>        {
>                printf("VIDIOCSYNC FAILED.....n");
>                munmap(cam->vid_map, cam->vid_buf.size);
>                exit(-1);
>        }
>}
>
>int main(int argc,char **argv)
>{
>        //int one = 1;
>        //int done = 0;
>        
>        cam cam;
>        lcd lcd;
>        
>        cam.x = 320;
>        cam.y = 240;
>
>        strcpy(lcd.lcd_dev, "/dev/fb0");
>        strcpy(cam.video_dev, "/dev/video0");
>
>        cam.dither = 128;
>        
>        lcd.dev = open(lcd.lcd_dev, O_RDWR);
>        cam.dev = open(cam.video_dev, O_RDWR);
>        
>        cam.image = malloc(cam.x * cam.y * 3);
>//        cam.vid_buf.size = cam.x * cam.y * 3;
>
>        video_open(&lcd);
>        camera_cap(&cam);
>
>        if(ioctl(cam.dev, VIDIOCSCHAN, cam.vid_chnl) == -1);
>
>        cam.vid_pic.palette = VIDEO_PALETTE_RGB24;
>        cam.vid_win.x = 0;
>        cam.vid_win.y = 0;
>        cam.vid_win.width = cam.x;
>        cam.vid_win.height = cam.y;
>
>        cam.ppmfile = "file.bmp";
>                
>        set_pic_info(&cam);
>
>        cam.contrast = cam.vid_pic.contrast * 256;
>        cam.brightness = cam.vid_pic.brightness * 256;
>        cam.colour = cam.vid_pic.colour * 256;
>        cam.hug = cam.vid_pic.hue * 256;
>
>        set_win_info(&cam);
>        
>        set_buffer(&cam);
>        init_cam(&cam);
>        //dev_open();
>
>        while(1)
>        {
>                frameloop(&cam);
>                ppm_save(&cam);
>        }
>        return 0;
>}
>