Skip to content

Commit 7136f2b

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 This includes the fixups that were present as separate patches in earlier versions. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
1 parent 068edd3 commit 7136f2b

2 files changed

Lines changed: 137 additions & 28 deletions

File tree

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

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,8 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
15561556
unsigned int ctb_size_y;
15571557
bool sps_changed = false;
15581558
unsigned int lkg_slot;
1559+
/* Old (downstream only) bit size meanings */
1560+
bool old_bits = false;
15591561

15601562
de = dec_env_new(ctx);
15611563
if (!de) {
@@ -1606,25 +1608,43 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
16061608
de->cmd_len = 0;
16071609
de->dpbno_col = ~0U;
16081610

1609-
de->luma_stride = ctx->dst_fmt.height * 128;
1610-
de->frame_luma_addr =
1611-
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1612-
de->chroma_stride = de->luma_stride / 2;
1613-
de->frame_chroma_addr =
1614-
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 1);
1615-
de->mvbase = 0;
1616-
de->frame_slot = run->dst->vb2_buf.index;
1611+
switch (ctx->dst_fmt.pixelformat) {
1612+
case V4L2_PIX_FMT_NV12MT_COL128:
1613+
case V4L2_PIX_FMT_NV12MT_10_COL128:
1614+
de->luma_stride = ctx->dst_fmt.height * 128;
1615+
de->frame_luma_addr =
1616+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1617+
de->chroma_stride = de->luma_stride / 2;
1618+
de->frame_chroma_addr =
1619+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 1);
1620+
de->mvbase = 0;
1621+
de->frame_slot = run->dst->vb2_buf.index;
1622+
break;
1623+
case V4L2_PIX_FMT_NV12_COL128:
1624+
case V4L2_PIX_FMT_NV12_10_COL128:
1625+
de->luma_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128;
1626+
de->frame_luma_addr =
1627+
vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
1628+
de->chroma_stride = de->luma_stride;
1629+
de->frame_chroma_addr = de->frame_luma_addr +
1630+
(ctx->dst_fmt.height * 128);
1631+
de->mvbase = 0;
1632+
de->frame_slot = run->dst->vb2_buf.index;
1633+
old_bits = true;
1634+
break;
1635+
}
16171636

