From patchwork Mon Oct 29 09:20:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martin X-Patchwork-Id: 15281 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1TSlWW-00045w-Qg for patchwork@linuxtv.org; Mon, 29 Oct 2012 10:20:44 +0100 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-4) with esmtp for id 1TSlWV-0001f3-B8; Mon, 29 Oct 2012 10:20:44 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752651Ab2J2JUl (ORCPT ); Mon, 29 Oct 2012 05:20:41 -0400 Received: from mail-wi0-f172.google.com ([209.85.212.172]:41716 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752008Ab2J2JUk (ORCPT ); Mon, 29 Oct 2012 05:20:40 -0400 Received: by mail-wi0-f172.google.com with SMTP id hq12so2019802wib.1 for ; Mon, 29 Oct 2012 02:20:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=pJZMqiaCcz5NQsUZXYEYN0e6PV4JGCCD5Taren88iPg=; b=JwXvjqa7rRQ8UPcDlu5K/TF/JVGFYpJXIHyLTz2hISanIHPv7lnkWJg24OC3UXqaut uI2ioknO5bo08okDzdHNFQdpDmLgl1h5HJHvHTdYW2xkOLPVnhS5L4/dTi/0Wo2JxlQk LPJ6ezfCEZmZsc/dy0qEoUmi5KVQ5VgkYFJxNMS1RYZnq/KkusBmRe8T7THB20XmXU3C cXNXFQf8MAa57tas+7k/YTwElglEaKmEw1GDgPSJjLCUWntM8sxJTFESeEYv8JBBMr7T F6JRcYtiim72Fu+tUfdQ1CvT7wURDTl02OKeJFM612A7TJ9kJD5nr58+NsWjVsHceQmg pjBg== Received: by 10.180.7.194 with SMTP id l2mr14105627wia.0.1351502439137; Mon, 29 Oct 2012 02:20:39 -0700 (PDT) Received: from piscis.vsilicon.net (149.93.18.95.dynamic.jazztel.es. [95.18.93.149]) by mx.google.com with ESMTPS id dm2sm9018332wib.4.2012.10.29.02.20.37 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 29 Oct 2012 02:20:38 -0700 (PDT) From: javier.martin@vista-silicon.com To: linux-media@vger.kernel.org Cc: p.zabel@pengutronix.de, mchehab@infradead.org, Javier Martin Subject: [PATCH] media: coda: Fix H.264 header alignment. Date: Mon, 29 Oct 2012 10:20:29 +0100 Message-Id: <508e4a66.c25fb40a.02b1.ffffbb4e@mx.google.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: X-Gm-Message-State: ALoCoQmMQSVm1MNQ55zyFdYkHCPEPsHMXXqsqwkOfunkAZQX6651voJD9gO+802z2F6HrXGZ7svt Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.10.29.91233 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_2000_2999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, NO_REAL_NAME 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' From: Javier Martin Length of H.264 headers is variable and thus it might not be aligned for the coda to append the encoded frame. This causes the first frame to overwrite part of the H.264 PPS. In order to solve that, a filler NAL must be added between the headers and the first frame to preserve alignment. Signed-off-by: Javier Martin --- drivers/media/platform/coda.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index a8c7a94..4cdb4f4 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -177,6 +177,8 @@ struct coda_ctx { int idx; }; +static u8 coda_filler_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff}; + static inline void coda_write(struct coda_dev *dev, u32 data, u32 reg) { v4l2_dbg(1, coda_debug, &dev->v4l2_dev, @@ -938,6 +940,29 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_d return 0; } +static int coda_h264_padding(int size, char *p) +{ + int size_align = size & ~0x3; + int filler_size = ARRAY_SIZE(coda_filler_nal); + int nal_size; + int diff; + + diff = size - size_align; + if (diff == 0) + return 0; + + nal_size = filler_size + 2 - diff; + if (nal_size > filler_size) + nal_size -= 4; + + memcpy(p, coda_filler_nal, nal_size); + + /* Add rbsp stop bit and trailing at the end */ + *(p + nal_size - 1) = 0x80; + + return nal_size; +} + static int coda_start_streaming(struct vb2_queue *q, unsigned int count) { struct coda_ctx *ctx = vb2_get_drv_priv(q); @@ -1165,7 +1190,13 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) coda_read(dev, CODA_CMD_ENC_HEADER_BB_START); memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0), ctx->vpu_header_size[1]); - ctx->vpu_header_size[2] = 0; + /* + * Length of H.264 headers is variable and thus it might not be + * aligned for the coda to append the encoded frame. In that is + * the case a filler NAL must be added to header 2. + */ + ctx->vpu_header_size[2] = coda_h264_padding((ctx->vpu_header_size[0] + + ctx->vpu_header_size[1]), ctx->vpu_header[2]); break; case V4L2_PIX_FMT_MPEG4: /*