Esempio n. 1
0
int main(int argc, char**argv){

	//--- create variables and initialize them. init()
	char* video_device = VIDEO_DEVICE;
	// 1) -------- 打开设备 /dev/video*: --------
	printf("--------------------------------------\n");
	printf("Step 1: Open devide using V4L2.\n");
	if(argc>1) {
		video_device=argv[1];
		printf("        Select: %s\n", video_device);
	}
	// create a handler for /dev/video* device:
	// 采用阻塞模式打开;若为非阻塞模式:O_RDWR | O_NONBLOCK
	int fdwr = 0;  // for /dev/video* handler
	if(NON_BLOCK_VIDEO){
		fdwr = open(video_device, O_RDWR | O_NONBLOCK);
		printf("        Open: %s using NON_BLOCK mode\n", video_device);
	} else{
		fdwr = open(video_device, O_RDWR);
		printf("        Open: %s using BLOCK mode\n", video_device);
	}
	assert(fdwr >= 0);
	printf("--------------------------------------\n");

	// 2) -------- 查询设备属性 --------
	printf("Step 2: v4l2_capacity check:\n");
	struct v4l2_capability vid_caps;
	memset(&vid_caps, 0, sizeof(vid_caps));
	int ret_code = 0; // for checking the V4L2 ioctl() method return status. 
	ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps);
	assert(ret_code != -1);
	if(debug==1) 
		print_cap(&vid_caps);

	// 3) 设置视频的制式和帧格式:
	printf("Step 3: v4l2_format check/set:\n");
	struct v4l2_format vid_format;
	memset(&vid_format, 0, sizeof(vid_format));
//	ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format);

	if(V4L2_BUF_TYPE == CAPTURE){
		vid_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	} else{
		vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	}
	
	vid_format.fmt.pix.width = FRAME_WIDTH;
	vid_format.fmt.pix.height = FRAME_HEIGHT;
	vid_format.fmt.pix.pixelformat = FRAME_FORMAT;

//	size_t framesize;
//	size_t linewidth;
	__u32 framesize;
	__u32 linewidth;
	if(!format_properties(vid_format.fmt.pix.pixelformat, vid_format.fmt.pix.width, 
						vid_format.fmt.pix.height, &linewidth, &framesize)) {
		printf("unable to guess correct settings for format '%d'\n", FRAME_FORMAT);
	} else{
//		printf("FrameSize = %d\n", framesize);
//		printf("linewidth = %d\n", linewidth);
	}

	// check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L87
	vid_format.fmt.pix.field = V4L2_FIELD_NONE; // V4L2_FIELD_ANY

	// check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L185
	vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
//	vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;

	vid_format.fmt.pix.sizeimage = framesize;
	vid_format.fmt.pix.bytesperline = linewidth;

	if(debug==1)
		print_format(&vid_format);

	ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format);
	assert(ret_code != -1);
/*
	// After set v4l2_format, read it back for double check. 
	// Just to make sure that there is no mis-set and the sys 'secretly' 
	// set the parameters to some 'default' value. 
	if(debug == 1){
		ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format);
		assert(ret_code != -1);
		printf("after set, get it back to double check:\n");
		print_format(&vid_format);
	}
*/	

/*
	struct v4l2_fmtdesc vid_desc;
	vid_desc.index = 0;
	if(debug==1)
		print_desc(fdwr,&vid_desc);
*/

	// 4) Check the video standard:
	// in general the standard is either PAL(720*576) for asian; or NTSC (720*480) for EU.
	// in our virtual camera scenario, the "v4l2_standard" does not matter much. 
	// 4.1) get the current video standard:
	printf("Step 4: check the video standard.\n");
	//struct v4l2_std_id vid_std_id;  // 64 bit length var.
	struct v4l2_standard vid_std;
	v4l2_std_id std_id;

	ret_code = ioctl(fdwr, VIDIOC_G_STD, &std_id);
	if(ret_code == -1){
		printf("        Acquire video standard ERROR:%d\n",ret_code);
	} else{
		memset(&vid_std, 0, sizeof(vid_std));
		vid_std.index = 0; // emun from the first one:
		while(0 == ioctl(fdwr, VIDIOC_ENUMSTD, &vid_std)){
			if(vid_std.id & std_id){
				printf("Current video standard: %s\n", vid_std.name);
			}
			vid_std.index++;
		}
	}

	struct v4l2_streamparm parm;
    memset(&parm, 0, sizeof(parm));
    parm.type =vid_format.type;
    ret_code = ioctl(fdwr,VIDIOC_G_PARM,&parm);
    if(ret_code == -1)
    	printf("get parameter failed.");
    parm.parm.output.timeperframe.numerator = 1000;
    parm.parm.output.timeperframe.denominator = FPS * parm.parm.output.timeperframe.numerator;
    if(ioctl(fdwr,VIDIOC_S_PARM,&parm)==0){
    	struct v4l2_fract *tf = &parm.parm.output.timeperframe;
    	if(!tf->denominator || !tf->numerator)
    		printf("invalid frame rate\n");
    	else
    		printf("        Frame Rate                     =%.3f fps\n", 
    			                            1.0 * tf->denominator/tf->numerator);
    }
