diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 103d14eada..aec7bb4e4e 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -48,6 +48,7 @@ #include #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 };