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

📄 v4l.c

📁 v4l usb 图像获取 v4l usb 图像获取
💻 C
字号:
#include <string.h>
#include <sys/types.h>

#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/videodev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>

#include "xvid_encode.h"
void *enc_handle = NULL;

int done = 0;
int enc_main(unsigned char *image,
   unsigned char *bitstream,
   int *key,
   int *stats_type,
   int *stats_quant,
   int *stats_length,
   int sse[3]);
   
int enc_stop();
int enc_init(int use_assembler);
double msecond();

#define VIDEO_PALETTE_JPEG  21

struct vdIn {
 int fd;
 char *videodevice ;
 struct video_capability videocap;
 struct video_picture videopict;
 struct video_window videowin;
 int framesizeIn ;
 int bppIn;
 int  hdrwidth;
 int  hdrheight;
 int  formatIn;
};

struct vdIn videoIn;
int init_videoIn (struct vdIn *vd, char *device, int width, int height,int format);
static int GetDepth (int format);
static int GetVideoPict (struct vdIn *vd);
static int SetVideoPict (struct vdIn *vd);

int main(int argc,char *argv[])
{
	char *device;
	
	int format = VIDEO_PALETTE_YUV420P;
	int width = 352;
	int height = 288;
	int i;
	unsigned char r_buffer[304128];
	unsigned char* mp4_buffer;
	
	double enctime;
	double totalenctime = 0.;
	float totalPSNR[3] = {0., 0., 0.};
	device = "/dev/video0";
	ARG_OUTPUTFILE = "test.m4v";
	int use_assembler = 1;
	int result;
	int totalsize;
	int m4v_size;
	int key;
	int stats_type;
	int stats_quant;
	int stats_length;
	int input_num;
	int output_num;
	
	char filename[256];
	FILE *out_file = NULL;
	
	memset (&videoIn, 0, sizeof (struct vdIn));
	if (init_videoIn(&videoIn, device, width, height,format) != 0)
		printf (" damned encore rate !!\n");
	/* xvid init */
	ARG_SAVEMPEGSTREAM = 1;
	ARG_SAVEINDIVIDUAL = 0;
	
	XDIM = width;
	YDIM = height;
	mp4_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM, YDIM) * 2);
	
	totalsize = 0;
	
	result = 0;
	result = enc_init(0);
	if (result != 0) {
		fprintf(stderr, "Encore INIT problem, return value %d\n",result);
		goto release_all;
	}
	
	/* i=read(videoIn.fd,r_buffer,304128);
	printf("i read : %d\n",i);
	if(i<0){
	printf("error read!\n");
	close(videoIn.fd);
	return -1;
	}
	*/
	input_num = 0;    /* input frame counter */
	output_num = 0;
		
	if (ARG_SAVEMPEGSTREAM && ARG_OUTPUTFILE) {
		if ((out_file = fopen(ARG_OUTPUTFILE, "w+b")) == NULL) {
			fprintf(stderr, "Error opening output file %s\n", ARG_OUTPUTFILE);
			goto release_all;
		}
	} 
	else {
		out_file = NULL;
	}
	
	/* Xvid encode */
	do {
		char *type;
		int sse[3];
		i=read(videoIn.fd,r_buffer,304128);
		printf("i read : %d\n",i);
		if(i<0){
			printf("error read!\n");
			close(videoIn.fd);
			return -1;
		}
		
		if (input_num >= ARG_MAXFRAMENR) {
			//result = 1;
			done = 1;
		}

		enctime = msecond();
		m4v_size =enc_main(!result ? (unsigned char*)r_buffer:0,mp4_buffer, &key, &stats_type,&stats_quant, &stats_length, sse);
		enctime = msecond() - enctime;
		printf("m4v_size is %d \n",m4v_size);
		if (m4v_size < 0) {
			printf("erro in encode....\n");
		}
		
		/* Update encoding time stats */
		totalenctime += enctime;
		totalsize += m4v_size;
		if (m4v_size > 0 && ARG_SAVEMPEGSTREAM) {		
			/* Save single files */
			if (ARG_SAVEINDIVIDUAL) {
				FILE *out;
				sprintf(filename, "%sframe%05d.m4v", filepath, output_num);
				out = fopen(filename, "w+b");
				fwrite(mp4_buffer, m4v_size, 1, out);
				fclose(out);
				output_num++;
			}
			/* Save ES stream */
			if (ARG_OUTPUTFILE && out_file)
				fwrite(mp4_buffer, 1, m4v_size, out_file);
		}
		
		input_num++;	
		
	} while (!done);
	
	if(m4v_size<0){
		printf("error write_jpeg!\n");
		close(videoIn.fd);
		fclose(out_file);
		return -1;
	}
	printf("OK.\n");
	
