mbox series

[RFC,00/12] Add support for HEVC and VP9 codecs in decoder

Message ID 20250305104335.3629945-1-quic_dikshita@quicinc.com
Headers show
Series Add support for HEVC and VP9 codecs in decoder | expand

Message

Dikshita Agarwal March 5, 2025, 10:43 a.m. UTC
Hi all,

This patch series adds initial support for the HEVC(H.265) and VP9
codecs in iris decoder. The objective of this work is to extend the 
decoder's capabilities to handle HEVC and VP9 codec streams,
including necessary format handling and buffer management.
In addition, the series also includes a set of fixes to address issues
identified during testing of these additional codecs.

I'm sharing this series as an RFC because compliance and conformance
testing are still in progress.
While initial functional tests show positive results, I would
appreciate early feedback on the design, implementation, and fixes
before moving to a formal submission.

I plan to submit a formal patch series after completing all compliance
checks. Meanwhile, any feedback or suggestion to improve this work are
very welcome.

Thanks,
Dikshita

Dikshita Agarwal (12):
  media: iris: Add HEVC and VP9 formats for decoder
  media: iris: Add platform capabilities for HEVC and VP9 decoders
  media: iris: Set mandatory properties for HEVC and VP9 decoders.
  media: iris: Add internal buffer calculation for HEVC and VP9 decoders
  media: iris: Skip destroying internal buffer if not dequeued
  media: iris: Update CAPTURE format info based on OUTPUT format
  media: iris: Add handling for corrupt and drop frames
  media: iris: Avoid updating frame size to firmware during reconfig
  media: iris: Avoid sending LAST flag multiple times
  media: iris: Send V4L2_BUF_FLAG_ERROR for buffers with 0 filled length
  media: iris: Fix handling of eos buffer during drain
  media: iris: Add handling for no show frames

 .../media/platform/qcom/iris/iris_buffer.c    |  22 +-
 drivers/media/platform/qcom/iris/iris_ctrls.c |  28 +-
 .../platform/qcom/iris/iris_hfi_common.h      |   1 +
 .../qcom/iris/iris_hfi_gen1_command.c         |  38 +-
 .../qcom/iris/iris_hfi_gen1_defines.h         |   4 +
 .../qcom/iris/iris_hfi_gen1_response.c        |  11 +
 .../qcom/iris/iris_hfi_gen2_command.c         | 129 +++++-
 .../qcom/iris/iris_hfi_gen2_defines.h         |   5 +
 .../qcom/iris/iris_hfi_gen2_response.c        |  56 ++-
 .../media/platform/qcom/iris/iris_instance.h  |   6 +
 .../platform/qcom/iris/iris_platform_common.h |  25 +-
 .../platform/qcom/iris/iris_platform_sm8250.c |   4 +-
 .../platform/qcom/iris/iris_platform_sm8550.c | 141 ++++++-
 drivers/media/platform/qcom/iris/iris_vb2.c   |   3 +-
 drivers/media/platform/qcom/iris/iris_vdec.c  |  80 +++-
 drivers/media/platform/qcom/iris/iris_vdec.h  |  11 +
 drivers/media/platform/qcom/iris/iris_vidc.c  |   3 -
 .../platform/qcom/iris/iris_vpu_buffer.c      | 397 +++++++++++++++++-
 .../platform/qcom/iris/iris_vpu_buffer.h      |  46 +-
 19 files changed, 931 insertions(+), 79 deletions(-)

Comments

