static enum ia_css_err pipeline_stage_create( struct ia_css_pipeline_stage_desc *stage_desc, struct ia_css_pipeline_stage **new_stage) { enum ia_css_err err = IA_CSS_SUCCESS; struct ia_css_pipeline_stage *stage = NULL; struct ia_css_binary *binary; struct ia_css_frame *vf_frame; struct ia_css_frame *out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; const struct ia_css_fw_info *firmware; unsigned int i; /* Verify input parameters*/ if (!(stage_desc->in_frame) && !(stage_desc->firmware) && (stage_desc->binary) && !(stage_desc->binary->online)) { err = IA_CSS_ERR_INTERNAL_ERROR; goto ERR; } binary = stage_desc->binary; firmware = stage_desc->firmware; vf_frame = stage_desc->vf_frame; for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { out_frame[i] = stage_desc->out_frame[i]; } stage = sh_css_malloc(sizeof(*stage)); if (stage == NULL) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } memset(stage, 0, sizeof(*stage)); if (firmware) { stage->binary = NULL; stage->binary_info = (struct ia_css_binary_info *)&firmware->info.isp; } else { stage->binary = binary; if (binary) stage->binary_info = (struct ia_css_binary_info *)binary->info; else stage->binary_info = NULL; } stage->firmware = firmware; stage->sp_func = stage_desc->sp_func; stage->max_input_width = stage_desc->max_input_width; stage->mode = stage_desc->mode; for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) stage->out_frame_allocated[i] = false; stage->vf_frame_allocated = false; stage->next = NULL; sh_css_binary_args_reset(&stage->args); for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { if (!(out_frame[i]) && (binary) && (binary->out_frame_info[i].res.width)) { err = ia_css_frame_allocate_from_info(&out_frame[i], &binary->out_frame_info[i]); if (err != IA_CSS_SUCCESS) goto ERR; stage->out_frame_allocated[i] = true; } } /* VF frame is not needed in case of need_pp However, the capture binary needs a vf frame to write to. */ if (!vf_frame) { if ((binary && binary->vf_frame_info.res.width) || (firmware && firmware->info.isp.sp.enable.vf_veceven) ) { err = ia_css_frame_allocate_from_info(&vf_frame, &binary->vf_frame_info); if (err != IA_CSS_SUCCESS) goto ERR; stage->vf_frame_allocated = true; } } else if (vf_frame && binary && binary->vf_frame_info.res.width && !firmware) { /* only mark as allocated if buffer pointer available */ if (vf_frame->data != mmgr_NULL) stage->vf_frame_allocated = true; } stage->args.in_frame = stage_desc->in_frame; for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) stage->args.out_frame[i] = out_frame[i]; stage->args.out_vf_frame = vf_frame; *new_stage = stage; return err; ERR: if (stage != NULL) pipeline_stage_destroy(stage); return err; }
static void construct_ispstage( struct sh_css_sp_pipeline *pipeline, struct sh_css_isp_stage *isp_stage, ia_css_process_group_t *process_group, ia_css_psys_pgpoc_context_t *context, struct ia_css_binary *binary, struct ia_css_binary_xinfo *binary_xinfo, const struct ia_css_pg_param *params, struct ia_css_frame **delay_frames, struct ia_css_frame **tnr_frames) { struct sh_css_isp_stage *this_isp_stage = isp_stage; struct ia_css_isp_param_css_segments mem_if; struct ia_css_frame_info effective_in_info; const struct ia_css_frame_info *ptr_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS], *vf_info, *bds_info; struct ia_css_frame_info *allocated_in_info, *out_info, *out_vf_info; struct ia_css_frame_info ref_info, tnr_info; enum ia_css_stream_format stream_format = 0; struct ia_css_resolution dvs_env; bool two_ppc = true, deinterleaved = false; enum ia_css_err err; uint32_t i = 0; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "construct_ispstage(): enter\n"); assert(this_isp_stage != NULL); assert(process_group != NULL && context != NULL); assert(binary != NULL); assert(binary_xinfo != NULL); assert(params != NULL); allocated_in_info = &context->allocated_in_info; out_info = &context->out_info; out_vf_info = &context->out_vf_info; vf_info = NULL; bds_info = NULL; this_isp_stage->blob_info = binary_xinfo->blob->header.blob; this_isp_stage->binary_info = binary_xinfo->sp; if(binary_xinfo->blob->name) { memcpy(this_isp_stage->binary_name, binary_xinfo->blob->name, strlen(binary_xinfo->blob->name)+1); } /* TODO Move this to user space? */ memset(&mem_if, 0, sizeof(struct ia_css_isp_param_css_segments)); dvs_env.width = params->dvs_envelope[IA_CSS_COL_DIMENSION]; dvs_env.height = params->dvs_envelope[IA_CSS_ROW_DIMENSION]; effective_in_info = *allocated_in_info; if ( allocated_in_info->format == IA_CSS_FRAME_FORMAT_RAW ) { /*CSS expects raw buffers size less by left/top cropping*/ effective_in_info.res.width -= (binary_xinfo->sp.pipeline.left_cropping + dvs_env.width); effective_in_info.res.height -= (binary_xinfo->sp.pipeline.top_cropping + dvs_env.height); effective_in_info.padded_width = CEIL_MUL(effective_in_info.res.width, 2 * ISP_VEC_NELEMS); /* Binary cropping requirement is known to be 12. * Assert if it changes */ assert(binary_xinfo->sp.pipeline.left_cropping+dvs_env.width==12); assert(binary_xinfo->sp.pipeline.top_cropping+dvs_env.height==12); } ptr_out_info[i] = out_info; for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { ptr_out_info[i] = NULL; } stream_format = get_stream_format(allocated_in_info); /* TODO: Fix this for other binaries */ if ((binary_xinfo->sp.pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) || (binary_xinfo->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO)) { vf_info = ptr_out_info[0]; /* assuming raw_binning is false */ bds_info = &effective_in_info; } else if (binary_xinfo->sp.pipeline.mode == IA_CSS_BINARY_MODE_PRIMARY) { vf_info = out_vf_info; assert(context->enable_vf_output); } /* destroy any existing isp_param structures, just in case */ ia_css_binary_destroy_isp_parameters(binary); /* isp params are allocated here. We only need * ia_css_isp_param_allocate_isp_parameters but some of the isp host * configure functions take a binary, so we might as well use it. */ err = ia_css_binary_fill_info(binary_xinfo, false, two_ppc, stream_format, &effective_in_info, bds_info, ptr_out_info, vf_info, binary, &dvs_env, -1, false); assert(err == IA_CSS_SUCCESS); ia_css_init_memory_interface(&mem_if, &binary->mem_params, &binary->css_params); /* Configure ISP via ISP specific host side functions. TODO: Add other host configure's here. */ ia_css_fpn_configure (binary, &binary->in_frame_info); ia_css_output0_configure(binary, out_info); ia_css_output1_configure(binary, out_vf_info); ia_css_copy_output_configure(binary, params->copy_output); ia_css_output0_configure(binary, out_info); ia_css_iterator_configure (binary, allocated_in_info); ia_css_output_configure(binary, out_info); ia_css_raw_configure(pipeline, binary, allocated_in_info, &binary->in_frame_info, two_ppc, deinterleaved); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "construct_ispstage(): init state configuration\n"); if (binary_xinfo->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO) { ref_info = binary->internal_frame_info; ref_info.format = IA_CSS_FRAME_FORMAT_YUV420; ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH; for (i = 0; i < NUM_VIDEO_DELAY_FRAMES ; i++){ if (delay_frames[i]) { ia_css_frame_free(delay_frames[i]); delay_frames[i] = NULL; } ia_css_frame_allocate_from_info( &delay_frames[i], &ref_info); #ifdef HRT_CSIM ia_css_frame_zero(delay_frames[i]); #endif } ia_css_ref_configure (binary, (const struct ia_css_frame **)delay_frames, pipeline->dvs_frame_delay); if (binary_xinfo->sp.enable.block_output){ tnr_info = binary->out_frame_info[0]; /* Make tnr reference buffers output block height align */ tnr_info.res.height = CEIL_MUL(tnr_info.res.height, binary_xinfo->sp.block.output_block_height); } else { tnr_info = binary->internal_frame_info; } tnr_info.format = IA_CSS_FRAME_FORMAT_YUV_LINE; tnr_info.raw_bit_depth = SH_CSS_TNR_BIT_DEPTH; for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++) { if (tnr_frames[i]) { ia_css_frame_free(tnr_frames[i]); tnr_frames[i] = NULL; } ia_css_frame_allocate_from_info( &tnr_frames[i], &tnr_info); #ifdef HRT_CSIM ia_css_frame_zero(tnr_frames[i]); #endif } ia_css_tnr_configure(binary, (const struct ia_css_frame **)tnr_frames); } for (i = 0; i < IA_CSS_NUM_STATE_IDS; i++) { ia_css_kernel_init_state[i](binary); } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "construct_ispstage(): commit config and state to iunit address\n"); err = ia_css_isp_param_copy_isp_mem_if_to_ddr( &binary->css_params, &binary->mem_params, IA_CSS_PARAM_CLASS_CONFIG); assert(err == IA_CSS_SUCCESS); err = ia_css_isp_param_copy_isp_mem_if_to_ddr( &binary->css_params, &binary->mem_params, IA_CSS_PARAM_CLASS_STATE); assert(err == IA_CSS_SUCCESS); this_isp_stage->mem_initializers = mem_if; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "construct_ispstage(): exit\n"); return; }