Commit 40fa8df6 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab

media: coda: use encoder crop rectangle to set visible width and height

Allow to set a crop rectangle on the encoder output queue to set the
visible resolution as required by the V4L2 codec API.
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 9e49ca53
...@@ -398,10 +398,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx, ...@@ -398,10 +398,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264 || ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264 ||
ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 || ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 ||
ctx->codec->dst_fourcc == V4L2_PIX_FMT_MPEG4) ctx->codec->dst_fourcc == V4L2_PIX_FMT_MPEG4)
ysize = round_up(q_data->width, 16) * ysize = round_up(q_data->rect.width, 16) *
round_up(q_data->height, 16); round_up(q_data->rect.height, 16);
else else
ysize = round_up(q_data->width, 8) * q_data->height; ysize = round_up(q_data->rect.width, 8) * q_data->rect.height;
if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP) if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
ycbcr_size = round_up(ysize, 4096) + ysize / 2; ycbcr_size = round_up(ysize, 4096) + ysize / 2;
...@@ -497,8 +497,8 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, ...@@ -497,8 +497,8 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) { if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) {
/* worst case slice size */ /* worst case slice size */
size = (DIV_ROUND_UP(q_data->width, 16) * size = (DIV_ROUND_UP(q_data->rect.width, 16) *
DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; DIV_ROUND_UP(q_data->rect.height, 16)) * 3200 / 8 + 512;
ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size,
"slicebuf"); "slicebuf");
if (ret < 0) if (ret < 0)
...@@ -630,7 +630,7 @@ static void coda_setup_iram(struct coda_ctx *ctx) ...@@ -630,7 +630,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
struct coda_q_data *q_data_src; struct coda_q_data *q_data_src;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
mb_width = DIV_ROUND_UP(q_data_src->width, 16); mb_width = DIV_ROUND_UP(q_data_src->rect.width, 16);
w128 = mb_width * 128; w128 = mb_width * 128;
w64 = mb_width * 64; w64 = mb_width * 64;
...@@ -927,25 +927,25 @@ static int coda_start_encoding(struct coda_ctx *ctx) ...@@ -927,25 +927,25 @@ static int coda_start_encoding(struct coda_ctx *ctx)
value = 0; value = 0;
switch (dev->devtype->product) { switch (dev->devtype->product) {
case CODA_DX6: case CODA_DX6:
value = (q_data_src->width & CODADX6_PICWIDTH_MASK) value = (q_data_src->rect.width & CODADX6_PICWIDTH_MASK)
<< CODADX6_PICWIDTH_OFFSET; << CODADX6_PICWIDTH_OFFSET;
value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) value |= (q_data_src->rect.height & CODADX6_PICHEIGHT_MASK)
<< CODA_PICHEIGHT_OFFSET; << CODA_PICHEIGHT_OFFSET;
break; break;
case CODA_HX4: case CODA_HX4:
case CODA_7541: case CODA_7541:
if (dst_fourcc == V4L2_PIX_FMT_H264) { if (dst_fourcc == V4L2_PIX_FMT_H264) {
value = (round_up(q_data_src->width, 16) & value = (round_up(q_data_src->rect.width, 16) &
CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET; CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
value |= (round_up(q_data_src->height, 16) & value |= (round_up(q_data_src->rect.height, 16) &
CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET; CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
break; break;
} }
/* fallthrough */ /* fallthrough */
case CODA_960: case CODA_960:
value = (q_data_src->width & CODA7_PICWIDTH_MASK) value = (q_data_src->rect.width & CODA7_PICWIDTH_MASK)
<< CODA7_PICWIDTH_OFFSET; << CODA7_PICWIDTH_OFFSET;
value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) value |= (q_data_src->rect.height & CODA7_PICHEIGHT_MASK)
<< CODA_PICHEIGHT_OFFSET; << CODA_PICHEIGHT_OFFSET;
} }
coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE); coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
......
...@@ -933,6 +933,40 @@ static int coda_g_selection(struct file *file, void *fh, ...@@ -933,6 +933,40 @@ static int coda_g_selection(struct file *file, void *fh,
return 0; return 0;
} }
static int coda_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct coda_ctx *ctx = fh_to_ctx(fh);
struct coda_q_data *q_data;
if (ctx->inst_type == CODA_INST_ENCODER &&
s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
s->target == V4L2_SEL_TGT_CROP) {
q_data = get_q_data(ctx, s->type);
if (!q_data)
return -EINVAL;
s->r.left = 0;
s->r.top = 0;
s->r.width = clamp(s->r.width, 2U, q_data->width);
s->r.height = clamp(s->r.height, 2U, q_data->height);
if (s->flags & V4L2_SEL_FLAG_LE) {
s->r.width = round_up(s->r.width, 2);
s->r.height = round_up(s->r.height, 2);
} else {
s->r.width = round_down(s->r.width, 2);
s->r.height = round_down(s->r.height, 2);
}
q_data->rect = s->r;
return 0;
}
return coda_g_selection(file, fh, s);
}
static int coda_try_encoder_cmd(struct file *file, void *fh, static int coda_try_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *ec) struct v4l2_encoder_cmd *ec)
{ {
...@@ -1146,6 +1180,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { ...@@ -1146,6 +1180,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
.vidioc_g_selection = coda_g_selection, .vidioc_g_selection = coda_g_selection,
.vidioc_s_selection = coda_s_selection,
.vidioc_try_encoder_cmd = coda_try_encoder_cmd, .vidioc_try_encoder_cmd = coda_try_encoder_cmd,
.vidioc_encoder_cmd = coda_encoder_cmd, .vidioc_encoder_cmd = coda_encoder_cmd,
...@@ -1587,12 +1622,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) ...@@ -1587,12 +1622,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
goto out; goto out;
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
if ((q_data_src->width != q_data_dst->width && if ((q_data_src->rect.width != q_data_dst->width &&
round_up(q_data_src->width, 16) != q_data_dst->width) || round_up(q_data_src->rect.width, 16) != q_data_dst->width) ||
(q_data_src->height != q_data_dst->height && (q_data_src->rect.height != q_data_dst->height &&
round_up(q_data_src->height, 16) != q_data_dst->height)) { round_up(q_data_src->rect.height, 16) != q_data_dst->height)) {
v4l2_err(v4l2_dev, "can't convert %dx%d to %dx%d\n", v4l2_err(v4l2_dev, "can't convert %dx%d to %dx%d\n",
q_data_src->width, q_data_src->height, q_data_src->rect.width, q_data_src->rect.height,
q_data_dst->width, q_data_dst->height); q_data_dst->width, q_data_dst->height);
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment