/* It should set the capture resolution Cheated from the openCV cap_libv4l.cpp the method is the following: Turn off the stream (video_disable) Unmap buffers Close the filedescriptor Initialize the camera again with the new resolution */ int setResolution(struct vdIn *vd, int width, int height) { int ret; DBG("setResolution(%d, %d)\n", width, height); vd->streamingState = STREAMING_PAUSED; if(video_disable(vd, STREAMING_PAUSED) == 0) { // do streamoff DBG("Unmap buffers\n"); int i; for(i = 0; i < NB_BUFFER; i++) munmap(vd->mem[i], vd->buf.length); if(CLOSE_VIDEO(vd->fd) == 0) { DBG("Device closed successfully\n"); } vd->width = width; vd->height = height; if(init_v4l2(vd) < 0) { fprintf(stderr, " Init v4L2 failed !! exit fatal \n"); return -1; } else { DBG("reinit done\n"); video_enable(vd); return 0; } } else { DBG("Unable to disable streaming\n"); return -1; } return ret; }
void destroy_video_device(struct video_device *vd) { if (vd->streaming_state == STREAMING_ON) { video_disable(vd, STREAMING_OFF); } if (CLOSE_VIDEO(vd->fd) != 0) { log_itf(LOG_ERROR, "Failed to close device %s.", vd->device_filename); } free(vd->framebuffer); vd->framebuffer = NULL; free(vd->device_filename); vd->device_filename = NULL; free(vd->formats); vd->formats = NULL; vd->format_count = 0; free(vd->resolutions); vd->resolutions = NULL; vd->resolution_count = 0; free(vd); }
int init_videoIn(struct vdIn *vd, char *device, int width, int height, int fps, int format, int grabmethod, globals *pglobal, int id) { if(vd == NULL || device == NULL) return -1; if(width == 0 || height == 0) return -1; if(grabmethod < 0 || grabmethod > 1) grabmethod = 1; //mmap by default; vd->videodevice = NULL; vd->status = NULL; vd->pictName = NULL; vd->videodevice = (char *) calloc(1, 16 * sizeof(char)); vd->status = (char *) calloc(1, 100 * sizeof(char)); vd->pictName = (char *) calloc(1, 80 * sizeof(char)); snprintf(vd->videodevice, 12, "%s", device); vd->toggleAvi = 0; vd->getPict = 0; vd->signalquit = 1; vd->width = width; vd->height = height; vd->fps = fps; vd->formatIn = format; vd->grabmethod = grabmethod; if(init_v4l2(vd) < 0) { fprintf(stderr, " Init v4L2 failed !! exit fatal \n"); goto error;; } // enumerating formats int currentWidth, currentHeight = 0; struct v4l2_format currentFormat; currentFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(xioctl(vd->fd, VIDIOC_G_FMT, ¤tFormat) == 0) { currentWidth = currentFormat.fmt.pix.width; currentHeight = currentFormat.fmt.pix.height; DBG("Current size: %dx%d\n", currentWidth, currentHeight); } pglobal->in[id].in_formats = NULL; for(pglobal->in[id].formatCount = 0; 1; pglobal->in[id].formatCount++) { struct v4l2_fmtdesc fmtdesc; fmtdesc.index = pglobal->in[id].formatCount; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(xioctl(vd->fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) { break; } if (pglobal->in[id].in_formats == NULL) { pglobal->in[id].in_formats = (input_format*)calloc(1, sizeof(input_format)); } else { pglobal->in[id].in_formats = (input_format*)realloc(pglobal->in[id].in_formats, (pglobal->in[id].formatCount + 1) * sizeof(input_format)); } if (pglobal->in[id].in_formats == NULL) { DBG("Calloc/realloc failed: %s\n", strerror(errno)); return -1; } memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(input_format)); if(fmtdesc.pixelformat == format) pglobal->in[id].currentFormat = pglobal->in[id].formatCount; DBG("Supported format: %s\n", fmtdesc.description); struct v4l2_frmsizeenum fsenum; fsenum.index = pglobal->in[id].formatCount; fsenum.pixel_format = fmtdesc.pixelformat; int j = 0; pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions = NULL; pglobal->in[id].in_formats[pglobal->in[id].formatCount].resolutionCount = 0; pglobal->in[id].in_formats[pglobal->in[id].formatCount].currentResolution = -1; while(1) { fsenum.index = j; j++; if(xioctl(vd->fd, VIDIOC_ENUM_FRAMESIZES, &fsenum) == 0) { pglobal->in[id].in_formats[pglobal->in[id].formatCount].resolutionCount++; if (pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions == NULL) { pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions = (input_resolution*)calloc(1, sizeof(input_resolution)); } else { pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions = (input_resolution*)realloc(pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions, j * sizeof(input_resolution)); } if (pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions == NULL) { DBG("Calloc/realloc failed\n"); return -1; } pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions[j-1].width = fsenum.discrete.width; pglobal->in[id].in_formats[pglobal->in[id].formatCount].supportedResolutions[j-1].height = fsenum.discrete.height; if(format == fmtdesc.pixelformat) { pglobal->in[id].in_formats[pglobal->in[id].formatCount].currentResolution = (j - 1); DBG("\tSupported size with the current format: %dx%d\n", fsenum.discrete.width, fsenum.discrete.height); } else { DBG("\tSupported size: %dx%d\n", fsenum.discrete.width, fsenum.discrete.height); } } else { break; } } } /* alloc a temp buffer to reconstruct the pict */ vd->framesizeIn = (vd->width * vd->height << 1); switch(vd->formatIn) { case V4L2_PIX_FMT_MJPEG: vd->tmpbuffer = (unsigned char *) calloc(1, (size_t) vd->framesizeIn); if(!vd->tmpbuffer) goto error; vd->framebuffer = (unsigned char *) calloc(1, (size_t) vd->width * (vd->height + 8) * 2); break; case V4L2_PIX_FMT_YUYV: vd->framebuffer = (unsigned char *) calloc(1, (size_t) vd->framesizeIn); break; default: fprintf(stderr, " should never arrive exit fatal !!\n"); goto error; break; } if(!vd->framebuffer) goto error; return 0; error: free(pglobal->in[id].in_parameters); free(vd->videodevice); free(vd->status); free(vd->pictName); CLOSE_VIDEO(vd->fd); return -1; }