[media] coda: pad first h.264 buffer to 512 bytes
authorPhilipp Zabel <p.zabel@pengutronix.de>
Fri, 3 Mar 2017 12:12:49 +0000 (09:12 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 22 Mar 2017 13:06:26 +0000 (10:06 -0300)
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>
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-h264.c
drivers/media/platform/coda/coda.h

index e3e32256078367e72b6e467f83e0dcbb65ca8c09..89965ca5bd250c444b0844e2f734dec741b25b3d 100644 (file)
@@ -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));
 }
 
+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,
                                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,
                                     struct vb2_v4l2_buffer *src_buf)
 {
+       unsigned long payload = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
        int ret;
 
-       if (coda_get_bitstream_payload(ctx) +
-           vb2_get_plane_payload(&src_buf->vb2_buf, 0) + 512 >=
+       if (coda_get_bitstream_payload(ctx) + payload + 512 >=
            ctx->bitstream.size)
                return false;
 
@@ -210,6 +229,11 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
                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);
        if (ret < 0) {
                v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n");
index 09dfcca7cc500f5f4784409cdd1b1b0c962efb82..dc137c3fd510bbaa5ae789568e155e988373c4e2 100644 (file)
 #include <linux/string.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 };
 
+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 nal_size;
@@ -29,10 +44,7 @@ int coda_h264_padding(int size, char *p)
                return 0;
 
        nal_size = coda_filler_size[diff];
-       memcpy(p, coda_filler_nal, nal_size);
-
-       /* Add rbsp stop bit and trailing at the end */
-       *(p + nal_size - 1) = 0x80;
+       coda_h264_filler_nal(nal_size, p);
 
        return nal_size;
 }
index 6aa9c19c4a896fa973cad4c3dc33c7878582d176..a730bc2a2ff99538d4e46fc407b4519f9c41835a 100644 (file)
@@ -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,
                       enum vb2_buffer_state state);
 
+int coda_h264_filler_nal(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);