static enum sh_css_err
fill_binary_info(const struct sh_css_binary_info *info,
                 bool online,
                 bool two_ppc,
                 enum sh_css_input_format stream_format,
                 const struct sh_css_frame_info *in_info,
                 const struct sh_css_frame_info *out_info,
                 const struct sh_css_frame_info *vf_info,
                 struct sh_css_binary *binary)
{
    unsigned int dvs_env_width = 0,
    dvs_env_height = 0,
    vf_log_ds = 0,
    s3a_log_deci = 0,
    bits_per_pixel = in_info->raw_bit_depth,
    ds_input_width = 0,
    ds_input_height = 0,
    isp_input_width,
    isp_input_height,
    isp_internal_width,
    isp_internal_height,
    isp_output_width  = out_info->padded_width,
    isp_output_height = out_info->height,
    s3a_isp_width;
    bool enable_ds = info->enable_ds;
    bool enable_hus = in_info->width < out_info->width;
    bool enable_vus = in_info->height < out_info->height;

    if (info->enable_dvs_envelope) {
        sh_css_video_get_dis_envelope(&dvs_env_width, &dvs_env_height);
        dvs_env_width  = MAX(dvs_env_width, SH_CSS_MIN_DVS_ENVELOPE);
        dvs_env_height = MAX(dvs_env_height, SH_CSS_MIN_DVS_ENVELOPE);
        binary->dvs_envelope_width  = dvs_env_width;
        binary->dvs_envelope_height = dvs_env_height;
    }
    if (vf_info) {
        enum sh_css_err err;
        err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
        if (err != sh_css_success)
            return err;
        vf_log_ds = min(vf_log_ds, info->max_vf_log_downscale);
    }
    if (online) {
        bits_per_pixel = sh_css_input_format_bits_per_pixel(
            stream_format, two_ppc);
    }
    ds_input_width  = in_info->padded_width + info->left_cropping;
    ds_input_height = in_info->height + info->top_cropping;
    if (enable_hus)
        ds_input_width  += dvs_env_width;
    if (enable_vus)
        ds_input_height += dvs_env_height;

    /* We first calculate the resolutions used by the ISP. After that,
     * we use those resolutions to compute sizes for tables etc. */
    isp_internal_width  =
    __ISP_INTERNAL_WIDTH(isp_output_width, dvs_env_width,
    info->left_cropping, info->mode,
    info->c_subsampling,
    info->output_num_chunks, info->pipelining,
    out_info->format ==
    SH_CSS_FRAME_FORMAT_RGBA888);
    isp_internal_height =
    __ISP_INTERNAL_HEIGHT(isp_output_height, info->top_cropping,
    dvs_env_height);
    isp_input_width = _ISP_INPUT_WIDTH(isp_internal_width,
    ds_input_width,
    enable_ds || enable_hus);
    isp_input_height = _ISP_INPUT_HEIGHT(isp_internal_height,
    ds_input_height,
    enable_ds || enable_vus);

    s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(isp_input_width,
    isp_internal_width, enable_hus, info->left_cropping);
    if (info->fixed_s3a_deci_log)
        s3a_log_deci = info->fixed_s3a_deci_log;
    else
        s3a_log_deci = sh_css_grid_deci_factor_log2(s3a_isp_width,
        isp_input_height);

