mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-15 23:36:40 +07:00
[media] coda: pad first h.264 buffer to 512 bytes
The bitstream reader needs 512 bytes ready to read to examine the headers in the first frame. If that frame is too small, prepend it with a filler NAL. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
331e7860f3
commit
0eef89403e
@ -179,6 +179,25 @@ static void coda_kfifo_sync_to_device_write(struct coda_ctx *ctx)
|
|||||||
coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
|
coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int coda_bitstream_pad(struct coda_ctx *ctx, u32 size)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
u32 n;
|
||||||
|
|
||||||
|
if (size < 6)
|
||||||
|
size = 6;
|
||||||
|
|
||||||
|
buf = kmalloc(size, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
coda_h264_filler_nal(size, buf);
|
||||||
|
n = kfifo_in(&ctx->bitstream_fifo, buf, size);
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
return (n < size) ? -ENOSPC : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int coda_bitstream_queue(struct coda_ctx *ctx,
|
static int coda_bitstream_queue(struct coda_ctx *ctx,
|
||||||
struct vb2_v4l2_buffer *src_buf)
|
struct vb2_v4l2_buffer *src_buf)
|
||||||
{
|
{
|
||||||
@ -198,10 +217,10 @@ static int coda_bitstream_queue(struct coda_ctx *ctx,
|
|||||||
static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
|
static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
|
||||||
struct vb2_v4l2_buffer *src_buf)
|
struct vb2_v4l2_buffer *src_buf)
|
||||||
{
|
{
|
||||||
|
unsigned long payload = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (coda_get_bitstream_payload(ctx) +
|
if (coda_get_bitstream_payload(ctx) + payload + 512 >=
|
||||||
vb2_get_plane_payload(&src_buf->vb2_buf, 0) + 512 >=
|
|
||||||
ctx->bitstream.size)
|
ctx->bitstream.size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -210,6 +229,11 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add zero padding before the first H.264 buffer, if it is too small */
|
||||||
|
if (ctx->qsequence == 0 && payload < 512 &&
|
||||||
|
ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
|
||||||
|
coda_bitstream_pad(ctx, 512 - payload);
|
||||||
|
|
||||||
ret = coda_bitstream_queue(ctx, src_buf);
|
ret = coda_bitstream_queue(ctx, src_buf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n");
|
v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n");
|
||||||
|
@ -15,10 +15,25 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <coda.h>
|
#include <coda.h>
|
||||||
|
|
||||||
static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 };
|
|
||||||
static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
|
static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
|
||||||
|
|
||||||
|
int coda_h264_filler_nal(int size, char *p)
|
||||||
|
{
|
||||||
|
if (size < 6)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
p[0] = 0x00;
|
||||||
|
p[1] = 0x00;
|
||||||
|
p[2] = 0x00;
|
||||||
|
p[3] = 0x01;
|
||||||
|
p[4] = 0x0c;
|
||||||
|
memset(p + 5, 0xff, size - 6);
|
||||||
|
/* Add rbsp stop bit and trailing at the end */
|
||||||
|
p[size - 1] = 0x80;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int coda_h264_padding(int size, char *p)
|
int coda_h264_padding(int size, char *p)
|
||||||
{
|
{
|
||||||
int nal_size;
|
int nal_size;
|
||||||
@ -29,10 +44,7 @@ int coda_h264_padding(int size, char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nal_size = coda_filler_size[diff];
|
nal_size = coda_filler_size[diff];
|
||||||
memcpy(p, coda_filler_nal, nal_size);
|
coda_h264_filler_nal(nal_size, p);
|
||||||
|
|
||||||
/* Add rbsp stop bit and trailing at the end */
|
|
||||||
*(p + nal_size - 1) = 0x80;
|
|
||||||
|
|
||||||
return nal_size;
|
return nal_size;
|
||||||
}
|
}
|
||||||
|
@ -290,6 +290,7 @@ void coda_bit_stream_end_flag(struct coda_ctx *ctx);
|
|||||||
void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
|
void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
|
||||||
enum vb2_buffer_state state);
|
enum vb2_buffer_state state);
|
||||||
|
|
||||||
|
int coda_h264_filler_nal(int size, char *p);
|
||||||
int coda_h264_padding(int size, char *p);
|
int coda_h264_padding(int size, char *p);
|
||||||
|
|
||||||
bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
|
bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
|
||||||
|
Loading…
Reference in New Issue
Block a user