⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capture.cpp

📁 嵌入式linux与arm板视频图像解析及静态图像对传
💻 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 + -