    binary->vf_downscale_log2 = vf_log_ds;
    binary->deci_factor_log2  = s3a_log_deci;
    binary->input_buf_vectors =
    SH_CSS_NUM_INPUT_BUF_LINES * _ISP_VECS(isp_input_width);
    binary->online            = online;
    binary->input_format      = stream_format;
    /* input info */
    binary->in_frame_info.format = in_info->format;
    binary->in_frame_info.width = in_info->width + info->left_cropping +
    dvs_env_width;
    binary->in_frame_info.padded_width  = isp_input_width;
    binary->in_frame_info.height        = isp_input_height;
    binary->in_frame_info.raw_bit_depth = bits_per_pixel;
    /* internal frame info */
    binary->internal_frame_info.format          = out_info->format;
    binary->internal_frame_info.width           = isp_internal_width;
    binary->internal_frame_info.padded_width    = isp_internal_width;
    binary->internal_frame_info.height          = isp_internal_height;
    binary->internal_frame_info.raw_bit_depth   = bits_per_pixel;
    /* output info */
    binary->out_frame_info.format        = out_info->format;
    binary->out_frame_info.width         = out_info->width;
    binary->out_frame_info.padded_width  = isp_output_width;
    binary->out_frame_info.height        = isp_output_height;
    binary->out_frame_info.raw_bit_depth = bits_per_pixel;

