static int vpif_check_format(struct channel_obj *ch, struct v4l2_pix_format *pixfmt) { struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; enum v4l2_field field = pixfmt->field; u32 sizeimage, hpitch, vpitch; if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) goto invalid_fmt_exit; if (!(VPIF_VALID_FIELD(field))) goto invalid_fmt_exit; if (pixfmt->bytesperline <= 0) goto invalid_pitch_exit; if (V4L2_MEMORY_USERPTR == common->memory) sizeimage = pixfmt->sizeimage; else sizeimage = config_params.channel_bufsize[ch->channel_id]; if (vpif_get_std_info(ch)) { vpif_err("Error getting the standard info\n"); return -EINVAL; } hpitch = pixfmt->bytesperline; vpitch = sizeimage / (hpitch * 2); /* Check for valid value of pitch */ if ((hpitch < ch->vpifparams.std_info.width) || (vpitch < ch->vpifparams.std_info.height)) goto invalid_pitch_exit; /* Check for 8 byte alignment */ if (!ISALIGNED(hpitch)) { vpif_err("invalid pitch alignment\n"); return -EINVAL; } pixfmt->width = common->fmt.fmt.pix.width; pixfmt->height = common->fmt.fmt.pix.height; return 0; invalid_fmt_exit: vpif_err("invalid field format\n"); return -EINVAL; invalid_pitch_exit: vpif_err("invalid pitch\n"); return -EINVAL; }
/** * vpif_check_format() - check given pixel format for compatibility * @ch - channel ptr * @pixfmt - Given pixel format * @update - update the values as per hardware requirement * * Check the application pixel format for S_FMT and update the input * values as per hardware limits for TRY_FMT. The default pixel and * field format is selected based on interface type. */ static int vpif_check_format(struct channel_obj *ch, struct v4l2_pix_format *pixfmt, int update) { struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); struct vpif_params *vpif_params = &ch->vpifparams; enum v4l2_field field = pixfmt->field; u32 sizeimage, hpitch, vpitch; int ret = -EINVAL; vpif_dbg(2, debug, "vpif_check_format\n"); /** * first check for the pixel format. If if_type is Raw bayer, * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only * V4L2_PIX_FMT_YUV422P is supported */ if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) { if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) { if (!update) { vpif_dbg(2, debug, "invalid pix format\n"); goto exit; } pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8; } } else { if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) { if (!update) { vpif_dbg(2, debug, "invalid pixel format\n"); goto exit; } pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P; } } if (!(VPIF_VALID_FIELD(field))) { if (!update) { vpif_dbg(2, debug, "invalid field format\n"); goto exit; } /** * By default use FIELD_NONE for RAW Bayer capture * and FIELD_INTERLACED for other interfaces */ field = vpif_get_default_field(&vpif_params->iface); } else if (field == V4L2_FIELD_ANY) /* unsupported field. Use default */ field = vpif_get_default_field(&vpif_params->iface); /* validate the hpitch */ hpitch = pixfmt->bytesperline; if (hpitch < vpif_params->std_info.width) { if (!update) { vpif_dbg(2, debug, "invalid hpitch\n"); goto exit; } hpitch = vpif_params->std_info.width; } if (V4L2_MEMORY_USERPTR == common->memory) sizeimage = pixfmt->sizeimage; else sizeimage = config_params.channel_bufsize[ch->channel_id]; vpitch = sizeimage / (hpitch * 2); /* validate the vpitch */ if (vpitch < vpif_params->std_info.height) { if (!update) { vpif_dbg(2, debug, "Invalid vpitch\n"); goto exit; } vpitch = vpif_params->std_info.height; } /* Check for 8 byte alignment */ if (!ALIGN(hpitch, 8)) { if (!update) { vpif_dbg(2, debug, "invalid pitch alignment\n"); goto exit; } /* adjust to next 8 byte boundary */ hpitch = (((hpitch + 7) / 8) * 8); } /* if update is set, modify the bytesperline and sizeimage */ if (update) { pixfmt->bytesperline = hpitch; pixfmt->sizeimage = hpitch * vpitch * 2; } /** * Image width and height is always based on current standard width and * height */ pixfmt->width = common->fmt.fmt.pix.width; pixfmt->height = common->fmt.fmt.pix.height; return 0; exit: return ret; }
static int vpif_check_format(struct channel_obj *ch, struct v4l2_pix_format *pixfmt, int update) { struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); struct vpif_params *vpif_params = &ch->vpifparams; enum v4l2_field field = pixfmt->field; u32 sizeimage, hpitch, vpitch; int ret = -EINVAL; vpif_dbg(2, debug, "vpif_check_format\n"); if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) { if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) { if (!update) { vpif_dbg(2, debug, "invalid pix format\n"); goto exit; } pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8; } } else { if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) { if (!update) { vpif_dbg(2, debug, "invalid pixel format\n"); goto exit; } pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P; } } if (!(VPIF_VALID_FIELD(field))) { if (!update) { vpif_dbg(2, debug, "invalid field format\n"); goto exit; } field = vpif_get_default_field(&vpif_params->iface); } else if (field == V4L2_FIELD_ANY) field = vpif_get_default_field(&vpif_params->iface); hpitch = pixfmt->bytesperline; if (hpitch < vpif_params->std_info.width) { if (!update) { vpif_dbg(2, debug, "invalid hpitch\n"); goto exit; } hpitch = vpif_params->std_info.width; } if (V4L2_MEMORY_USERPTR == common->memory) sizeimage = pixfmt->sizeimage; else sizeimage = config_params.channel_bufsize[ch->channel_id]; vpitch = sizeimage / (hpitch * 2); if (vpitch < vpif_params->std_info.height) { if (!update) { vpif_dbg(2, debug, "Invalid vpitch\n"); goto exit; } vpitch = vpif_params->std_info.height; } if (!ALIGN(hpitch, 8)) { if (!update) { vpif_dbg(2, debug, "invalid pitch alignment\n"); goto exit; } hpitch = (((hpitch + 7) / 8) * 8); } if (update) { pixfmt->bytesperline = hpitch; pixfmt->sizeimage = hpitch * vpitch * 2; } pixfmt->width = common->fmt.fmt.pix.width; pixfmt->height = common->fmt.fmt.pix.height; return 0; exit: return ret; }