📄 capture.cpp
字号:
#include "capture.h"
int frameSize;
unsigned char *nextBuff;
unsigned char *toBuff;
void rgb_to_framebuffer( fb_v41 *vd,int width,int height,int xoffset,int yoffset,
unsigned short *img_ptr )
{
int x,y;
int location;
unsigned short *loca_ptr;
// Figure out where in memory to put the pixel
for ( y = 0; y < height; y++ )
{
location = xoffset * 2 +(y + yoffset) * vd->finfo.line_length;
loca_ptr = (unsigned short *) (vd->fbp + location);
for ( x = 0; x < width; x++ ) // �ɨ�
{
*(loca_ptr + x) = *img_ptr++;
}
}
}
int get_grab_frame(fb_v41 *vd, int frame)
{
vd->mmap.frame = frame;
if (ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) < 0)
{
perror("v4l_grab_frame");
return ERR_GET_FRAME;
}
return 0;
}
int get_first_frame(fb_v41 *vd)
{
int ret;
vd->frame_current = 0;
ret = get_grab_frame( vd, 0 );
if ( ret<0 )
return ret;
// ȴ֡ͬ
if (ioctl(vd->fd, VIDIOCSYNC, &(vd->frame_current)) < 0)
{
perror("v4l_grab_sync");
return ERR_SYNC;
}
vd->frame_using[vd->frame_current] = 0 ;
return (0);
}
char *get_frame_address(fb_v41 *vd)
{
//return (vd->map + vd->mbuf.offsets[vd->frame_current]);
return ((char *)vd->map);
}
int get_next_frame(fb_v41 *vd)
{
int ret;
vd->frame_current ^= 1;
ret = get_grab_frame( vd,vd->frame_current); // �ͼ���
if( ret < 0 )
return ret;
if (ioctl(vd->fd, VIDIOCSYNC, &(vd->frame_current)) < 0) // ȴ֡ͬ
{ perror("v4l_grab_sync");
return ERR_SYNC;
}
vd->frame_using[vd->frame_current] = 0 ;
return 0;
}
int open_framebuffer(char *ptr,fb_v41 *vd)
{
int fbfd,screensize;
// Open the file for reading and writing
fbfd = open( ptr, O_RDWR);
if (fbfd < 0)
{
printf("Error: cannot open framebuffer device.%x\n",fbfd);
return ERR_FRAME_BUFFER;
}
printf("The framebuffer device was opened successfully.\n");
vd->fbfd = fbfd; // �FrameBuffer�ľ�
// Get fixed screen information �FrameBuffer̶��Ϣ
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &vd->finfo))
{
printf("Error reading fixed information.\n");
return ERR_FRAME_BUFFER;
}
// Get variable screen information �FrameBuffer�Ļɱ��Ϣ
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vd->vinfo))
{
printf("Error reading variable information.\n");
return ERR_FRAME_BUFFER;
}
printf("%dx%d, %dbpp, xoffset=%d ,yoffset=%d \n", vd->vinfo.xres,
vd->vinfo.yres, vd->vinfo.bits_per_pixel,vd->vinfo.xoffset,vd->vinfo.yoffset );
// Figure out the size of the screen in bytes
screensize = vd->vinfo.xres * vd->vinfo.yres * vd->vinfo.bits_per_pixel / 8;
// Map the device to memory
vd->fbp = (char *)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0);
if ((int)vd->fbp == -1)
{
printf("Error: failed to map framebuffer device to memory.\n");
return ERR_FRAME_BUFFER;
}
printf("The framebuffer device was mapped to memory successfully.\n");
return 0;
}
int open_video( char *fileptr,fb_v41 *vd ,int dep,int pal,int width,int height)
{
int i;// ���
if ((vd->fd = open(fileptr, O_RDWR)) < 0)
{
perror("v4l_open:");
return ERR_VIDEO_OPEN;
}
// ��
if (ioctl(vd->fd, VIDIOCGCAP, &(vd->capability)) < 0)
{
perror("v4l_get_capability:");
return ERR_VIDEO_GCAP;
}
if (ioctl(vd->fd, VIDIOCGPICT, &(vd->picture)) < 0)
{
perror("v4l_get_picture");
return ERR_VIDEO_GPIC;
}
printf("%d , %d",vd->picture.palette,vd->picture.depth);
vd->picture.palette = pal; // ��
vd->picture.depth = dep; // ����
vd->mmap.format =pal;
if (ioctl(vd->fd, VIDIOCSPICT, &(vd->picture)) < 0)
{
perror("v4l_set_palette");
return ERR_VIDEO_SPIC;
}
vd->mmap.width = width; // width;
vd->mmap.height = height; // height;
vd->mmap.format = vd->picture.palette;
vd->frame_current = 0;
vd->frame_using[0] = 0;
vd->frame_using[1] = 0;
if (ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf)) < 0)
{
perror("v4l_get_mbuf");
return -1;
}
vd->map = (unsigned char*)mmap(0,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,0);
if ( vd->map < 0)
{
perror("v4l_mmap_init:mmap");
return -1;
}
printf("The video device was opened successfully.\n");
return 0;
}
void compress_to_jpeg_file( FILE *outfile, char * image_buffer,int w,int h, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
int image_width;
int image_height;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
image_width = w;
image_height = h;
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] = (JSAMPROW)& image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
/* And we're done! */
}
//***************************************************************************//
void initDest(j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,\
JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof(JOCTET));
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
frameSize = 0;
}
boolean emptyObuff(j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
toBuff = (unsigned char*)realloc(toBuff, frameSize+OUTPUT_BUF_SIZE);
nextBuff = &(toBuff[frameSize]);
memcpy(nextBuff, dest->buffer, OUTPUT_BUF_SIZE);
frameSize += OUTPUT_BUF_SIZE;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
}
void termDest(j_compress_ptr cinfo)
{
my_dest_ptr dest = ( my_dest_ptr ) cinfo->dest;
size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
if ( datacount > 0 )
{
toBuff = (unsigned char*)realloc(toBuff, frameSize+datacount);
nextBuff = &(toBuff[frameSize]);
memcpy(nextBuff, dest->buffer, datacount);
frameSize += datacount;
}
}
void jpeg_buff_dest(j_compress_ptr cinfo)
{
my_dest_ptr dest;
if (cinfo->dest == NULL)
{ // first time for this JPEG object?
cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)\
((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_destination_mgr));
}
dest = (my_dest_ptr) cinfo->dest;
dest->pub.init_destination = initDest;
dest->pub.empty_output_buffer = emptyObuff;
dest->pub.term_destination = termDest;
dest->outBuff = toBuff;
}
void compress_Jpeg( unsigned char *fromBuff,int width,int height,int quality,int rgbData,int snapshot)
{
FILE * outfile;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
int row_stride;
// uchar *fromBuff = (uchar *)tempBuff;
outfile = NULL;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if(snapshot == 1) //如果snapshot == 1 则把压缩的结果写进文件里面!
{
if ((outfile = fopen("/tmp/video.jpg", "wb")) == NULL)
{
printf("file open Error!\n");
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
}
else jpeg_buff_dest(&cinfo);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
if( rgbData )
cinfo.in_color_space = JCS_RGB;
else
cinfo.in_color_space = JCS_YCbCr;//JCS_GRAYSCALE;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE); // 设置压缩质量!
jpeg_start_compress(&cinfo, TRUE);
row_stride = width * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = & fromBuff[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
if(snapshot == 1)
fclose(outfile);
}
unsigned char *jpegImg()
{
return toBuff;
}
int jpegSize()
{
return frameSize;
}
void exchange_r_b( char * f,long size)
{
char r,b;
long i;
for( i = 0; i < size ; i++)
{
r = *f;
b = *( f + 2);
*f = b;
*(f + 2) = r;
f = f +3;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -