[media] coda: allocate per-context buffers from REQBUFS
authorPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 24 Mar 2015 17:30:51 +0000 (14:30 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Fri, 10 Apr 2015 13:06:46 +0000 (10:06 -0300)
Allocate the per-context buffers from REQBUFS instead in start_encoding or
start_decoding. This allows to stop and start streaming independently of
buffer (re)allocation

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h

index 856b542b35b9c4a3c6d2930edcf8773304003d5e..12b93867e6657b3eb21572f22a7834d0c2af1639 100644 (file)
@@ -709,6 +709,27 @@ err_clk_per:
  * Encoder context operations
  */
 
+static int coda_encoder_reqbufs(struct coda_ctx *ctx,
+                               struct v4l2_requestbuffers *rb)
+{
+       struct coda_q_data *q_data_src;
+       int ret;
+
+       if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return 0;
+
+       if (rb->count) {
+               q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+               ret = coda_alloc_context_buffers(ctx, q_data_src);
+               if (ret < 0)
+                       return ret;
+       } else {
+               coda_free_context_buffers(ctx);
+       }
+
+       return 0;
+}
+
 static int coda_start_encoding(struct coda_ctx *ctx)
 {
        struct coda_dev *dev = ctx->dev;
@@ -725,11 +746,6 @@ static int coda_start_encoding(struct coda_ctx *ctx)
        q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
        dst_fourcc = q_data_dst->fourcc;
 
-       /* Allocate per-instance buffers */
-       ret = coda_alloc_context_buffers(ctx, q_data_src);
-       if (ret < 0)
-               return ret;
-
        buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
        bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
        bitstream_size = q_data_dst->sizeimage;
@@ -1311,7 +1327,6 @@ static void coda_seq_end_work(struct work_struct *work)
                ctx->bitstream.vaddr, ctx->bitstream.size);
 
        coda_free_framebuffers(ctx);
-       coda_free_context_buffers(ctx);
 
        mutex_unlock(&dev->coda_mutex);
        mutex_unlock(&ctx->buffer_mutex);
@@ -1327,6 +1342,7 @@ static void coda_bit_release(struct coda_ctx *ctx)
 
 const struct coda_context_ops coda_bit_encode_ops = {
        .queue_init = coda_encoder_queue_init,
+       .reqbufs = coda_encoder_reqbufs,
        .start_streaming = coda_start_encoding,
        .prepare_run = coda_prepare_encode,
        .finish_run = coda_finish_encode,
@@ -1338,6 +1354,27 @@ const struct coda_context_ops coda_bit_encode_ops = {
  * Decoder context operations
  */
 
+static int coda_decoder_reqbufs(struct coda_ctx *ctx,
+                               struct v4l2_requestbuffers *rb)
+{
+       struct coda_q_data *q_data_src;
+       int ret;
+
+       if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return 0;
+
+       if (rb->count) {
+               q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+               ret = coda_alloc_context_buffers(ctx, q_data_src);
+               if (ret < 0)
+                       return ret;
+       } else {
+               coda_free_context_buffers(ctx);
+       }
+
+       return 0;
+}
+
 static int __coda_start_decoding(struct coda_ctx *ctx)
 {
        struct coda_q_data *q_data_src, *q_data_dst;
@@ -1356,11 +1393,6 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
        src_fourcc = q_data_src->fourcc;
        dst_fourcc = q_data_dst->fourcc;
 
-       /* Allocate per-instance buffers */
-       ret = coda_alloc_context_buffers(ctx, q_data_src);
-       if (ret < 0)
-               return ret;
-
        coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
 
        /* Update coda bitstream read and write pointers from kfifo */
@@ -1906,6 +1938,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
 
 const struct coda_context_ops coda_bit_decode_ops = {
        .queue_init = coda_decoder_queue_init,
+       .reqbufs = coda_decoder_reqbufs,
        .start_streaming = coda_start_decoding,
        .prepare_run = coda_prepare_decode,
        .finish_run = coda_finish_decode,
index 443886535230ee034835eaef0967382b0f8b337e..a8a6c36a1f000daec9d96ddaef0d6c8d861af78b 100644 (file)
@@ -696,6 +696,26 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
        return coda_s_fmt(ctx, &f_cap);
 }
 
+static int coda_reqbufs(struct file *file, void *priv,
+                       struct v4l2_requestbuffers *rb)
+{
+       struct coda_ctx *ctx = fh_to_ctx(priv);
+       int ret;
+
+       ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb);
+       if (ret)
+               return ret;
+
+       /*
+        * Allow to allocate instance specific per-context buffers, such as
+        * bitstream ringbuffer, slice buffer, work buffer, etc. if needed.
+        */
+       if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs)
+               return ctx->ops->reqbufs(ctx, rb);
+
+       return 0;
+}
+
 static int coda_qbuf(struct file *file, void *priv,
                     struct v4l2_buffer *buf)
 {
@@ -841,7 +861,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
        .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out,
        .vidioc_s_fmt_vid_out   = coda_s_fmt_vid_out,
 
-       .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_reqbufs         = coda_reqbufs,
        .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
 
        .vidioc_qbuf            = coda_qbuf,
index 499049f3896b7c1d69de9f5efbc2b4ce3e236787..57d070ce666515253b37f22f9008c5bf26bd2e9a 100644 (file)
@@ -178,6 +178,7 @@ struct coda_ctx;
 struct coda_context_ops {
        int (*queue_init)(void *priv, struct vb2_queue *src_vq,
                          struct vb2_queue *dst_vq);
+       int (*reqbufs)(struct coda_ctx *ctx, struct v4l2_requestbuffers *rb);
        int (*start_streaming)(struct coda_ctx *ctx);
        int (*prepare_run)(struct coda_ctx *ctx);
        void (*finish_run)(struct coda_ctx *ctx);