On 26.04.2023 09:00, Dikshita Agarwal wrote: > - Add support for V4L2_PIX_FMT_P010 color format. > - Add handling of bit depth change from firmware. > - Return P010 as preferred format for 10 bit decode. Sounds like this should be 3 separate patches, preferably with some insight in each commit message. Konrad > > Signed-off-by: Vikash Garodia <quic_vgarodia@xxxxxxxxxxx> > Signed-off-by: Dikshita Agarwal <quic_dikshita@xxxxxxxxxxx> > --- > drivers/media/platform/qcom/venus/helpers.c | 25 ++++++++++++++++++++++ > drivers/media/platform/qcom/venus/hfi_plat_bufs.h | 3 +++ > .../media/platform/qcom/venus/hfi_plat_bufs_v6.c | 9 +++++++- > drivers/media/platform/qcom/venus/vdec.c | 18 +++++++++++++--- > 4 files changed, 51 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c > index ab6a29f..193215c 100644 > --- a/drivers/media/platform/qcom/venus/helpers.c > +++ b/drivers/media/platform/qcom/venus/helpers.c > @@ -612,6 +612,8 @@ static u32 to_hfi_raw_fmt(u32 v4l2_fmt) > return HFI_COLOR_FORMAT_NV12_UBWC; > case V4L2_PIX_FMT_QC10C: > return HFI_COLOR_FORMAT_YUV420_TP10_UBWC; > + case V4L2_PIX_FMT_P010: > + return HFI_COLOR_FORMAT_P010; > default: > break; > } > @@ -639,12 +641,16 @@ static int platform_get_bufreq(struct venus_inst *inst, u32 buftype, > if (is_dec) { > params.width = inst->width; > params.height = inst->height; > + params.out_width = inst->out_width; > + params.out_height = inst->out_height; > params.codec = inst->fmt_out->pixfmt; > params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_cap->pixfmt); > params.dec.max_mbs_per_frame = mbs_per_frame_max(inst); > params.dec.buffer_size_limit = 0; > params.dec.is_secondary_output = > inst->opb_buftype == HFI_BUFFER_OUTPUT2; > + if (params.dec.is_secondary_output) > + params.hfi_dpb_color_fmt = inst->dpb_fmt; > params.dec.is_interlaced = > inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE; > } else { > @@ -1764,6 +1770,25 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt, > if (!caps) > return -EINVAL; > > + if (inst->bit_depth == VIDC_BITDEPTH_10 && > + inst->session_type == VIDC_SESSION_TYPE_DEC) { > + found_ubwc = > + find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, > + HFI_COLOR_FORMAT_YUV420_TP10_UBWC); > + found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, > + fmt); > + if (found_ubwc && found) { > + /* > + * Hard-code DPB buffers to be 10bit UBWC > + * until V4L2 is able to expose compressed/tiled > + * formats to applications. > + */ > + *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC; > + *out2_fmt = fmt; > + return 0; > + } > + } > + > if (ubwc) { > ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE; > found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, > diff --git a/drivers/media/platform/qcom/venus/hfi_plat_bufs.h b/drivers/media/platform/qcom/venus/hfi_plat_bufs.h > index 52a51a3..25e6074 100644 > --- a/drivers/media/platform/qcom/venus/hfi_plat_bufs.h > +++ b/drivers/media/platform/qcom/venus/hfi_plat_bufs.h > @@ -12,8 +12,11 @@ > struct hfi_plat_buffers_params { > u32 width; > u32 height; > + u32 out_width; > + u32 out_height; > u32 codec; > u32 hfi_color_fmt; > + u32 hfi_dpb_color_fmt; > enum hfi_version version; > u32 num_vpp_pipes; > union { > diff --git a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c > index ea25c45..08caab1 100644 > --- a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c > +++ b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c > @@ -1185,6 +1185,7 @@ static int bufreq_dec(struct hfi_plat_buffers_params *params, u32 buftype, > enum hfi_version version = params->version; > u32 codec = params->codec; > u32 width = params->width, height = params->height, out_min_count; > + u32 out_width = params->out_width, out_height = params->out_height; > struct dec_bufsize_ops *dec_ops; > bool is_secondary_output = params->dec.is_secondary_output; > bool is_interlaced = params->dec.is_interlaced; > @@ -1235,7 +1236,13 @@ static int bufreq_dec(struct hfi_plat_buffers_params *params, u32 buftype, > bufreq->count_min = out_min_count; > bufreq->size = > venus_helper_get_framesz_raw(params->hfi_color_fmt, > - width, height); > + out_width, out_height); > + > + if (buftype == HFI_BUFFER_OUTPUT && > + params->dec.is_secondary_output) > + bufreq->size = > + venus_helper_get_framesz_raw(params->hfi_dpb_color_fmt, > + out_width, out_height); > } else if (buftype == HFI_BUFFER_INTERNAL_SCRATCH(version)) { > bufreq->size = dec_ops->scratch(width, height, is_interlaced); > } else if (buftype == HFI_BUFFER_INTERNAL_SCRATCH_1(version)) { > diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c > index 4ceaba3..99d0e96 100644 > --- a/drivers/media/platform/qcom/venus/vdec.c > +++ b/drivers/media/platform/qcom/venus/vdec.c > @@ -43,6 +43,10 @@ static const struct venus_format vdec_formats[] = { > .num_planes = 1, > .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, > }, { > + .pixfmt = V4L2_PIX_FMT_P010, > + .num_planes = 1, > + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, > + }, { > .pixfmt = V4L2_PIX_FMT_MPEG4, > .num_planes = 1, > .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, > @@ -697,6 +701,9 @@ static int vdec_set_work_route(struct venus_inst *inst) > } > > #define is_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_UBWC_BASE)) > +#define is_10bit_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_10_BIT_BASE & \ > + HFI_COLOR_FORMAT_UBWC_BASE)) > + > > static int vdec_output_conf(struct venus_inst *inst) > { > @@ -744,7 +751,7 @@ static int vdec_output_conf(struct venus_inst *inst) > inst->opb_fmt = out2_fmt; > inst->dpb_buftype = HFI_BUFFER_OUTPUT; > inst->dpb_fmt = out_fmt; > - } else if (is_ubwc_fmt(out2_fmt)) { > + } else if (is_ubwc_fmt(out2_fmt) || is_10bit_ubwc_fmt(out_fmt)) { > inst->opb_buftype = HFI_BUFFER_OUTPUT; > inst->opb_fmt = out_fmt; > inst->dpb_buftype = HFI_BUFFER_OUTPUT2; > @@ -1420,7 +1427,7 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, > static void vdec_event_change(struct venus_inst *inst, > struct hfi_event_data *ev_data, bool sufficient) > { > - static const struct v4l2_event ev = { > + struct v4l2_event ev = { > .type = V4L2_EVENT_SOURCE_CHANGE, > .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION }; > struct device *dev = inst->core->dev_dec; > @@ -1461,8 +1468,13 @@ static void vdec_event_change(struct venus_inst *inst, > inst->out_width = ev_data->width; > inst->out_height = ev_data->height; > > - if (inst->bit_depth != ev_data->bit_depth) > + if (inst->bit_depth != ev_data->bit_depth) { > inst->bit_depth = ev_data->bit_depth; > + if (inst->bit_depth == VIDC_BITDEPTH_10) > + inst->fmt_cap = &vdec_formats[3]; > + else > + inst->fmt_cap = &vdec_formats[0]; > + } > > if (inst->pic_struct != ev_data->pic_struct) > inst->pic_struct = ev_data->pic_struct;