mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-14 05:56:56 +07:00
media: ti-vpe: Add support for SEQ_BT
SEQ_BT indicates the buffer for bottom field needs to be processed before the top field. Simplify the field selection logic to support SEQ_BT as well. Modify the interlace flags to include any of alternate, SEQ_TB, SEQ_BT. Update other format error checking to consider SEQ_BT. Replace SEQ_TB with SEQ_XX wherever applicable. Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com> Signed-off-by: Benoit Parrot <bparrot@ti.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
55c686ff93
commit
95959793d2
@ -328,9 +328,14 @@ struct vpe_q_data {
|
||||
#define Q_DATA_MODE_TILED BIT(1)
|
||||
#define Q_DATA_INTERLACED_ALTERNATE BIT(2)
|
||||
#define Q_DATA_INTERLACED_SEQ_TB BIT(3)
|
||||
#define Q_DATA_INTERLACED_SEQ_BT BIT(4)
|
||||
|
||||
#define Q_IS_SEQ_XX (Q_DATA_INTERLACED_SEQ_TB | \
|
||||
Q_DATA_INTERLACED_SEQ_BT)
|
||||
|
||||
#define Q_IS_INTERLACED (Q_DATA_INTERLACED_ALTERNATE | \
|
||||
Q_DATA_INTERLACED_SEQ_TB)
|
||||
Q_DATA_INTERLACED_SEQ_TB | \
|
||||
Q_DATA_INTERLACED_SEQ_BT)
|
||||
|
||||
enum {
|
||||
Q_DATA_SRC = 0,
|
||||
@ -1105,24 +1110,31 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
|
||||
dma_addr += offset;
|
||||
stride = q_data->bytesperline[VPE_LUMA];
|
||||
|
||||
if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) {
|
||||
/*
|
||||
* Use top or bottom field from same vb alternately
|
||||
* f,f-1,f-2 = TBT when seq is even
|
||||
* f,f-1,f-2 = BTB when seq is odd
|
||||
*/
|
||||
field = (p_data->vb_index + (ctx->sequence % 2)) % 2;
|
||||
/*
|
||||
* field used in VPDMA desc = 0 (top) / 1 (bottom)
|
||||
* Use top or bottom field from same vb alternately
|
||||
* For each de-interlacing operation, f,f-1,f-2 should be one
|
||||
* of TBT or BTB
|
||||
*/
|
||||
if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB ||
|
||||
q_data->flags & Q_DATA_INTERLACED_SEQ_BT) {
|
||||
/* Select initial value based on format */
|
||||
if (q_data->flags & Q_DATA_INTERLACED_SEQ_BT)
|
||||
field = 1;
|
||||
else
|
||||
field = 0;
|
||||
|
||||
/* Toggle for each vb_index and each operation */
|
||||
field = (field + p_data->vb_index + ctx->sequence) % 2;
|
||||
|
||||
if (field) {
|
||||
/*
|
||||
* bottom field of a SEQ_TB buffer
|
||||
* Skip the top field data by
|
||||
*/
|
||||
int height = q_data->height / 2;
|
||||
int bpp = fmt->fourcc == V4L2_PIX_FMT_NV12 ?
|
||||
1 : (vpdma_fmt->depth >> 3);
|
||||
|
||||
if (plane)
|
||||
height /= 2;
|
||||
|
||||
dma_addr += q_data->width * height * bpp;
|
||||
}
|
||||
}
|
||||
@ -1177,12 +1189,14 @@ static void device_run(void *priv)
|
||||
struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
|
||||
struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
|
||||
|
||||
if (ctx->deinterlacing && s_q_data->flags & Q_DATA_INTERLACED_SEQ_TB &&
|
||||
ctx->sequence % 2 == 0) {
|
||||
/* When using SEQ_TB buffers, When using it first time,
|
||||
* No need to remove the buffer as the next field is present
|
||||
* in the same buffer. (so that job_ready won't fail)
|
||||
* It will be removed when using bottom field
|
||||
if (ctx->deinterlacing && s_q_data->flags & Q_IS_SEQ_XX &&
|
||||
ctx->sequence % 2 == 0) {
|
||||
/* When using SEQ_XX type buffers, each buffer has two fields
|
||||
* each buffer has two fields (top & bottom)
|
||||
* Removing one buffer is actually getting two fields
|
||||
* Alternate between two operations:-
|
||||
* Even : consume one field but DO NOT REMOVE from queue
|
||||
* Odd : consume other field and REMOVE from queue
|
||||
*/
|
||||
ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
|
||||
WARN_ON(ctx->src_vbs[0] == NULL);
|
||||
@ -1573,8 +1587,10 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE
|
||||
&& pix->field != V4L2_FIELD_SEQ_TB)
|
||||
if (pix->field != V4L2_FIELD_NONE &&
|
||||
pix->field != V4L2_FIELD_ALTERNATE &&
|
||||
pix->field != V4L2_FIELD_SEQ_TB &&
|
||||
pix->field != V4L2_FIELD_SEQ_BT)
|
||||
pix->field = V4L2_FIELD_NONE;
|
||||
|
||||
depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
|
||||
@ -1626,9 +1642,9 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
|
||||
|
||||
/*
|
||||
* For the actual image parameters, we need to consider the field
|
||||
* height of the image for SEQ_TB buffers.
|
||||
* height of the image for SEQ_XX buffers.
|
||||
*/
|
||||
if (pix->field == V4L2_FIELD_SEQ_TB)
|
||||
if (pix->field == V4L2_FIELD_SEQ_TB || pix->field == V4L2_FIELD_SEQ_BT)
|
||||
height = pix->height / 2;
|
||||
else
|
||||
height = pix->height;
|
||||
@ -1734,11 +1750,13 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
|
||||
q_data->flags |= Q_DATA_INTERLACED_ALTERNATE;
|
||||
else if (q_data->field == V4L2_FIELD_SEQ_TB)
|
||||
q_data->flags |= Q_DATA_INTERLACED_SEQ_TB;
|
||||
else if (q_data->field == V4L2_FIELD_SEQ_BT)
|
||||
q_data->flags |= Q_DATA_INTERLACED_SEQ_BT;
|
||||
else
|
||||
q_data->flags &= ~Q_IS_INTERLACED;
|
||||
|
||||
/* the crop height is halved for the case of SEQ_TB buffers */
|
||||
if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB)
|
||||
/* the crop height is halved for the case of SEQ_XX buffers */
|
||||
if (q_data->flags & Q_IS_SEQ_XX)
|
||||
q_data->c_rect.height /= 2;
|
||||
|
||||
vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d",
|
||||
@ -1811,10 +1829,10 @@ static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
|
||||
}
|
||||
|
||||
/*
|
||||
* For SEQ_TB buffers, crop height should be less than the height of
|
||||
* For SEQ_XX buffers, crop height should be less than the height of
|
||||
* the field height, not the buffer height
|
||||
*/
|
||||
if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB)
|
||||
if (q_data->flags & Q_IS_SEQ_XX)
|
||||
height = q_data->height / 2;
|
||||
else
|
||||
height = q_data->height;
|
||||
@ -2031,7 +2049,8 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
|
||||
} else {
|
||||
if (vbuf->field != V4L2_FIELD_TOP &&
|
||||
vbuf->field != V4L2_FIELD_BOTTOM &&
|
||||
vbuf->field != V4L2_FIELD_SEQ_TB)
|
||||
vbuf->field != V4L2_FIELD_SEQ_TB &&
|
||||
vbuf->field != V4L2_FIELD_SEQ_BT)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user