diff --git a/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c b/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c index 96483a59396..2400cd9b3b2 100644 --- a/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c +++ b/src/amd/vpelib/src/chip/vpe10/vpe10_resource.c @@ -537,7 +537,7 @@ enum vpe_status vpe10_calculate_segments( struct dpp *dpp = vpe_priv->resource.dpp[0]; const uint32_t max_lb_size = dpp->funcs->get_line_buffer_size(); - for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) { + for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) { stream_ctx = &vpe_priv->stream_ctx[stream_idx]; src_rect = &stream_ctx->stream.scaling_info.src_rect; dst_rect = &stream_ctx->stream.scaling_info.dst_rect; diff --git a/src/amd/vpelib/src/core/color.c b/src/amd/vpelib/src/core/color.c index 57089de7231..7f57f774bec 100644 --- a/src/amd/vpelib/src/core/color.c +++ b/src/amd/vpelib/src/core/color.c @@ -229,7 +229,7 @@ static enum vpe_status vpe_allocate_cm_memory(struct vpe_priv *vpe_priv, const s struct output_ctx *output_ctx; enum vpe_status status = VPE_STATUS_OK; - for (uint32_t stream_idx = 0; stream_idx < param->num_streams; stream_idx++) { + for (uint32_t stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) { stream_ctx = &vpe_priv->stream_ctx[stream_idx]; if (!stream_ctx->input_cs) { @@ -640,7 +640,7 @@ enum vpe_status vpe_color_update_color_space_and_tf( vpe_update_geometric_scaling(vpe_priv, param, &geometric_update, &geometric_scaling); color_check_output_cm_update(vpe_priv, &vpe_priv->output_ctx.surface.cs, geometric_update); - for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) { + for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) { new_matrix_scaling_factor = vpe_fixpt_one; stream_ctx = &vpe_priv->stream_ctx[stream_idx]; @@ -757,7 +757,7 @@ enum vpe_status vpe_color_update_movable_cm( struct stream_ctx *stream_ctx; struct output_ctx *output_ctx = &vpe_priv->output_ctx; - for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) { + for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) { stream_ctx = &vpe_priv->stream_ctx[stream_idx]; bool enable_3dlut = stream_ctx->stream.tm_params.UID != 0 || stream_ctx->stream.tm_params.enable_3dlut; diff --git a/src/amd/vpelib/src/core/inc/vpe_priv.h b/src/amd/vpelib/src/core/inc/vpe_priv.h index 5eaedccc8c1..749d031b5aa 100644 --- a/src/amd/vpelib/src/core/inc/vpe_priv.h +++ b/src/amd/vpelib/src/core/inc/vpe_priv.h @@ -72,6 +72,11 @@ enum vpe_cmd_type { VPE_CMD_TYPE_COUNT }; +enum vpe_stream_type { + VPE_STREAM_TYPE_INPUT, + VPE_STREAM_TYPE_BG_GEN, +}; + /** this represents a segement context. * each segment has its own version of data */ struct segment_ctx { @@ -124,8 +129,9 @@ struct vpe_3dlut_cache { struct stream_ctx { struct vpe_priv *vpe_priv; - int32_t stream_idx; - struct vpe_stream stream; /**< stores all the input data */ + enum vpe_stream_type stream_type; + int32_t stream_idx; + struct vpe_stream stream; /**< stores all the input data */ uint16_t num_segments; struct segment_ctx *segment_ctx; @@ -255,8 +261,10 @@ struct vpe_priv { struct config_backend_cb_ctx be_cb_ctx; // input ctx - uint32_t num_streams; - struct stream_ctx *stream_ctx; + uint32_t num_virtual_streams; // streams created by VPE + uint32_t num_input_streams; // streams inputed from build params + uint32_t num_streams; // input streams + virtual streams + struct stream_ctx *stream_ctx; // input streams allocated first, then virtual streams // output ctx struct output_ctx output_ctx; diff --git a/src/amd/vpelib/src/core/resource.c b/src/amd/vpelib/src/core/resource.c index fdadd53d379..3f3a5b782ea 100644 --- a/src/amd/vpelib/src/core/resource.c +++ b/src/amd/vpelib/src/core/resource.c @@ -246,6 +246,7 @@ void vpe_free_stream_ctx(struct vpe_priv *vpe_priv) vpe_free(vpe_priv->stream_ctx); vpe_priv->stream_ctx = NULL; vpe_priv->num_streams = 0; + vpe_priv->num_virtual_streams = 0; } void vpe_free_output_ctx(struct vpe_priv *vpe_priv) diff --git a/src/amd/vpelib/src/core/vpe_visual_confirm.c b/src/amd/vpelib/src/core/vpe_visual_confirm.c index f5fd34147c4..f83259c0a16 100644 --- a/src/amd/vpelib/src/core/vpe_visual_confirm.c +++ b/src/amd/vpelib/src/core/vpe_visual_confirm.c @@ -48,7 +48,7 @@ static uint16_t vpe_get_visual_confirm_total_seg_count( struct stream_ctx *stream_ctx; if (vpe_priv->init.debug.visual_confirm_params.input_format) { - for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) { + for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) { stream_ctx = &vpe_priv->stream_ctx[stream_idx]; total_visual_confirm_segs += get_visual_confirm_segs_count( max_seg_width, stream_ctx->stream.scaling_info.dst_rect.width); diff --git a/src/amd/vpelib/src/core/vpelib.c b/src/amd/vpelib/src/core/vpelib.c index e82101aa7b0..e5fd99575ad 100644 --- a/src/amd/vpelib/src/core/vpelib.c +++ b/src/amd/vpelib/src/core/vpelib.c @@ -215,132 +215,190 @@ void vpe_destroy(struct vpe **vpe) /***************************************************************************************** - * handle_zero_input - * handle any zero input stream but background output only + * populate_bg_stream + * populate virtual stream for background output only * struct vpe* vpe * [input] vpe context * const struct vpe_build_param* org_param * [input] original parameter from caller - * struct vpe_build_param* dummy_input_param - * [output] caller provided param struct for filling with dummy input - * struct struct vpe_stream* dummy_stream - * [output] caller provided vpe_stream struct for use in dummy_input_param->streams + * struct struct vpe_stream_ctx* stream_ctx + * [input/output] caller provided vpe_stream_ctx struct to populate *****************************************************************************************/ -static enum vpe_status handle_zero_input(struct vpe *vpe, const struct vpe_build_param *in_param, - const struct vpe_build_param **out_param) +static enum vpe_status populate_bg_stream(struct vpe_priv *vpe_priv, const struct vpe_build_param *param, struct stream_ctx *stream_ctx) { - struct vpe_priv *vpe_priv; struct vpe_surface_info *surface_info; struct vpe_scaling_info *scaling_info; struct vpe_scaling_filter_coeffs *polyphaseCoeffs; struct vpe_stream *stream; - vpe_priv = container_of(vpe, struct vpe_priv, pub); - - if (!in_param || !out_param) + if (!param || !stream_ctx) return VPE_STATUS_ERROR; - *out_param = NULL; + stream = &stream_ctx->stream; + stream_ctx->stream_type = VPE_STREAM_TYPE_BG_GEN; - if (in_param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) { + // if output surface is too small, don't use it as dummy input + // request 2x2 instead of 1x1 for bpc safety + // as we are to treat output as input for RGB 1x1, need 4bytes at least + // but if output is YUV, bpc will be smaller and need larger dimension - // if output surface is too small, don't use it as dummy input - // request 2x2 instead of 1x1 for bpc safety - // as we are to treat output as input for RGB 1x1, need 4bytes at least - // but if output is YUV, bpc will be smaller and need larger dimension - - if (in_param->dst_surface.plane_size.surface_size.width < VPE_MIN_VIEWPORT_SIZE || - in_param->dst_surface.plane_size.surface_size.height < VPE_MIN_VIEWPORT_SIZE || - in_param->dst_surface.plane_size.surface_pitch < 256 / 4 || // 256bytes, 4bpp - in_param->target_rect.width < VPE_MIN_VIEWPORT_SIZE || - in_param->target_rect.height < VPE_MIN_VIEWPORT_SIZE) { - return VPE_STATUS_ERROR; - } - - if (!vpe_priv->dummy_input_param) { - vpe_priv->dummy_input_param = vpe_zalloc(sizeof(struct vpe_build_param)); - if (!vpe_priv->dummy_input_param) - return VPE_STATUS_NO_MEMORY; - } - - if (!vpe_priv->dummy_stream) { - vpe_priv->dummy_stream = vpe_zalloc(sizeof(struct vpe_stream)); - if (!vpe_priv->dummy_stream) - return VPE_STATUS_NO_MEMORY; - } - - *vpe_priv->dummy_input_param = *in_param; - - vpe_priv->dummy_input_param->num_streams = 1; - vpe_priv->dummy_input_param->streams = vpe_priv->dummy_stream; - - // set output surface as our dummy input - stream = vpe_priv->dummy_stream; - surface_info = &stream->surface_info; - scaling_info = &stream->scaling_info; - polyphaseCoeffs = &stream->polyphase_scaling_coeffs; - surface_info->address.type = VPE_PLN_ADDR_TYPE_GRAPHICS; - surface_info->address.tmz_surface = in_param->dst_surface.address.tmz_surface; - surface_info->address.grph.addr.quad_part = - in_param->dst_surface.address.grph.addr.quad_part; - - surface_info->swizzle = VPE_SW_LINEAR; // treat it as linear for simple - surface_info->plane_size.surface_size.x = 0; - surface_info->plane_size.surface_size.y = 0; - surface_info->plane_size.surface_size.width = VPE_MIN_VIEWPORT_SIZE; // min width in pixels - surface_info->plane_size.surface_size.height = - VPE_MIN_VIEWPORT_SIZE; // min height in pixels - surface_info->plane_size.surface_pitch = 256 / 4; // pitch in pixels - surface_info->plane_size.surface_aligned_height = VPE_MIN_VIEWPORT_SIZE; - surface_info->dcc.enable = false; - surface_info->format = VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888; - surface_info->cs.encoding = VPE_PIXEL_ENCODING_RGB; - surface_info->cs.range = VPE_COLOR_RANGE_FULL; - surface_info->cs.tf = VPE_TF_G22; - surface_info->cs.cositing = VPE_CHROMA_COSITING_NONE; - surface_info->cs.primaries = VPE_PRIMARIES_BT709; - scaling_info->src_rect.x = 0; - scaling_info->src_rect.y = 0; - scaling_info->src_rect.width = VPE_MIN_VIEWPORT_SIZE; - scaling_info->src_rect.height = VPE_MIN_VIEWPORT_SIZE; - scaling_info->dst_rect.x = in_param->target_rect.x; - scaling_info->dst_rect.y = in_param->target_rect.y; - scaling_info->dst_rect.width = VPE_MIN_VIEWPORT_SIZE; - scaling_info->dst_rect.height = VPE_MIN_VIEWPORT_SIZE; - scaling_info->taps.v_taps = 4; - scaling_info->taps.h_taps = 4; - scaling_info->taps.v_taps_c = 2; - scaling_info->taps.h_taps_c = 2; - - polyphaseCoeffs->taps = scaling_info->taps; - polyphaseCoeffs->nb_phases = 64; - - stream->blend_info.blending = true; - stream->blend_info.pre_multiplied_alpha = false; - stream->blend_info.global_alpha = true; // hardcoded upon DAL request - stream->blend_info.global_alpha_value = 0; // transparent as we are dummy input - - stream->color_adj.brightness = 0.0f; - stream->color_adj.contrast = 1.0f; - stream->color_adj.hue = 0.0f; - stream->color_adj.saturation = 1.0f; - stream->rotation = VPE_ROTATION_ANGLE_0; - stream->horizontal_mirror = false; - stream->vertical_mirror = false; - stream->enable_luma_key = false; - stream->lower_luma_bound = 0; - stream->upper_luma_bound = 0; - stream->flags.hdr_metadata = 0; - stream->flags.geometric_scaling = 0; - stream->use_external_scaling_coeffs = false; - *out_param = vpe_priv->dummy_input_param; - } else { - *out_param = in_param; + if (param->dst_surface.plane_size.surface_size.width < VPE_MIN_VIEWPORT_SIZE || + param->dst_surface.plane_size.surface_size.height < VPE_MIN_VIEWPORT_SIZE || + param->dst_surface.plane_size.surface_pitch < 256 / 4 || // 256bytes, 4bpp + param->target_rect.width < VPE_MIN_VIEWPORT_SIZE || + param->target_rect.height < VPE_MIN_VIEWPORT_SIZE) { + return VPE_STATUS_ERROR; } + // set output surface as our dummy input + surface_info = &stream->surface_info; + scaling_info = &stream->scaling_info; + polyphaseCoeffs = &stream->polyphase_scaling_coeffs; + surface_info->address.type = VPE_PLN_ADDR_TYPE_GRAPHICS; + surface_info->address.tmz_surface = param->dst_surface.address.tmz_surface; + surface_info->address.grph.addr.quad_part = + param->dst_surface.address.grph.addr.quad_part; + + surface_info->swizzle = VPE_SW_LINEAR; // treat it as linear for simple + surface_info->plane_size.surface_size.x = 0; + surface_info->plane_size.surface_size.y = 0; + surface_info->plane_size.surface_size.width = VPE_MIN_VIEWPORT_SIZE; // min width in pixels + surface_info->plane_size.surface_size.height = + VPE_MIN_VIEWPORT_SIZE; // min height in pixels + surface_info->plane_size.surface_pitch = 256 / 4; // pitch in pixels + surface_info->plane_size.surface_aligned_height = VPE_MIN_VIEWPORT_SIZE; + surface_info->dcc.enable = false; + surface_info->format = VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888; + surface_info->cs.encoding = VPE_PIXEL_ENCODING_RGB; + surface_info->cs.range = VPE_COLOR_RANGE_FULL; + surface_info->cs.tf = VPE_TF_G22; + surface_info->cs.cositing = VPE_CHROMA_COSITING_NONE; + surface_info->cs.primaries = VPE_PRIMARIES_BT709; + scaling_info->src_rect.x = 0; + scaling_info->src_rect.y = 0; + scaling_info->src_rect.width = VPE_MIN_VIEWPORT_SIZE; + scaling_info->src_rect.height = VPE_MIN_VIEWPORT_SIZE; + scaling_info->dst_rect.x = param->target_rect.x; + scaling_info->dst_rect.y = param->target_rect.y; + scaling_info->dst_rect.width = VPE_MIN_VIEWPORT_SIZE; + scaling_info->dst_rect.height = VPE_MIN_VIEWPORT_SIZE; + scaling_info->taps.v_taps = 4; + scaling_info->taps.h_taps = 4; + scaling_info->taps.v_taps_c = 2; + scaling_info->taps.h_taps_c = 2; + + polyphaseCoeffs->taps = scaling_info->taps; + polyphaseCoeffs->nb_phases = 64; + + stream->blend_info.blending = true; + stream->blend_info.pre_multiplied_alpha = false; + stream->blend_info.global_alpha = true; // hardcoded upon DAL request + stream->blend_info.global_alpha_value = 0; // transparent as we are dummy input + + stream->color_adj.brightness = 0.0f; + stream->color_adj.contrast = 1.0f; + stream->color_adj.hue = 0.0f; + stream->color_adj.saturation = 1.0f; + stream->rotation = VPE_ROTATION_ANGLE_0; + stream->horizontal_mirror = false; + stream->vertical_mirror = false; + stream->enable_luma_key = false; + stream->lower_luma_bound = 0; + stream->upper_luma_bound = 0; + stream->flags.hdr_metadata = 0; + stream->flags.geometric_scaling = 0; + stream->use_external_scaling_coeffs = false; + return VPE_STATUS_OK; } +static uint32_t get_required_virtual_stream_count(struct vpe_priv *vpe_priv, const struct vpe_build_param *param) +{ + uint32_t result = 0; + + // Check for zero-input background stream + // Normally we result++ instead of returning, but bg_color_fill_only removes other streams (and therefore other features) + if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) + return 1; + + return result; +} + +static enum vpe_status populate_input_streams(struct vpe_priv *vpe_priv, const struct vpe_build_param *param, struct stream_ctx *stream_ctx_base) +{ + enum vpe_status result = VPE_STATUS_OK; + uint32_t i; + struct stream_ctx* stream_ctx; + bool input_h_mirror, output_h_mirror; + + vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror); + + for (i = 0; i < vpe_priv->num_input_streams; i++) { + stream_ctx = &stream_ctx_base[i]; + stream_ctx->stream_type = VPE_STREAM_TYPE_INPUT; + stream_ctx->stream_idx = (int32_t)i; + stream_ctx->per_pixel_alpha = + vpe_has_per_pixel_alpha(param->streams[i].surface_info.format); + if (vpe_priv->init.debug.bypass_per_pixel_alpha) { + stream_ctx->per_pixel_alpha = false; + } + if (param->streams[i].horizontal_mirror && !input_h_mirror && output_h_mirror) + stream_ctx->flip_horizonal_output = true; + else + stream_ctx->flip_horizonal_output = false; + + memcpy(&stream_ctx->stream, ¶m->streams[i], sizeof(struct vpe_stream)); + + /* if top-bottom blending is not supported, + * the 1st stream still can support blending with background, + * however, the 2nd stream and onward can't enable blending. + */ + if (i && param->streams[i].blend_info.blending && + !vpe_priv->pub.caps->color_caps.mpc.top_bottom_blending) { + result = VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED; + break; + } + } + + return result; +} + +static enum vpe_status populate_virtual_streams(struct vpe_priv* vpe_priv, const struct vpe_build_param* param, struct stream_ctx* stream_ctx_base, uint32_t num_virtual_streams) +{ + enum vpe_status result = VPE_STATUS_OK; + uint32_t virtual_stream_idx = 0; + struct stream_ctx *stream_ctx; + bool input_h_mirror, output_h_mirror; + + vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror); + + if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) { + if (num_virtual_streams != 1) + result = VPE_STATUS_ERROR; + else + result = populate_bg_stream(vpe_priv, param, &vpe_priv->stream_ctx[virtual_stream_idx++]); + } + + if (result != VPE_STATUS_OK) + return result; + + for (virtual_stream_idx = 0; virtual_stream_idx < num_virtual_streams; virtual_stream_idx++) { + stream_ctx = &stream_ctx_base[virtual_stream_idx]; + stream_ctx->stream_idx = virtual_stream_idx + vpe_priv->num_input_streams; + stream_ctx->per_pixel_alpha = + vpe_has_per_pixel_alpha(stream_ctx->stream.surface_info.format); + if (vpe_priv->init.debug.bypass_per_pixel_alpha) { + stream_ctx->per_pixel_alpha = false; + } + if (stream_ctx->stream.horizontal_mirror && !input_h_mirror && output_h_mirror) + stream_ctx->flip_horizonal_output = true; + else + stream_ctx->flip_horizonal_output = false; + } + + return result; +} + enum vpe_status vpe_check_support( struct vpe *vpe, const struct vpe_build_param *param, struct vpe_bufs_req *req) { @@ -348,18 +406,13 @@ enum vpe_status vpe_check_support( struct vpec *vpec; struct dpp *dpp; enum vpe_status status; - struct stream_ctx *stream_ctx; struct output_ctx *output_ctx = NULL; - uint32_t i; - bool input_h_mirror, output_h_mirror; + uint32_t i, required_virtual_streams; - vpe_priv = container_of(vpe, struct vpe_priv, pub); - vpec = &vpe_priv->resource.vpec; - dpp = vpe_priv->resource.dpp[0]; - - status = handle_zero_input(vpe, param, ¶m); - if (status != VPE_STATUS_OK) - status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED; + vpe_priv = container_of(vpe, struct vpe_priv, pub); + vpec = &vpe_priv->resource.vpec; + dpp = vpe_priv->resource.dpp[0]; + status = VPE_STATUS_OK; #ifdef VPE_BUILD_1_1 vpe_priv->collaboration_mode = param->collaboration_mode; @@ -367,15 +420,36 @@ enum vpe_status vpe_check_support( verify_collaboration_mode(vpe_priv); #endif - if (!vpe_priv->stream_ctx || vpe_priv->num_streams != param->num_streams) { + required_virtual_streams = get_required_virtual_stream_count(vpe_priv, param); + + if (!vpe_priv->stream_ctx || + vpe_priv->num_streams != (param->num_streams + vpe_priv->num_virtual_streams) || + vpe_priv->num_virtual_streams != required_virtual_streams) { if (vpe_priv->stream_ctx) vpe_free_stream_ctx(vpe_priv); - vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, param->num_streams); + vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, param->num_streams + required_virtual_streams); } if (!vpe_priv->stream_ctx) status = VPE_STATUS_NO_MEMORY; + else { + vpe_priv->num_streams = param->num_streams + required_virtual_streams; + vpe_priv->num_virtual_streams = required_virtual_streams; + vpe_priv->num_input_streams = param->num_streams; + } + + if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) { + vpe_free_stream_ctx(vpe_priv); + vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, 1); + vpe_priv->num_streams = required_virtual_streams; + vpe_priv->num_virtual_streams = required_virtual_streams; + vpe_priv->num_input_streams = 0; + + if (!vpe_priv->stream_ctx) + status = VPE_STATUS_NO_MEMORY; + } + if (status == VPE_STATUS_OK) { // output checking - check per asic support @@ -419,39 +493,20 @@ enum vpe_status vpe_check_support( vpe_priv->num_vpe_cmds = 0; output_ctx->clamping_params = vpe_priv->init.debug.clamping_params; - - vpe_priv->num_streams = param->num_streams; } + if (status == VPE_STATUS_OK) { // blending support check - vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror); + status = populate_input_streams(vpe_priv, param, vpe_priv->stream_ctx); + if (status != VPE_STATUS_OK) + vpe_log("fail input stream population. status %d\n", (int)status); + } - for (i = 0; i < param->num_streams; i++) { - stream_ctx = &vpe_priv->stream_ctx[i]; - stream_ctx->stream_idx = (int32_t)i; - stream_ctx->per_pixel_alpha = - vpe_has_per_pixel_alpha(param->streams[i].surface_info.format); - if (vpe_priv->init.debug.bypass_per_pixel_alpha) { - stream_ctx->per_pixel_alpha = false; - } - if (param->streams[i].horizontal_mirror && !input_h_mirror && output_h_mirror) - stream_ctx->flip_horizonal_output = true; - else - stream_ctx->flip_horizonal_output = false; - - memcpy(&stream_ctx->stream, ¶m->streams[i], sizeof(struct vpe_stream)); - - /* if top-bottom blending is not supported, - * the 1st stream still can support blending with background, - * however, the 2nd stream and onward can't enable blending. - */ - if (i && param->streams[i].blend_info.blending && - !vpe_priv->pub.caps->color_caps.mpc.top_bottom_blending) { - status = VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED; - break; - } - } + if (status == VPE_STATUS_OK) { + status = populate_virtual_streams(vpe_priv, param, vpe_priv->stream_ctx + vpe_priv->num_input_streams, vpe_priv->num_virtual_streams); + if (status != VPE_STATUS_OK) + vpe_log("fail virtual stream population. status %d\n", (int)status); } if (status == VPE_STATUS_OK) { @@ -513,7 +568,8 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu uint32_t i; struct output_ctx *output_ctx; - if (vpe_priv->num_streams != param->num_streams) + if (vpe_priv->num_input_streams != param->num_streams && + !(vpe_priv->init.debug.bg_color_fill_only == true && vpe_priv->num_streams == 1)) return false; #ifdef VPE_BUILD_1_1 @@ -524,7 +580,7 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu return false; #endif - for (i = 0; i < param->num_streams; i++) { + for (i = 0; i < vpe_priv->num_input_streams; i++) { struct vpe_stream stream = param->streams[i]; vpe_clip_stream( @@ -573,12 +629,6 @@ enum vpe_status vpe_build_commands( status = VPE_STATUS_NOT_SUPPORTED; } - if (status == VPE_STATUS_OK) { - status = handle_zero_input(vpe, param, ¶m); - if (status != VPE_STATUS_OK) - status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED; - } - if (status == VPE_STATUS_OK) { if (!validate_cached_param(vpe_priv, param)) { status = VPE_STATUS_PARAM_CHECK_ERROR;