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)
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 ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo, 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 *bds_out_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 ia_css_binary *binary, struct ia_css_resolution *dvs_env, int stream_config_left_padding, bool accelerator) { const struct ia_css_binary_info *info = &xinfo->sp; unsigned int dvs_env_width = 0, dvs_env_height = 0, vf_log_ds = 0, s3a_log_deci = 0, bits_per_pixel = 0, /* Resolution at SC/3A/DIS kernel. */ sc_3a_dis_width = 0, /* Resolution at SC/3A/DIS kernel. */ sc_3a_dis_padded_width = 0, /* Resolution at SC/3A/DIS kernel. */ sc_3a_dis_height = 0, isp_internal_width = 0, isp_internal_height = 0, s3a_isp_width = 0; bool need_scaling = false; struct ia_css_resolution binary_dvs_env, internal_res; enum ia_css_err err; unsigned int i; const struct ia_css_frame_info *bin_out_info = NULL; assert(info != NULL); assert(binary != NULL); binary->info = xinfo; if (!accelerator) { /* binary->css_params has been filled by accelerator itself. */ err = ia_css_isp_param_allocate_isp_parameters( &binary->mem_params, &binary->css_params, &info->mem_initializers); if (err != IA_CSS_SUCCESS) { return err; } } for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { if (out_info[i] && (out_info[i]->res.width != 0)) { bin_out_info = out_info[i]; break; } } if (in_info != NULL && bin_out_info != NULL) { need_scaling = (in_info->res.width != bin_out_info->res.width) || (in_info->res.height != bin_out_info->res.height); } /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */ binary_dvs_env.width = 0; binary_dvs_env.height = 0; ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env); dvs_env_width = binary_dvs_env.width; dvs_env_height = binary_dvs_env.height; binary->dvs_envelope.width = dvs_env_width; binary->dvs_envelope.height = dvs_env_height; /* internal resolution calculation */ internal_res.width = 0; internal_res.height = 0; ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env, info, &internal_res); isp_internal_width = internal_res.width; isp_internal_height = internal_res.height; /* internal frame info */ if (bin_out_info != NULL) /* { */ binary->internal_frame_info.format = bin_out_info->format; /* } */ binary->internal_frame_info.res.width = isp_internal_width; binary->internal_frame_info.padded_width = CEIL_MUL(isp_internal_width, 2*ISP_VEC_NELEMS); binary->internal_frame_info.res.height = isp_internal_height; binary->internal_frame_info.raw_bit_depth = bits_per_pixel; if (in_info != NULL) { binary->effective_in_frame_res.width = in_info->res.width; binary->effective_in_frame_res.height = in_info->res.height; bits_per_pixel = in_info->raw_bit_depth; /* input info */ binary->in_frame_info.res.width = in_info->res.width + info->pipeline.left_cropping; binary->in_frame_info.res.height = in_info->res.height + info->pipeline.top_cropping; #if !defined(HAS_RES_MGR) /* dvs env is included already */ binary->in_frame_info.res.width += dvs_env_width; binary->in_frame_info.res.height += dvs_env_height; #endif binary->in_frame_info.padded_width = binary_in_frame_padded_width(in_info->res.width, isp_internal_width, dvs_env_width, stream_config_left_padding, info->pipeline.left_cropping, need_scaling); binary->in_frame_info.format = in_info->format; binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order; binary->in_frame_info.crop_info = in_info->crop_info; } if (online) { bits_per_pixel = ia_css_util_input_format_bpp( stream_format, two_ppc); } binary->in_frame_info.raw_bit_depth = bits_per_pixel; for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { if (out_info[i] != NULL) { binary->out_frame_info[i].res.width = out_info[i]->res.width; binary->out_frame_info[i].res.height = out_info[i]->res.height; binary->out_frame_info[i].padded_width = out_info[i]->padded_width; if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) { binary->out_frame_info[i].raw_bit_depth = bits_per_pixel; } else { /* Only relevant for RAW format. * At the moment, all outputs are raw, 16 bit per pixel, except for copy. * To do this cleanly, the binary should specify in its info * the bit depth per output channel. */ binary->out_frame_info[i].raw_bit_depth = 16; } binary->out_frame_info[i].format = out_info[i]->format; } } #ifndef IS_ISP_2500_SYSTEM if (vf_info && (vf_info->res.width != 0)) { err = ia_css_vf_configure(binary, bin_out_info, (struct ia_css_frame_info *)vf_info, &vf_log_ds); if (err != IA_CSS_SUCCESS) { if (!accelerator) { ia_css_isp_param_destroy_isp_parameters( &binary->mem_params, &binary->css_params); } return err; } } #else (void)err; #endif binary->vf_downscale_log2 = vf_log_ds; binary->online = online; binary->input_format = stream_format; /* viewfinder output info */ if ((vf_info != NULL) && (vf_info->res.width != 0)) { unsigned int vf_out_vecs, vf_out_width, vf_out_height; binary->vf_frame_info.format = vf_info->format; if (bin_out_info == NULL) return IA_CSS_ERR_INTERNAL_ERROR; vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width, vf_log_ds); vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs); vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height, vf_log_ds); /* For preview mode, output pin is used instead of vf. */ if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) { binary->out_frame_info[0].res.width = (bin_out_info->res.width >> vf_log_ds); binary->out_frame_info[0].padded_width = vf_out_width; binary->out_frame_info[0].res.height = vf_out_height; binary->vf_frame_info.res.width = 0; binary->vf_frame_info.padded_width = 0; binary->vf_frame_info.res.height = 0; } else {
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 {