Re: [PATCH v3 4/5] media: meson: vdec: add VP9 input support

From: Maxime Jourdan
Date: Fri Jan 24 2020 - 06:18:52 EST


On Thu, Jan 16, 2020 at 2:34 PM Neil Armstrong <narmstrong@xxxxxxxxxxxx> wrote:
>
> From: Maxime Jourdan <mjourdan@xxxxxxxxxxxx>
>
> Amlogic VP9 decoder requires an additional 16-byte payload before every
> frame header.
>
> The source buffer is updated in-place, then given to the Parser FIFO DMA.
>
> The FIFO DMA copies the blocks into the 16MiB parser ring buffer, then parses
> and copies the slice into the decoder "workspace".
>
> Signed-off-by: Maxime Jourdan <mjourdan@xxxxxxxxxxxx>
> Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx>
> ---

[...]

> @@ -186,13 +294,27 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
> int ret;
> struct vb2_buffer *vb = &vbuf->vb2_buf;
> struct amvdec_core *core = sess->core;
> + struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
> u32 payload_size = vb2_get_plane_payload(vb, 0);
> dma_addr_t phy = vb2_dma_contig_plane_dma_addr(vb, 0);
> + u32 num_dst_bufs = 0;
> u32 offset;
> u32 pad_size;
>
> - if (esparser_vififo_get_free_space(sess) < payload_size)
> + if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9) {
> + if (codec_ops->num_pending_bufs)
> + num_dst_bufs = codec_ops->num_pending_bufs(sess);
> +
> + num_dst_bufs += v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx);
> + if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9)
> + num_dst_bufs -= 2;

With the changes that happened in the updated series where one more
ref frame is held by VP9, this should be -= 3 to prevent a shortage of
CAPTURE buffers on the decoder side.

For the future, a good enhancement of the way this is handled could be
to notify new capture buffers to the decoding modules (codec_*.c), so
that they could pause when there is no capture buffer available and
resume on this notification.

> +
> + if (esparser_vififo_get_free_space(sess) < payload_size ||
> + atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs)
> + return -EAGAIN;
> + } else if (esparser_vififo_get_free_space(sess) < payload_size) {
> return -EAGAIN;
> + }
>
> v4l2_m2m_src_buf_remove_by_buf(sess->m2m_ctx, vbuf);
>
> @@ -206,7 +328,19 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
> vbuf->field = V4L2_FIELD_NONE;
> vbuf->sequence = sess->sequence_out++;
>
> - pad_size = esparser_pad_start_code(core, vb);
> + if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9) {
> + payload_size = vp9_update_header(core, vb);
> +
> + /* If unable to alter buffer to add headers */
> + if (payload_size == 0) {
> + amvdec_remove_ts(sess, vb->timestamp);
> + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +
> + return 0;
> + }
> + }
> +
> + pad_size = esparser_pad_start_code(core, vb, payload_size);
> ret = esparser_write_data(core, phy, payload_size + pad_size);
>
> if (ret <= 0) {
> --
> 2.22.0
>