Dikshita Agarwal March 6, 2025, 11:55 a.m. UTC | #1
On 3/6/2025 5:47 AM, Bryan O'Donoghue wrote:
> On 05/03/2025 10:43, Dikshita Agarwal wrote:
>> Extend the decoder driver's supported formats to include HEVC (H.265)
>> and VP9. This change updates the format enumeration (VIDIOC_ENUM_FMT)
>> and allows setting these formats via VIDIOC_S_FMT.
>>
>> Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
>> ---
>>   .../qcom/iris/iris_hfi_gen1_command.c         | 18 ++++-
>>   .../qcom/iris/iris_hfi_gen1_defines.h         |  2 +
>>   .../qcom/iris/iris_hfi_gen2_command.c         | 16 ++++-
>>   .../qcom/iris/iris_hfi_gen2_defines.h         |  3 +
>>   .../media/platform/qcom/iris/iris_instance.h  |  2 +
>>   drivers/media/platform/qcom/iris/iris_vdec.c  | 69 +++++++++++++++++--
>>   drivers/media/platform/qcom/iris/iris_vdec.h  | 11 +++
>>   drivers/media/platform/qcom/iris/iris_vidc.c  |  3 -
>>   8 files changed, 113 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> index 64f887d9a17d..1e774b058ab9 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> @@ -26,6 +26,20 @@ static u32 iris_hfi_gen1_buf_type_from_driver(enum
>> iris_buffer_type buffer_type)
>>       }
>>   }
>>   +static u32 iris_hfi_gen1_v4l2_to_codec_type(u32 pixfmt)
>> +{
>> +    switch (pixfmt) {
>> +    case V4L2_PIX_FMT_H264:
>> +        return HFI_VIDEO_CODEC_H264;
>> +    case V4L2_PIX_FMT_HEVC:
>> +        return HFI_VIDEO_CODEC_HEVC;
>> +    case V4L2_PIX_FMT_VP9:
>> +        return HFI_VIDEO_CODEC_VP9;
>> +    default:
>> +        return 0;
>> +    }
> 
> Unknown is 0 here - perhaps it should be a define.
> 
>> +}
>> +
>>   static int iris_hfi_gen1_sys_init(struct iris_core *core)
>>   {
>>       struct hfi_sys_init_pkt sys_init_pkt;
>> @@ -88,16 +102,18 @@ static int iris_hfi_gen1_sys_pc_prep(struct
>> iris_core *core)
>>   static int iris_hfi_gen1_session_open(struct iris_inst *inst)
>>   {
>>       struct hfi_session_open_pkt packet;
>> +    u32 codec;
>>       int ret;
>>         if (inst->state != IRIS_INST_DEINIT)
>>           return -EALREADY;
>>   +    codec = iris_hfi_gen1_v4l2_to_codec_type(inst->codec);
> 
> 
> You can return an error from this function - suggest better error handling is
> 
> if (!codec)
>     return -EINVAL; -ENO
> 
> or some other error value that makes more sense to you.
> 
This will never happen, as code will not reach to this point for
unsupported codec. I can just simply remove the default case.
>> +static u32 iris_hfi_gen2_v4l2_to_codec_type(struct iris_inst *inst)
>> +{
>> +    switch (inst->codec) {
>> +    case V4L2_PIX_FMT_H264:
>> +        return HFI_CODEC_DECODE_AVC;
>> +    case V4L2_PIX_FMT_HEVC:
>> +        return HFI_CODEC_DECODE_HEVC;
>> +    case V4L2_PIX_FMT_VP9:
>> +        return HFI_CODEC_DECODE_VP9;
>> +    default:
>> +        return 0;
> 
>>   static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
>>   {
>>       struct iris_inst_hfi_gen2 *inst_hfi_gen2 =
>> to_iris_inst_hfi_gen2(inst);
>> -    u32 codec = HFI_CODEC_DECODE_AVC;
>> +    u32 codec = iris_hfi_gen2_v4l2_to_codec_type(inst);
> 
> Same comment for gen2
> 
>>         iris_hfi_gen2_packet_session_property(inst,
>>                             HFI_PROP_CODEC,
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> index 806f8bb7f505..2fcf7914b70f 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
>> @@ -104,6 +104,9 @@ enum hfi_color_format {
>>   enum hfi_codec_type {
>>       HFI_CODEC_DECODE_AVC            = 1,
>>       HFI_CODEC_ENCODE_AVC            = 2,
>> +    HFI_CODEC_DECODE_HEVC            = 3,
>> +    HFI_CODEC_ENCODE_HEVC            = 4,
>> +    HFI_CODEC_DECODE_VP9            = 5,
>>   };
>>     enum hfi_picture_type {
>> diff --git a/drivers/media/platform/qcom/iris/iris_instance.h
>> b/drivers/media/platform/qcom/iris/iris_instance.h
>> index caa3c6507006..d8f076936c2b 100644
>> --- a/drivers/media/platform/qcom/iris/iris_instance.h
>> +++ b/drivers/media/platform/qcom/iris/iris_instance.h
>> @@ -42,6 +42,7 @@
>>    * @sequence_out: a sequence counter for output queue
>>    * @tss: timestamp metadata
>>    * @metadata_idx: index for metadata buffer
>> + * @codec: codec type
>>    */
>>     struct iris_inst {
>> @@ -72,6 +73,7 @@ struct iris_inst {
>>       u32                sequence_out;
>>       struct iris_ts_metadata        tss[VIDEO_MAX_FRAME];
>>       u32                metadata_idx;
>> +    u32                codec;
>>   };
>>     #endif
>> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c
>> b/drivers/media/platform/qcom/iris/iris_vdec.c
>> index 4143acedfc57..cdcfe71f5b96 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vdec.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
>> @@ -32,6 +32,7 @@ int iris_vdec_inst_init(struct iris_inst *inst)
>>       f->fmt.pix_mp.width = DEFAULT_WIDTH;
>>       f->fmt.pix_mp.height = DEFAULT_HEIGHT;
>>       f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
>> +    inst->codec = f->fmt.pix_mp.pixelformat;
>>       f->fmt.pix_mp.num_planes = 1;
>>       f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
>>       f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst,
>> BUF_INPUT);
>> @@ -67,14 +68,67 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
>>       kfree(inst->fmt_src);
>>   }
>>   +static const struct iris_fmt iris_vdec_formats[] = {
>> +    [IRIS_FMT_H264] = {
>> +        .pixfmt = V4L2_PIX_FMT_H264,
>> +        .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
>> +    },
>> +    [IRIS_FMT_HEVC] = {
>> +        .pixfmt = V4L2_PIX_FMT_HEVC,
>> +        .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
>> +    },
>> +    [IRIS_FMT_VP9] = {
>> +        .pixfmt = V4L2_PIX_FMT_VP9,
>> +        .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
>> +    },
>> +};
>> +
>> +static const struct iris_fmt *
>> +find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
>> +{
>> +    const struct iris_fmt *fmt = iris_vdec_formats;
>> +    unsigned int size = ARRAY_SIZE(iris_vdec_formats);
>> +    unsigned int i;
> 
> Slightly neater as a reverse christmas tree.
> 
Noted.
>> +
>> +    for (i = 0; i < size; i++) {
>> +        if (fmt[i].pixfmt == pixfmt)
>> +            break;
>> +    }
>> +
>> +    if (i == size || fmt[i].type != type)
>> +        return NULL;
>> +
>> +    return &fmt[i];
>> +}
>> +
>> +static const struct iris_fmt *
>> +find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>> +{
>> +    const struct iris_fmt *fmt = iris_vdec_formats;
>> +    unsigned int size = ARRAY_SIZE(iris_vdec_formats);
>> +
>> +    if (index >= size || fmt[index].type != type)
>> +        return NULL;
>> +
>> +    return &fmt[index];
>> +}
>> +
>>   int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
>>   {
>> +    const struct iris_fmt *fmt;
>> +
>>       switch (f->type) {
>>       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
>> -        f->pixelformat = V4L2_PIX_FMT_H264;
>> +        fmt = find_format_by_index(inst, f->index, f->type);
>> +        if (!fmt)
>> +            return -EINVAL;
>> +
>> +        f->pixelformat = fmt->pixfmt;
>>           f->flags = V4L2_FMT_FLAG_COMPRESSED |
>> V4L2_FMT_FLAG_DYN_RESOLUTION;
>>           break;
>>       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
>> +        if (f->index)
>> +            return -EINVAL;
>>           f->pixelformat = V4L2_PIX_FMT_NV12;
>>           break;
>>       default:
>> @@ -88,13 +142,15 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct
>> v4l2_format *f)
>>   {
>>       struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
>>       struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
>> +    const struct iris_fmt *fmt;
>>       struct v4l2_format *f_inst;
>>       struct vb2_queue *src_q;
>>         memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
>> +    fmt = find_format(inst, pixmp->pixelformat, f->type);
>>       switch (f->type) {
>>       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
>> -        if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) {
>> +        if (!fmt) {
>>               f_inst = inst->fmt_src;
>>               f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
>>               f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
>> @@ -102,7 +158,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct
>> v4l2_format *f)
>>           }
>>           break;
>>       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
>> -        if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
>> +        if (!fmt) {
>>               f_inst = inst->fmt_dst;
>>               f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
>>               f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
>> @@ -145,13 +201,14 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct
>> v4l2_format *f)
>>         switch (f->type) {
>>       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
>> -        if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264)
>> +        if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
>>               return -EINVAL;
>>             fmt = inst->fmt_src;
>>           fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
>> -
>> -        codec_align = DEFAULT_CODEC_ALIGNMENT;
>> +        fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
>> +        inst->codec = fmt->fmt.pix_mp.pixelformat;
>> +        codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
> 
> For preference I'd choose a default assignment and then an if for whatever
> you choose as non-default.
> 
> codec_align = 16;
> if (inst->codec == V4L2_PIX_FMT_HEVC)
>     codec_align = 32;
> 
I don't see any issue with using ternary operator here, since it's just a
simple value selection.
>>           fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
>>           fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
>>           fmt->fmt.pix_mp.num_planes = 1;
>> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h
>> b/drivers/media/platform/qcom/iris/iris_vdec.h
>> index b24932dc511a..cd7aab66dc7c 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vdec.h
>> +++ b/drivers/media/platform/qcom/iris/iris_vdec.h
>> @@ -8,6 +8,17 @@
>>     struct iris_inst;
>>   +enum iris_fmt_type {
>> +    IRIS_FMT_H264,
> 
> I persoanlly like to init enums = 0,
> 
we are initializing enum only if it starts with non zero value in the
driver code currently so would like to follow the same practise, unless
there is strong concern here.
> 
>> +    IRIS_FMT_HEVC,
>> +    IRIS_FMT_VP9,
>> +};
>> +
>> +struct iris_fmt {
>> +    u32 pixfmt;
>> +    u32 type;
>> +};
>> +
>>   int iris_vdec_inst_init(struct iris_inst *inst);
>>   void iris_vdec_inst_deinit(struct iris_inst *inst);
>>   int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
>> diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c
>> b/drivers/media/platform/qcom/iris/iris_vidc.c
>> index ca0f4e310f77..6a6afa15b647 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vidc.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vidc.c
>> @@ -249,9 +249,6 @@ static int iris_enum_fmt(struct file *filp, void *fh,
>> struct v4l2_fmtdesc *f)
>>   {
>>       struct iris_inst *inst = iris_get_inst(filp, NULL);
>>   -    if (f->index)
>> -        return -EINVAL;
>> -
>>       return iris_vdec_enum_fmt(inst, f);
>>   }
>>   
> 
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

Thanks,
Dikshita
Dikshita Agarwal March 6, 2025, 12:10 p.m. UTC | #2
On 3/5/2025 7:30 PM, neil.armstrong@linaro.org wrote:
> On 05/03/2025 11:43, Dikshita Agarwal wrote:
>> Subscribe and set mandatory properties to the firmware for HEVC and VP9
>> decoders.
>>
>> Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
>> ---
>>   .../platform/qcom/iris/iris_hfi_common.h      |  1 +
>>   .../qcom/iris/iris_hfi_gen1_command.c         |  4 +-
>>   .../qcom/iris/iris_hfi_gen2_command.c         | 83 +++++++++++++++++--
>>   .../qcom/iris/iris_hfi_gen2_response.c        |  7 ++
>>   .../platform/qcom/iris/iris_platform_common.h | 16 +++-
>>   .../platform/qcom/iris/iris_platform_sm8250.c |  4 +-
>>   .../platform/qcom/iris/iris_platform_sm8550.c | 61 ++++++++++++--
>>   7 files changed, 151 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h
>> b/drivers/media/platform/qcom/iris/iris_hfi_common.h
>> index b2c541367fc6..9e6aadb83783 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
>> @@ -140,6 +140,7 @@ struct hfi_subscription_params {
>>       u32    color_info;
>>       u32    profile;
>>       u32    level;
>> +    u32    tier;
>>   };
>>     u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries);
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> index 1e774b058ab9..a160ae915886 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
>> @@ -784,8 +784,8 @@ static int
>> iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p
>>               iris_hfi_gen1_set_bufsize},
>>       };
>>   -    config_params = core->iris_platform_data->input_config_params;
>> -    config_params_size =
>> core->iris_platform_data->input_config_params_size;
>> +    config_params = core->iris_platform_data->input_config_params_default;
>> +    config_params_size =
>> core->iris_platform_data->input_config_params_default_size;
>>         if (V4L2_TYPE_IS_OUTPUT(plane)) {
>>           for (i = 0; i < config_params_size; i++) {
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
>> index a3ebcda9a2ba..5b4c89184297 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
>> @@ -192,7 +192,7 @@ static int iris_hfi_gen2_set_crop_offsets(struct
>> iris_inst *inst)
>>                             sizeof(u64));
>>   }
>>   -static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst)
>> +static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
> 
> Please move typo fixes to separate patch with Fixes tag.
> 
> Neil
> 
Ack.

Thanks,
Dikshita
>>   {
>>       struct iris_inst_hfi_gen2 *inst_hfi_gen2 =
>> to_iris_inst_hfi_gen2(inst);
>>       u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
>> @@ -407,6 +407,23 @@ static int
>> iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
>>                             sizeof(u64));
>>   }
>>   +static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
>> +{
>> +    struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
>> +    u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
>> +    u32 tier = inst->fw_caps[TIER].value;
>> +
>> +    inst_hfi_gen2->src_subcr_params.tier = tier;
>> +
>> +    return iris_hfi_gen2_session_set_property(inst,
>> +                          HFI_PROP_TIER,
>> +                          HFI_HOST_FLAGS_NONE,
>> +                          port,
>> +                          HFI_PAYLOAD_U32_ENUM,
>> +                          &tier,
>> +                          sizeof(u32));
>> +}
>> +
>>   static int iris_hfi_gen2_session_set_config_params(struct iris_inst
>> *inst, u32 plane)
>>   {
>>       struct iris_core *core = inst->core;
>> @@ -418,7 +435,7 @@ static int
>> iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
>>           {HFI_PROP_BITSTREAM_RESOLUTION,      
>> iris_hfi_gen2_set_bitstream_resolution   },
>>           {HFI_PROP_CROP_OFFSETS,              
>> iris_hfi_gen2_set_crop_offsets           },
>>           {HFI_PROP_CODED_FRAMES,              
>> iris_hfi_gen2_set_coded_frames           },
>> -        {HFI_PROP_LUMA_CHROMA_BIT_DEPTH,     
>> iris_hfi_gen2_set_bit_dpeth              },
>> +        {HFI_PROP_LUMA_CHROMA_BIT_DEPTH,     
>> iris_hfi_gen2_set_bit_depth              },
>>           {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>> iris_hfi_gen2_set_min_output_count       },
>>           {HFI_PROP_PIC_ORDER_CNT_TYPE,        
>> iris_hfi_gen2_set_picture_order_count    },
>>           {HFI_PROP_SIGNAL_COLOR_INFO,         
>> iris_hfi_gen2_set_colorspace             },
>> @@ -426,11 +443,25 @@ static int
>> iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
>>           {HFI_PROP_LEVEL,                     
>> iris_hfi_gen2_set_level                  },
>>           {HFI_PROP_COLOR_FORMAT,              
>> iris_hfi_gen2_set_colorformat            },
>>           {HFI_PROP_LINEAR_STRIDE_SCANLINE,    
>> iris_hfi_gen2_set_linear_stride_scanline },
>> +        {HFI_PROP_TIER,                      
>> iris_hfi_gen2_set_tier                   },
>>       };
>>         if (V4L2_TYPE_IS_OUTPUT(plane)) {
>> -        config_params = core->iris_platform_data->input_config_params;
>> -        config_params_size =
>> core->iris_platform_data->input_config_params_size;
>> +        if (inst->codec == V4L2_PIX_FMT_H264) {
>> +            config_params =
>> core->iris_platform_data->input_config_params_default;
>> +            config_params_size =
>> +                core->iris_platform_data->input_config_params_default_size;
>> +        } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
>> +            config_params =
>> core->iris_platform_data->input_config_params_hevc;
>> +            config_params_size =
>> +                core->iris_platform_data->input_config_params_hevc_size;
>> +        } else if (inst->codec == V4L2_PIX_FMT_VP9) {
>> +            config_params =
>> core->iris_platform_data->input_config_params_vp9;
>> +            config_params_size =
>> +                core->iris_platform_data->input_config_params_vp9_size;
>> +        } else {
>> +            return -EINVAL;
>> +        }
>>       } else {
>>           config_params = core->iris_platform_data->output_config_params;
>>           config_params_size =
>> core->iris_platform_data->output_config_params_size;
>> @@ -600,8 +631,21 @@ static int
>> iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
>>           return 0;
>>       }
>>   -    change_param = core->iris_platform_data->input_config_params;
>> -    change_param_size = core->iris_platform_data->input_config_params_size;
>> +    if (inst->codec == V4L2_PIX_FMT_H264) {
>> +        change_param =
>> core->iris_platform_data->input_config_params_default;
>> +        change_param_size =
>> +            core->iris_platform_data->input_config_params_default_size;
>> +    } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
>> +        change_param = core->iris_platform_data->input_config_params_hevc;
>> +        change_param_size =
>> +            core->iris_platform_data->input_config_params_hevc_size;
>> +    } else if (inst->codec == V4L2_PIX_FMT_VP9) {
>> +        change_param = core->iris_platform_data->input_config_params_vp9;
>> +        change_param_size =
>> +            core->iris_platform_data->input_config_params_vp9_size;
>> +    } else {
>> +        return -EINVAL;
>> +    }
>>         payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
>>   @@ -648,6 +692,11 @@ static int
>> iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
>>                   payload_size = sizeof(u32);
>>                   payload_type = HFI_PAYLOAD_U32;
>>                   break;
>> +            case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
>> +                payload[0] = subsc_params.bit_depth;
>> +                payload_size = sizeof(u32);
>> +                payload_type = HFI_PAYLOAD_U32;
>> +                break;
>>               case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
>>                   payload[0] = subsc_params.fw_min_count;
>>                   payload_size = sizeof(u32);
>> @@ -673,6 +722,11 @@ static int
>> iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
>>                   payload_size = sizeof(u32);
>>                   payload_type = HFI_PAYLOAD_U32;
>>                   break;
>> +            case HFI_PROP_TIER:
>> +                payload[0] = subsc_params.tier;
>> +                payload_size = sizeof(u32);
>> +                payload_type = HFI_PAYLOAD_U32;
>> +                break;
>>               default:
>>                   prop_type = 0;
>>                   ret = -EINVAL;
>> @@ -709,8 +763,21 @@ static int iris_hfi_gen2_subscribe_property(struct
>> iris_inst *inst, u32 plane)
>>           subscribe_prop_size =
>> core->iris_platform_data->dec_input_prop_size;
>>           subcribe_prop = core->iris_platform_data->dec_input_prop;
>>       } else {
>> -        subscribe_prop_size =
>> core->iris_platform_data->dec_output_prop_size;
>> -        subcribe_prop = core->iris_platform_data->dec_output_prop;
>> +        if (inst->codec == V4L2_PIX_FMT_H264) {
>> +            subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
>> +            subscribe_prop_size =
>> +                core->iris_platform_data->dec_output_prop_avc_size;
>> +        } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
>> +            subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
>> +            subscribe_prop_size =
>> +                core->iris_platform_data->dec_output_prop_hevc_size;
>> +        } else if (inst->codec == V4L2_PIX_FMT_VP9) {
>> +            subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
>> +            subscribe_prop_size =
>> +                core->iris_platform_data->dec_output_prop_vp9_size;
>> +        } else {
>> +            return -EINVAL;
>> +        }
>>       }
>>         for (i = 0; i < subscribe_prop_size; i++)
>> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
>> b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
>> index 809bf0f238bd..6846311a26c3 100644
>> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
>> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
>> @@ -580,6 +580,7 @@ static void
>> iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst)
>>       }
>>         inst->fw_caps[POC].value = subsc_params.pic_order_cnt;
>> +    inst->fw_caps[TIER].value = subsc_params.tier;
>>         if (subsc_params.bit_depth != BIT_DEPTH_8 ||
>>           !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) {
>> @@ -664,6 +665,9 @@ static int
>> iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
>>           inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0];
>>           inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1];
>>           break;
>> +    case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
>> +        inst_hfi_gen2->src_subcr_params.bit_depth = pkt->payload[0];
>> +        break;
>>       case HFI_PROP_CODED_FRAMES:
>>           inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0];
>>           break;
>> @@ -682,6 +686,9 @@ static int
>> iris_hfi_gen2_handle_session_property(struct iris_inst *inst,
>>       case HFI_PROP_LEVEL:
>>           inst_hfi_gen2->src_subcr_params.level = pkt->payload[0];
>>           break;
>> +    case HFI_PROP_TIER:
>> +        inst_hfi_gen2->src_subcr_params.tier = pkt->payload[0];
>> +        break;
>>       case HFI_PROP_PICTURE_TYPE:
>>           inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0];
>>           break;
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> index 67204cddd44a..433ce9b00c68 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> @@ -174,14 +174,22 @@ struct iris_platform_data {
>>       u32 num_vpp_pipe;
>>       u32 max_session_count;
>>       u32 max_core_mbpf;
>> -    const u32 *input_config_params;
>> -    unsigned int input_config_params_size;
>> +    const u32 *input_config_params_default;
>> +    unsigned int input_config_params_default_size;
>> +    const u32 *input_config_params_hevc;
>> +    unsigned int input_config_params_hevc_size;
>> +    const u32 *input_config_params_vp9;
>> +    unsigned int input_config_params_vp9_size;
>>       const u32 *output_config_params;
>>       unsigned int output_config_params_size;
>>       const u32 *dec_input_prop;
>>       unsigned int dec_input_prop_size;
>> -    const u32 *dec_output_prop;
>> -    unsigned int dec_output_prop_size;
>> +    const u32 *dec_output_prop_avc;
>> +    unsigned int dec_output_prop_avc_size;
>> +    const u32 *dec_output_prop_hevc;
>> +    unsigned int dec_output_prop_hevc_size;
>> +    const u32 *dec_output_prop_vp9;
>> +    unsigned int dec_output_prop_vp9_size;
>>       const u32 *dec_ip_int_buf_tbl;
>>       unsigned int dec_ip_int_buf_tbl_size;
>>       const u32 *dec_op_int_buf_tbl;
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
>> b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
>> index 5c86fd7b7b6f..5f74e57f04fc 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
>> @@ -137,9 +137,9 @@ struct iris_platform_data sm8250_data = {
>>       .num_vpp_pipe = 4,
>>       .max_session_count = 16,
>>       .max_core_mbpf = (8192 * 4352) / 256,
>> -    .input_config_params =
>> +    .input_config_params_default =
>>           sm8250_vdec_input_config_param_default,
>> -    .input_config_params_size =
>> +    .input_config_params_default_size =
>>           ARRAY_SIZE(sm8250_vdec_input_config_param_default),
>>         .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl,
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
>> b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
>> index 29bc50785da5..779c71885f51 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c
>> @@ -254,9 +254,10 @@ static struct tz_cp_config tz_cp_config_sm8550 = {
>>       .cp_nonpixel_size = 0x24800000,
>>   };
>>   -static const u32 sm8550_vdec_input_config_params[] = {
>> +static const u32 sm8550_vdec_input_config_params_default[] = {
>>       HFI_PROP_BITSTREAM_RESOLUTION,
>>       HFI_PROP_CROP_OFFSETS,
>> +    HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>>       HFI_PROP_CODED_FRAMES,
>>       HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>>       HFI_PROP_PIC_ORDER_CNT_TYPE,
>> @@ -265,6 +266,26 @@ static const u32 sm8550_vdec_input_config_params[] = {
>>       HFI_PROP_SIGNAL_COLOR_INFO,
>>   };
>>   +static const u32 sm8550_vdec_input_config_param_hevc[] = {
>> +    HFI_PROP_BITSTREAM_RESOLUTION,
>> +    HFI_PROP_CROP_OFFSETS,
>> +    HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>> +    HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>> +    HFI_PROP_PROFILE,
>> +    HFI_PROP_LEVEL,
>> +    HFI_PROP_TIER,
>> +    HFI_PROP_SIGNAL_COLOR_INFO,
>> +};
>> +
>> +static const u32 sm8550_vdec_input_config_param_vp9[] = {
>> +    HFI_PROP_BITSTREAM_RESOLUTION,
>> +    HFI_PROP_CROP_OFFSETS,
>> +    HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>> +    HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>> +    HFI_PROP_PROFILE,
>> +    HFI_PROP_LEVEL,
>> +};
>> +
>>   static const u32 sm8550_vdec_output_config_params[] = {
>>       HFI_PROP_COLOR_FORMAT,
>>       HFI_PROP_LINEAR_STRIDE_SCANLINE,
>> @@ -274,11 +295,19 @@ static const u32
>> sm8550_vdec_subscribe_input_properties[] = {
>>       HFI_PROP_NO_OUTPUT,
>>   };
>>   -static const u32 sm8550_vdec_subscribe_output_properties[] = {
>> +static const u32 sm8550_vdec_subscribe_output_properties_avc[] = {
>>       HFI_PROP_PICTURE_TYPE,
>>       HFI_PROP_CABAC_SESSION,
>>   };
>>   +static const u32 sm8550_vdec_subscribe_output_properties_hevc[] = {
>> +    HFI_PROP_PICTURE_TYPE,
>> +};
>> +
>> +static const u32 sm8550_vdec_subscribe_output_properties_vp9[] = {
>> +    HFI_PROP_PICTURE_TYPE,
>> +};
>> +
>>   static const u32 sm8550_dec_ip_int_buf_tbl[] = {
>>       BUF_BIN,
>>       BUF_COMV,
>> @@ -322,19 +351,33 @@ struct iris_platform_data sm8550_data = {
>>       .num_vpp_pipe = 4,
>>       .max_session_count = 16,
>>       .max_core_mbpf = ((8192 * 4352) / 256) * 2,
>> -    .input_config_params =
>> -        sm8550_vdec_input_config_params,
>> -    .input_config_params_size =
>> -        ARRAY_SIZE(sm8550_vdec_input_config_params),
>> +    .input_config_params_default =
>> +        sm8550_vdec_input_config_params_default,
>> +    .input_config_params_default_size =
>> +        ARRAY_SIZE(sm8550_vdec_input_config_params_default),
>> +    .input_config_params_hevc =
>> +        sm8550_vdec_input_config_param_hevc,
>> +    .input_config_params_hevc_size =
>> +        ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
>> +    .input_config_params_vp9 =
>> +        sm8550_vdec_input_config_param_vp9,
>> +    .input_config_params_vp9_size =
>> +        ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
>>       .output_config_params =
>>           sm8550_vdec_output_config_params,
>>       .output_config_params_size =
>>           ARRAY_SIZE(sm8550_vdec_output_config_params),
>>       .dec_input_prop = sm8550_vdec_subscribe_input_properties,
>>       .dec_input_prop_size =
>> ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
>> -    .dec_output_prop = sm8550_vdec_subscribe_output_properties,
>> -    .dec_output_prop_size =
>> ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
>> -
>> +    .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
>> +    .dec_output_prop_avc_size =
>> +        ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
>> +    .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
>> +    .dec_output_prop_hevc_size =
>> +        ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
>> +    .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
>> +    .dec_output_prop_vp9_size =
>> +        ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
>>       .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
>>       .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
>>       .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
>
Dikshita Agarwal March 6, 2025, 12:34 p.m. UTC | #3
On 3/5/2025 7:52 PM, neil.armstrong@linaro.org wrote:
> Hi,
> 
> On 05/03/2025 11:43, Dikshita Agarwal wrote:
>> Hi all,
>>
>> This patch series adds initial support for the HEVC(H.265) and VP9
>> codecs in iris decoder. The objective of this work is to extend the
>> decoder's capabilities to handle HEVC and VP9 codec streams,
>> including necessary format handling and buffer management.
>> In addition, the series also includes a set of fixes to address issues
>> identified during testing of these additional codecs.
>>
>> I'm sharing this series as an RFC because compliance and conformance
>> testing are still in progress.
>> While initial functional tests show positive results, I would
>> appreciate early feedback on the design, implementation, and fixes
>> before moving to a formal submission.
>>
>> I plan to submit a formal patch series after completing all compliance
>> checks. Meanwhile, any feedback or suggestion to improve this work are
>> very welcome.
>>
>> Thanks,
>> Dikshita
>>
>> Dikshita Agarwal (12):
>>    media: iris: Add HEVC and VP9 formats for decoder
>>    media: iris: Add platform capabilities for HEVC and VP9 decoders
>>    media: iris: Set mandatory properties for HEVC and VP9 decoders.
>>    media: iris: Add internal buffer calculation for HEVC and VP9 decoders
>>    media: iris: Skip destroying internal buffer if not dequeued
>>    media: iris: Update CAPTURE format info based on OUTPUT format
>>    media: iris: Add handling for corrupt and drop frames
>>    media: iris: Avoid updating frame size to firmware during reconfig
>>    media: iris: Avoid sending LAST flag multiple times
>>    media: iris: Send V4L2_BUF_FLAG_ERROR for buffers with 0 filled length
>>    media: iris: Fix handling of eos buffer during drain
>>    media: iris: Add handling for no show frames
> 
> I should be better to move patches 1, 2 & 3 at the end, after the patches
> adding support for specific hecv & h265 features, and please check that
> none of the patches breaks h264 at any time to keep bisectability.
> 
Noted.

Thanks,
Dikshita
> Neil
> 
> Neil
> 
>>
>>   .../media/platform/qcom/iris/iris_buffer.c    |  22 +-
>>   drivers/media/platform/qcom/iris/iris_ctrls.c |  28 +-
>>   .../platform/qcom/iris/iris_hfi_common.h      |   1 +
>>   .../qcom/iris/iris_hfi_gen1_command.c         |  38 +-
>>   .../qcom/iris/iris_hfi_gen1_defines.h         |   4 +
>>   .../qcom/iris/iris_hfi_gen1_response.c        |  11 +
>>   .../qcom/iris/iris_hfi_gen2_command.c         | 129 +++++-
>>   .../qcom/iris/iris_hfi_gen2_defines.h         |   5 +
>>   .../qcom/iris/iris_hfi_gen2_response.c        |  56 ++-
>>   .../media/platform/qcom/iris/iris_instance.h  |   6 +
>>   .../platform/qcom/iris/iris_platform_common.h |  25 +-
>>   .../platform/qcom/iris/iris_platform_sm8250.c |   4 +-
>>   .../platform/qcom/iris/iris_platform_sm8550.c | 141 ++++++-
>>   drivers/media/platform/qcom/iris/iris_vb2.c   |   3 +-
>>   drivers/media/platform/qcom/iris/iris_vdec.c  |  80 +++-
>>   drivers/media/platform/qcom/iris/iris_vdec.h  |  11 +
>>   drivers/media/platform/qcom/iris/iris_vidc.c  |   3 -
>>   .../platform/qcom/iris/iris_vpu_buffer.c      | 397 +++++++++++++++++-
>>   .../platform/qcom/iris/iris_vpu_buffer.h      |  46 +-
>>   19 files changed, 931 insertions(+), 79 deletions(-)
>>
>