static void ia_css_binary_internal_res(const struct ia_css_frame_info *in_info, const struct ia_css_frame_info *bds_out_info, const struct ia_css_frame_info *out_info, const struct ia_css_resolution *dvs_env, const struct ia_css_binary_info *info, struct ia_css_resolution *internal_res) { unsigned int isp_tmp_internal_width = 0, isp_tmp_internal_height = 0; bool binary_supports_yuv_ds = info->enable.ds & 2; struct ia_css_resolution binary_dvs_env; binary_dvs_env.width = 0; binary_dvs_env.height = 0; ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env); if (binary_supports_yuv_ds) { if (in_info != NULL) { isp_tmp_internal_width = in_info->res.width + info->pipeline.left_cropping + binary_dvs_env.width; isp_tmp_internal_height = in_info->res.height + info->pipeline.top_cropping + binary_dvs_env.height; } } else if ((bds_out_info != NULL) && (out_info != NULL) && /* TODO: hack to make video_us case work. this should be reverted after a nice solution in ISP */ (bds_out_info->res.width >= out_info->res.width)) { isp_tmp_internal_width = bds_out_info->padded_width; isp_tmp_internal_height = bds_out_info->res.height; } else { if (out_info != NULL) { isp_tmp_internal_width = out_info->padded_width; isp_tmp_internal_height = out_info->res.height; } } /* We first calculate the resolutions used by the ISP. After that, * we use those resolutions to compute sizes for tables etc. */ internal_res->width = __ISP_INTERNAL_WIDTH(isp_tmp_internal_width, (int)binary_dvs_env.width, info->pipeline.left_cropping, info->pipeline.mode, info->pipeline.c_subsampling, info->output.num_chunks, info->pipeline.pipelining); internal_res->height = __ISP_INTERNAL_HEIGHT(isp_tmp_internal_height, info->pipeline.top_cropping, binary_dvs_env.height); #if defined(HAS_RES_MGR) internal_res->height = (bds_out_info == NULL) ? internal_res->height : bds_out_info->res.height; internal_res->width = (bds_out_info == NULL) ? internal_res->width: bds_out_info->res.width; #endif }
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 init_binary_info(struct sh_css_binary_info *info, bool *binary_found) { unsigned int max_internal_width; switch (info->id) { case SH_CSS_BINARY_ID_COPY: _init_binary_info(info, ISP_COPY_); break; case SH_CSS_BINARY_ID_VF_PP: _init_binary_info(info, ISP_VF_PP_); break; case SH_CSS_BINARY_ID_CAPTURE_PP: _init_binary_info(info, ISP_CAPTURE_PP_); break; case SH_CSS_BINARY_ID_PRE_ISP: _init_binary_info(info, ISP_PRE_ISP_); break; case SH_CSS_BINARY_ID_GDC: _init_binary_info(info, ISP_GDC_); break; case SH_CSS_BINARY_ID_POST_ISP: _init_binary_info(info, ISP_POST_ISP_); break; #ifndef SYSTEM_hive_isp_css_2400_system case SH_CSS_BINARY_ID_ANR: _init_binary_info(info, ISP_ANR_); #endif break; case SH_CSS_BINARY_ID_PREVIEW_DZ: _init_binary_info(info, ISP_PREVIEW_DZ_); break; case SH_CSS_BINARY_ID_PREVIEW_DS: _init_binary_info(info, ISP_PREVIEW_DS_); break; case SH_CSS_BINARY_ID_PRIMARY_SMALL: _init_binary_info(info, ISP_PRIMARY_SMALL_); break; case SH_CSS_BINARY_ID_PRIMARY_DS: _init_binary_info(info, ISP_PRIMARY_DS_); break; case SH_CSS_BINARY_ID_BAYER_DS: _init_binary_info(info, ISP_BAYER_DS_); break; case SH_CSS_BINARY_ID_VIDEO_OFFLINE: _init_binary_info(info, ISP_VIDEO_OFFLINE_); break; case SH_CSS_BINARY_ID_PRIMARY_VAR: _init_binary_info(info, ISP_PRIMARY_VAR_); break; case SH_CSS_BINARY_ID_PRIMARY_8MP: _init_binary_info(info, ISP_PRIMARY_8MP_); break; case SH_CSS_BINARY_ID_PRIMARY_14MP: _init_binary_info(info, ISP_PRIMARY_14MP_); break; case SH_CSS_BINARY_ID_PRIMARY_16MP: _init_binary_info(info, ISP_PRIMARY_16MP_); break; case SH_CSS_BINARY_ID_PRIMARY_REF: _init_binary_info(info, ISP_PRIMARY_REF_); break; case SH_CSS_BINARY_ID_VIDEO_DZ: _init_binary_info(info, ISP_VIDEO_DZ_); break; case SH_CSS_BINARY_ID_VIDEO_NODZ: _init_binary_info(info, ISP_VIDEO_NODZ_); break; case SH_CSS_BINARY_ID_VIDEO_DS: _init_binary_info(info, ISP_VIDEO_DS_); break; default: return sh_css_err_invalid_arguments; } info->s3atbl_use_dmem = _S3ATBL_USE_DMEM(info->min_output_width != info->max_output_width); /* The ISP uses the veceven module for output, on the host however * we don't want to know about it. We treat preview output as regular * output, not as viewfinder output. */ if (info->mode == SH_CSS_BINARY_MODE_PREVIEW) info->enable_vf_veceven = false; info->variable_vf_veceven = info->mode == SH_CSS_BINARY_MODE_COPY; max_internal_width = __ISP_INTERNAL_WIDTH(info->max_output_width, info->max_dvs_envelope_width, info->left_cropping, info->mode, info->c_subsampling, info->output_num_chunks, info->pipelining, supports_output_format(info, SH_CSS_FRAME_FORMAT_RGBA888)); info->max_input_width = _ISP_MAX_INPUT_WIDTH(max_internal_width, info->enable_ds); info->xmem_addr = NULL; info->next = NULL; return load_binary(info, binary_found); }
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 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 {