//    printf("        v4l2_streamparm set/check:\n");
    printf("        parm.type(capture=1/output=2)  =%d\n", parm.type);
    printf("        parm.parm.output.capability    =0x%4x\n", parm.parm.output.capability);
	printf("--------------------------------------\n");

// 5) request buffer:
	printf("Step 5: Request video buffers\n");
	struct v4l2_requestbuffers req;
	req.count = NUM_BUFFER;
	req.memory = V4L2_MEMORY_MMAP;
    req.type = vid_format.type;  // V4L2_BUF_TYPE_VIDEO_OUTPUT = 2;

	ret_code = ioctl(fdwr, VIDIOC_REQBUFS, &req);
	if(debug == 1){
		print_requestbuffers(&req);
	}
    
  	tp_buffers *data;
    // malloc() + memset (p, 0, size);
    data= (struct buffer*) calloc(req.count, sizeof( tp_buffers));
    //data=(tp_buffers*) calloc(req.count,sizeof (tp_buffers));
	if(!data){
		printf ("Out of memory/n");
		exit (EXIT_FAILURE);
	}

	int index = 0;
	// set the parameter for every buffer in the buf_arr[], 
	// to make sure they are the same as thos in the 'req'. 
    for(index=0; index<req.count; index++){
        memset(&buf_arr[index], 0, sizeof(buf_arr[index]));
        buf_arr[index].index = index;
        buf_arr[index].type = vid_format.type;
        buf_arr[index].memory = req.memory; // should be V4L2_MEMORY_MMAP;

        // 查询序号为i 的缓冲区,得到其起始物理地址和大小
		if(-1 == ioctl (fdwr, VIDIOC_QUERYBUF, &buf_arr[index]))
			exit(-1);
		
		data[index].length = buf_arr[index].length;
		// 映射内存
		data[index].start = mmap(NULL, buf_arr[index].length, PROT_READ | PROT_WRITE, 
						MAP_SHARED, fdwr, buf_arr[index].m.offset);

		if(MAP_FAILED == data[index].start)
			exit(-1);

//		printf("        data[%d].start = 0x%08x", index, data[index].start);
		printf("        data[%d].length                     = %d\n", index, data[index].length);
//		printf("buf.length = %d, framesize = %d ,buf.m.offset = %d\n",
//					buf_arr[index].length,(int)framesize,buf_arr[index].m.offset);   
    }

    // 6) assign buffers to the queue.
	printf("step 6: assign buffers to the queue.\n");

	// Queue buffers:
    for(index = 0; index < req.count; index++){
    	ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]);
    }

    // STREAM-ON
    enum v4l2_buf_type type = vid_format.type;
    ret_code = ioctl(fdwr, VIDIOC_STREAMON, &type);
    assert(ret_code != -1);

    // image streaming testing. 
    // need to convert from RGBA format to YUYV format, 
    // and then QBUF to the buffer array. 
    int color = 128;
	// write AVOS mFrame image to buffers[ind]:
	const int BENCH = 255;

	FILE * bmp_fd = NULL;
	BYTE bmp_header[128];
	int bmp_width;
	int bmp_height;
	int bmp_header_len;
	BYTE * rgb = NULL;
	BYTE * yuv = NULL;
	char *pic[4]={"1.bmp","2.bmp","3.bmp","4.bmp"}; 		
// 	char *pic[4]={"5.bmp","5.bmp","5.bmp","5.bmp"}; 		
	while(1){
	/*
	// set image/
		if(color >= BENCH)
			color = color % BENCH;
		else
			color++;

		for(index=0; index < req.count; index++){
//			memset(data[index].start, color,1179648);
			memset(data[index].start, 128,1024);
			memset(data[index].start+1024, 255,vid_format.fmt.pix.sizeimage-1024);
		}*/
		for(index=0; index < req.count; index++){
	//		printf("%s\n",pic[index]);
			bmp_fd = fopen(pic[index],"rb");
			if(!bmp_fd)
			{
				fprintf(stderr,"open bmp file failed!\n");
				exit(1);
			}
			fgets(bmp_header,sizeof(bmp_header),bmp_fd);
			bmp_header_len = get_long_value(&bmp_header[10]);
			bmp_width = get_long_value(&bmp_header[18]);
			bmp_height = get_long_value(&bmp_header[22]);
			fclose(bmp_fd);
	//		printf("hearder_len:%d\n",bmp_header_len);	
		//	printf("image :%d*%d\n",bmp_width,bmp_height);
		//	printf("width*height*2:%d\n",bmp_width*bmp_height*2);
	//		printf("sizeimage:%d\n",vid_format.fmt.pix.sizeimage);
			rgb = malloc(bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len);
			if(!rgb)
			{
				fprintf(stderr,"rgb malloc failed\n");
			}
			yuv = malloc(bmp_width*bmp_height*sizeof(YUVTRIPLE));
			if(!yuv)
			{
				fprintf(stderr,"yuv malloc failed\n");
			}
//			fread(rgb,bmp_width*bmp_height*3+bmp_header_len,1,bmp_fd);
			bmp_fd = fopen(pic[index],"rb");
			fread(rgb,bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len,1,bmp_fd);
			bgr2yuv(yuv,(RGBTRIPLE *)(rgb+bmp_header_len),bmp_width,bmp_height);	
			memcpy(data[index].start, yuv,vid_format.fmt.pix.sizeimage);
			if(rgb)
			{
			free(rgb);
			}
			if(yuv)
			{
				free(yuv);
			}
			fclose(bmp_fd);
		}
		for(index = 0; index < req.count; index++){
		//buf_arr[index].m.offset = 0;
	//		usleep(40000);
			sleep(1);
			ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]);
		}

<<<<<<< HEAD
//		usleep(1/FPS * 1000 * 1000);
		usleep(40000);
=======
	//	usleep(40000);
>>>>>>> d1308ed6e339365aa9876a4e3f265d74eb880e0a
Esempio n. 2
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : ecat_get_value
@INPUT      : file - ECAT file pointer
              which_header - header in which to look
              volume_number - frame or bed position for subheader 
                 (counting from 0)
              slice_number - number of slice for subheader (counting from 0)
              field - field to look for
              index - index for multi-valued fields (counting from zero)
@OUTPUT     : ivalue - integer value
              fvalue - floating-point value
              svalue - string value
@RETURNS    : FALSE if successful, TRUE otherwise
@DESCRIPTION: Routine to look up a field value in a header table.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : January 4, 1996 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static int ecat_get_value(Ecat_file *file,
                           Ecat_which_header which_header,
                           int volume_number, int slice_number,
                           Ecat_field_name field,
                           int index,
                           int *ivalue, double *fvalue, char *svalue)
{
   /* Sizes of ECAT types */
   static int ecat_type_sizes[] = {1, 2, 4, 4, 1};

   /* Variables */
   unsigned char *header;
   Ecat_header_table_type *table;
   int offset, length;
   Ecat_type type;
   unsigned char byte_value;
   short short_value;
   long long_value;
   float float_value;
   char string[ECAT_MAX_STRING_LENGTH];

   /* Get the appropriate header */
   switch (which_header) {
   case ECAT_MAIN_HEADER: 
      header = file->main_header;
      table = file->header_description->main_header;
      break;
   case ECAT_SUBHEADER:
      if (ecat_read_subhdr(file, volume_number, slice_number)) {
         return TRUE;
      }
      header = file->subheader;
      table = file->header_description->subheader;
      break;
   default:
      return TRUE;
   }

   /* Look for the field description */
   if (ecat_lookup_field(table, field, &offset, &length, &type, NULL)) {
      return TRUE;
   }

   /* Check the index */
   if ((index < 0) || (index >= length) || 
       ((type == ecat_char) && (index > 0))) {
      return TRUE;
   }
   offset += index * ecat_type_sizes[type];

   /* Get the value and convert it */
   switch (type) {
   case ecat_byte:
     byte_value = header[offset];
     if (ivalue != NULL) *ivalue = byte_value;
     if (fvalue != NULL) *fvalue = byte_value;
     if (svalue != NULL) (void) sprintf(svalue, "%d", (int) byte_value);
     break;
   case ecat_short:
     if (file->vax_byte_order) {
	get_vax_short(1, &header[offset], &short_value);
     }
     else {
       get_short_value(& header[offset], &short_value);
     }
     if (ivalue != NULL) *ivalue = short_value;
     if (fvalue != NULL) *fvalue = short_value;
     if (svalue != NULL) (void) sprintf(svalue, "%d", (int) short_value);
     break;
   case ecat_long:
     if (file->vax_byte_order) {
       get_vax_long(1, &header[offset], &long_value);
     }
     else {
       get_long_value(& header[offset], &long_value);
     }
      if (ivalue != NULL) *ivalue = long_value;
      if (fvalue != NULL) *fvalue = long_value;
      if (svalue != NULL) (void) sprintf(svalue, "%d", (int) long_value);
      break;
   case ecat_float:
      offset += index * sizeof(float);
      if (file->vax_byte_order) {
	get_vax_float(1, &header[offset], &float_value);
      }
      else {
	get_long_value(& header[offset], &float_value);
      }
      if (ivalue != NULL) *ivalue = float_value;
      if (fvalue != NULL) *fvalue = float_value;
      if (svalue != NULL) (void) sprintf(svalue, "%.7g", 
                                         (double) float_value);
      break;
   case ecat_char:
      (void) memcpy(string, &header[offset], length);
      string[length] = '\0';
      if (ivalue != NULL) *ivalue = atoi(svalue);
      if (fvalue != NULL) *fvalue = atof(svalue);
      if (svalue != NULL) (void) strcpy(svalue, string);
      break;
   default:
      return TRUE;
   }

   return FALSE;

}