release_all:	
	if (enc_handle) {
		result = enc_stop();
		if (result)
			fprintf(stderr, "Encore RELEASE problem return value %d\n",result);
	}
	
	fclose(out_file);
	close(videoIn.fd);
	return 0;
}

int init_videoIn (struct vdIn *vd, char *device, int width, int height,
       int format)
{
	int erreur;
	vd->hdrwidth = width;
	vd->hdrheight = height;
	vd->formatIn = format;
	vd->bppIn = GetDepth (vd->formatIn);
	
	if ((vd->fd = open (device, O_RDWR)) == -1){
		printf("ERROR opening V4L interface\n");
		close(vd->fd);
		return -1;
	}
	if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1){
		printf("ERROR opening video_capability interface\n");
		close(vd->fd);
		return -1;
	}
	printf ("Camera found: %s \n", vd->videocap.name);
	
	erreur = GetVideoPict (vd);
	vd->videopict.palette = vd->formatIn;
	vd->videopict.depth = GetDepth (vd->formatIn);
	vd->bppIn = GetDepth (vd->formatIn);
	
	vd->framesizeIn = (vd->hdrwidth * vd->hdrheight * vd->bppIn) >> 3;
	
	erreur = SetVideoPict (vd);
	erreur = GetVideoPict (vd);
	if (vd->formatIn != vd->videopict.palette || vd->bppIn != vd->videopict.depth){
		printf("ERROR set video_picture interface\n");
		close(vd->fd);
		return -1;
	}

	if (erreur < 0){
		printf("ERROR set palette \n");
		close(vd->fd);
		return -1;
	}

	if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0)
		perror ("VIDIOCGWIN failed \n");

	vd->videowin.height = vd->hdrheight;
	vd->videowin.width = vd->hdrwidth;

	if (ioctl (vd->fd, VIDIOCSWIN, &(vd->videowin)) < 0)
		perror ("VIDIOCSWIN failed \n");
		
	if (ioctl (vd->fd, VIDIOCGWIN, &(vd->videowin)) < 0)
		perror ("VIDIOCGWIN failed \n");

	printf ("VIDIOCSWIN height %d  width %d \n",
	vd->videowin.height, vd->videowin.width);
	return 0;
}

static int
GetDepth (int format)
{
	int depth;
	switch (format)
	{
		case VIDEO_PALETTE_JPEG:
			{
			depth = 8;  
			}
			break;
		case VIDEO_PALETTE_RAW:
			{
			depth = 8;  
			}
			break;
		case VIDEO_PALETTE_YUV420P:
			{
			//depth = (8 * 3) >> 1;
			depth = 24;
			}
			break;
		case VIDEO_PALETTE_RGB565:
			depth = 16;
			break;
		case VIDEO_PALETTE_RGB24:
			depth = 24;
			break;
		case VIDEO_PALETTE_RGB32:
			{
			depth = 32;
			}
			break;
		default:
			depth = -1;
			break;
	}
	return depth;
}

static int
GetVideoPict (struct vdIn *vd)
{
  if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0){
		printf("ERROR opening video_capability interface\n");
		close(vd->fd);
		return -1;
  }

  printf ("VIDIOCGPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
		"depth=%d palette=%d\n", vd->videopict.brightness,
		vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
		vd->videopict.whiteness, vd->videopict.depth,
		vd->videopict.palette);

  return 0;
}

static int
SetVideoPict (struct vdIn *vd)
{
  if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0){
		printf("ERROR set video_capability interface\n");
		close(vd->fd);
		return -1;
  }

  printf ("VIDIOCSPICT brightnes=%d hue=%d color=%d contrast=%d whiteness=%d"
		"depth=%d palette=%d\n", vd->videopict.brightness,
		vd->videopict.hue, vd->videopict.colour, vd->videopict.contrast,
		vd->videopict.whiteness, vd->videopict.depth,
		vd->videopict.palette);

  return 0;
}

double
msecond()
{	
	struct timeval tv;
	
	gettimeofday(&tv, 0);
	return (tv.tv_sec * 1.0e3 + tv.tv_usec * 1.0e-3);
	
}

