From: Andrew D'Addesio <modchip...@gmail.com> Signed-off-by: Justin Ruggles <justin.rugg...@gmail.com> --- libavcodec/alac.c | 183 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 109 insertions(+), 74 deletions(-)
diff --git a/libavcodec/alac.c b/libavcodec/alac.c index ab9fb81..8e2b803 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -46,6 +46,7 @@ */ +#include "libavutil/audioconvert.h" #include "avcodec.h" #include "get_bits.h" #include "bytestream.h" @@ -53,7 +54,7 @@ #include "mathops.h" #define ALAC_EXTRADATA_SIZE 36 -#define MAX_CHANNELS 2 +#define MAX_CHANNELS 8 typedef struct { @@ -64,11 +65,11 @@ typedef struct { int numchannels; /* buffers */ - int32_t *predicterror_buffer[MAX_CHANNELS]; + int32_t *predicterror_buffer[2]; - int32_t *outputsamples_buffer[MAX_CHANNELS]; + int32_t *outputsamples_buffer[2]; - int32_t *extra_bits_buffer[MAX_CHANNELS]; + int32_t *extra_bits_buffer[2]; /* stuff from setinfo */ uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ @@ -81,6 +82,40 @@ typedef struct { int extra_bits; /**< number of extra bits beyond 16-bit */ } ALACContext; +enum RawDataBlockType { + /* At the moment, only SCE, CPE, LFE, and END are recognized. */ + TYPE_SCE, + TYPE_CPE, + TYPE_CCE, + TYPE_LFE, + TYPE_DSE, + TYPE_PCE, + TYPE_FIL, + TYPE_END +}; + +static const uint8_t alac_channel_layout_offsets[8][8] = { + { 0 }, + { 0, 1 }, + { 2, 0, 1 }, + { 2, 0, 1, 3 }, + { 2, 0, 1, 3, 4 }, + { 2, 0, 1, 4, 5, 3 }, + { 2, 0, 1, 4, 5, 6, 3 }, + { 2, 6, 7, 0, 1, 4, 5, 3 } +}; + +static const uint16_t alac_channel_layouts[8] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_6POINT1_BACK, + AV_CH_LAYOUT_7POINT1_WIDE_BACK +}; + static inline int decode_scalar(GetBitContext *gb, int k, int limit, int readsamplesize){ /* read x - number of 1s before 0 represent the rice */ int x = get_unary_0_9(gb); @@ -294,7 +329,7 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, } } -static void decorrelate_stereo(int32_t *buffer[MAX_CHANNELS], +static void decorrelate_stereo(int32_t *buffer[2], int numsamples, uint8_t interlacing_shift, uint8_t interlacing_leftweight) { @@ -314,39 +349,17 @@ static void decorrelate_stereo(int32_t *buffer[MAX_CHANNELS], } } -static void append_extra_bits(int32_t *buffer[MAX_CHANNELS], - int32_t *extra_bits_buffer[MAX_CHANNELS], - int extra_bits, int numchannels, int numsamples) +static void append_extra_bits(int32_t *buffer[2], + int32_t *extra_bits_buffer[2], + int extra_bits, int paired, int numsamples) { int i, ch; - for (ch = 0; ch < numchannels; ch++) + for (ch = 0; ch <= paired; ch++) for (i = 0; i < numsamples; i++) buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i]; } -static void interleave_stereo_16(int32_t *buffer[MAX_CHANNELS], - int16_t *buffer_out, int numsamples) -{ - int i; - - for (i = 0; i < numsamples; i++) { - *buffer_out++ = buffer[0][i]; - *buffer_out++ = buffer[1][i]; - } -} - -static void interleave_stereo_24(int32_t *buffer[MAX_CHANNELS], - int32_t *buffer_out, int numsamples) -{ - int i; - - for (i = 0; i < numsamples; i++) { - *buffer_out++ = buffer[0][i] << 8; - *buffer_out++ = buffer[1][i] << 8; - } -} - static int alac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -354,20 +367,31 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, int input_buffer_size = avpkt->size; ALACContext *alac = avctx->priv_data; - int channels; - unsigned int outputsamples; + int channels = avctx->channels; + unsigned int outputsamples = 0; int hassize; unsigned int readsamplesize; int isnotcompressed; uint8_t interlacing_shift; uint8_t interlacing_leftweight; int i, ch, ret; + int offsetL, offsetR; init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); - channels = get_bits(&alac->gb, 3) + 1; - if (channels != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "frame header channel count mismatch\n"); + while (channels > 0) { + enum RawDataBlockType element; + int paired; + + element = get_bits(&alac->gb, 3); + if (element > TYPE_CPE && element != TYPE_LFE) { + av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element); + return AVERROR_PATCHWELCOME; + } + + paired = (element == TYPE_CPE); + if (paired && channels < 2) { + av_log(avctx, AV_LOG_ERROR, "stereo frame in mono audio track\n"); return AVERROR_INVALIDDATA; } @@ -386,6 +410,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, /* whether the frame is compressed */ isnotcompressed = get_bits1(&alac->gb); + if (outputsamples == 0) { if (hassize) { /* now read the number of samples as a 32bit integer */ outputsamples = get_bits_long(&alac->gb, 32); @@ -393,7 +418,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame); return -1; } - } else + } + if (outputsamples == 0) outputsamples = alac->setinfo_max_samples_per_frame; /* get output buffer */ @@ -406,8 +432,14 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } + } else { + if (hassize && get_bits_long(&alac->gb, 32) != outputsamples) { + av_log(avctx, AV_LOG_ERROR, "sample count disparity between channels\n"); + return AVERROR_INVALIDDATA; + } + } - readsamplesize = alac->setinfo_sample_size - alac->extra_bits + channels - 1; + readsamplesize = alac->setinfo_sample_size - alac->extra_bits + paired; if (readsamplesize > MIN_CACHE_BITS) { av_log(avctx, AV_LOG_ERROR, "readsamplesize too big (%d)\n", readsamplesize); return -1; @@ -415,16 +447,16 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, if (!isnotcompressed) { /* so it is compressed */ - int16_t predictor_coef_table[MAX_CHANNELS][32]; - int predictor_coef_num[MAX_CHANNELS]; - int prediction_type[MAX_CHANNELS]; - int prediction_quantitization[MAX_CHANNELS]; - int ricemodifier[MAX_CHANNELS]; + int16_t predictor_coef_table[2][32]; + int predictor_coef_num[2]; + int prediction_type[2]; + int prediction_quantitization[2]; + int ricemodifier[2]; interlacing_shift = get_bits(&alac->gb, 8); interlacing_leftweight = get_bits(&alac->gb, 8); - for (ch = 0; ch < channels; ch++) { + for (ch = 0; ch <= paired; ch++) { prediction_type[ch] = get_bits(&alac->gb, 4); prediction_quantitization[ch] = get_bits(&alac->gb, 4); @@ -438,11 +470,11 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, if (alac->extra_bits) { for (i = 0; i < outputsamples; i++) { - for (ch = 0; ch < channels; ch++) + for (ch = 0; ch <= paired; ch++) alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits); } } - for (ch = 0; ch < channels; ch++) { + for (ch = 0; ch <= paired; ch++) { bastardized_rice_decompress(alac, alac->predicterror_buffer[ch], outputsamples, @@ -479,7 +511,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, } else { /* not compressed, easy case */ for (i = 0; i < outputsamples; i++) { - for (ch = 0; ch < channels; ch++) { + for (ch = 0; ch <= paired; ch++) { alac->outputsamples_buffer[ch][i] = get_sbits_long(&alac->gb, alac->setinfo_sample_size); } @@ -488,45 +520,46 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, interlacing_shift = 0; interlacing_leftweight = 0; } - if (get_bits(&alac->gb, 3) != 7) - av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n"); - if (channels == 2 && interlacing_leftweight) { + if (paired && interlacing_leftweight) { decorrelate_stereo(alac->outputsamples_buffer, outputsamples, interlacing_shift, interlacing_leftweight); } + offsetL = alac_channel_layout_offsets[avctx->channels - 1][avctx->channels - channels]; + if (paired) + offsetR = alac_channel_layout_offsets[avctx->channels - 1][avctx->channels - channels + 1]; if (alac->extra_bits) { append_extra_bits(alac->outputsamples_buffer, alac->extra_bits_buffer, - alac->extra_bits, alac->numchannels, outputsamples); + alac->extra_bits, paired, outputsamples); } switch(alac->setinfo_sample_size) { - case 16: - if (channels == 2) { - interleave_stereo_16(alac->outputsamples_buffer, - (int16_t *)alac->frame.data[0], outputsamples); - } else { - int16_t *outbuffer = (int16_t *)alac->frame.data[0]; - for (i = 0; i < outputsamples; i++) { - outbuffer[i] = alac->outputsamples_buffer[0][i]; - } - } + case 16: { + int16_t *outbuffer = (int16_t *)alac->frame.data[0]; + for (i = 0; i < outputsamples; i++) { + outbuffer[i * avctx->channels + offsetL] = alac->outputsamples_buffer[0][i]; + if (paired) + outbuffer[i * avctx->channels + offsetR] = alac->outputsamples_buffer[1][i]; + }} break; - case 24: - if (channels == 2) { - interleave_stereo_24(alac->outputsamples_buffer, - (int32_t *)alac->frame.data[0], outputsamples); - } else { - int32_t *outbuffer = (int32_t *)alac->frame.data[0]; - for (i = 0; i < outputsamples; i++) - outbuffer[i] = alac->outputsamples_buffer[0][i] << 8; - } + case 24: { + int32_t *outbuffer = (int32_t *)alac->frame.data[0]; + for (i = 0; i < outputsamples; i++) { + outbuffer[i * avctx->channels + offsetL] = alac->outputsamples_buffer[0][i] << 8; + if (paired) + outbuffer[i * avctx->channels + offsetR] = alac->outputsamples_buffer[1][i] << 8; + }} break; } - if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8) - av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb)); + channels -= (paired) ? 2 : 1; + } + + if (get_bits(&alac->gb, 3) != TYPE_END) + av_log(avctx, AV_LOG_ERROR, "Error : Missing frame epilogue\n"); + if (input_buffer_size * 8 - get_bits_count(&alac->gb) >= 8) + av_log(avctx, AV_LOG_ERROR, "Error : %d unused bits in frame\n", input_buffer_size * 8 - get_bits_count(&alac->gb)); *got_frame_ptr = 1; *(AVFrame *)data = alac->frame; @@ -539,7 +572,7 @@ static av_cold int alac_decode_close(AVCodecContext *avctx) ALACContext *alac = avctx->priv_data; int ch; - for (ch = 0; ch < alac->numchannels; ch++) { + for (ch = 0; ch < 2; ch++) { av_freep(&alac->predicterror_buffer[ch]); av_freep(&alac->outputsamples_buffer[ch]); av_freep(&alac->extra_bits_buffer[ch]); @@ -551,7 +584,7 @@ static av_cold int alac_decode_close(AVCodecContext *avctx) static int allocate_buffers(ALACContext *alac) { int ch; - for (ch = 0; ch < alac->numchannels; ch++) { + for (ch = 0; ch < 2; ch++) { int buf_size = alac->setinfo_max_samples_per_frame * sizeof(int32_t); FF_ALLOC_OR_GOTO(alac->avctx, alac->predicterror_buffer[ch], @@ -596,6 +629,8 @@ static int alac_set_info(ALACContext *alac) bytestream2_get_be32u(&gb); // average bitrate bytestream2_get_be32u(&gb); // samplerate + alac->avctx->channel_layout = alac_channel_layouts[alac->numchannels - 1]; + return 0; } -- 1.7.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel