2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-24 13:13:57 +08:00
linux-next/drivers/media/platform/coda/coda-mpeg4.c
Philipp Zabel 2719ef7d1b 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 0eef89403e ("[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>
2019-06-24 14:30:59 -04:00

88 lines
2.0 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Coda multi-standard codec IP - MPEG-4 helper functions
*
* Copyright (C) 2019 Pengutronix, Philipp Zabel
*/
#include <linux/kernel.h>
#include <linux/videodev2.h>
#include "coda.h"
int coda_mpeg4_profile(int profile_idc)
{
switch (profile_idc) {
case 0:
return V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
case 15:
return V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
case 2:
return V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE;
case 1:
return V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE;
case 11:
return V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
default:
return -EINVAL;
}
}
int coda_mpeg4_level(int level_idc)
{
switch (level_idc) {
case 0:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
case 1:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
case 2:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
case 3:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
case 4:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
case 5:
return V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
default:
return -EINVAL;
}
}
/*
* Check if the buffer starts with the MPEG-4 visual object sequence and visual
* object headers, for example:
*
* 00 00 01 b0 f1
* 00 00 01 b5 a9 13 00 00 01 00 00 00 01 20 08
* d4 8d 88 00 f5 04 04 08 14 30 3f
*
* Returns the detected header size in bytes or 0.
*/
u32 coda_mpeg4_parse_headers(struct coda_ctx *ctx, u8 *buf, u32 size)
{
static const u8 vos_start[4] = { 0x00, 0x00, 0x01, 0xb0 };
static const union {
u8 vo_start[4];
u8 start_code_prefix[3];
} u = { { 0x00, 0x00, 0x01, 0xb5 } };
if (size < 30 ||
memcmp(buf, vos_start, 4) != 0 ||
memcmp(buf + 5, u.vo_start, 4) != 0)
return 0;
if (size == 30 ||
(size >= 33 && memcmp(buf + 30, u.start_code_prefix, 3) == 0))
return 30;
if (size == 31 ||
(size >= 34 && memcmp(buf + 31, u.start_code_prefix, 3) == 0))
return 31;
if (size == 32 ||
(size >= 35 && memcmp(buf + 32, u.start_code_prefix, 3) == 0))
return 32;
return 0;
}