static int find_best_palette(struct capture_device *c, int *palettes, int nb, int fd){ int best_palette=-1, best_width =-1, best_height=-1, i; struct v4l2_format src, dst; for(i=0; i<nb; i++) { dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG1, "CAP: trying palette %#x (%s) %dx%d - ...\n", libvideo_palettes[palettes[i]].v4l2_palette, libvideo_palettes[palettes[i]].name, c->width, c->height); if(try_image_format(c, &src, &dst, palettes[i])!=-1){ if( (best_palette == -1) || (abs(c->width*c->height - dst.fmt.pix.width*dst.fmt.pix.height) < abs(c->width*c->height - best_width*best_height)) ){ best_palette = palettes[i]; best_width = dst.fmt.pix.width; best_height = dst.fmt.pix.height; dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: palette (%s) is best palette so far\n", libvideo_palettes[palettes[i]].name); } } //else //palette rejected } return best_palette; }
static int set_image_format(struct capture_device *c, int *palettes, int nb, int fd){ int best_palette = -1, i; XMALLOC(c->convert->src_fmt,struct v4l2_format *,sizeof(struct v4l2_format)); XMALLOC(c->convert->dst_fmt,struct v4l2_format *,sizeof(struct v4l2_format)); if(c->width==MAX_WIDTH) c->width=V4L2_MAX_WIDTH; if(c->height==MAX_HEIGHT) c->height=V4L2_MAX_HEIGHT; dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: trying palettes (%d to try in total)\n", nb); //we try all the supplied palettes and find the best one that give us //a resolution closes to the desired one best_palette = find_best_palette(c, palettes, nb, fd); if(best_palette == -1) { info("libvideo was unable to find a suitable palette. The following " "palettes have been tried and failed:\n"); for(i=0; i<nb;i++) info("%s\n",libvideo_palettes[palettes[i]].name); info("Please let the author know about this error.\n"); info("See the ISSUES section in the libvideo README file.\n"); return -1; } else { dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: Setting to best palette %s...\n", libvideo_palettes[best_palette].name); c->convert->src_palette = try_image_format( c, c->convert->src_fmt, c->convert->dst_fmt, best_palette); if (0 == apply_image_format(c->convert->src_fmt, fd)) { dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG1, "CAP: setting src palette (%s) accepted\n", libvideo_palettes[c->convert->src_palette].name); c->palette = best_palette; } else { info("Unable to set the best detected palette: %s\n", libvideo_palettes[best_palette].name); info("Please let the author know about this error.\n"); info("See the ISSUES section in the libvideo README file.\n"); return -1; } } dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: capturing (src) using width: %d, " " height: %d, bytes/line %d, image size: %d - palette: %d (%s)\n", c->convert->src_fmt->fmt.pix.width, c->convert->src_fmt->fmt.pix.height, c->convert->src_fmt->fmt.pix.bytesperline, c->convert->src_fmt->fmt.pix.sizeimage, c->convert->src_palette, libvideo_palettes[c->convert->src_palette].name ); c->is_native = v4lconvert_needs_conversion( c->convert->priv,c->convert->src_fmt, c->convert->dst_fmt)==1?0:1; dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: libv4lconvert required ? %s\n", (c->is_native==0?"Yes":"No")); dprint(LIBVIDEO_SOURCE_CAP, LIBVIDEO_LOG_DEBUG, "CAP: conv to (dst) width: %d, " "height: %d, bytes/line %d, image size: %d - palette: %d (%s)\n", c->convert->dst_fmt->fmt.pix.width, c->convert->dst_fmt->fmt.pix.height, c->convert->dst_fmt->fmt.pix.bytesperline, c->convert->dst_fmt->fmt.pix.sizeimage, c->palette, libvideo_palettes[c->palette].name ); //Store actual width & height c->width = c->convert->dst_fmt->fmt.pix.width; c->height= c->convert->dst_fmt->fmt.pix.height; if(c->is_native==1){ //if no need for conversion, libv4lconvert sometimes returns 0 in //sizeimage and bytesperline fields, so get values from src palette c->imagesize = c->convert->src_fmt->fmt.pix.sizeimage; } else { c->imagesize = c->convert->dst_fmt->fmt.pix.sizeimage; } return 0; }
static int set_image_format(struct capture_device *c, int *palettes, int nb, int fd){ int found=0, i, best_palette=-1, best_width =-1, best_height=-1; struct v4l2_format fmt; if(c->width==MAX_WIDTH) c->width=V4L2_MAX_WIDTH; if(c->height==MAX_HEIGHT) c->height=V4L2_MAX_HEIGHT; dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG, "CAP: trying palettes (%d to try in total)\n", nb); //we try all the supplied palettes and find the best one that give us a resolution closes to the desired one for(i=0; i<nb; i++) { dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG1, "CAP: trying palette %#x (%s) %dx%d - ...\n",\ libv4l_palettes[palettes[i]].v4l2_palette, libv4l_palettes[palettes[i]].name, c->width, c->height); if( (try_image_format(&fmt, c->width, c->height, fd, libv4l_palettes[palettes[i]].v4l2_palette)==0) && ((best_palette == -1) || \ (abs(c->width*c->height - fmt.fmt.pix.width*fmt.fmt.pix.height) < abs(c->width*c->height - best_width*best_height))) ){ best_palette = i; best_width = fmt.fmt.pix.width; best_height = fmt.fmt.pix.height; found = 1; dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG, "CAP: palette (%s) is best palette so far\n", libv4l_palettes[palettes[i]].name); } } if(!found) { info("libv4l was unable to find a suitable palette. The following palettes have been tried and failed:\n"); for(i=0; i<nb;i++) info("%s\n",libv4l_palettes[palettes[i]].name); info("Please let the author know about this error.\n"); info("See the ISSUES section in the libv4l README file.\n"); return -1; } else { dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG, "CAP: Setting to best palette %s...\n",\ libv4l_palettes[palettes[best_palette]].name); if (0 == try_image_format(&fmt, c->width, c->height, fd, libv4l_palettes[palettes[best_palette]].v4l2_palette)) { dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG1, "CAP: palette (%s) accepted\n", libv4l_palettes[palettes[best_palette]].name); c->palette = palettes[best_palette]; } else { info("Unable to set the best detected palette: %s\n", libv4l_palettes[palettes[best_palette]].name); info("Please let the author know about this error.\n"); info("See the ISSUES section in the libv4l README file.\n"); return -1; } } dprint(LIBV4L_LOG_SOURCE_CAPTURE, LIBV4L_LOG_LEVEL_DEBUG, "CAP: Using width: %d, height: %d, bytes/line %d, image size: %d\n", \ fmt.fmt.pix.width,fmt.fmt.pix.height, fmt.fmt.pix.bytesperline, fmt.fmt.pix.sizeimage); //Store actual width & height c->width = fmt.fmt.pix.width; c->height= fmt.fmt.pix.height; if (COMPRESSED_FORMAT_DEPTH == libv4l_palettes[palettes[best_palette]].depth) c->imagesize = fmt.fmt.pix.sizeimage; else { c->imagesize = c->width*c->height*libv4l_palettes[palettes[best_palette]].depth / 8; if(c->imagesize != fmt.fmt.pix.sizeimage) { info("The image size (%d) is not the same as what the driver returned (%d)\n",c->imagesize, fmt.fmt.pix.sizeimage); info("Please let the author know about this error.\n"); info("See the ISSUES section in the libv4l README file.\n"); c->imagesize = fmt.fmt.pix.sizeimage; } } return 0; }