From patchwork Tue Oct 6 00:17:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 22732 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 4C86F44AE80 for ; Tue, 6 Oct 2020 03:25:17 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 321BF68B57F; Tue, 6 Oct 2020 03:25:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f65.google.com (mail-ed1-f65.google.com [209.85.208.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 78B9A68B4FA for ; Tue, 6 Oct 2020 03:25:10 +0300 (EEST) Received: by mail-ed1-f65.google.com with SMTP id t21so8750139eds.6 for ; Mon, 05 Oct 2020 17:25:10 -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=n6EyzLpD4o//VKmVgSELGGcnfQBjwH1a9Sv4BJDxL3E=; b=CyE0iaZrFHCWMcOW9+U3ZRpsiyj3kNl2e1bi9dBmqPrm0L8SsU5snL9tVxYoY7ujHx 43SyRov7ciHJLzp0SS2iBr9z5FRawtW8uJ4bcSSU4+otMdk0PQOGOO/DoVH6SBC6PRKt sHXDX9kGBEIUzHexAaEMnRmRsDy0R3fQxF0/eld/ybr+vAFBSPbxC4b9i++N7At7y4HX inFzvqEbJPtJT+zRNlUvUDP7MEKGHcGBvneC4JzDg/emnqLw9vuQK/EXY6rJdLfjliep Z2r8brQ9z6H8S/Kzs4awxzBqtEJRC7l1uYv81wBJL7PtBRGWtkcfiwY6I61BS1bnA4m1 3fiA== 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=n6EyzLpD4o//VKmVgSELGGcnfQBjwH1a9Sv4BJDxL3E=; b=KxzrD+b/qaK+TdAQh57d9iH8LWhhCxVZqjPUF37mLMZBmg+5is/KnGfF4vfwuE80w5 r5Xr0Ai+2vFzh5oCSjKRkAUCAmJVT2y9Ip41kcclHTa3OUDpWgTVLAxD758AFF7DcVrl fq9DPe4gwORDzSmtpPi8TVrc8sfNF+UHzqRyHtvB7pkniWDh835oiftobrXIkr6DgQw6 bCIg+ECoNPO8ntTVXVakYN9UrknitrXIqGeT/A3xe5/UrcB/n6MjOldC5OATXuGrER+G Q5VDGE88h3WRGpkOh/TssvTWXkcDJ/tDG/rFV34wyEx73QjdczWL3c3XXEr5bTs9L3R7 P+tA== X-Gm-Message-State: AOAM531H92Betm83lct+zleRe/VLdqp0NsFSb11HgcElCKqQowDw7eHU HKzZqLibxbajPdIbJBc3BfL4d5ctwvVWFQ== X-Google-Smtp-Source: ABdhPJzBymDJAoD/xGnDXczWGJJIRLEXE63oUENE+ah5v2AmXUaYNQ2j97/gMvk8j2SOIA2HlOkfCg== X-Received: by 2002:a05:6402:2055:: with SMTP id bc21mr2392413edb.67.1601943445242; Mon, 05 Oct 2020 17:17:25 -0700 (PDT) Received: from localhost.localdomain ([109.227.55.37]) by smtp.gmail.com with ESMTPSA id q12sm1017137edj.19.2020.10.05.17.17.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Oct 2020 17:17:23 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Tue, 6 Oct 2020 02:17:11 +0200 Message-Id: <20201006001714.19577-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH 1/4] avcodec/apedec: fix decoding insane files with recent versions 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" Signed-off-by: Paul B Mahol --- libavcodec/apedec.c | 59 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index c76c0509df..273abe2490 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -133,6 +133,21 @@ typedef struct APEPredictor { unsigned int sample_pos; } APEPredictor; +typedef struct APEPredictor64 { + int64_t *buf; + + int64_t lastA[2]; + + int64_t filterA[2]; + int64_t filterB[2]; + + uint64_t coeffsA[2][4]; ///< adaption coefficients + uint64_t coeffsB[2][5]; ///< adaption coefficients + int64_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE]; + + unsigned int sample_pos; +} APEPredictor64; + /** Decoder context */ typedef struct APEContext { AVClass *class; ///< class for AVOptions @@ -152,6 +167,7 @@ typedef struct APEContext { uint32_t CRC_state; ///< accumulated CRC int frameflags; ///< frame flags APEPredictor predictor; ///< predictor used for final reconstruction + APEPredictor64 predictor64; ///< 64bit predictor used for final reconstruction int32_t *decoded_buffer; int decoded_size; @@ -789,13 +805,20 @@ static const int32_t initial_coeffs_3930[4] = { 360, 317, -109, 98 }; +static const int64_t initial_coeffs_3930_64bit[4] = { + 360, 317, -109, 98 +}; + static void init_predictor_decoder(APEContext *ctx) { APEPredictor *p = &ctx->predictor; + APEPredictor64 *p64 = &ctx->predictor64; /* Zero the history buffers */ memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p->historybuffer)); + memset(p64->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p64->historybuffer)); p->buf = p->historybuffer; + p64->buf = p64->historybuffer; /* Initialize and zero the coefficients */ if (ctx->fileversion < 3930) { @@ -813,8 +836,11 @@ static void init_predictor_decoder(APEContext *ctx) } else { memcpy(p->coeffsA[0], initial_coeffs_3930, sizeof(initial_coeffs_3930)); memcpy(p->coeffsA[1], initial_coeffs_3930, sizeof(initial_coeffs_3930)); + memcpy(p64->coeffsA[0], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit)); + memcpy(p64->coeffsA[1], initial_coeffs_3930_64bit, sizeof(initial_coeffs_3930_64bit)); } memset(p->coeffsB, 0, sizeof(p->coeffsB)); + memset(p64->coeffsB, 0, sizeof(p64->coeffsB)); if (ctx->fileversion < 3930) { memcpy(p->coeffsB[0], initial_coeffs_b_3800, sizeof(initial_coeffs_b_3800)); @@ -826,7 +852,13 @@ static void init_predictor_decoder(APEContext *ctx) p->filterB[0] = p->filterB[1] = 0; p->lastA[0] = p->lastA[1] = 0; + p64->filterA[0] = p64->filterA[1] = 0; + p64->filterB[0] = p64->filterB[1] = 0; + p64->lastA[0] = p64->lastA[1] = 0; + p->sample_pos = 0; + + p64->sample_pos = 0; } /** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */ @@ -1132,16 +1164,17 @@ static void predictor_decode_mono_3930(APEContext *ctx, int count) } } -static av_always_inline int predictor_update_filter(APEPredictor *p, +static av_always_inline int predictor_update_filter(APEPredictor64 *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) { - int32_t predictionA, predictionB, sign; + int64_t predictionA, predictionB; + int32_t sign; p->buf[delayA] = p->lastA[filter]; p->buf[adaptA] = APESIGN(p->buf[delayA]); - p->buf[delayA - 1] = p->buf[delayA] - (unsigned)p->buf[delayA - 1]; + p->buf[delayA - 1] = p->buf[delayA] - (uint64_t)p->buf[delayA - 1]; p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]); predictionA = p->buf[delayA ] * p->coeffsA[filter][0] + @@ -1150,9 +1183,9 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, p->buf[delayA - 3] * p->coeffsA[filter][3]; /* Apply a scaled first-order filter compression */ - p->buf[delayB] = p->filterA[filter ^ 1] - ((int)(p->filterB[filter] * 31U) >> 5); + p->buf[delayB] = p->filterA[filter ^ 1] - ((int64_t)(p->filterB[filter] * 31ULL) >> 5); p->buf[adaptB] = APESIGN(p->buf[delayB]); - p->buf[delayB - 1] = p->buf[delayB] - (unsigned)p->buf[delayB - 1]; + p->buf[delayB - 1] = p->buf[delayB] - (uint64_t)p->buf[delayB - 1]; p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]); p->filterB[filter] = p->filterA[filter ^ 1]; @@ -1162,8 +1195,8 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, p->buf[delayB - 3] * p->coeffsB[filter][3] + p->buf[delayB - 4] * p->coeffsB[filter][4]; - p->lastA[filter] = decoded + ((int)((unsigned)predictionA + (predictionB >> 1)) >> 10); - p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5); + p->lastA[filter] = decoded + ((int64_t)((uint64_t)predictionA + (predictionB >> 1)) >> 10); + p->filterA[filter] = p->lastA[filter] + ((int64_t)(p->filterA[filter] * 31ULL) >> 5); sign = APESIGN(decoded); p->coeffsA[filter][0] += p->buf[adaptA ] * sign; @@ -1181,7 +1214,7 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, static void predictor_decode_stereo_3950(APEContext *ctx, int count) { - APEPredictor *p = &ctx->predictor; + APEPredictor64 *p = &ctx->predictor64; int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; @@ -1210,7 +1243,7 @@ static void predictor_decode_stereo_3950(APEContext *ctx, int count) static void predictor_decode_mono_3950(APEContext *ctx, int count) { - APEPredictor *p = &ctx->predictor; + APEPredictor64 *p = &ctx->predictor64; int32_t *decoded0 = ctx->decoded[0]; int32_t predictionA, currentA, A, sign; @@ -1222,14 +1255,14 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count) A = *decoded0; p->buf[YDELAYA] = currentA; - p->buf[YDELAYA - 1] = p->buf[YDELAYA] - (unsigned)p->buf[YDELAYA - 1]; + p->buf[YDELAYA - 1] = p->buf[YDELAYA] - (uint64_t)p->buf[YDELAYA - 1]; predictionA = p->buf[YDELAYA ] * p->coeffsA[0][0] + p->buf[YDELAYA - 1] * p->coeffsA[0][1] + p->buf[YDELAYA - 2] * p->coeffsA[0][2] + p->buf[YDELAYA - 3] * p->coeffsA[0][3]; - currentA = A + (unsigned)(predictionA >> 10); + currentA = A + (uint64_t)(predictionA >> 10); p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]); p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]); @@ -1249,7 +1282,7 @@ static void predictor_decode_mono_3950(APEContext *ctx, int count) p->buf = p->historybuffer; } - p->filterA[0] = currentA + (unsigned)((int)(p->filterA[0] * 31U) >> 5); + p->filterA[0] = currentA + (uint64_t)((int64_t)(p->filterA[0] * 31U) >> 5); *(decoded0++) = p->filterA[0]; } @@ -1286,7 +1319,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data)); - res = (int)(res + (1U << (fracbits - 1))) >> fracbits; + res = (int64_t)(res + (1LL << (fracbits - 1))) >> fracbits; res += (unsigned)*data; *data++ = res;