📄 main.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "ccvt.h"#include "v4l/v4l.h"#include <jpeglib.h>#include <jerror.h>#include <jconfig.h>#define DEFAULT_PALETTE VIDEO_PALETTE_YUV420P//#define DEFAULT_PALETTE VIDEO_PALETTE_RGB24//if need to debug, please open it//#define DEBUG 0#define PUSH_RGB24 1#define PUSH_BGR24 2#define PUSH_RGB32 3#define PUSH_BGR32 4#define IMAGE_WIDTH 320#define IMAGE_HEIGHT 240v4l_device vd;int device_init(char *dev,int norm){ int i; if(dev == NULL) { dev = "/dev/v4l/video0"; //set to default device } if(v4l_open(dev,&vd)) return -1; if(v4l_get_channels(&vd)) return -1; if(v4l_set_norm(&vd,norm)) return -1; if(v4l_mmap_init(&vd)) return -1;#ifdef DEBUG printf("%s: initialization Ok... %s\n %d channels \n %d audios \n" ,dev,vd.capability.name,vd.capability.channels ,vd.capability.audios); for(i=0;i<vd.capability.channels;i++) { printf("Channel %d: %s \n",i,vd.channel[i].name); } printf("v4l:mmap's address = %p\n",vd.map); printf("v4l:mmap's buffer size = 0x%x\n",vd.mbuf.size); printf("v4l:mmap's frames = %d(%d max)\n",vd.mbuf.frames,VIDEO_MAX_FRAME); for(i=0; i< vd.mbuf.frames;i++) { printf("v4l: frames %d's offset = 0x%x\n",i,vd.mbuf.offsets[i]); }#endif //start initialize grab if(v4l_get_picture(&vd)) return -1; if(v4l_set_palette(&vd,DEFAULT_PALETTE)) return -1;#ifdef DEBUG printf("test open 3\n");#endif if(v4l_grab_init(&vd,IMAGE_WIDTH,IMAGE_HEIGHT)) return -1; if(v4l_grab_sync(&vd)) return -1;#ifdef DEBUG printf("test open 4\n");#endif return 0;}int device_grab_frame(){ vd.frame_current = 0; if(v4l_grab_frame(&vd,0) < 0) return -1; return 0;}int device_next_frame(){ vd.frame_current ^= 1; if(v4l_grab_frame(&vd,vd.frame_current) < 0) return -1; return 0;}/* This is a simplistic approach. */static void ccvt_420p(int width, int height, const unsigned char *src, unsigned char *dst, int push){ int line, col, linewidth; int y, u, v, yy, vr, ug, vg, ub; int r, g, b; const unsigned char *py, *pu, *pv; linewidth = width >> 1; py = src; pu = py + (width * height); pv = pu + (width * height) / 4; y = *py++; yy = y << 8; u = *pu - 128; ug = 88 * u; ub = 454 * u; v = *pv - 128; vg = 183 * v; vr = 359 * v; for (line = 0; line < height; line++) { for (col = 0; col < width; col++) { r = (yy + vr) >> 8; g = (yy - ug - vg) >> 8; b = (yy + ub ) >> 8; if (r < 0) r = 0; if (r > 255) r = 255; if (g < 0) g = 0; if (g > 255) g = 255; if (b < 0) b = 0; if (b > 255) b = 255; switch(push) { case PUSH_RGB24: *dst++ = r; *dst++ = g; *dst++ = b; break; case PUSH_BGR24: *dst++ = b; *dst++ = g; *dst++ = r; break; case PUSH_RGB32: *dst++ = r; *dst++ = g; *dst++ = b; *dst++ = 0; break; case PUSH_BGR32: *dst++ = b; *dst++ = g; *dst++ = r; *dst++ = 0; break; } y = *py++; yy = y << 8; if (col & 1) { pu++; pv++; u = *pu - 128; ug = 88 * u; ub = 454 * u; v = *pv - 128; vg = 183 * v; vr = 359 * v; } } /* ..for col */ if ((line & 1) == 0) { // even line: rewind pu -= linewidth; pv -= linewidth; } } /* ..for line */}void ccvt_420p_rgb24(int width, int height, const void *src, void *dst){ ccvt_420p(width, height, (const unsigned char *)src, (unsigned char *)dst, PUSH_RGB24);}void ccvt_420p_bgr24(int width, int height, const void *src, void *dst){ ccvt_420p(width, height, (const unsigned char *)src, (unsigned char *)dst, PUSH_BGR24);}void ccvt_420p_rgb32(int width, int height, const void *src, void *dst){ ccvt_420p(width, height, (const unsigned char *)src, (unsigned char *)dst, PUSH_RGB32);}void ccvt_420p_bgr32(int width, int height, const void *src, void *dst){ ccvt_420p(width, height, (const unsigned char *)src, (unsigned char *)dst, PUSH_BGR32);}int write_jpeg(char *filename, unsigned char *img,int quality,int gray){ FILE *fp; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; unsigned int i; unsigned char *line; int line_length; if(NULL == (fp = fopen(filename,"w"))) { fprintf(stderr,"grab: can't open %s\n",filename); return -1; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, fp); cinfo.image_width = IMAGE_WIDTH; cinfo.image_height = IMAGE_HEIGHT; cinfo.input_components = gray ? 1 : 3 ; cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;#ifdef DEBUG printf("test jpeg stage 1 ok\n");#endif jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo,quality,TRUE); jpeg_start_compress(&cinfo,TRUE);#ifdef DEBUG printf("test jpeg stage 2 ok\n");#endif line_length = gray ? IMAGE_WIDTH : IMAGE_WIDTH*3; for(i=0,line=img;i<IMAGE_HEIGHT;i++,line+=line_length) jpeg_write_scanlines(&cinfo,&line,1); jpeg_finish_compress(&(cinfo)); jpeg_destroy_compress(&(cinfo)); fclose(fp);#ifdef DEBUG printf("test jpeg stage 3 ok\n");#endif return 0;}int main(){ unsigned char *img; unsigned char *img_out = malloc(IMAGE_WIDTH*IMAGE_HEIGHT*3); FILE *fp; memset(img_out,0,sizeof(img_out)); if(device_init("/dev/v4l/video0",3) == -1) { perror("device_init:failed...\n"); exit(1); } else { #ifdef DEBUG printf("OK!\n");#endif //device_next_frame(); //device_grab_frame(); img = device_get_address(&vd);#ifdef DEBUG printf("img address is: %p \n",img); printf("img_out address is: %p \n",img_out);#endif ccvt_420p_rgb24(IMAGE_WIDTH,IMAGE_HEIGHT,img,img_out);#ifdef DEBUG printf("ccvt_420p_rgb24_ok\n"); fp = fopen("test.ppm","w"); fprintf(fp,"P6\n%d %d\n255\n",IMAGE_WIDTH,IMAGE_HEIGHT); fwrite(img_out,IMAGE_WIDTH*3,IMAGE_HEIGHT,fp); fclose(fp);#endif write_jpeg("test.jpeg", img_out , 75, 0); #ifdef DEBUG printf("write_jpeg_ok\n");#endif } exit(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -