Exemplo n.º 1
0
// Custom camera initialiazation function
void custom_v4l2_init(void* parm_void)
{
#define V4L2_CID_C920_ZOOMVAL    0x9A090D  //Zoom           (wide=0, telephoto=500)
#define V4L2_CID_C920_AUTOFOCUS  0x9A090C  //Autofocus      (0=OFF, 1 = ON)
#define V4L2_CID_C920_FOCUSVAL   0X9A090A  //Focus Value    (min=0, max=250)
#define V4L2_C920_FOCUS_INF      0
#define V4L2_C920_FOCUS_MACRO    250

    struct v4l2Parms* parm = (struct v4l2Parms*) parm_void;

    set_parm(parm->fd, V4L2_CID_C920_AUTOFOCUS,0);      // Turn autofocus off
    set_parm(parm->fd, V4L2_CID_C920_FOCUSVAL,V4L2_C920_FOCUS_INF);   // Use infinity focus (no macro)
    set_parm(parm->fd, V4L2_CID_C920_ZOOMVAL,107);      // Zoom (trying to match PS3 Eye)
    //set_parm(parm->fd, V4L2_CID_C920_ZOOMVAL,150);
    set_parm(parm->fd, V4L2_CID_SATURATION,170);        // Adjust Saturation (0-255)
    set_parm(parm->fd, V4L2_CID_SHARPNESS,128);         // Blur the image to get smoother contours (0-255)

#ifdef INDOOR
    set_manual_exposure(parm->fd, 20);  // Indoor exposure
    set_parm(parm->fd, V4L2_CID_GAIN, 255); // Indoor gain
#endif

#ifdef OUTDOOR
    set_manual_exposure(parm->fd, 3); // Outdoor exposure (4 to 2046)
    set_parm(parm->fd, V4L2_CID_GAIN, 15); // Outdoor gain
#endif

#ifdef AUTO
    set_auto_exposure(parm->fd);
#endif

    set_parm(parm->fd, V4L2_CID_BRIGHTNESS, 128);
    set_parm(parm->fd, V4L2_CID_CONTRAST, 128);
}
Exemplo n.º 2
0
void camera_server() {
	size_t count = 0;

	initialise_termination_handler();

	int deviceDescriptor = v4l2_open("/dev/video0",
			O_RDWR /* required */| O_NONBLOCK, 0);
	if (deviceDescriptor == -1) {
		throw std::runtime_error("Unable to open device");
	}

//	disable_output_processing(deviceDescriptor);

	if (!isStreamingIOSupported(deviceDescriptor)) {
		throw std::runtime_error("Streaming is not supported");
	}


	setCameraOutputFormat(deviceDescriptor, CAMERA_FRAME_WIDTH, CAMERA_FRAME_HEIGHT, V4L2_PIX_FMT_YUYV);


	std::cout << "Absolute focus supported: " << isControlSupported(deviceDescriptor,V4L2_CID_FOCUS_ABSOLUTE) << std::endl;
	std::cout << "Relative focus supported: " << isControlSupported(deviceDescriptor,V4L2_CID_FOCUS_RELATIVE) << std::endl;


	set_manual_exposure(deviceDescriptor,true);
	printf("Is manual exposure set = %u\n", is_manual_exposure(deviceDescriptor));
	set_absolute_exposure(100,deviceDescriptor);

	set_exposure_auto_priority(deviceDescriptor,false);
	printf("Is exposure auto priority set = %u\n", is_exposure_auto_priority(deviceDescriptor));

	set_auto_white_balance(deviceDescriptor,false);
	printf("Is auto white balance set = %u\n", is_auto_white_balance_set(deviceDescriptor));

	set_gain(deviceDescriptor,1);
	printf("Gain set = %u\n", get_gain(deviceDescriptor));


    printf("Focus value = %u\n", get_focus_variable(deviceDescriptor));

	set_fps(deviceDescriptor,30);


	start_capturing(deviceDescriptor);


	unsigned int counter;



	int announce_socket=socket(AF_INET,SOCK_DGRAM,0);
	if (announce_socket < 0) {
	  perror("socket");
	  exit(1);
	}

	sockaddr_in announce_address;
	memset(&announce_address,0,sizeof(announce_address));
	announce_address.sin_family=AF_INET;
	announce_address.sin_addr.s_addr=inet_addr(CAMERA_ANNOUNCE_GROUP);
	announce_address.sin_port=htons(CAMERA_ANNOUNCE_PORT);

	while (running != 0) {
		fd_set fds;
		int r;

		FD_ZERO(&fds);
		FD_SET(deviceDescriptor, &fds);

		r = select(deviceDescriptor + 1, &fds, NULL, NULL, NULL);

		if (r > 0) {
			struct v4l2_buffer buf;

			memset(&buf, 0, sizeof(buf));

			buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buf.memory = V4L2_MEMORY_USERPTR;

			if (-1 == xioctl(deviceDescriptor, VIDIOC_DQBUF, &buf)) {
				switch (errno) {
				case EAGAIN:
					continue;

				case EIO:
					/* Could ignore EIO, see spec. */

					/* fall through */

				default:
					perror("VIDIOC_DQBUF");
					exit(1);
				}
			}

			if ((buf.flags | V4L2_BUF_FLAG_ERROR) != 0) {
//TODO Investigate the permanent occurence of the V4L2_BUF_FLAG_ERROR
//				std::cerr << "Frame buffer error" << std::endl;
			}

			printf("Index = %u, seconds = %ld us = %ld\n", buf.index,buf.timestamp.tv_sec,buf.timestamp.tv_usec);
		//	printf("Real time: seconds = %ld, us = %ld\n", tp.tv_sec,tp.tv_nsec/1000);

			int ret;
			assert(ptrToSequenceMap.count(buf.m.userptr) != 0);
			size_t sequence_number = ptrToSequenceMap[buf.m.userptr];
			ptrToSequenceMap.erase(buf.m.userptr);

			queueNextFrameBuffer(deviceDescriptor, buf.index, sequence_number, CAMERA_FRAME_WIDTH*CAMERA_FRAME_HEIGHT*2);

//TODO Investigate why the video streaming fails if the unmap call below is placed before the queueNextFrameBuffer call above.
//Probably this is because in that case the mmap call returns the same virtual address as the munmap call had just used for the deallocation
			ret = munmap(reinterpret_cast<void*>(buf.m.userptr),buf.length);
			if (ret == -1) {
				perror("munmap");
			}

			BufferReference readyBuffer;
			readyBuffer.index = buf.index;
			readyBuffer.offset = 0;
			readyBuffer.size = buf.bytesused;
			readyBuffer.timestamp_seconds = buf.timestamp.tv_sec;
			readyBuffer.timestamp_microseconds = buf.timestamp.tv_usec;

			readyBuffer.width = CAMERA_FRAME_WIDTH;
			readyBuffer.height = CAMERA_FRAME_HEIGHT;
			readyBuffer.sequence = sequence_number;

			std::array<char,1024> ipc_buffer;
			asn_enc_rval_t encode_result = der_encode_to_buffer(&asn_DEF_BufferReference, &readyBuffer,ipc_buffer.data(),ipc_buffer.size());


			ret = sendto(announce_socket,ipc_buffer.data(),encode_result.encoded,0,(struct sockaddr *) &announce_address,sizeof(announce_address));
			if (ret < 0) {
			   perror("sendto");
			   exit(1);
			}

			timespec tp;
			clock_gettime(CLOCK_MONOTONIC,&tp);

			std::cout << "Grab frame delay = " << get_milliseconds_delta(buf.timestamp,tp) << " ms" << std::endl;

			count++;

			counter++;


		}
	}

	v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if (-1 == xioctl(deviceDescriptor, VIDIOC_STREAMOFF, &type))
		perror("VIDIOC_STREAMOFF");

	if (-1 == close(deviceDescriptor))
		perror("close");

	close(announce_socket);
}