On Tue, Mar 12, 2013 at 08:09:16PM +0100, Kostya Shishkov wrote:
> ---
>  libavcodec/apedec.c |   93 
> +++++++++++++++++++++++++++++++++++++++++++++++++--
>  libavformat/ape.c   |    2 +-
>  2 files changed, 92 insertions(+), 3 deletions(-)

The same thing for 3.93 support.
>From 246d0ed4d5b23ab524fd9e3e72684dee2b92c79e Mon Sep 17 00:00:00 2001
From: Kostya Shishkov <[email protected]>
Date: Tue, 12 Mar 2013 19:33:29 +0100
Subject: [PATCH 3/3] add support for Monkey's Audio versions from 3.93

---
 libavcodec/apedec.c |   97 +++++++++++++++++++++++++++++++++++++++++++++++++--
 libavformat/ape.c   |    2 +-
 2 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 3d6da17..c916c73 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -176,6 +176,8 @@ static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode);
 static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode);
 static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode);
 
+static void predictor_decode_mono_3930(APEContext *ctx, int count);
+static void predictor_decode_stereo_3930(APEContext *ctx, int count);
 static void predictor_decode_mono_3950(APEContext *ctx, int count);
 static void predictor_decode_stereo_3950(APEContext *ctx, int count);
 
@@ -255,8 +257,13 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
         s->entropy_decode_stereo = entropy_decode_stereo_3990;
     }
 
-    s->predictor_decode_mono   = predictor_decode_mono_3950;
-    s->predictor_decode_stereo = predictor_decode_stereo_3950;
+    if (s->fileversion < 3950) {
+        s->predictor_decode_mono   = predictor_decode_mono_3930;
+        s->predictor_decode_stereo = predictor_decode_stereo_3930;
+    } else {
+        s->predictor_decode_mono   = predictor_decode_mono_3950;
+        s->predictor_decode_stereo = predictor_decode_stereo_3950;
+    }
 
     ff_dsputil_init(&s->dsp, avctx);
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
@@ -603,6 +610,92 @@ static inline int APESIGN(int32_t x) {
     return (x < 0) - (x > 0);
 }
 
+static av_always_inline int predictor_update_3930(APEPredictor *p,
+                                                  const int decoded, const int filter,
+                                                  const int delayA,  const int delayB,
+                                                  const int adaptA,  const int adaptB)
+{
+    int32_t predictionA, sign;
+    int32_t d0, d1, d2, d3;
+
+    p->buf[delayA]     = p->lastA[filter];
+    d0 = p->buf[delayA    ];
+    d1 = p->buf[delayA    ] - p->buf[delayA - 1];
+    d2 = p->buf[delayA - 1] - p->buf[delayA - 2];
+    d3 = p->buf[delayA - 2] - p->buf[delayA - 3];
+    p->buf[adaptA]     = APESIGN(p->buf[delayA]);
+    p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]);
+
+    predictionA = d0 * p->coeffsA[filter][0] +
+                  d1 * p->coeffsA[filter][1] +
+                  d2 * p->coeffsA[filter][2] +
+                  d3 * p->coeffsA[filter][3];
+
+    p->lastA[filter] = decoded + (predictionA >> 9);
+    p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5);
+
+    sign = APESIGN(decoded);
+    p->coeffsA[filter][0] += ((d0 < 0)*2 - 1) * sign;
+    p->coeffsA[filter][1] += ((d1 < 0)*2 - 1) * sign;
+    p->coeffsA[filter][2] += ((d2 < 0)*2 - 1) * sign;
+    p->coeffsA[filter][3] += ((d3 < 0)*2 - 1) * sign;
+
+    return p->filterA[filter];
+}
+
+static void predictor_decode_stereo_3930(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+
+    ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count);
+
+    while (count--) {
+        /* Predictor Y */
+        int Y = *decoded1, X = *decoded0;
+        *decoded0 = predictor_update_3930(p, Y, 0, YDELAYA, YDELAYB,
+                                          YADAPTCOEFFSA, YADAPTCOEFFSB);
+        decoded0++;
+        *decoded1 = predictor_update_3930(p, X, 1, XDELAYA, XDELAYB,
+                                          XADAPTCOEFFSA, XADAPTCOEFFSB);
+        decoded1++;
+
+        /* Combined */
+        p->buf++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
+static void predictor_decode_mono_3930(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+
+    ape_apply_filters(ctx, ctx->decoded[0], NULL, count);
+
+    while (count--) {
+        *decoded0 = predictor_update_3930(p, *decoded0, 0, YDELAYA, YDELAYB,
+                                          YADAPTCOEFFSA, YADAPTCOEFFSB);
+        decoded0++;
+
+        p->buf++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
 static av_always_inline int predictor_update_filter(APEPredictor *p,
                                                     const int decoded, const int filter,
                                                     const int delayA,  const int delayB,
diff --git a/libavformat/ape.c b/libavformat/ape.c
index d67e684..7efc819 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -28,7 +28,7 @@
 #include "apetag.h"
 
 /* The earliest and latest file formats supported by this library */
-#define APE_MIN_VERSION 3950
+#define APE_MIN_VERSION 3930
 #define APE_MAX_VERSION 3990
 
 #define MAC_FORMAT_FLAG_8_BIT                 1 // is 8-bit [OBSOLETE]
-- 
1.7.9.5

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to