#define FRAMERATE_INCR 1001

int
enc_init(int use_assembler)
{
	int xerr;
	
	//xvid_plugin_cbr_t cbr;

	xvid_plugin_single_t single;	
	xvid_plugin_2pass1_t rc2pass1;
	xvid_plugin_2pass2_t rc2pass2;
	
	//xvid_plugin_fixed_t rcfixed;
	xvid_enc_plugin_t plugins[7];
	xvid_gbl_init_t xvid_gbl_init;
	xvid_enc_create_t xvid_enc_create;

	/*------------------------------------------------------------------------
	* XviD core initialization
	*----------------------------------------------------------------------*/
	
	/* Set version -- version checking will done by xvidcore */
	
	memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
	xvid_gbl_init.version = XVID_VERSION;
	
	xvid_gbl_init.debug = 0;

	/* Do we have to enable ASM optimizations ? */
	if (use_assembler) {
		xvid_gbl_init.cpu_flags = 0;
	}

	/* Initialize XviD core -- Should be done once per __process__ */	
	xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);

 /*------------------------------------------------------------------------
  * XviD encoder initialization
  *----------------------------------------------------------------------*/

 /* Version again */
	memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));	
	xvid_enc_create.version = XVID_VERSION;

	/* Width and Height of input frames */
	xvid_enc_create.width = XDIM;
	xvid_enc_create.height = YDIM;
	xvid_enc_create.profile = XVID_PROFILE_S_L3;

	/* init plugins  */
	xvid_enc_create.zones = NULL;
	xvid_enc_create.num_zones = 0;
	
	xvid_enc_create.plugins = NULL;
	xvid_enc_create.num_plugins = 0;
	
	/* No fancy thread tests */
	xvid_enc_create.num_threads = 0;

 /* Frame rate - Do some quick float fps = fincr/fbase hack */
	if ((ARG_FRAMERATE - (int) ARG_FRAMERATE) < SMALL_EPS) {	
		xvid_enc_create.fincr = 1;
		xvid_enc_create.fbase = (int) ARG_FRAMERATE;
	} 
	else {
		xvid_enc_create.fincr = FRAMERATE_INCR;
		xvid_enc_create.fbase = (int) (FRAMERATE_INCR * ARG_FRAMERATE);
	}

 	/* Maximum key frame interval */
	if (ARG_MAXKEYINTERVAL > 0) {	
		xvid_enc_create.max_key_interval = ARG_MAXKEYINTERVAL;
	}
	else { 
		xvid_enc_create.max_key_interval = (int) ARG_FRAMERATE *10;
	}
	
	/* Bframes settings */
	xvid_enc_create.max_bframes = 0;
	xvid_enc_create.bquant_ratio = 150;
	xvid_enc_create.bquant_offset = 100;
	
	/* Dropping ratio frame -- we don't need that */	
	xvid_enc_create.frame_drop_ratio = 0;

	/* Global encoder options */
	xvid_enc_create.global = 0;
	
	/* I use a small value here, since will not encode whole movies, but short clips */
	xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
	
	/* Retrieve the encoder instance from the structure */	
	enc_handle = xvid_enc_create.handle;

	return (xerr);
}

int
enc_stop()
{
	int xerr;
	
	/* Destroy the encoder instance */
	xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);
	
	return (xerr);
}

