From patchwork Fri Mar 3 12:12:49 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Philipp Zabel
X-Patchwork-Id: 9602671
Return-Path:
Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org
[172.30.200.125])
by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id
32511600CB for ;
Fri, 3 Mar 2017 12:32:19 +0000 (UTC)
Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1])
by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CFDB27F8F
for ;
Fri, 3 Mar 2017 12:32:19 +0000 (UTC)
Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486)
id 11D8128494; Fri, 3 Mar 2017 12:32:19 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
pdx-wl-mail.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI
autolearn=ham version=3.3.1
Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 036F727F8F
for ;
Fri, 3 Mar 2017 12:32:17 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1751872AbdCCMcP (ORCPT
);
Fri, 3 Mar 2017 07:32:15 -0500
Received: from metis.ext.4.pengutronix.de ([92.198.50.35]:60157 "EHLO
metis.ext.4.pengutronix.de" rhost-flags-OK-OK-OK-OK)
by vger.kernel.org with ESMTP id S1751611AbdCCMcO (ORCPT
);
Fri, 3 Mar 2017 07:32:14 -0500
Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]
helo=dude.pengutronix.de.)
by metis.ext.pengutronix.de with esmtp (Exim 4.84_2)
(envelope-from )
id 1cjm57-0002CY-4t; Fri, 03 Mar 2017 13:13:09 +0100
From: Philipp Zabel
To: linux-media@vger.kernel.org
Cc: kernel@pengutronix.de, Philipp Zabel
Subject: [PATCH 3/4] [media] coda: pad first h.264 buffer to 512 bytes
Date: Fri, 3 Mar 2017 13:12:49 +0100
Message-Id: <20170303121250.13693-3-p.zabel@pengutronix.de>
X-Mailer: git-send-email 2.11.0
In-Reply-To: <20170303121250.13693-1-p.zabel@pengutronix.de>
References: <20170303121250.13693-1-p.zabel@pengutronix.de>
X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7
X-SA-Exim-Mail-From: p.zabel@pengutronix.de
X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de);
SAEximRunCond expanded to false
X-PTX-Original-Recipient: linux-media@vger.kernel.org
Sender: linux-media-owner@vger.kernel.org
Precedence: bulk
List-ID:
X-Mailing-List: linux-media@vger.kernel.org
X-Virus-Scanned: ClamAV using ClamSMTP
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
---
drivers/media/platform/coda/coda-bit.c | 28 ++++++++++++++++++++++++++--
drivers/media/platform/coda/coda-h264.c | 24 ++++++++++++++++++------
drivers/media/platform/coda/coda.h | 1 +
3 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index e3e3225607836..89965ca5bd250 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -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");
diff --git a/drivers/media/platform/coda/coda-h264.c b/drivers/media/platform/coda/coda-h264.c
index 09dfcca7cc500..dc137c3fd510b 100644
--- a/drivers/media/platform/coda/coda-h264.c
+++ b/drivers/media/platform/coda/coda-h264.c
@@ -15,10 +15,25 @@
#include
#include
-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;
}
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 6aa9c19c4a896..a730bc2a2ff99 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -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);