lkml.org 
[lkml]   [2021]   [Apr]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 13/15] media: mtk-vcodec: make flush buffer reusable by encoder
    Date
    The flush buffer is a special buffer that tells the decoder driver to
    send an empty CAPTURE frame to the client with V4L2_BUF_FLAG_LAST set.

    We need similar functionality for the encoder ; however currently the
    flush buffer depends on decoder-specific structures and thus cannot be
    reused with the encoder.

    Fix this by testing for this buffer by its VB2 address, and not through
    a dedicated flag stored in a higher-level decoder structure. This also
    allows us to remove said flag and simplify the code a bit.

    Since the flush buffer should never be used in the stateless decoder,
    also add safeguards to check against it.

    Signed-off-by: Alexandre Courbot <acourbot@chromium.org>
    ---
    .../media/platform/mtk-vcodec/mtk_vcodec_dec.c | 9 ++-------
    .../media/platform/mtk-vcodec/mtk_vcodec_dec.h | 2 --
    .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 12 +-----------
    .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c | 15 +++++++++------
    .../media/platform/mtk-vcodec/mtk_vcodec_drv.h | 6 ++++--
    5 files changed, 16 insertions(+), 28 deletions(-)

    diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
    index 0fafe8f9e1b9..914b1c526943 100644
    --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
    +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
    @@ -86,8 +86,7 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
    mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
    return 0;
    }
    - v4l2_m2m_buf_queue(ctx->m2m_ctx,
    - &ctx->empty_flush_buf->m2m_buf.vb);
    + v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
    v4l2_m2m_try_schedule(ctx->m2m_ctx);
    break;

    @@ -779,8 +778,6 @@ int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
    if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    buf->used = false;
    buf->queued_in_v4l2 = false;
    - } else {
    - buf->lastframe = false;
    }

    return 0;
    @@ -807,9 +804,7 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q)

    if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
    - struct mtk_video_dec_buf *buf_info = container_of(
    - src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
    - if (!buf_info->lastframe) {
    + if (src_buf != &ctx->empty_flush_buf.vb) {
    struct media_request *req =
    src_buf->vb2_buf.req_obj.req;
    v4l2_m2m_buf_done(src_buf,
    diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
    index 6b29d7d9ae15..bb0dfa9795b8 100644
    --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
    +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
    @@ -42,7 +42,6 @@ struct vdec_fb {
    * @queued_in_vb2: Capture buffer is queue in vb2
    * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2
    * queue yet
    - * @lastframe: Intput buffer is last buffer - EOS
    * @error: An unrecoverable error occurs on this buffer.
    * @frame_buffer: Decode status, and buffer information of Capture buffer
    * @bs_buffer: Output buffer info
    @@ -55,7 +54,6 @@ struct mtk_video_dec_buf {
    bool used;
    bool queued_in_vb2;
    bool queued_in_v4l2;
    - bool lastframe;

    bool error;

    diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
    index e0526c0900c8..4789e669c258 100644
    --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
    +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
    @@ -82,21 +82,14 @@ static int fops_vcodec_open(struct file *file)
    {
    struct mtk_vcodec_dev *dev = video_drvdata(file);
    struct mtk_vcodec_ctx *ctx = NULL;
    - struct mtk_video_dec_buf *mtk_buf = NULL;
    int ret = 0;
    struct vb2_queue *src_vq;

    ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    if (!ctx)
    return -ENOMEM;
    - mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
    - if (!mtk_buf) {
    - kfree(ctx);
    - return -ENOMEM;
    - }

    mutex_lock(&dev->dev_mutex);
    - ctx->empty_flush_buf = mtk_buf;
    ctx->id = dev->id_counter++;
    v4l2_fh_init(&ctx->fh, video_devdata(file));
    file->private_data = &ctx->fh;
    @@ -122,8 +115,7 @@ static int fops_vcodec_open(struct file *file)
    }
    src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
    V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
    - ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
    - ctx->empty_flush_buf->lastframe = true;
    + ctx->empty_flush_buf.vb.vb2_buf.vb2_queue = src_vq;
    mtk_vcodec_dec_set_default_params(ctx);

    if (v4l2_fh_is_singular(&ctx->fh)) {
    @@ -161,7 +153,6 @@ static int fops_vcodec_open(struct file *file)
    err_ctrls_setup:
    v4l2_fh_del(&ctx->fh);
    v4l2_fh_exit(&ctx->fh);
    - kfree(ctx->empty_flush_buf);
    kfree(ctx);
    mutex_unlock(&dev->dev_mutex);

    @@ -192,7 +183,6 @@ static int fops_vcodec_release(struct file *file)
    v4l2_ctrl_handler_free(&ctx->ctrl_hdl);

    list_del_init(&ctx->list);
    - kfree(ctx->empty_flush_buf);
    kfree(ctx);
    mutex_unlock(&dev->dev_mutex);
    return 0;
    diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
    index d815125c81a4..1f68d92e5c3a 100644
    --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
    +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
    @@ -337,8 +337,6 @@ static void mtk_vdec_worker(struct work_struct *work)
    return;
    }

    - src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
    - m2m_buf.vb);
    dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf,
    m2m_buf.vb);

    @@ -359,7 +357,7 @@ static void mtk_vdec_worker(struct work_struct *work)
    pfb->base_y.va, &pfb->base_y.dma_addr,
    &pfb->base_c.dma_addr, pfb->base_y.size);

    - if (src_buf_info->lastframe) {
    + if (src_buf == &ctx->empty_flush_buf.vb) {
    mtk_v4l2_debug(1, "Got empty flush input buffer.");
    src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);

    @@ -380,6 +378,10 @@ static void mtk_vdec_worker(struct work_struct *work)
    v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
    return;
    }
    +
    + src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
    + m2m_buf.vb);
    +
    buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
    buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
    buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
    @@ -459,7 +461,6 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
    unsigned int dpbsize = 1, i = 0;
    struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
    struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
    - struct mtk_video_dec_buf *buf = NULL;
    struct mtk_q_data *dst_q_data;

    mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p",
    @@ -469,6 +470,8 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
    * check if this buffer is ready to be used after decode
    */
    if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    + struct mtk_video_dec_buf *buf;
    +
    vb2_v4l2 = to_vb2_v4l2_buffer(vb);
    buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
    m2m_buf.vb);
    @@ -498,8 +501,8 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
    mtk_v4l2_err("No src buffer");
    return;
    }
    - buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
    - if (buf->lastframe) {
    +
    + if (src_buf == &ctx->empty_flush_buf.vb) {
    /* This shouldn't happen. Just in case. */
    mtk_v4l2_err("Invalid flush buffer.");
    v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
    diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
    index 10edd238c939..c2f4cad6cfc2 100644
    --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
    +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
    @@ -13,6 +13,7 @@
    #include <media/v4l2-ctrls.h>
    #include <media/v4l2-device.h>
    #include <media/v4l2-ioctl.h>
    +#include <media/v4l2-mem2mem.h>
    #include <media/videobuf2-core.h>
    #include "mtk_vcodec_util.h"

    @@ -249,7 +250,8 @@ struct vdec_pic_info {
    * @decode_work: worker for the decoding
    * @encode_work: worker for the encoding
    * @last_decoded_picinfo: pic information get from latest decode
    - * @empty_flush_buf: a fake size-0 capture buffer that indicates flush
    + * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
    + * to be used with encoder and stateful decoder.
    * @current_codec: current set input codec, in V4L2 pixel format
    *
    * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
    @@ -288,7 +290,7 @@ struct mtk_vcodec_ctx {
    struct work_struct decode_work;
    struct work_struct encode_work;
    struct vdec_pic_info last_decoded_picinfo;
    - struct mtk_video_dec_buf *empty_flush_buf;
    + struct v4l2_m2m_buffer empty_flush_buf;

    u32 current_codec;

    --
    2.31.1.498.g6c1eba8ee3d-goog
    \
     
     \ /
      Last update: 2021-04-27 13:39    [W:3.779 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site