From: hverkuil-cisco@xs4all.nl
To: linux-media@vger.kernel.org
Cc: Tomasz Figa <tfiga@chromium.org>,
Ezequiel Garcia <ezequiel@collabora.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Hans Verkuil <hverkuil-cisco@xs4all.nl>
Subject: [PATCH 2/2] vicodec: add encoder support to write to multiple buffers
Date: Fri, 14 Dec 2018 16:43:16 +0100 [thread overview]
Message-ID: <20181214154316.62011-3-hverkuil-cisco@xs4all.nl> (raw)
In-Reply-To: <20181214154316.62011-1-hverkuil-cisco@xs4all.nl>
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
With the new mem2mem functionality it is now easy to write the
result of the encoder to multiple buffers.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
drivers/media/platform/vicodec/vicodec-core.c | 91 +++++++++++++++----
1 file changed, 75 insertions(+), 16 deletions(-)
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 2b7daff63425..f422804ab40e 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -115,6 +115,11 @@ struct vicodec_ctx {
struct vb2_v4l2_buffer *last_src_buf;
struct vb2_v4l2_buffer *last_dst_buf;
+ u64 dst_timestamp;
+ u32 dst_field;
+ u32 dst_flags;
+ struct v4l2_timecode dst_timecode;
+
/* Source and destination queue data */
struct vicodec_q_data q_data[2];
struct v4l2_fwht_state state;
@@ -161,11 +166,13 @@ static int device_process(struct vicodec_ctx *ctx,
int ret;
q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (ctx->is_enc)
+ if (ctx->is_enc) {
p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0);
- else
+ p_dst = state->compressed_frame;
+ } else {
p_src = state->compressed_frame;
- p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
+ p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
+ }
if (!p_src || !p_dst) {
v4l2_err(&dev->v4l2_dev,
"Acquiring kernel pointers to buffers failed\n");
@@ -180,7 +187,11 @@ static int device_process(struct vicodec_ctx *ctx,
ret = v4l2_fwht_encode(state, p_src, p_dst);
if (ret < 0)
return ret;
+ ctx->comp_size = ret;
+ ret = min_t(u32, ret, vb2_plane_size(&dst_vb->vb2_buf, 0));
+ ctx->cur_buf_offset = ret;
vb2_set_plane_payload(&dst_vb->vb2_buf, 0, ret);
+ memcpy(vb2_plane_vaddr(&dst_vb->vb2_buf, 0), p_dst, ret);
} else {
state->info = q_dst->info;
ret = v4l2_fwht_decode(state, p_src, p_dst);
@@ -240,6 +251,14 @@ static void device_run(void *priv)
src_buf->sequence = q_src->sequence++;
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_buf_done(src_buf, state);
+ if (ctx->cur_buf_offset < ctx->comp_size) {
+ ctx->dst_timestamp = dst_buf->vb2_buf.timestamp;
+ ctx->dst_field = dst_buf->field;
+ ctx->dst_flags = dst_buf->flags;
+ dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
+ if (dst_buf->flags & V4L2_BUF_FLAG_TIMECODE)
+ ctx->dst_timecode = dst_buf->timecode;
+ }
} else if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == ctx->cur_buf_offset) {
src_buf->sequence = q_src->sequence++;
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
@@ -247,16 +266,22 @@ static void device_run(void *priv)
ctx->cur_buf_offset = 0;
ctx->comp_has_next_frame = false;
}
- v4l2_m2m_buf_done(dst_buf, state);
- ctx->comp_size = 0;
- ctx->comp_magic_cnt = 0;
- ctx->comp_has_frame = false;
+ if (!ctx->is_enc) {
+ ctx->comp_size = 0;
+ ctx->comp_magic_cnt = 0;
+ ctx->comp_has_frame = false;
+ }
spin_unlock(ctx->lock);
- if (ctx->is_enc)
- v4l2_m2m_job_finish(dev->enc_dev, ctx->fh.m2m_ctx);
- else
+ if (ctx->is_enc) {
+ if (ctx->cur_buf_offset < ctx->comp_size)
+ v4l2_m2m_job_writing(dev->enc_dev, ctx->fh.m2m_ctx);
+ else
+ v4l2_m2m_job_finish(dev->enc_dev, ctx->fh.m2m_ctx);
+ } else {
v4l2_m2m_job_finish(dev->dec_dev, ctx->fh.m2m_ctx);
+ }
+ v4l2_m2m_buf_done(dst_buf, state);
}
static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
@@ -273,6 +298,41 @@ static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
spin_unlock(ctx->lock);
}
+static void job_write(void *priv)
+{
+ struct vicodec_ctx *ctx = priv;
+ struct v4l2_fwht_state *state = &ctx->state;
+ struct vb2_v4l2_buffer *dst_buf;
+ struct vicodec_q_data *q_cap;
+ u32 size;
+
+ q_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ while (v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) &&
+ ctx->cur_buf_offset < ctx->comp_size) {
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ size = min_t(u32, ctx->comp_size - ctx->cur_buf_offset,
+ vb2_plane_size(&dst_buf->vb2_buf, 0));
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, size);
+ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0),
+ state->compressed_frame + ctx->cur_buf_offset, size);
+ ctx->cur_buf_offset += size;
+
+ dst_buf->sequence = q_cap->sequence++;
+ dst_buf->vb2_buf.timestamp = ctx->dst_timestamp;
+ if (ctx->dst_flags & V4L2_BUF_FLAG_TIMECODE)
+ dst_buf->timecode = ctx->dst_timecode;
+ dst_buf->field = ctx->dst_field;
+ dst_buf->flags = ctx->dst_flags;
+
+ if (ctx->cur_buf_offset < ctx->comp_size)
+ dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
+
+ if (ctx->cur_buf_offset == ctx->comp_size)
+ v4l2_m2m_job_finish(ctx->dev->enc_dev, ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+ }
+}
+
static int job_ready(void *priv)
{
static const u8 magic[] = {
@@ -536,7 +596,7 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
pix->sizeimage = pix->width * pix->height *
info->sizeimage_mult / info->sizeimage_div;
if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
- pix->sizeimage += sizeof(struct fwht_cframe_hdr);
+ pix->sizeimage /= 16;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
@@ -554,7 +614,7 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
plane->sizeimage = pix_mp->width * pix_mp->height *
info->sizeimage_mult / info->sizeimage_div;
if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
- plane->sizeimage += sizeof(struct fwht_cframe_hdr);
+ plane->sizeimage /= 16;
memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
memset(plane->reserved, 0, sizeof(plane->reserved));
break;
@@ -1204,16 +1264,14 @@ static int vicodec_open(struct file *file)
if (ctx->is_enc)
ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
else
- ctx->q_data[V4L2_M2M_SRC].sizeimage =
- size + sizeof(struct fwht_cframe_hdr);
+ ctx->q_data[V4L2_M2M_SRC].sizeimage = size / 16;
ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
ctx->q_data[V4L2_M2M_DST].info =
ctx->is_enc ? &pixfmt_fwht : v4l2_fwht_get_pixfmt(0);
size = 1280 * 720 * ctx->q_data[V4L2_M2M_DST].info->sizeimage_mult /
ctx->q_data[V4L2_M2M_DST].info->sizeimage_div;
if (ctx->is_enc)
- ctx->q_data[V4L2_M2M_DST].sizeimage =
- size + sizeof(struct fwht_cframe_hdr);
+ ctx->q_data[V4L2_M2M_DST].sizeimage = size / 16;
else
ctx->q_data[V4L2_M2M_DST].sizeimage = size;
ctx->state.colorspace = V4L2_COLORSPACE_REC709;
@@ -1281,6 +1339,7 @@ static const struct video_device vicodec_videodev = {
static const struct v4l2_m2m_ops m2m_ops = {
.device_run = device_run,
.job_ready = job_ready,
+ .job_write = job_write,
};
static int vicodec_probe(struct platform_device *pdev)
--
2.19.2
prev parent reply other threads:[~2018-12-14 15:43 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-14 15:43 [PATCH 0/2] v4l2-mem2mem: add job_write() to support encoders hverkuil-cisco
2018-12-14 15:43 ` [PATCH 1/2] v4l2-mem2mem: add job_write callback hverkuil-cisco
2019-01-07 14:42 ` Hans Verkuil
2019-01-08 5:49 ` Tomasz Figa
2019-01-08 10:26 ` Philipp Zabel
2018-12-14 15:43 ` hverkuil-cisco [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181214154316.62011-3-hverkuil-cisco@xs4all.nl \
--to=hverkuil-cisco@xs4all.nl \
--cc=ezequiel@collabora.com \
--cc=linux-media@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=tfiga@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).