summaryrefslogtreecommitdiff
path: root/drivers/media/platform/coda/coda-mpeg2.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2019-06-18 12:45:19 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-06-24 14:30:59 -0400
commit2719ef7d1b1107892923a1f5b7cbc28cccbdea3d (patch)
tree766f9f8eebeca0d55a33973ae74893d1feaa189f /drivers/media/platform/coda/coda-mpeg2.c
parentccb901196ec5298458f2cd2c4c43652c3c0d5032 (diff)
downloadlinux-2719ef7d1b1107892923a1f5b7cbc28cccbdea3d.tar.gz
linux-2719ef7d1b1107892923a1f5b7cbc28cccbdea3d.tar.bz2
linux-2719ef7d1b1107892923a1f5b7cbc28cccbdea3d.zip
media: coda: pad first buffer with repeated MPEG headers to fix sequence init
If the first buffer contains only headers, the sequence initialization command fails. On CodaHx4 the buffer must be padded to at least 512 bytes, on CODA960 it seems to be enough to just repeat the sequence and extension headers (MPEG-2) or the VOS and VO headers (MPEG-4) once for for sequence initialization to succeed without further bitstream data. On CodaHx4 the headers can be repeated multiple times until the 512 byte mark is reached. A similar issue was solved for h.264 by padding with a filler NAL in commit 0eef89403ece ("[media] coda: pad first h.264 buffer to 512 bytes"). Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/coda/coda-mpeg2.c')
-rw-r--r--drivers/media/platform/coda/coda-mpeg2.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/media/platform/coda/coda-mpeg2.c b/drivers/media/platform/coda/coda-mpeg2.c
index 73e50dabce19..6f3f6721d286 100644
--- a/drivers/media/platform/coda/coda-mpeg2.c
+++ b/drivers/media/platform/coda/coda-mpeg2.c
@@ -42,3 +42,46 @@ int coda_mpeg2_level(int level_idc)
return -EINVAL;
}
}
+
+/*
+ * Check if the buffer starts with the MPEG-2 sequence header (with or without
+ * quantization matrix) and extension header, for example:
+ *
+ * 00 00 01 b3 2d 01 e0 34 08 8b a3 81
+ * 10 11 11 12 12 12 13 13 13 13 14 14 14 14 14 15
+ * 15 15 15 15 15 16 16 16 16 16 16 16 17 17 17 17
+ * 17 17 17 17 18 18 18 19 18 18 18 19 1a 1a 1a 1a
+ * 19 1b 1b 1b 1b 1b 1c 1c 1c 1c 1e 1e 1e 1f 1f 21
+ * 00 00 01 b5 14 8a 00 01 00 00
+ *
+ * or:
+ *
+ * 00 00 01 b3 08 00 40 15 ff ff e0 28
+ * 00 00 01 b5 14 8a 00 01 00 00
+ *
+ * Returns the detected header size in bytes or 0.
+ */
+u32 coda_mpeg2_parse_headers(struct coda_ctx *ctx, u8 *buf, u32 size)
+{
+ static const u8 sequence_header_start[4] = { 0x00, 0x00, 0x01, 0xb3 };
+ static const union {
+ u8 extension_start[4];
+ u8 start_code_prefix[3];
+ } u = { { 0x00, 0x00, 0x01, 0xb5 } };
+
+ if (size < 22 ||
+ memcmp(buf, sequence_header_start, 4) != 0)
+ return 0;
+
+ if ((size == 22 ||
+ (size >= 25 && memcmp(buf + 22, u.start_code_prefix, 3) == 0)) &&
+ memcmp(buf + 12, u.extension_start, 4) == 0)
+ return 22;
+
+ if ((size == 86 ||
+ (size > 89 && memcmp(buf + 86, u.start_code_prefix, 3) == 0)) &&
+ memcmp(buf + 76, u.extension_start, 4) == 0)
+ return 86;
+
+ return 0;
+}