Skip to content

Commit c6faf08

Browse files
6by9pelwell
authored andcommitted
media: hevc_dec: Add in downstream single planar SAND variant
Upstream will take the multi-planar SAND format, but add back in the downstream single planar variant for backwards compatibility Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
1 parent 93572f2 commit c6faf08

2 files changed

Lines changed: 149 additions & 31 deletions

File tree

drivers/media/platform/raspberrypi/hevc_dec/hevc_d_h265.c

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,24 +1628,40 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
16281628
de->cmd_len = 0;
16291629
de->dpbno_col = ~0U;
16301630

1631-
de->luma_stride = ctx->dst_fmt.height * 128;
1632-
de->frame_luma_addr =
1633-
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1634-
de->chroma_stride = de->luma_stride / 2;
1635-
de->frame_chroma_addr =
1636-
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 1);
1631+
switch (ctx->dst_fmt.pixelformat) {
1632+
case V4L2_PIX_FMT_NV12MT_COL128:
1633+
case V4L2_PIX_FMT_NV12MT_10_COL128:
1634+
de->luma_stride = ctx->dst_fmt.height * 128;
1635+
de->frame_luma_addr =
1636+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1637+
de->chroma_stride = de->luma_stride / 2;
1638+
de->frame_chroma_addr =
1639+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 1);
1640+
break;
1641+
case V4L2_PIX_FMT_NV12_COL128:
1642+
case V4L2_PIX_FMT_NV12_10_COL128:
1643+
de->luma_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128;
1644+
de->frame_luma_addr =
1645+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1646+
de->chroma_stride = de->luma_stride;
1647+
de->frame_chroma_addr = de->frame_luma_addr +
1648+
(ctx->dst_fmt.height * 128);
1649+
break;
1650+
}
1651+
16371652
de->frame_aux = NULL;
16381653

