From patchwork Wed Sep 6 04:48:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 5002 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp163984jao; Tue, 5 Sep 2017 21:48:39 -0700 (PDT) X-Received: by 10.223.161.23 with SMTP id o23mr668262wro.103.1504673319484; Tue, 05 Sep 2017 21:48:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504673319; cv=none; d=google.com; s=arc-20160816; b=WRC5D2AJkbsaDt/zi0TY00huHU6hbc2Z0CvRci9IVXO+vU1C2NFtOxAPLKtBntInjF x02nGHG+wKcYpfE65oBq4+Wlpdk2SYznlIwaNe686tQdt+17UY92vK3/efbEQ4F7ZkTc +YBEPMFvaH1/mkPdeOT7HPQelcdzD2anZAdbrrSvDbqfmtxDD6jhBkvgOmcnH/A26Q6E q/riJFrJ+eTBAjKvCLCxTabi2rEu/u6iVArMDpvaiMkocPQw+h7f67JOMl/4CWULrpmQ eAarWvB9Msc78jmsgfz/FzSmGTWZcysNBs0C18mZhPGJC8aHQFPQmbl4Q/1SFhT/7ySi SNjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=4UOgo0662NzenpLK+8BSPAVgUa0y2OZZoDP/5NF+sLg=; b=0nI1C0TnEcLzj/v1skoVckBOyILC0b+6OHkpas2ifOWGT2yPmEJC7utZKn4XIKfH3L EkUs7dHiZbblBbhkwFB3EK57GjNdKu3yz57MlLZE0qF+WeAV1E9Y/274d6HIFGR4cCwm Cm86AAWiF24fEue2zHUynW59Wt5d8Snes2PcsNWRup8H78hIsrK1i+El3qsxN2q8j/DA JCvJ62JgUSb2FEFGPZhvivLr+XoM1U1ksRQ+LHmKPQZVDnrOH8oPt68Qz3dBPK4omxGH qLuaqKwaygzbHVQO6aygGQvCsffLduWn54+uMgwtvAvI00Lp3LqR5z3Hc4fANGDcuGi5 u4Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=KzIikrE3; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id x1si1599496wrc.99.2017.09.05.21.48.38; Tue, 05 Sep 2017 21:48:39 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=KzIikrE3; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6FEC8689AF0; Wed, 6 Sep 2017 07:48:34 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C6F69689A32 for ; Wed, 6 Sep 2017 07:48:27 +0300 (EEST) Received: by mail-qk0-f195.google.com with SMTP id p12so3269238qkl.0 for ; Tue, 05 Sep 2017 21:48:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=l4mP+HLlinWHykfcH+Dewyi7l1SHGSH35X+DwypBX3Y=; b=KzIikrE38METzhvdhVgRYHrZ7NvqAqeSw1DYCqn1658iblRXkoFwNGJocYD5CaOdJ4 tDSoSrQ6b18VcHaOxBOH89F4TK1+fA39uFb3SHI2s4RGwRjaZyfoLEyBbjoQlOPxII5F ksNycFCGa627XMuneGffkGRM6uq24hytKdq1IfjDE4JWbNRbmhieYloGZedIV7kE1kzS +/AuDdL8oo3dF7IcqYWkp4G8ZIZXs0geKRzzTqOSbOPBiLoUNugfiWpoLlOgs4RDvoTp Bs8Tphn+42hqbMeWJX/55VZQhRtLPTfYJpj68QQKebrEH3ao3gGDv5zpfTYkjTGzLDPP RsWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=l4mP+HLlinWHykfcH+Dewyi7l1SHGSH35X+DwypBX3Y=; b=Cwg0BsMlDLe3fZQFGnJqFUnoudGS89LL50bzeaViO15a5QrEa4rBIvowtvWDK7McsF 4XVxgRtOO/HOG4UoxIwGjhfg53f4A2bdoBeRe2MD0KEkzr5sWa8GhEHr+ggNT/YNSNUx j1/zRQC/AabqnhwNsYmGONMWZv+xbcZ1K/owiOLrrbNCTX6AZOvnulNSoW103+eNo/jx 6FIb7IjzUioK6C/388oc3IxVVulOEq5muWdVIRpeoKhYlrX0TMnk3rAmnbDNcdkEuBR9 +edLhm4eMxJSUAjAJm8W5OjXITd8jj0ElN+WVDStUmis2N2SStlIyQep8tfELU90jvbc KHEA== X-Gm-Message-State: AHPjjUixW8MFH7LXIqLJDagsahvogl7vGutOUqEDP2UNj1PSTd6a2a/A MIBddJMYfn49CgEN X-Google-Smtp-Source: ADKCNb66SAiafVvWasoXr8sV7KayCK5fHz6NZwxAt3GR3xiIeFSKkedRF4CU5C/GNvDxB7KJSaBK1A== X-Received: by 10.55.59.136 with SMTP id i130mr1657809qka.99.1504673309455; Tue, 05 Sep 2017 21:48:29 -0700 (PDT) Received: from localhost.localdomain ([181.231.60.193]) by smtp.gmail.com with ESMTPSA id 25sm1628892qtv.14.2017.09.05.21.48.27 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Sep 2017 21:48:28 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Wed, 6 Sep 2017 01:48:05 -0300 Message-Id: <20170906044805.8284-1-jamrial@gmail.com> X-Mailer: git-send-email 2.13.3 Subject: [FFmpeg-devel] [PATCH v2] avformat/aacdec: don't immediately abort if an ADTS frame is not found X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Instead, skip the invalid data in an attempt to find an ADTS frame, and continue decoding from there. Fixes ticket #6634 Signed-off-by: James Almer --- New in v2: - avpriv_aac_parse_header() used to validate ADTS headers more thoroughly. - Removed the usage of avio_tell(s->pb) in resync() and replaced it with a local counter. libavformat/aacdec.c | 77 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c index 364b33404f..e744a9f40d 100644 --- a/libavformat/aacdec.c +++ b/libavformat/aacdec.c @@ -21,6 +21,7 @@ */ #include "libavutil/intreadwrite.h" +#include "libavcodec/aacadtsdec.h" #include "avformat.h" #include "internal.h" #include "id3v1.h" @@ -77,10 +78,52 @@ static int adts_aac_probe(AVProbeData *p) return 0; } +static int resync(AVFormatContext *s) +{ + AACADTSHeaderInfo hdr; + GetBitContext gbc; + uint8_t buf[AAC_ADTS_HEADER_SIZE]; + uint16_t state; + int64_t cnt = 1; + + state = avio_r8(s->pb); + while (!avio_feof(s->pb) && cnt++ < s->probesize) { + int fsize, ret; + + state = ((state << 8) | avio_r8(s->pb)); + if ((state >> 4) != 0xFFF) + continue; + + avio_seek(s->pb, -2, SEEK_CUR); + ret = avio_read(s->pb, buf, sizeof(buf)); + if (ret < 0) + return ret; + if (ret < AAC_ADTS_HEADER_SIZE) + return AVERROR(EIO); + + init_get_bits8(&gbc, buf, sizeof(buf)); + fsize = avpriv_aac_parse_header(&gbc, &hdr); + if (fsize < 0) { + // not a valid frame. Seek back to the "state" offset and continue. + avio_seek(s->pb, -5, SEEK_CUR); + continue; + } + + // likely to be a valid frame. Seek back to the start and return. + avio_seek(s->pb, -ret, SEEK_CUR); + break; + } + + if ((state >> 4) != 0xFFF) + return avio_feof(s->pb) ? AVERROR_EOF : AVERROR_INVALIDDATA; + + return 0; +} + static int adts_aac_read_header(AVFormatContext *s) { AVStream *st; - uint16_t state; + int ret; st = avformat_new_stream(s, NULL); if (!st) @@ -99,16 +142,9 @@ static int adts_aac_read_header(AVFormatContext *s) } // skip data until the first ADTS frame is found - state = avio_r8(s->pb); - while (!avio_feof(s->pb) && avio_tell(s->pb) < s->probesize) { - state = (state << 8) | avio_r8(s->pb); - if ((state >> 4) != 0xFFF) - continue; - avio_seek(s->pb, -2, SEEK_CUR); - break; - } - if ((state >> 4) != 0xFFF) - return AVERROR_INVALIDDATA; + ret = resync(s); + if (ret < 0) + return ret; // LCM of all possible ADTS sample rates avpriv_set_pts_info(st, 64, 1, 28224000); @@ -118,6 +154,8 @@ static int adts_aac_read_header(AVFormatContext *s) static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) { + AACADTSHeaderInfo hdr; + GetBitContext gbc; int ret, fsize; ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE); @@ -128,15 +166,16 @@ static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); } - if ((AV_RB16(pkt->data) >> 4) != 0xfff) { - av_packet_unref(pkt); - return AVERROR_INVALIDDATA; - } - - fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF; - if (fsize < ADTS_HEADER_SIZE) { + init_get_bits8(&gbc, pkt->data, AAC_ADTS_HEADER_SIZE); + fsize = avpriv_aac_parse_header(&gbc, &hdr); + if (fsize < 0) { + // skip data in an attempt to find an ADTS frame. av_packet_unref(pkt); - return AVERROR_INVALIDDATA; + avio_seek(s->pb, -ret, SEEK_CUR); + ret = resync(s); + if (ret < 0) + return ret; + return adts_aac_read_packet(s, pkt); } return av_append_packet(s->pb, pkt, fsize - ADTS_HEADER_SIZE);