16181637
if (s->sps.bit_depth_luma_minus8 == 0) {
1619-
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_COL128) {
1638+
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_COL128 &&
1639+
ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_COL128) {
16201640
v4l2_err(&dev->v4l2_dev,
16211641
"Pixel format %#x != NV12MT_COL128 for 8-bit output",
16221642
ctx->dst_fmt.pixelformat);
16231643
goto fail;
16241644
}
16251645
} else {
1626-
if (ctx->dst_fmt.pixelformat !=
1627-
V4L2_PIX_FMT_NV12MT_10_COL128) {
1646+
if (ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12MT_10_COL128 &&
1647+
ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_10_COL128) {
16281648
v4l2_err(&dev->v4l2_dev,
16291649
"Pixel format %#x != NV12MT_10_COL128 for 10-bit output",
16301650
ctx->dst_fmt.pixelformat);
@@ -1643,6 +1663,42 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
16431663
goto fail;
16441664
}
16451665

1666+
switch (ctx->dst_fmt.pixelformat) {
1667+
case V4L2_PIX_FMT_NV12MT_COL128:
1668+
case V4L2_PIX_FMT_NV12MT_10_COL128:
1669+
if (run->dst->vb2_buf.num_planes != 2) {
1670+
v4l2_warn(&dev->v4l2_dev, "Capture planes (%d) != 2\n",
1671+
run->dst->vb2_buf.num_planes);
1672+
goto fail;
1673+
}
1674+
if (run->dst->planes[0].length < ctx->dst_fmt.plane_fmt[0].sizeimage ||
1675+
run->dst->planes[1].length < ctx->dst_fmt.plane_fmt[1].sizeimage) {
1676+
v4l2_warn(&dev->v4l2_dev,
1677+
"Capture planes length (%d/%d) < sizeimage (%d/%d)\n",
1678+
run->dst->planes[0].length,
1679+
run->dst->planes[1].length,
1680+
ctx->dst_fmt.plane_fmt[0].sizeimage,
1681+
ctx->dst_fmt.plane_fmt[1].sizeimage);
1682+
goto fail;
1683+
}
1684+
break;
1685+
case V4L2_PIX_FMT_NV12_COL128:
1686+
case V4L2_PIX_FMT_NV12_10_COL128:
1687+
if (run->dst->vb2_buf.num_planes != 1) {
1688+
v4l2_warn(&dev->v4l2_dev, "Capture planes (%d) != 1\n",
1689+
run->dst->vb2_buf.num_planes);
1690+
goto fail;
1691+
}
1692+
if (run->dst->planes[0].length < ctx->dst_fmt.plane_fmt[0].sizeimage) {
1693+
v4l2_warn(&dev->v4l2_dev,
1694+
"Capture planes length (%d) < sizeimage (%d)\n",
1695+
run->dst->planes[0].length,
1696+
ctx->dst_fmt.plane_fmt[0].sizeimage);
1697+
goto fail;
1698+
}
1699+
break;
1700+
}
1701+
16461702
/*
16471703
* Need Aux ents for all (ref) DPB ents if temporal MV could
16481704
* be enabled for any pic
@@ -1688,15 +1744,24 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
16881744
for (i = 0; i != run->h265.slice_ents; ++i) {
16891745
const struct v4l2_ctrl_hevc_slice_params *const sh = sh0 + i;
16901746
const bool last_slice = i + 1 == run->h265.slice_ents;
1691-
const u32 byte_size = DIV_ROUND_UP(sh->bit_size, 8);
1747+
unsigned int bit_size = old_bits ? sh->bit_size - 8 * sh->data_byte_offset :
1748+
sh->bit_size;
1749+
const u32 byte_size = DIV_ROUND_UP(bit_size, 8);
16921750
unsigned int j;
16931751

16941752
s->sh = sh;
16951753

1754+
if (old_bits && sh->bit_size <= 8 * sh->data_byte_offset) {
1755+
v4l2_warn(&dev->v4l2_dev,
1756+
"data_byte_offset %d * 8 >= bits %d\n",
1757+
sh->data_byte_offset, sh->bit_size);
1758+
goto fail;
1759+
}
1760+
16961761
if (sh->data_byte_offset + byte_size > run->src->planes[0].bytesused) {
16971762
v4l2_warn(&dev->v4l2_dev,
16981763
"data_byte_offset %d + bits %d (= %d bytes) > bytesused %d\n",
1699-
sh->data_byte_offset, sh->bit_size, byte_size,
1764+
sh->data_byte_offset, bit_size, byte_size,
17001765
run->src->planes[0].bytesused);
17011766
goto fail;
17021767
}
@@ -1706,7 +1771,7 @@ static int hevc_d_h265_setup(struct hevc_d_ctx *ctx, struct hevc_d_run *run)
17061771
* actual size of the buffer (which may well be what is used to set
17071772
* bit_size if the caller isn't being very pedantic).
17081773
*/
1709-
s->data_len = min(sh->bit_size / 8 + 1,
1774+
s->data_len = min(bit_size / 8 + 1,
17101775
run->src->planes[0].bytesused - sh->data_byte_offset);
17111776

17121777
s->slice_qp = 26 + s->pps.init_qp_minus26 + sh->slice_qp_delta;

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

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,49 @@ static void hevc_d_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
128128
bytesperline = width * 4 / 3;
129129
sizeimage = bytesperline * height;
130130
break;
131+
132+
case V4L2_PIX_FMT_NV12_COL128:
133+
/* Width rounds up to columns */
134+
width = ALIGN(width, 128);
135+
height = ALIGN(height, 16);
136+
137+
bytesperline = height * 3 / 2;
138+
sizeimage = bytesperline * width;
139+
break;
140+
141+
case V4L2_PIX_FMT_NV12_10_COL128:
142+
/* width in pixels (3 pels = 4 bytes) rounded to 128 byte
143+
* columns
144+
*/
145+
width = ALIGN(((width + 2) / 3), 32) * 3;
146+
height = ALIGN(height, 16);
147+
148+
bytesperline = height * 3 / 2;
149+
sizeimage = bytesperline * width * 4 / 3;
150+
break;
131151
}
132152

133153
pix_fmt->width = width;
134154
pix_fmt->height = height;
135155

136156
pix_fmt->field = V4L2_FIELD_NONE;
137-
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
138-
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
139-
pix_fmt->plane_fmt[1].bytesperline = bytesperline;
140-
pix_fmt->plane_fmt[1].sizeimage = sizeimage / 2;
141-
pix_fmt->num_planes = 2;
157+
switch (pix_fmt->pixelformat) {
158+
default:
159+
case V4L2_PIX_FMT_NV12MT_COL128:
160+
case V4L2_PIX_FMT_NV12MT_10_COL128:
161+
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
162+
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
163+
pix_fmt->plane_fmt[1].bytesperline = bytesperline;
164+
pix_fmt->plane_fmt[1].sizeimage = sizeimage / 2;
165+
pix_fmt->num_planes = 2;
166+
break;
167+
case V4L2_PIX_FMT_NV12_COL128:
168+
case V4L2_PIX_FMT_NV12_10_COL128:
169+
pix_fmt->plane_fmt[0].bytesperline = bytesperline;
170+
pix_fmt->plane_fmt[0].sizeimage = sizeimage;
171+
pix_fmt->num_planes = 1;
172+
break;
173+
}
142174
}
143175

144176
static int hevc_d_querycap(struct file *file, void *priv,
@@ -223,19 +255,31 @@ static int hevc_d_hevc_validate_sps(const struct v4l2_ctrl_hevc_sps * const sps)
223255
static u32 pixelformat_from_sps(const struct v4l2_ctrl_hevc_sps * const sps,
224256
const int index)
225257
{
258+
static const u32 all_formats[] = {
259+
V4L2_PIX_FMT_NV12MT_COL128,
260+
V4L2_PIX_FMT_NV12MT_10_COL128,
261+
V4L2_PIX_FMT_NV12_COL128,
262+
V4L2_PIX_FMT_NV12_10_COL128,
263+
};
226264
u32 pf = 0;
227265

228266
if (!is_sps_set(sps) || !hevc_d_hevc_validate_sps(sps)) {
229267
/* Treat this as an error? For now return both */
230-
if (index == 0)
231-
pf = V4L2_PIX_FMT_NV12MT_COL128;
232-
else if (index == 1)
233-
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
234-
} else if (index == 0) {
235-
if (sps->bit_depth_luma_minus8 == 0)
236-
pf = V4L2_PIX_FMT_NV12MT_COL128;
237-
else if (sps->bit_depth_luma_minus8 == 2)
238-
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
268+
269+
if (index < ARRAY_SIZE(all_formats))
270+
pf = all_formats[index];
271+
} else {
272+
if (index == 0) {
273+
if (sps->bit_depth_luma_minus8 == 0)
274+
pf = V4L2_PIX_FMT_NV12MT_COL128;
275+
else if (sps->bit_depth_luma_minus8 == 2)
276+
pf = V4L2_PIX_FMT_NV12MT_10_COL128;
277+
} else if (index == 1) {
278+
if (sps->bit_depth_luma_minus8 == 0)
279+
pf = V4L2_PIX_FMT_NV12_COL128;
280+
else if (sps->bit_depth_luma_minus8 == 2)
281+
pf = V4L2_PIX_FMT_NV12_10_COL128;
282+
}
239283
}
240284

241285
return pf;

0 commit comments

Comments
 (0)