diff options
Diffstat (limited to 'libavcodec/alacenc.c')
-rw-r--r-- | libavcodec/alacenc.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index d921fa1..804cc7b 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -2,20 +2,20 @@ * ALAC audio encoder * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -38,6 +38,7 @@ #define DEFAULT_MAX_PRED_ORDER 6 #define DEFAULT_MIN_PRED_ORDER 4 #define ALAC_MAX_LPC_PRECISION 9 +#define ALAC_MIN_LPC_SHIFT 0 #define ALAC_MAX_LPC_SHIFT 9 #define ALAC_CHMODE_LEFT_RIGHT 0 @@ -70,7 +71,7 @@ typedef struct AlacEncodeContext { int write_sample_size; int extra_bits; int32_t sample_buf[2][DEFAULT_FRAME_SIZE]; - int32_t predictor_buf[DEFAULT_FRAME_SIZE]; + int32_t predictor_buf[2][DEFAULT_FRAME_SIZE]; int interlacing_shift; int interlacing_leftweight; PutBitContext pbctx; @@ -171,7 +172,8 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch) s->max_prediction_order, ALAC_MAX_LPC_PRECISION, coefs, shift, FF_LPC_TYPE_LEVINSON, 0, - ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1); + ORDER_METHOD_EST, ALAC_MIN_LPC_SHIFT, + ALAC_MAX_LPC_SHIFT, 1); s->lpc[ch].lpc_order = opt_order; s->lpc[ch].lpc_quant = shift[opt_order-1]; @@ -256,13 +258,14 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) { int i; AlacLPCContext lpc = s->lpc[ch]; + int32_t *residual = s->predictor_buf[ch]; if (lpc.lpc_order == 31) { - s->predictor_buf[0] = s->sample_buf[ch][0]; + residual[0] = s->sample_buf[ch][0]; for (i = 1; i < s->frame_size; i++) { - s->predictor_buf[i] = s->sample_buf[ch][i ] - - s->sample_buf[ch][i - 1]; + residual[i] = s->sample_buf[ch][i ] - + s->sample_buf[ch][i - 1]; } return; @@ -272,12 +275,11 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) if (lpc.lpc_order > 0) { int32_t *samples = s->sample_buf[ch]; - int32_t *residual = s->predictor_buf; // generate warm-up samples residual[0] = samples[0]; for (i = 1; i <= lpc.lpc_order; i++) - residual[i] = samples[i] - samples[i-1]; + residual[i] = sign_extend(samples[i] - samples[i-1], s->write_sample_size); // perform lpc on remaining samples for (i = lpc.lpc_order + 1; i < s->frame_size; i++) { @@ -316,11 +318,11 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) } } -static void alac_entropy_coder(AlacEncodeContext *s) +static void alac_entropy_coder(AlacEncodeContext *s, int ch) { unsigned int history = s->rc.initial_history; int sign_modifier = 0, i, k; - int32_t *samples = s->predictor_buf; + int32_t *samples = s->predictor_buf[ch]; for (i = 0; i < s->frame_size;) { int x; @@ -397,6 +399,19 @@ static void write_element(AlacEncodeContext *s, init_sample_buffers(s, channels, samples); write_element_header(s, element, instance); + // extract extra bits if needed + if (s->extra_bits) { + uint32_t mask = (1 << s->extra_bits) - 1; + for (j = 0; j < channels; j++) { + int32_t *extra = s->predictor_buf[j]; + int32_t *smp = s->sample_buf[j]; + for (i = 0; i < s->frame_size; i++) { + extra[i] = smp[i] & mask; + smp[i] >>= s->extra_bits; + } + } + } + if (channels == 2) alac_stereo_decorrelation(s); else @@ -419,11 +434,9 @@ static void write_element(AlacEncodeContext *s, // write extra bits if needed if (s->extra_bits) { - uint32_t mask = (1 << s->extra_bits) - 1; for (i = 0; i < s->frame_size; i++) { for (j = 0; j < channels; j++) { - put_bits(pb, s->extra_bits, s->sample_buf[j][i] & mask); - s->sample_buf[j][i] >>= s->extra_bits; + put_bits(pb, s->extra_bits, s->predictor_buf[j][i]); } } } @@ -435,10 +448,11 @@ static void write_element(AlacEncodeContext *s, // TODO: determine when this will actually help. for now it's not used. if (prediction_type == 15) { // 2nd pass 1st order filter + int32_t *residual = s->predictor_buf[i]; for (j = s->frame_size - 1; j > 0; j--) - s->predictor_buf[j] -= s->predictor_buf[j - 1]; + residual[j] -= residual[j - 1]; } - alac_entropy_coder(s); + alac_entropy_coder(s, i); } } } @@ -611,10 +625,8 @@ static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, else max_frame_size = s->max_coded_frame_size; - if ((ret = ff_alloc_packet(avpkt, 2 * max_frame_size))) { - av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); + if ((ret = ff_alloc_packet2(avctx, avpkt, 4 * max_frame_size, 0)) < 0) return ret; - } /* use verbatim mode for compression_level 0 */ if (s->compression_level) { |