int
enc_main(unsigned char *image,
   unsigned char *bitstream,
   int *key,
   int *stats_type,
   int *stats_quant,
   int *stats_length,
   int sse[3])
{
	int ret;
	
	xvid_enc_frame_t xvid_enc_frame;
	xvid_enc_stats_t xvid_enc_stats;
	
	/* Version for the frame and the stats */
	memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
	xvid_enc_frame.version = XVID_VERSION;
	
	memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
	xvid_enc_stats.version = XVID_VERSION;
	
	/* Bind output buffer */
	xvid_enc_frame.bitstream = bitstream;
	xvid_enc_frame.length = -1;
	
	/* Initialize input image fields */
	if (image) {
		xvid_enc_frame.input.plane[0] = image;
#ifndef READ_PNM
		if (ARG_INPUTTYPE==2)
			xvid_enc_frame.input.csp = XVID_CSP_YV12;
		else
		 	xvid_enc_frame.input.csp = XVID_CSP_I420;
		xvid_enc_frame.input.stride[0] = XDIM;
#else
		xvid_enc_frame.input.csp = XVID_CSP_BGR;
		xvid_enc_frame.input.stride[0] = XDIM*3;
#endif
	} 
	else {
		xvid_enc_frame.input.csp = XVID_CSP_NULL;
	}
	
	/* Set up core's general features */
	xvid_enc_frame.vol_flags = 0;
	if (ARG_STATS)
		xvid_enc_frame.vol_flags |= XVID_VOL_EXTRASTATS;
	if (ARG_QTYPE)
		xvid_enc_frame.vol_flags |= XVID_VOL_MPEGQUANT;
	if (ARG_QPEL)
		xvid_enc_frame.vol_flags |= XVID_VOL_QUARTERPEL;
	if (ARG_GMC)
		xvid_enc_frame.vol_flags |= XVID_VOL_GMC;
	if (ARG_INTERLACING)
		xvid_enc_frame.vol_flags |= XVID_VOL_INTERLACING;
	
	/* Set up core's general features */
	xvid_enc_frame.vop_flags = vop_presets[ARG_QUALITY];
	
	if (ARG_VOPDEBUG) {
		xvid_enc_frame.vop_flags |= XVID_VOP_DEBUG;
	}
	
	if (ARG_GREYSCALE) {
		xvid_enc_frame.vop_flags |= XVID_VOP_GREYSCALE;
	}
	
	/* Frame type -- let core decide for us */
	xvid_enc_frame.type = XVID_TYPE_AUTO;
	
	/* Force the right quantizer -- It is internally managed by RC plugins */
	xvid_enc_frame.quant = 0;
	
	/* Set up motion estimation flags */
	xvid_enc_frame.motion = motion_presets[ARG_QUALITY];
	
	if (ARG_GMC)
		xvid_enc_frame.motion |= XVID_ME_GME_REFINE;
	
	if (ARG_QPEL)
		xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16;
	if (ARG_QPEL && (xvid_enc_frame.vop_flags & XVID_VOP_INTER4V))
		xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8;
	
	if (ARG_TURBO)
		xvid_enc_frame.motion |= XVID_ME_FASTREFINE16 | XVID_ME_FASTREFINE8 |
	       XVID_ME_SKIP_DELTASEARCH | XVID_ME_FAST_MODEINTERPOLATE |
	       XVID_ME_BFRAME_EARLYSTOP;
	
	if (ARG_BVHQ)
		xvid_enc_frame.vop_flags |= XVID_VOP_RD_BVOP;
	
	switch (ARG_VHQMODE) /* this is the same code as for vfw */
	{
		case 1: /* VHQ_MODE_DECISION */
			xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
		break;
		
		case 2: /* VHQ_LIMITED_SEARCH */
			xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
			xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
			xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
		break;
		
		case 3: /* VHQ_MEDIUM_SEARCH */
			xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
			xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
			xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE8_RD;
			xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
			xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
			xvid_enc_frame.motion |= XVID_ME_CHECKPREDICTION_RD;
		break;
		
		case 4: /* VHQ_WIDE_SEARCH */
			xvid_enc_frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
			xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE16_RD;
			xvid_enc_frame.motion |= XVID_ME_HALFPELREFINE8_RD;
			xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
			xvid_enc_frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
			xvid_enc_frame.motion |= XVID_ME_CHECKPREDICTION_RD;
			xvid_enc_frame.motion |= XVID_ME_EXTSEARCH_RD;
		break;
		
		default :
		break;
	}
	 
	if (ARG_QMATRIX) {
		/* We don't use special matrices */
		xvid_enc_frame.quant_intra_matrix = qmatrix_intra;
		xvid_enc_frame.quant_inter_matrix = qmatrix_inter;
	}
	else {
		/* We don't use special matrices */
		xvid_enc_frame.quant_intra_matrix = NULL;
		xvid_enc_frame.quant_inter_matrix = NULL;
	}
	
	/* Encode the frame */
	ret = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame,&xvid_enc_stats);
	
	*key = (xvid_enc_frame.out_flags & XVID_KEYFRAME);
	*stats_type = xvid_enc_stats.type;
	*stats_quant = xvid_enc_stats.quant;
	*stats_length = xvid_enc_stats.length;
	sse[0] = xvid_enc_stats.sse_y;
	sse[1] = xvid_enc_stats.sse_u;
	sse[2] = xvid_enc_stats.sse_v;
	
	return (ret);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -