mirror of https://git.ffmpeg.org/ffmpeg.git
alac: add option to decoded incorrect ALAC
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>
This commit is contained in:
parent
cdd0ad7be1
commit
30cac8313a
|
@ -48,6 +48,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "libavutil/channel_layout.h"
|
#include "libavutil/channel_layout.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "get_bits.h"
|
#include "get_bits.h"
|
||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
|
@ -60,6 +61,7 @@
|
||||||
#define ALAC_EXTRADATA_SIZE 36
|
#define ALAC_EXTRADATA_SIZE 36
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
AVClass *class;
|
||||||
AVCodecContext *avctx;
|
AVCodecContext *avctx;
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
int channels;
|
int channels;
|
||||||
|
@ -78,6 +80,7 @@ typedef struct {
|
||||||
int nb_samples; /**< number of samples in the current frame */
|
int nb_samples; /**< number of samples in the current frame */
|
||||||
|
|
||||||
int direct_output;
|
int direct_output;
|
||||||
|
int extra_bit_bug;
|
||||||
} ALACContext;
|
} ALACContext;
|
||||||
|
|
||||||
static inline unsigned int decode_scalar(GetBitContext *gb, int k, int bps)
|
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;
|
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) {
|
if (channels == 2 && decorr_left_weight) {
|
||||||
decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
|
decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
|
||||||
decorr_shift, decorr_left_weight);
|
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,
|
append_extra_bits(alac->output_samples_buffer, alac->extra_bits_buffer,
|
||||||
alac->extra_bits, channels, alac->nb_samples);
|
alac->extra_bits, channels, alac->nb_samples);
|
||||||
}
|
}
|
||||||
|
@ -630,6 +638,20 @@ static int init_thread_copy(AVCodecContext *avctx)
|
||||||
return allocate_buffers(alac);
|
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 = {
|
AVCodec ff_alac_decoder = {
|
||||||
.name = "alac",
|
.name = "alac",
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
|
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
|
||||||
|
@ -641,4 +663,5 @@ AVCodec ff_alac_decoder = {
|
||||||
.decode = alac_decode_frame,
|
.decode = alac_decode_frame,
|
||||||
.init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
|
.init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
|
||||||
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
|
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
|
||||||
|
.priv_class = &alac_class
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue