@ -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
} ;