    /* viewfinder output info */
    binary->vf_frame_info.format = SH_CSS_FRAME_FORMAT_YUV_LINE;
    if (vf_info) {
        unsigned int vf_out_vecs, vf_out_width, vf_out_height;
        vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(isp_output_width,
        vf_log_ds);
        vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
        vf_out_height = _ISP_VF_OUTPUT_HEIGHT(isp_output_height,
        vf_log_ds);
        /* we also store the raw downscaled width. This is used for
         * digital zoom in preview to zoom only on the width that
         * we actually want to keep, not on the aligned width. */
        binary->vf_frame_info.width = (out_info->width >> vf_log_ds);
        binary->vf_frame_info.padded_width = vf_out_width;
        binary->vf_frame_info.height       = vf_out_height;
    } else {
enum ia_css_err
sh_css_fill_binary_info(const struct ia_css_binary_info *info,
		 bool online,
		 bool two_ppc,
		 enum ia_css_stream_format stream_format,
		 const struct ia_css_frame_info *in_info, /* can be NULL */
		 const struct ia_css_frame_info *out_info, /* can be NULL */
		 const struct ia_css_frame_info *vf_info, /* can be NULL */
		 struct sh_css_binary *binary,
		 bool continuous,
		 struct ia_css_resolution *dvs_env)
{
	unsigned int dvs_env_width = 0,
		     dvs_env_height = 0,
		     vf_log_ds = 0,
		     s3a_log_deci = 0,
		     bits_per_pixel = 0,
		     ds_input_width = 0,
		     ds_input_height = 0,
		     isp_input_width,
		     isp_input_height,
		     isp_internal_width,
		     isp_internal_height,
		     isp_output_width = 0,
		     isp_output_height = 0,
		     s3a_isp_width;
	unsigned char enable_ds = info->enable.ds;
	bool enable_yuv_ds = enable_ds & 2;
	bool enable_hus = false;
	bool enable_vus = false;
	bool is_out_format_rgba888 = false;
	unsigned int tmp_width, tmp_height;

	assert(info != NULL);
	assert(binary != NULL);

	if (in_info != NULL) {
		bits_per_pixel = in_info->raw_bit_depth;
		if (out_info != NULL) {
			enable_hus = in_info->res.width < out_info->res.width;
			enable_vus = in_info->res.height < out_info->res.height;
		}
	}
	if (out_info != NULL) {
		isp_output_width  = out_info->padded_width;
		isp_output_height = out_info->res.height;
		is_out_format_rgba888 =
			out_info->format == IA_CSS_FRAME_FORMAT_RGBA888;
	}
	if (info->enable.dvs_envelope) {
		assert(dvs_env != NULL);
		dvs_env_width  = max(dvs_env->width, SH_CSS_MIN_DVS_ENVELOPE);
		dvs_env_height = max(dvs_env->height, SH_CSS_MIN_DVS_ENVELOPE);
	}
	binary->dvs_envelope.width  = dvs_env_width;
	binary->dvs_envelope.height = dvs_env_height;
	if (vf_info != NULL) {
		enum ia_css_err err;
		err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
		if (err != IA_CSS_SUCCESS)
			return err;
		vf_log_ds = min(vf_log_ds, info->max_vf_log_downscale);
	}
	if (online) {
		bits_per_pixel = sh_css_input_format_bits_per_pixel(
			stream_format, two_ppc);
	}
	if (in_info != NULL) {
		ds_input_width  = in_info->padded_width + info->left_cropping;
		ds_input_height = in_info->res.height + info->top_cropping;
	}
	if (enable_hus) /* { */
		ds_input_width  += dvs_env_width;
	/* } */
	if (enable_vus) /* { */
		ds_input_height += dvs_env_height;
	/* } */
	tmp_width  = (enable_yuv_ds && (ds_input_width > isp_output_width)) ?
			ds_input_width  : isp_output_width;
	tmp_height = (enable_yuv_ds && (ds_input_height > isp_output_height)) ?
			ds_input_height : isp_output_height;

	/* We first calculate the resolutions used by the ISP. After that,
	 * we use those resolutions to compute sizes for tables etc. */
	isp_internal_width = __ISP_INTERNAL_WIDTH(tmp_width,
		(int)dvs_env_width, /* the typecast here is added to avoid a signed/unsigned warning in visual studio */
		info->left_cropping, info->mode,
		info->c_subsampling,
		info->output_num_chunks, info->pipelining,
		is_out_format_rgba888);
	isp_internal_height = __ISP_INTERNAL_HEIGHT(tmp_height,
		info->top_cropping,
		dvs_env_height);
	isp_input_width = _ISP_INPUT_WIDTH(isp_internal_width,
		ds_input_width,
		enable_ds || enable_hus);
	isp_input_height = _ISP_INPUT_HEIGHT(isp_internal_height,
		ds_input_height,
		enable_ds || enable_vus);
	s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(isp_input_width,
		isp_internal_width, enable_hus || enable_yuv_ds,
		info->left_cropping);
	if (info->fixed_s3a_deci_log) {
/* */
		s3a_log_deci = info->fixed_s3a_deci_log;
	}
	else {
/* */
		s3a_log_deci = sh_css_grid_deci_factor_log2(s3a_isp_width,
							    isp_input_height);
	}

	binary->vf_downscale_log2 = vf_log_ds;
	binary->deci_factor_log2  = s3a_log_deci;
	binary->input_buf_vectors =
			SH_CSS_NUM_INPUT_BUF_LINES * _ISP_VECS(isp_input_width);
	binary->online            = online;
	binary->input_format      = stream_format;
	/* input info */
	if (in_info != NULL) {
		binary->in_frame_info.format = in_info->format;
		binary->in_frame_info.res.width = in_info->res.width +
			info->left_cropping + dvs_env_width;
	}
	binary->in_frame_info.padded_width  = isp_input_width;
	binary->in_frame_info.res.height    = isp_input_height;
	binary->in_frame_info.raw_bit_depth = bits_per_pixel;
	/* internal frame info */
	if (out_info != NULL) /* { */
		binary->internal_frame_info.format          = out_info->format;
	/* } */
	binary->internal_frame_info.res.width       = isp_internal_width;
	binary->internal_frame_info.padded_width    = isp_internal_width;
	binary->internal_frame_info.res.height      = isp_internal_height;
	binary->internal_frame_info.raw_bit_depth   = bits_per_pixel;
	/* output info */
	if (out_info != NULL) {
		binary->out_frame_info.format        = out_info->format;
		binary->out_frame_info.res.width     = out_info->res.width;
	}
	binary->out_frame_info.padded_width  = isp_output_width;
	binary->out_frame_info.res.height    = isp_output_height;
	binary->out_frame_info.raw_bit_depth = bits_per_pixel;

	/* viewfinder output info */
	binary->vf_frame_info.format = IA_CSS_FRAME_FORMAT_YUV_LINE;
	if (vf_info != NULL) {
		unsigned int vf_out_vecs, vf_out_width, vf_out_height;
		vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(isp_output_width,
			vf_log_ds);
		vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
		vf_out_height = _ISP_VF_OUTPUT_HEIGHT(isp_output_height,
			vf_log_ds);
		/* If we are in continuous preview mode, then out port is
		 * active instead of vfout port
		 */
		if (info->enable.raw_binning && continuous) {
			if (in_info == NULL)
				return IA_CSS_ERR_INTERNAL_ERROR;
			binary->out_frame_info.res.width =
				(in_info->res.width >> vf_log_ds);
			binary->out_frame_info.padded_width = vf_out_width;
			binary->out_frame_info.res.height   = vf_out_height;
		} else {
		/* we also store the raw downscaled width. This is used for
		 * digital zoom in preview to zoom only on the width that
		 * we actually want to keep, not on the aligned width. */
			if (out_info == NULL)
enum sh_css_err
sh_css_fill_binary_info(const struct sh_css_binary_info *info,
		 bool online,
		 bool two_ppc,
		 enum sh_css_input_format stream_format,
		 const struct sh_css_frame_info *in_info, /* can be NULL */
		 const struct sh_css_frame_info *out_info, /* can be NULL */
		 const struct sh_css_frame_info *vf_info, /* can be NULL */
		 struct sh_css_binary *binary,
		 bool continuous)
{
	unsigned int dvs_env_width = 0,
		     dvs_env_height = 0,
		     vf_log_ds = 0,
		     s3a_log_deci = 0,
		     bits_per_pixel = 0,
		     ds_input_width = 0,
		     ds_input_height = 0,
		     isp_input_width,
		     isp_input_height,
		     isp_internal_width,
		     isp_internal_height,
		     isp_output_width = 0,
		     isp_output_height = 0,
		     s3a_isp_width;
	unsigned char enable_ds = info->enable.ds;
	bool enable_yuv_ds = enable_ds & 2;
	bool enable_hus = false;
	bool enable_vus = false;
	bool is_out_format_rgba888 = false;
	bool is_in_format_rawreordered = false;
	unsigned int tmp_width, tmp_height;

assert(info != NULL);

	if (in_info != NULL) {
		bits_per_pixel = in_info->raw_bit_depth;
		if (out_info != NULL) {
			enable_hus = in_info->width < out_info->width;
			enable_vus = in_info->height < out_info->height;
		}
		is_in_format_rawreordered =
			in_info->format == SH_CSS_FRAME_FORMAT_RAW_REORDERED;
	}
	if (out_info != NULL) {
		isp_output_width  = out_info->padded_width;
		isp_output_height = out_info->height;
		is_out_format_rgba888 =
			out_info->format == SH_CSS_FRAME_FORMAT_RGBA888;
	}
	if (info->enable.dvs_envelope) {
		sh_css_video_get_dis_envelope(&dvs_env_width, &dvs_env_height);
		dvs_env_width  = MAX(dvs_env_width, SH_CSS_MIN_DVS_ENVELOPE);
		dvs_env_height = MAX(dvs_env_height, SH_CSS_MIN_DVS_ENVELOPE);
	}
	binary->dvs_envelope.width  = dvs_env_width;
	binary->dvs_envelope.height = dvs_env_height;
	if (vf_info != NULL) {
		enum sh_css_err err;
		err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
		if (err != sh_css_success)
			return err;
		vf_log_ds = min(vf_log_ds, info->max_vf_log_downscale);
	}
	if (online) {
		bits_per_pixel = sh_css_input_format_bits_per_pixel(
			stream_format, two_ppc);
	}
	if (in_info != NULL) {
		ds_input_width  = in_info->padded_width + info->left_cropping;
		ds_input_height = in_info->height + info->top_cropping;
	}
	if (enable_hus) /* { */
		ds_input_width  += dvs_env_width;
	/* } */
	if (enable_vus) /* { */
		ds_input_height += dvs_env_height;
	/* } */
	tmp_width  = (enable_yuv_ds && (ds_input_width > isp_output_width)) ?
			ds_input_width  : isp_output_width;
	tmp_height = (enable_yuv_ds && (ds_input_height > isp_output_height)) ?
			ds_input_height : isp_output_height;

	/* We first calculate the resolutions used by the ISP. After that,
	 * we use those resolutions to compute sizes for tables etc. */
	isp_internal_width = __ISP_INTERNAL_WIDTH(tmp_width,
		dvs_env_width,
		info->left_cropping, info->mode,
		info->c_subsampling,
		info->output_num_chunks, info->pipelining,
		is_out_format_rgba888);
	isp_internal_height = __ISP_INTERNAL_HEIGHT(tmp_height,
		info->top_cropping,
		dvs_env_height);
	isp_input_width = _ISP_INPUT_WIDTH(isp_internal_width,
		ds_input_width,
		enable_ds || enable_hus);
	isp_input_height = _ISP_INPUT_HEIGHT(isp_internal_height,
		ds_input_height,
		enable_ds || enable_vus);
	s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(isp_input_width,
		isp_internal_width, enable_hus || enable_yuv_ds,
		info->left_cropping);
	if (info->fixed_s3a_deci_log) /* { */
		s3a_log_deci = info->fixed_s3a_deci_log;
	/* } */
	else /* { */
		s3a_log_deci = sh_css_grid_deci_factor_log2(s3a_isp_width,
							    isp_input_height);
	/* } */

	binary->vf_downscale_log2 = vf_log_ds;
	binary->deci_factor_log2  = s3a_log_deci;
	binary->input_buf_vectors =
			SH_CSS_NUM_INPUT_BUF_LINES * _ISP_VECS(isp_input_width);
	binary->online            = online;
	binary->input_format      = stream_format;
	/* input info */
	if (in_info != NULL) {
		binary->in_frame_info.format = in_info->format;
		binary->in_frame_info.width = in_info->width +
			info->left_cropping + dvs_env_width;
	}
	binary->in_frame_info.padded_width  = isp_input_width;
	binary->in_frame_info.height        = isp_input_height;
	binary->in_frame_info.raw_bit_depth = bits_per_pixel;
	/* internal frame info */
	if (out_info != NULL) /* { */
		binary->internal_frame_info.format          = out_info->format;
	/* } */
	binary->internal_frame_info.width           = isp_internal_width;
	binary->internal_frame_info.padded_width    = isp_internal_width;
	binary->internal_frame_info.height          = isp_internal_height;
	binary->internal_frame_info.raw_bit_depth   = bits_per_pixel;
	/* output info */
	if (out_info != NULL) {
		binary->out_frame_info.format        = out_info->format;
		binary->out_frame_info.width         = out_info->width;
	}
	binary->out_frame_info.padded_width  = isp_output_width;
	binary->out_frame_info.height        = isp_output_height;
	binary->out_frame_info.raw_bit_depth = bits_per_pixel;

	/* viewfinder output info */
	binary->vf_frame_info.format = SH_CSS_FRAME_FORMAT_YUV_LINE;
	if (vf_info != NULL) {
		unsigned int vf_out_vecs, vf_out_width, vf_out_height;
		vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(isp_output_width,
			vf_log_ds);
		vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
		vf_out_height = _ISP_VF_OUTPUT_HEIGHT(isp_output_height,
			vf_log_ds);
		/* If we are in continuous preview mode, then out port is
		 * active instead of vfout port
		 */
		if (info->enable.rawdeci && continuous) {
			binary->out_frame_info.width =
				(in_info->width >> vf_log_ds);
			binary->out_frame_info.padded_width = vf_out_width;
			binary->out_frame_info.height       = vf_out_height;
		} else {