alac: add option to decoded incorrect ALAC
authorChristophe Gisquet <christophe.gisquet@gmail.com>
Mon, 18 Aug 2014 07:53:20 +0000 (09:53 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 18 Aug 2014 19:59:23 +0000 (21:59 +0200)
Prior to 56.1.100, incorrect ALAC files for 24bps content were produced, in
particular not decoding losslessly.

Add an option to allow correctly decoding those streams.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/alac.c

index 103d14e..aec7bb4 100644 (file)
@@ -48,6 +48,7 @@
 #include <inttypes.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
@@ -60,6 +61,7 @@
 #define ALAC_EXTRADATA_SIZE 36
 
 typedef struct {
+    AVClass *class;
     AVCodecContext *avctx;
     GetBitContext gb;
     int channels;
@@ -78,6 +80,7 @@ typedef struct {
     int nb_samples;     /**< number of samples in the current frame */
 
     int direct_output;
+    int extra_bit_bug;
 } ALACContext;
 
 static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps)
@@ -380,12 +383,17 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
         decorr_left_weight = 0;
     }
 
+    if (alac->extra_bits && alac->extra_bit_bug) {
+        append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
+                          alac->extra_bits, channels, alac->nb_samples);
+    }
+
     if (channels == 2 && decorr_left_weight) {
         decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
                            decorr_shift, decorr_left_weight);
     }
 
-    if (alac->extra_bits) {
+    if (alac->extra_bits && !alac->extra_bit_bug) {
         append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
                           alac->extra_bits, channels, alac->nb_samples);
     }
@@ -630,6 +638,20 @@ static int init_thread_copy(AVCodecContext *avctx)
     return allocate_buffers(alac);
 }
 
+static const AVOption options[] = {
+    { "extra_bits_bug", "Force non-standard decoding process",
+      offsetof(ALACContext, extra_bit_bug), AV_OPT_TYPE_INT, { .i64 = 0 },
+      0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass alac_class = {
+    .class_name = "alac",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_alac_decoder = {
     .name           = "alac",
     .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
@@ -641,4 +663,5 @@ AVCodec ff_alac_decoder = {
     .decode         = alac_decode_frame,
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+    .priv_class     = &alac_class
 };