📄 camera_adv.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
//#include <ctype.h>
#include <sys/mman.h>
//#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
#include <errno.h>
#include "jpeglib.h"
#include <setjmp.h>
#include "bitmap_convert.h"
#define CAMERA_DEV "/dev/video0"
struct video4linux_struct
{
int dev;
struct video_window win;
struct video_capability caps;
struct video_picture pic;
struct video_mbuf mbuf;
struct video_mmap mmap;
unsigned char *map;
char *buffer;
int frame;
int framestat[2];
};
/*
struct spca5xx_struct
{
};
*/
unsigned char * image_buffer; /* Points to large array of R,G,B-order data */
int image_height; /* Number of rows in image */
int image_width; /* Number of columns in image */
//================[camera]================
//================[camera]================
//================[camera]================
int func_camera_init(struct video4linux_struct *v4l_info)
{
//----------[open-device]-------------------------
v4l_info->dev=open(CAMERA_DEV,O_RDWR);
if (v4l_info->dev < 0)
{ printf("open CAMERA_DEV : error\n"); return -1; }
else
{ printf("open CAMERA_DEV : ok \n"); }
//---------[capability]-------------[获得摄像头属性]
ioctl(v4l_info->dev,VIDIOCGCAP,&v4l_info->caps);
printf("1.VIDIOCGCAP %s %d %d %d %d type: %d\n",
v4l_info->caps.name,
v4l_info->caps.maxwidth,
v4l_info->caps.maxheight,
v4l_info->caps.minwidth,
v4l_info->caps.minheight,
v4l_info->caps.type);
//----------[Capture Windows]-------------------
ioctl(v4l_info->dev , VIDIOCGWIN , &v4l_info->win);
printf("2.VIDIOCGWIN %d %d %d %d %d \n",
v4l_info->win.x,
v4l_info->win.y,
v4l_info->win.width,
v4l_info->win.height,
v4l_info->win.chromakey);
//-----------[picture]---------------[设备采集的图象的各种属性]
ioctl(v4l_info->dev , VIDIOCGPICT , &v4l_info->pic);
printf("3.VIDIOCGPICT : brightness[%d] hue[%d] colour[%d] contrast[%d]\n whiteness[%d] depth[%d] palette[%d]\n",
v4l_info->pic.brightness,
v4l_info->pic.hue,
v4l_info->pic.colour,
v4l_info->pic.contrast,
v4l_info->pic.whiteness,
v4l_info->pic.depth,
v4l_info->pic.palette);
// &v4l_info->pic.colour=65535;//65535//16777215
// &v4l_info->pic.depth=8;//16//24
// &v4l_info->pic.palette=VIDEO_PALETTE_RGB565;
// ioctl(v4l_info->dev,VIDIOCSPICT,&v4l_info->pic); //SET video_picture
// printf("3.VIDIOCGPICT [set]:brightness[%d] hue[%d] colour[%d] contrast[%d]\n whiteness[%d] depth[%d] palette[%d]\n",vid_pic.brightness,vid_pic.hue,vid_pic.colour,vid_pic.contrast,vid_pic.whiteness,vid_pic.depth,vid_pic.palette);
//-------------[mbuf]--------------[利用mmap进行映射的帧的信息]
ioctl(v4l_info->dev ,VIDIOCGMBUF, &v4l_info->mbuf);
printf("4.video_mbuf : size[%d] frames[%d] offsets0[%d] offsets1[%d] \n\n",
v4l_info->mbuf.size ,
v4l_info->mbuf.frames,
v4l_info->mbuf.offsets[0],
v4l_info->mbuf.offsets[1]);
//------------[video_mmap]-----[用于mmap]
/* struct video_mmap
* {
* unsigned int frame;
* int height,width;
* unsigned int format; // should be VIDEO_PALETTE_*
* };
*/
/* #define VIDEO_PALETTE_RAW_JPEG 20 (spca5xx.h)
* #define VIDEO_PALETTE_JPEG 21
*/
v4l_info->mmap.format=VIDEO_PALETTE_RGB565;//21;//vid_pic.palette//VIDEO_PALETTE_RGB24//VIDEO_PALETTE_RGB565
v4l_info->mmap.width=320;
v4l_info->mmap.height=240;
v4l_info->framestat[0] =v4l_info->framestat[1] = 0;
v4l_info->frame = 0;
v4l_info->mmap.frame=v4l_info->frame;
/* 把/dev/video0 文件映射到内存中 [mmap] */
v4l_info->map = mmap(0,v4l_info->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,v4l_info->dev,0);
if ((int)v4l_info->map<0) printf("camera mmap(mbuf.size : error\n");
/* 开始截取一帧,帧内容自动存入map指向的地址中(/dev/video0) */
if (ioctl(v4l_info->dev,VIDIOCMCAPTURE,&v4l_info->mmap)<0) printf("camera VIDIOCMCAPTURE : error\n");
v4l_info->framestat[v4l_info->frame]=1;
printf("5.camera INIT :ok capturing_1st_pic\n");
return 0;
}
int func_camera_exit(struct video4linux_struct *v4l_info)
{
close(v4l_info->dev);
printf("close-Camera~~~\n");
return 0;
}
int func_camera_loop(struct video4linux_struct *v4l_info)
{
//--------------[wait for complete]-------
if (ioctl(v4l_info->dev , VIDIOCSYNC , &v4l_info->frame)<0) printf("camera VIDIOCSYNC : error\n");
v4l_info->framestat[v4l_info->frame]=0;
//---------------[get the address]--------
v4l_info->buffer=(char*)(v4l_info->map+v4l_info->mbuf.offsets[v4l_info->frame]);
// *GUI_bmBits=v4l_info->buffer;
//------------------[for next]------------
v4l_info->frame=(v4l_info->frame+1)%2;
v4l_info->mmap.frame=v4l_info->frame;
if (ioctl(v4l_info->dev,VIDIOCMCAPTURE,&v4l_info->mmap)<0) printf("camera VIDIOCAMCAPTURE : error\n");
v4l_info->framestat[v4l_info->frame]=1;
//-----------------------------------------
printf("func_camera_loop++ : ok \n");
return 0;
}
//================[camera]================
//================[camera]================
//--------------[write_JPEG_file]----------------
//--------------[write_JPEG_file]--------------------------------------------
//--------------[write_JPEG_file]----------------
GLOBAL(void)
write_JPEG_file (char * filename, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
/* More stuff */
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
}
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
//--------------[read_JPEG_file]----------------
//--------------[read_JPEG_file]--------------------------------------------
//--------------[read_JPEG_file]----------------
GLOBAL(int)
read_JPEG_file (unsigned char* mem_jpeg_src,unsigned char* fb_mem)
{
unsigned char *buffer_addr;
int offset=0;
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE * infile; /* source file */
JSAMPARRAY buffer; /* Output row buffer */
int row_stride; /* physical row width in output buffer */
/*
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
*/
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 0;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, mem_jpeg_src);
printf("warning~~~~~\n");
(void) jpeg_read_header(&cinfo, TRUE);
printf("warning~~~~~\n");
(void) jpeg_start_decompress(&cinfo);
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
printf("jpeg width: %d\n",cinfo.output_width);
offset=0;
while (cinfo.output_scanline < cinfo.output_height)
{
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
buffer_addr=buffer[0];
RGB24_to_RGB565(buffer_addr,fb_mem+offset,cinfo.output_width); //one line : width
offset+=240*2;
}
(void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 1;
}
int main()
{
struct video4linux_struct v4l_info;
// unsigned char *camera_buffer;
// unsigned char *jpeg_buffer;
int offset_i,offset_j;
int i=0,j;
// char filename[20];
int tmpb;
int fb;
// unsigned char * tmpb_mem;
unsigned char * fb_mem;
//-------------[frame-buffer&mmap]------------------------------
fb = open ("/dev/fb0", O_RDWR);
printf("fb: %d\n",fb);
if (fb<0) return -1;
fb_mem = mmap (NULL, 240*360, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
printf("fb_mem: %d\n",(int)fb_mem);
if ((int)fb_mem<0) return -1;
//--------------[camera.jpg&mmap]----------------------------
/* tmpb = open("/tmp/camera.jpg",O_RDWR);
printf("outfile: %d\n",tmpb);
if (tmpb<0) return -1;
tmpb_mem = mmap (*/
/* INIT the camera */
if (func_camera_init(&v4l_info)==-1) { printf("camera INIT: error\n"); return -1; }
// jpeg_buffer=malloc(320*240*3);
/*
while(i>=0)
{
fun_camera(2,&camera_buffer);
image_buffer=camera_buffer;
image_width=320;
image_height=240;
sprintf(filename,"%d.jpg",i);
printf("%s\n",filename);
write_JPEG_file(filename,75);
i=(i+1)%2;
}
*/
offset_i=0;
offset_j=0;
func_camera_loop(&v4l_info);
// read_JPEG_file (camera_buffer,fb_mem);
/*
printf("fopen\n");
outfile =fopen ("/tmp/a.jpg","wb");
if (outfile==NULL)
{
printf("open outfile: error\n");
return 0;
}
printf("start writing... %x\n",(unsigned int)camera_buffer);
while (fwrite(camera_buffer+offset_i,1,1,outfile)) offset_i++;
fclose(outfile);
printf("write over %d\n",offset_i);
*/
for (i=0;i<240;i++)
{
for (j=0;j<240*2;j++)
{
*(fb_mem+offset_i+j)=*(v4l_info.buffer+offset_j+j);
}
offset_i+=240*2;
offset_j+=320*2;
}
func_camera_exit(&v4l_info);
close(fb);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -