media: coda: add sequence initialization work
authorPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 18 Jun 2019 16:45:15 +0000 (12:45 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 24 Jun 2019 18:24:13 +0000 (14:24 -0400)
Add a sequence initialization work item to be run when OUTPUT buffers
are queued in the initialization state.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h

index cecfd51e3838146be01fc7a1dd7319851ec6a920..9f8e2342d17551a7f1201f0014ec140e60771954 100644 (file)
@@ -1824,6 +1824,30 @@ static int __coda_decoder_seq_init(struct coda_ctx *ctx)
        return 0;
 }
 
+static void coda_dec_seq_init_work(struct work_struct *work)
+{
+       struct coda_ctx *ctx = container_of(work,
+                                           struct coda_ctx, seq_init_work);
+       struct coda_dev *dev = ctx->dev;
+       int ret;
+
+       mutex_lock(&ctx->buffer_mutex);
+       mutex_lock(&dev->coda_mutex);
+
+       if (ctx->initialized == 1)
+               goto out;
+
+       ret = __coda_decoder_seq_init(ctx);
+       if (ret < 0)
+               goto out;
+
+       ctx->initialized = 1;
+
+out:
+       mutex_unlock(&dev->coda_mutex);
+       mutex_unlock(&ctx->buffer_mutex);
+}
+
 static int __coda_start_decoding(struct coda_ctx *ctx)
 {
        struct coda_q_data *q_data_src, *q_data_dst;
@@ -2352,6 +2376,7 @@ const struct coda_context_ops coda_bit_decode_ops = {
        .prepare_run = coda_prepare_decode,
        .finish_run = coda_finish_decode,
        .run_timeout = coda_decode_timeout,
+       .seq_init_work = coda_dec_seq_init_work,
        .seq_end_work = coda_seq_end_work,
        .release = coda_bit_release,
 };
index 43820cfac76cbad6475118445e4fae4201434e49..3fe374287600dd2788e5c698de85a7d5674e97fc 100644 (file)
@@ -1684,6 +1684,19 @@ static void coda_buf_queue(struct vb2_buffer *vb)
                        /* This set buf->sequence = ctx->qsequence++ */
                        coda_fill_bitstream(ctx, NULL);
                mutex_unlock(&ctx->bitstream_mutex);
+
+               if (!ctx->initialized) {
+                       /*
+                        * Run sequence initialization in case the queued
+                        * buffer contained headers.
+                        */
+                       if (vb2_is_streaming(vb->vb2_queue) &&
+                           ctx->ops->seq_init_work) {
+                               queue_work(ctx->dev->workqueue,
+                                          &ctx->seq_init_work);
+                               flush_work(&ctx->seq_init_work);
+                       }
+               }
        } else {
                if (ctx->inst_type == CODA_INST_ENCODER &&
                    vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -1761,6 +1774,15 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
                                ret = -EINVAL;
                                goto err;
                        }
+
+                       if (!ctx->initialized) {
+                               /* Run sequence initialization */
+                               if (ctx->ops->seq_init_work) {
+                                       queue_work(ctx->dev->workqueue,
+                                                  &ctx->seq_init_work);
+                                       flush_work(&ctx->seq_init_work);
+                               }
+                       }
                }
 
                ctx->streamon_out = 1;
@@ -2317,6 +2339,8 @@ static int coda_open(struct file *file)
        ctx->use_bit = !ctx->cvd->direct;
        init_completion(&ctx->completion);
        INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
+       if (ctx->ops->seq_init_work)
+               INIT_WORK(&ctx->seq_init_work, ctx->ops->seq_init_work);
        if (ctx->ops->seq_end_work)
                INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
        v4l2_fh_init(&ctx->fh, video_devdata(file));
index 0c2cace53ce8ad2ae0df82297545138b3ecc50df..c97ea3e24b808471793f4658beefc3d945d342d0 100644 (file)
@@ -185,6 +185,7 @@ struct coda_context_ops {
        int (*prepare_run)(struct coda_ctx *ctx);
        void (*finish_run)(struct coda_ctx *ctx);
        void (*run_timeout)(struct coda_ctx *ctx);
+       void (*seq_init_work)(struct work_struct *work);
        void (*seq_end_work)(struct work_struct *work);
        void (*release)(struct coda_ctx *ctx);
 };
@@ -193,6 +194,7 @@ struct coda_ctx {
        struct coda_dev                 *dev;
        struct mutex                    buffer_mutex;
        struct work_struct              pic_run_work;
+       struct work_struct              seq_init_work;
        struct work_struct              seq_end_work;
        struct completion               completion;
        const struct coda_video_device  *cvd;