16391654
if (s->sps.bit_depth_luma_minus8 == 0) {
1640-
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_COL128) {
1655+
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_COL128 &&
1656+
ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_COL128) {
16411657
v4l2_err(&dev->v4l2_dev,
16421658
"Pixel format %#x != NV12MT_COL128 for 8-bit output",
16431659
ctx->dst_fmt.pixelformat);
16441660
goto fail;
16451661
}
16461662
} else {
1647-
if (ctx->dst_fmt.pixelformat !=
1648-
V4L2_PIX_FMT_NV12MT_10_COL128) {
1663+
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_10_COL128 &&
1664+
ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_10_COL128) {
16491665
v4l2_err(&dev->v4l2_dev,
16501666
"Pixel format %#x != NV12MT_10_COL128 for 10-bit output",
16511667
ctx->dst_fmt.pixelformat);
@@ -1664,6 +1680,42 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
16641680
goto fail;
16651681
}
16661682

1683+
switch (ctx->dst_fmt.pixelformat) {
1684+
case V4L2_PIX_FMT_NV12MT_COL128:
1685+
case V4L2_PIX_FMT_NV12MT_10_COL128:
1686+
if (run->dst->vb2_buf.num_planes != 2) {
1687+
v4l2_warn(&dev->v4l2_dev, "Capture planes (%d) != 2\n",
1688+
run->dst->vb2_buf.num_planes);
1689+
goto fail;
1690+
}
1691+
if (run->dst->planes[0].length < ctx->dst_fmt.plane_fmt[0].sizeimage ||
1692+
run->dst->planes[1].length < ctx->dst_fmt.plane_fmt[1].sizeimage) {
1693+
v4l2_warn(&dev->v4l2_dev,
1694+
"Capture planes length (%d/%d) < sizeimage (%d/%d)\n",
1695+
run->dst->planes[0].length,
1696+
run->dst->planes[1].length,
1697+
ctx->dst_fmt.plane_fmt[0].sizeimage,
1698+
ctx->dst_fmt.plane_fmt[1].sizeimage);
1699+
goto fail;
1700+
}
1701+
break;
1702+
case V4L2_PIX_FMT_NV12_COL128:
1703+
case V4L2_PIX_FMT_NV12_10_COL128:
1704+
if (run->dst->vb2_buf.num_planes != 1) {
1705+
v4l2_warn(&dev->v4l2_dev, "Capture planes (%d) != 1\n",
1706+
run->dst->vb2_buf.num_planes);
1707+
goto fail;
1708+
}
1709+
if (run->dst->planes[0].length < ctx->dst_fmt.plane_fmt[0].sizeimage) {
1710+
v4l2_warn(&dev->v4l2_dev,
1711+
"Capture planes length (%d) < sizeimage (%d)\n",
1712+
run->dst->planes[0].length,
1713+
ctx->dst_fmt.plane_fmt[0].sizeimage);
1714+
goto fail;
1715+
}
1716+
break;
1717+
}
1718+
16671719
/*
16681720
* Fill in ref planes with our address s.t. if we mess up refs
16691721
* somehow then we still have a valid address entry
@@ -1833,8 +1885,13 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
18331885

18341886
de->ref_addrs[i][0] =
18351887
vb2_dma_contig_plane_dma_addr(buf, 0);
1836-
de->ref_addrs[i][1] =
1837-
vb2_dma_contig_plane_dma_addr(buf, 1);
1888+
if (ctx->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12MT_COL128 ||
1889+
ctx->dst_fmt.pixelformat == V4L2_PIX_FMT_NV12MT_10_COL128)
1890+
de->ref_addrs[i][1] =
1891+
vb2_dma_contig_plane_dma_addr(buf, 1);
1892+
else
1893+
de->ref_addrs[i][1] = de->ref_addrs[i][0] +
1894+
(ctx->dst_fmt.height * 128);
18381895
}
18391896

18401897
/* Move DPB from temp */

drivers/media/platform/raspberrypi/hevc_dec/hevc_d_video.c

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,55 @@ static void hevc_d_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
140140
bytesperline = width * 4 / 3;
141141
sizeimage = bytesperline * height;
142142
break;
143+
144+
case V4L2_PIX_FMT_NV12_COL128:
145+
/* Width rounds up to columns */
146+
width = ALIGN(width, 128);
147+
height = ALIGN(height, 8);
148+
149+
/* column height
150+
* Accept suggested shape if at least min & < 2 * min
151+
*/
152+
bytesperline = constrain2x(bytesperline, height * 3 / 2);
153+
sizeimage = bytesperline * width;
154+
break;
155+
156+
case V4L2_PIX_FMT_NV12_10_COL128:
157+
/* width in pixels (3 pels = 4 bytes) rounded to 128 byte
158+
* columns
159+
*/
160+
width = ALIGN(((width + 2) / 3), 32) * 3;
161+
height = ALIGN(height, 8);
162+
163+
/* column height
164+
* Accept suggested shape if at least min & < 2 * min
165+
*/
166+
bytesperline = constrain2x(bytesperline, height * 3 / 2);
167+
sizeimage = bytesperline * width * 4 / 3;
168+
break;
143169
}
144170

145171
pix_fmt->width = width;
146172
pix_fmt->height = height;
147173

148174
pix_fmt->field = V4L2_FIELD_NONE;
149-
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
150-
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
151-
pix_fmt->plane_fmt[1].bytesperline = bytesperline;
152-
pix_fmt->plane_fmt[1].sizeimage = sizeimage / 2;
153-
pix_fmt->num_planes = 2;
175+
switch (pix_fmt->pixelformat) {
176+
default:
177+
case V4L2_PIX_FMT_NV12MT_COL128:
178+
case V4L2_PIX_FMT_NV12MT_10_COL128:
179+
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
180+
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
181+
pix_fmt->plane_fmt[1].bytesperline = bytesperline;
182+
pix_fmt->plane_fmt[1].sizeimage = sizeimage / 2;
183+
pix_fmt->num_planes = 2;
184+
break;
185+
case V4L2_PIX_FMT_NV12_COL128:
186+
case V4L2_PIX_FMT_NV12_10_COL128:
187+
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
188+
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
189+
pix_fmt->num_planes = 1;
190+
break;
191+
}
154192
}
155193

