diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2015-03-24 13:30:51 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-10 09:06:46 -0400 |
commit | 73751da61c00db9914ae1c47a25f7462722bc76b (patch) | |
tree | 33a095f7aa8aabe88375b55a032ee3ed2e1f4f24 | |
parent | bf249daf079492d60306ad1c5c78d53255ff15a3 (diff) |
[media] coda: allocate per-context buffers from REQBUFS
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>
-rw-r--r-- | drivers/media/platform/coda/coda-bit.c | 55 | ||||
-rw-r--r-- | drivers/media/platform/coda/coda-common.c | 22 | ||||
-rw-r--r-- | drivers/media/platform/coda/coda.h | 1 |
3 files changed, 66 insertions, 12 deletions
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 856b542b35b9..12b93867e665 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c | |||
@@ -709,6 +709,27 @@ err_clk_per: | |||
709 | * Encoder context operations | 709 | * Encoder context operations |
710 | */ | 710 | */ |
711 | 711 | ||
712 | static int coda_encoder_reqbufs(struct coda_ctx *ctx, | ||
713 | struct v4l2_requestbuffers *rb) | ||
714 | { | ||
715 | struct coda_q_data *q_data_src; | ||
716 | int ret; | ||
717 | |||
718 | if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
719 | return 0; | ||
720 | |||
721 | if (rb->count) { | ||
722 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
723 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
724 | if (ret < 0) | ||
725 | return ret; | ||
726 | } else { | ||
727 | coda_free_context_buffers(ctx); | ||
728 | } | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
712 | static int coda_start_encoding(struct coda_ctx *ctx) | 733 | static int coda_start_encoding(struct coda_ctx *ctx) |
713 | { | 734 | { |
714 | struct coda_dev *dev = ctx->dev; | 735 | struct coda_dev *dev = ctx->dev; |
@@ -725,11 +746,6 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
725 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | 746 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); |
726 | dst_fourcc = q_data_dst->fourcc; | 747 | dst_fourcc = q_data_dst->fourcc; |
727 | 748 | ||
728 | /* Allocate per-instance buffers */ | ||
729 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
730 | if (ret < 0) | ||
731 | return ret; | ||
732 | |||
733 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | 749 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
734 | bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); | 750 | bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); |
735 | bitstream_size = q_data_dst->sizeimage; | 751 | bitstream_size = q_data_dst->sizeimage; |
@@ -1311,7 +1327,6 @@ static void coda_seq_end_work(struct work_struct *work) | |||
1311 | ctx->bitstream.vaddr, ctx->bitstream.size); | 1327 | ctx->bitstream.vaddr, ctx->bitstream.size); |
1312 | 1328 | ||
1313 | coda_free_framebuffers(ctx); | 1329 | coda_free_framebuffers(ctx); |
1314 | coda_free_context_buffers(ctx); | ||
1315 | 1330 | ||
1316 | mutex_unlock(&dev->coda_mutex); | 1331 | mutex_unlock(&dev->coda_mutex); |
1317 | mutex_unlock(&ctx->buffer_mutex); | 1332 | mutex_unlock(&ctx->buffer_mutex); |
@@ -1327,6 +1342,7 @@ static void coda_bit_release(struct coda_ctx *ctx) | |||
1327 | 1342 | ||
1328 | const struct coda_context_ops coda_bit_encode_ops = { | 1343 | const struct coda_context_ops coda_bit_encode_ops = { |
1329 | .queue_init = coda_encoder_queue_init, | 1344 | .queue_init = coda_encoder_queue_init, |
1345 | .reqbufs = coda_encoder_reqbufs, | ||
1330 | .start_streaming = coda_start_encoding, | 1346 | .start_streaming = coda_start_encoding, |
1331 | .prepare_run = coda_prepare_encode, | 1347 | .prepare_run = coda_prepare_encode, |
1332 | .finish_run = coda_finish_encode, | 1348 | .finish_run = coda_finish_encode, |
@@ -1338,6 +1354,27 @@ const struct coda_context_ops coda_bit_encode_ops = { | |||
1338 | * Decoder context operations | 1354 | * Decoder context operations |
1339 | */ | 1355 | */ |
1340 | 1356 | ||
1357 | static int coda_decoder_reqbufs(struct coda_ctx *ctx, | ||
1358 | struct v4l2_requestbuffers *rb) | ||
1359 | { | ||
1360 | struct coda_q_data *q_data_src; | ||
1361 | int ret; | ||
1362 | |||
1363 | if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
1364 | return 0; | ||
1365 | |||
1366 | if (rb->count) { | ||
1367 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
1368 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
1369 | if (ret < 0) | ||
1370 | return ret; | ||
1371 | } else { | ||
1372 | coda_free_context_buffers(ctx); | ||
1373 | } | ||
1374 | |||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1341 | static int __coda_start_decoding(struct coda_ctx *ctx) | 1378 | static int __coda_start_decoding(struct coda_ctx *ctx) |
1342 | { | 1379 | { |
1343 | struct coda_q_data *q_data_src, *q_data_dst; | 1380 | struct coda_q_data *q_data_src, *q_data_dst; |
@@ -1356,11 +1393,6 @@ static int __coda_start_decoding(struct coda_ctx *ctx) | |||
1356 | src_fourcc = q_data_src->fourcc; | 1393 | src_fourcc = q_data_src->fourcc; |
1357 | dst_fourcc = q_data_dst->fourcc; | 1394 | dst_fourcc = q_data_dst->fourcc; |
1358 | 1395 | ||
1359 | /* Allocate per-instance buffers */ | ||
1360 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
1361 | if (ret < 0) | ||
1362 | return ret; | ||
1363 | |||
1364 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); | 1396 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); |
1365 | 1397 | ||
1366 | /* Update coda bitstream read and write pointers from kfifo */ | 1398 | /* Update coda bitstream read and write pointers from kfifo */ |
@@ -1906,6 +1938,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1906 | 1938 | ||
1907 | const struct coda_context_ops coda_bit_decode_ops = { | 1939 | const struct coda_context_ops coda_bit_decode_ops = { |
1908 | .queue_init = coda_decoder_queue_init, | 1940 | .queue_init = coda_decoder_queue_init, |
1941 | .reqbufs = coda_decoder_reqbufs, | ||
1909 | .start_streaming = coda_start_decoding, | 1942 | .start_streaming = coda_start_decoding, |
1910 | .prepare_run = coda_prepare_decode, | 1943 | .prepare_run = coda_prepare_decode, |
1911 | .finish_run = coda_finish_decode, | 1944 | .finish_run = coda_finish_decode, |
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 443886535230..a8a6c36a1f00 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
@@ -696,6 +696,26 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv, | |||
696 | return coda_s_fmt(ctx, &f_cap); | 696 | return coda_s_fmt(ctx, &f_cap); |
697 | } | 697 | } |
698 | 698 | ||
699 | static int coda_reqbufs(struct file *file, void *priv, | ||
700 | struct v4l2_requestbuffers *rb) | ||
701 | { | ||
702 | struct coda_ctx *ctx = fh_to_ctx(priv); | ||
703 | int ret; | ||
704 | |||
705 | ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb); | ||
706 | if (ret) | ||
707 | return ret; | ||
708 | |||
709 | /* | ||
710 | * Allow to allocate instance specific per-context buffers, such as | ||
711 | * bitstream ringbuffer, slice buffer, work buffer, etc. if needed. | ||
712 | */ | ||
713 | if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs) | ||
714 | return ctx->ops->reqbufs(ctx, rb); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
699 | static int coda_qbuf(struct file *file, void *priv, | 719 | static int coda_qbuf(struct file *file, void *priv, |
700 | struct v4l2_buffer *buf) | 720 | struct v4l2_buffer *buf) |
701 | { | 721 | { |
@@ -841,7 +861,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { | |||
841 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, | 861 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, |
842 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, | 862 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, |
843 | 863 | ||
844 | .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, | 864 | .vidioc_reqbufs = coda_reqbufs, |
845 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, | 865 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, |
846 | 866 | ||
847 | .vidioc_qbuf = coda_qbuf, | 867 | .vidioc_qbuf = coda_qbuf, |
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 499049f3896b..57d070ce6665 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h | |||
@@ -178,6 +178,7 @@ struct coda_ctx; | |||
178 | struct coda_context_ops { | 178 | struct coda_context_ops { |
179 | int (*queue_init)(void *priv, struct vb2_queue *src_vq, | 179 | int (*queue_init)(void *priv, struct vb2_queue *src_vq, |
180 | struct vb2_queue *dst_vq); | 180 | struct vb2_queue *dst_vq); |
181 | int (*reqbufs)(struct coda_ctx *ctx, struct v4l2_requestbuffers *rb); | ||
181 | int (*start_streaming)(struct coda_ctx *ctx); | 182 | int (*start_streaming)(struct coda_ctx *ctx); |
182 | int (*prepare_run)(struct coda_ctx *ctx); | 183 | int (*prepare_run)(struct coda_ctx *ctx); |
183 | void (*finish_run)(struct coda_ctx *ctx); | 184 | void (*finish_run)(struct coda_ctx *ctx); |