Message ID | 20250328064819.784-1-ming.qian@oss.nxp.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v4,1/2] media: amphion: Reduce decoding latency for HEVC decoder | expand |
On Fri, Mar 28, 2025 at 02:48:16PM +0800, ming.qian@oss.nxp.com wrote: > From: Ming Qian <ming.qian@oss.nxp.com> > > The amphion decoder firmware supports a low latency flush mode for the > HEVC format since v1.9.0. This feature, which is enabled when the > display delay is set to 0, can help to reduce the decoding latency by > appending some padding data to every frame. > > Signed-off-by: Ming Qian <ming.qian@oss.nxp.com> > Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> > --- > v4 > - Add CHECK_VERSION macro > v3 > - Improve commit message as recommended > v2 > - Improve commit message > - Add firmware version check > > drivers/media/platform/amphion/vpu_malone.c | 24 ++++++++++++++++++--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c > index 5c6b2a841b6f..88f8c16a451e 100644 > --- a/drivers/media/platform/amphion/vpu_malone.c > +++ b/drivers/media/platform/amphion/vpu_malone.c > @@ -68,6 +68,12 @@ > > #define MALONE_DEC_FMT_RV_MASK BIT(21) > > +#define MALONE_VERSION_MASK 0xFFFFF > +#define MALONE_VERSION(maj, min, inc) \ > + ((((maj) << 16) | ((min) << 16) | (inc)) & MALONE_VERSION_MASK) > +#define CHECK_VERSION(iface, maj, min) \ > + (((iface)->fw_version & MALONE_VERSION_MASK) >= MALONE_VERSION(maj, min, 0)) > + Suggest use FIELD_PREP FILED_GET macro because it can check input value exceed the range. #define FIELD_PREP(_mask, _val) \ ({ \ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ ^^^^ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ }) Frank > enum vpu_malone_stream_input_mode { > INVALID_MODE = 0, > FRAME_LVL, > @@ -332,6 +338,8 @@ struct vpu_dec_ctrl { > u32 buf_addr[VID_API_NUM_STREAMS]; > }; > > +static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt); > + > u32 vpu_malone_get_data_size(void) > { > return sizeof(struct vpu_dec_ctrl); > @@ -654,9 +662,15 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, > hc->jpg[instance].jpg_mjpeg_interlaced = 0; > } > > - hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0; > - if (malone_format != MALONE_FMT_AVC) > + if (params->display_delay_enable && > + get_padding_scode(SCODE_PADDING_BUFFLUSH, params->codec_format)) > + hc->codec_param[instance].disp_imm = 1; > + else > hc->codec_param[instance].disp_imm = 0; > + > + if (params->codec_format == V4L2_PIX_FMT_HEVC && !CHECK_VERSION(iface, 1, 9)) > + hc->codec_param[instance].disp_imm = 0; > + > hc->codec_param[instance].dbglog_enable = 0; > iface->dbglog_desc.level = 0; > > @@ -1024,6 +1038,7 @@ static const struct malone_padding_scode padding_scodes[] = { > {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0x0, 0x0}}, > {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264, {0x15010000, 0x0}}, > {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC, {0x15010000, 0x0}}, > + {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_HEVC, {0x3e010000, 0x20}}, > }; > > static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0}; > @@ -1058,8 +1073,11 @@ static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer, > int ret; > > ps = get_padding_scode(scode_type, pixelformat); > - if (!ps) > + if (!ps) { > + if (scode_type == SCODE_PADDING_BUFFLUSH) > + return 0; > return -EINVAL; > + } > > wptr = readl(&str_buf->wptr); > if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length) > -- > 2.43.0-rc1 >
Hi Frank, On 2025/3/28 22:23, Frank Li wrote: > On Fri, Mar 28, 2025 at 02:48:16PM +0800, ming.qian@oss.nxp.com wrote: >> From: Ming Qian <ming.qian@oss.nxp.com> >> >> The amphion decoder firmware supports a low latency flush mode for the >> HEVC format since v1.9.0. This feature, which is enabled when the >> display delay is set to 0, can help to reduce the decoding latency by >> appending some padding data to every frame. >> >> Signed-off-by: Ming Qian <ming.qian@oss.nxp.com> >> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> >> --- >> v4 >> - Add CHECK_VERSION macro >> v3 >> - Improve commit message as recommended >> v2 >> - Improve commit message >> - Add firmware version check >> >> drivers/media/platform/amphion/vpu_malone.c | 24 ++++++++++++++++++--- >> 1 file changed, 21 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c >> index 5c6b2a841b6f..88f8c16a451e 100644 >> --- a/drivers/media/platform/amphion/vpu_malone.c >> +++ b/drivers/media/platform/amphion/vpu_malone.c >> @@ -68,6 +68,12 @@ >> >> #define MALONE_DEC_FMT_RV_MASK BIT(21) >> >> +#define MALONE_VERSION_MASK 0xFFFFF >> +#define MALONE_VERSION(maj, min, inc) \ >> + ((((maj) << 16) | ((min) << 16) | (inc)) & MALONE_VERSION_MASK) >> +#define CHECK_VERSION(iface, maj, min) \ >> + (((iface)->fw_version & MALONE_VERSION_MASK) >= MALONE_VERSION(maj, min, 0)) >> + > > Suggest use FIELD_PREP FILED_GET macro because it can check input value > exceed the range. > > #define FIELD_PREP(_mask, _val) \ > ({ \ > __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ > > ^^^^ > > ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ > }) > > Frank Sure, I'll apply it in V5 > >> enum vpu_malone_stream_input_mode { >> INVALID_MODE = 0, >> FRAME_LVL, >> @@ -332,6 +338,8 @@ struct vpu_dec_ctrl { >> u32 buf_addr[VID_API_NUM_STREAMS]; >> }; >> >> +static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt); >> + >> u32 vpu_malone_get_data_size(void) >> { >> return sizeof(struct vpu_dec_ctrl); >> @@ -654,9 +662,15 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, >> hc->jpg[instance].jpg_mjpeg_interlaced = 0; >> } >> >> - hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0; >> - if (malone_format != MALONE_FMT_AVC) >> + if (params->display_delay_enable && >> + get_padding_scode(SCODE_PADDING_BUFFLUSH, params->codec_format)) >> + hc->codec_param[instance].disp_imm = 1; >> + else >> hc->codec_param[instance].disp_imm = 0; >> + >> + if (params->codec_format == V4L2_PIX_FMT_HEVC && !CHECK_VERSION(iface, 1, 9)) >> + hc->codec_param[instance].disp_imm = 0; >> + >> hc->codec_param[instance].dbglog_enable = 0; >> iface->dbglog_desc.level = 0; >> >> @@ -1024,6 +1038,7 @@ static const struct malone_padding_scode padding_scodes[] = { >> {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0x0, 0x0}}, >> {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264, {0x15010000, 0x0}}, >> {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC, {0x15010000, 0x0}}, >> + {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_HEVC, {0x3e010000, 0x20}}, >> }; >> >> static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0}; >> @@ -1058,8 +1073,11 @@ static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer, >> int ret; >> >> ps = get_padding_scode(scode_type, pixelformat); >> - if (!ps) >> + if (!ps) { >> + if (scode_type == SCODE_PADDING_BUFFLUSH) >> + return 0; >> return -EINVAL; >> + } >> >> wptr = readl(&str_buf->wptr); >> if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length) >> -- >> 2.43.0-rc1 >>
diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index 5c6b2a841b6f..88f8c16a451e 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -68,6 +68,12 @@ #define MALONE_DEC_FMT_RV_MASK BIT(21) +#define MALONE_VERSION_MASK 0xFFFFF +#define MALONE_VERSION(maj, min, inc) \ + ((((maj) << 16) | ((min) << 16) | (inc)) & MALONE_VERSION_MASK) +#define CHECK_VERSION(iface, maj, min) \ + (((iface)->fw_version & MALONE_VERSION_MASK) >= MALONE_VERSION(maj, min, 0)) + enum vpu_malone_stream_input_mode { INVALID_MODE = 0, FRAME_LVL, @@ -332,6 +338,8 @@ struct vpu_dec_ctrl { u32 buf_addr[VID_API_NUM_STREAMS]; }; +static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt); + u32 vpu_malone_get_data_size(void) { return sizeof(struct vpu_dec_ctrl); @@ -654,9 +662,15 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, hc->jpg[instance].jpg_mjpeg_interlaced = 0; } - hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0; - if (malone_format != MALONE_FMT_AVC) + if (params->display_delay_enable && + get_padding_scode(SCODE_PADDING_BUFFLUSH, params->codec_format)) + hc->codec_param[instance].disp_imm = 1; + else hc->codec_param[instance].disp_imm = 0; + + if (params->codec_format == V4L2_PIX_FMT_HEVC && !CHECK_VERSION(iface, 1, 9)) + hc->codec_param[instance].disp_imm = 0; + hc->codec_param[instance].dbglog_enable = 0; iface->dbglog_desc.level = 0; @@ -1024,6 +1038,7 @@ static const struct malone_padding_scode padding_scodes[] = { {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0x0, 0x0}}, {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264, {0x15010000, 0x0}}, {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC, {0x15010000, 0x0}}, + {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_HEVC, {0x3e010000, 0x20}}, }; static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0}; @@ -1058,8 +1073,11 @@ static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer, int ret; ps = get_padding_scode(scode_type, pixelformat); - if (!ps) + if (!ps) { + if (scode_type == SCODE_PADDING_BUFFLUSH) + return 0; return -EINVAL; + } wptr = readl(&str_buf->wptr); if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length)