156194
static int hevc_d_querycap(struct file *file, void *priv,
@@ -235,19 +273,31 @@ static int hevc_d_hevc_validate_sps(const struct v4l2_ctrl_hevc_sps * const sps)
235273
static u32 pixelformat_from_sps(const struct v4l2_ctrl_hevc_sps * const sps,
236274
const int index)
237275
{
276+
static const u32 all_formats[] = {
277+
V4L2_PIX_FMT_NV12MT_COL128,
278+
V4L2_PIX_FMT_NV12MT_10_COL128,
279+
V4L2_PIX_FMT_NV12_COL128,
280+
V4L2_PIX_FMT_NV12_10_COL128,
281+
};
238282
u32 pf = 0;
239283

240284
if (!is_sps_set(sps) || !hevc_d_hevc_validate_sps(sps)) {
241285
/* Treat this as an error? For now return both */
242-
if (index == 0)
243-
pf = V4L2_PIX_FMT_NV12MT_COL128;
244-
else if (index == 1)
245-
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
246-
} else if (index == 0) {
247-
if (sps->bit_depth_luma_minus8 == 0)
248-
pf = V4L2_PIX_FMT_NV12MT_COL128;
249-
else if (sps->bit_depth_luma_minus8 == 2)
250-
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
286+
287+
if (index < ARRAY_SIZE(all_formats))
288+
pf = all_formats[index];
289+
} else {
290+
if (index == 0) {
291+
if (sps->bit_depth_luma_minus8 == 0)
292+
pf = V4L2_PIX_FMT_NV12MT_COL128;
293+
else if (sps->bit_depth_luma_minus8 == 2)
294+
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
295+
} else if (index == 1) {
296+
if (sps->bit_depth_luma_minus8 == 0)
297+
pf = V4L2_PIX_FMT_NV12_COL128;
298+
else if (sps->bit_depth_luma_minus8 == 2)
299+
pf = V4L2_PIX_FMT_NV12_10_COL128;
300+
}
251301
}
252302

253303
return pf;
@@ -459,17 +509,28 @@ static int hevc_d_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
459509
}
460510

461511
if (*nplanes) {
462-
if (*nplanes != expected_nplanes ||
463-
sizes[0] < pix_fmt->plane_fmt[0].sizeimage ||
464-
sizes[1] < pix_fmt->plane_fmt[1].sizeimage)
465-
return -EINVAL;
512+
if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12MT_COL128 ||
513+
pix_fmt->pixelformat == V4L2_PIX_FMT_NV12MT_10_COL128) {
514+
if (*nplanes != expected_nplanes ||
515+
sizes[0] < pix_fmt->plane_fmt[0].sizeimage ||
516+
sizes[1] < pix_fmt->plane_fmt[1].sizeimage)
517+
return -EINVAL;
518+
} else {
519+
if (sizes[0] < pix_fmt->plane_fmt[0].sizeimage)
520+
return -EINVAL;
521+
}
466522
} else {
467523
sizes[0] = pix_fmt->plane_fmt[0].sizeimage;
468524
if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
469525
*nplanes = 1;
470526
} else {
471-
sizes[1] = pix_fmt->plane_fmt[1].sizeimage;
472-
*nplanes = 2;
527+
if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12MT_COL128 ||
528+
pix_fmt->pixelformat == V4L2_PIX_FMT_NV12MT_10_COL128) {
529+
sizes[1] = pix_fmt->plane_fmt[1].sizeimage;
530+
*nplanes = 2;
531+
} else {
532+
*nplanes = 1;
533+
}
473534
}
474535
}
475536

0 commit comments

Comments
 (0)