X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Falacenc.c;h=fe03bb7dad11c69400ee5a99c14c5e27f0658a08;hb=ec6402b7c595c3ceed6d1b8c1b75c6aa8336e052;hp=82761c03b35928b8b4ef27d0ad04ca96bf1e6d5d;hpb=b275500706ac3a20ac59bdb6ee080dc32f3254cf;p=ffmpeg diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index 82761c03b35..fe03bb7dad1 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -2,25 +2,24 @@ * ALAC audio encoder * Copyright (c) 2008 Jaikrishnan Menon * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" -#include "bitstream.h" #include "put_bits.h" #include "dsputil.h" #include "lpc.h" @@ -52,11 +51,11 @@ typedef struct RiceContext { int rice_modifier; } RiceContext; -typedef struct LPCContext { +typedef struct AlacLPCContext { int lpc_order; int lpc_coeff[ALAC_MAX_LPC_ORDER+1]; int lpc_quant; -} LPCContext; +} AlacLPCContext; typedef struct AlacEncodeContext { int compression_level; @@ -70,18 +69,18 @@ typedef struct AlacEncodeContext { int interlacing_leftweight; PutBitContext pbctx; RiceContext rc; - LPCContext lpc[MAX_CHANNELS]; - DSPContext dspctx; + AlacLPCContext lpc[MAX_CHANNELS]; + LPCContext lpc_ctx; AVCodecContext *avctx; } AlacEncodeContext; -static void init_sample_buffers(AlacEncodeContext *s, int16_t *input_samples) +static void init_sample_buffers(AlacEncodeContext *s, const int16_t *input_samples) { int ch, i; for(ch=0;chavctx->channels;ch++) { - int16_t *sptr = input_samples + ch; + const int16_t *sptr = input_samples + ch; for(i=0;iavctx->frame_size;i++) { s->sample_buf[ch][i] = *sptr; sptr += s->avctx->channels; @@ -123,7 +122,7 @@ static void write_frame_header(AlacEncodeContext *s, int is_verbatim) put_bits(&s->pbctx, 1, 1); // Sample count is in the header put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim - put_bits(&s->pbctx, 32, s->avctx->frame_size); // No. of samples in the frame + put_bits32(&s->pbctx, s->avctx->frame_size); // No. of samples in the frame } static void calc_predictor_params(AlacEncodeContext *s, int ch) @@ -132,12 +131,28 @@ static void calc_predictor_params(AlacEncodeContext *s, int ch) int shift[MAX_LPC_ORDER]; int opt_order; - opt_order = ff_lpc_calc_coefs(&s->dspctx, s->sample_buf[ch], s->avctx->frame_size, s->min_prediction_order, s->max_prediction_order, - ALAC_MAX_LPC_PRECISION, coefs, shift, 1, ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1); - - s->lpc[ch].lpc_order = opt_order; - s->lpc[ch].lpc_quant = shift[opt_order-1]; - memcpy(s->lpc[ch].lpc_coeff, coefs[opt_order-1], opt_order*sizeof(int)); + if (s->compression_level == 1) { + s->lpc[ch].lpc_order = 6; + s->lpc[ch].lpc_quant = 6; + s->lpc[ch].lpc_coeff[0] = 160; + s->lpc[ch].lpc_coeff[1] = -190; + s->lpc[ch].lpc_coeff[2] = 170; + s->lpc[ch].lpc_coeff[3] = -130; + s->lpc[ch].lpc_coeff[4] = 80; + s->lpc[ch].lpc_coeff[5] = -25; + } else { + opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, s->sample_buf[ch], + s->avctx->frame_size, + s->min_prediction_order, + s->max_prediction_order, + ALAC_MAX_LPC_PRECISION, coefs, shift, + FF_LPC_TYPE_LEVINSON, 0, + ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1); + + s->lpc[ch].lpc_order = opt_order; + s->lpc[ch].lpc_quant = shift[opt_order-1]; + memcpy(s->lpc[ch].lpc_coeff, coefs[opt_order-1], opt_order*sizeof(int)); + } } static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) @@ -222,7 +237,7 @@ static void alac_stereo_decorrelation(AlacEncodeContext *s) static void alac_linear_predictor(AlacEncodeContext *s, int ch) { int i; - LPCContext lpc = s->lpc[ch]; + AlacLPCContext lpc = s->lpc[ch]; if(lpc.lpc_order == 31) { s->predictor_buf[0] = s->sample_buf[ch][0]; @@ -332,7 +347,6 @@ static void write_compressed_frame(AlacEncodeContext *s) { int i, j; - /* only simple mid/side decorrelation supported as of now */ if(s->avctx->channels == 2) alac_stereo_decorrelation(s); put_bits(&s->pbctx, 8, s->interlacing_shift); @@ -364,21 +378,22 @@ static void write_compressed_frame(AlacEncodeContext *s) static av_cold int alac_encode_init(AVCodecContext *avctx) { AlacEncodeContext *s = avctx->priv_data; + int ret; uint8_t *alac_extradata = av_mallocz(ALAC_EXTRADATA_SIZE+1); avctx->frame_size = DEFAULT_FRAME_SIZE; avctx->bits_per_coded_sample = DEFAULT_SAMPLE_SIZE; - if(avctx->sample_fmt != SAMPLE_FMT_S16) { + if(avctx->sample_fmt != AV_SAMPLE_FMT_S16) { av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n"); return -1; } // Set default compression level if(avctx->compression_level == FF_COMPRESSION_DEFAULT) - s->compression_level = 1; + s->compression_level = 2; else - s->compression_level = av_clip(avctx->compression_level, 0, 1); + s->compression_level = av_clip(avctx->compression_level, 0, 2); // Initialize default Rice parameters s->rc.history_mult = 40; @@ -386,8 +401,7 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) s->rc.k_modifier = 14; s->rc.rice_modifier = 4; - s->max_coded_frame_size = (ALAC_FRAME_HEADER_SIZE + ALAC_FRAME_FOOTER_SIZE + - avctx->frame_size*avctx->channels*avctx->bits_per_coded_sample)>>3; + s->max_coded_frame_size = 8 + (avctx->frame_size*avctx->channels*avctx->bits_per_coded_sample>>3); s->write_sample_size = avctx->bits_per_coded_sample + avctx->channels - 1; // FIXME: consider wasted_bytes @@ -442,9 +456,10 @@ static av_cold int alac_encode_init(AVCodecContext *avctx) avctx->coded_frame->key_frame = 1; s->avctx = avctx; - dsputil_init(&s->dspctx, avctx); + ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size, s->max_prediction_order, + FF_LPC_TYPE_LEVINSON); - return 0; + return ret; } static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame, @@ -469,7 +484,7 @@ verbatim: if((s->compression_level == 0) || verbatim_flag) { // Verbatim mode - int16_t *samples = data; + const int16_t *samples = data; write_frame_header(s, 1); for(i=0; iframe_size*avctx->channels; i++) { put_sbits(pb, 16, *samples++); @@ -500,20 +515,23 @@ verbatim: static av_cold int alac_encode_close(AVCodecContext *avctx) { + AlacEncodeContext *s = avctx->priv_data; + ff_lpc_end(&s->lpc_ctx); av_freep(&avctx->extradata); avctx->extradata_size = 0; av_freep(&avctx->coded_frame); return 0; } -AVCodec alac_encoder = { - "alac", - CODEC_TYPE_AUDIO, - CODEC_ID_ALAC, - sizeof(AlacEncodeContext), - alac_encode_init, - alac_encode_frame, - alac_encode_close, +AVCodec ff_alac_encoder = { + .name = "alac", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_ALAC, + .priv_data_size = sizeof(AlacEncodeContext), + .init = alac_encode_init, + .encode = alac_encode_frame, + .close = alac_encode_close, .capabilities = CODEC_CAP_SMALL_LAST_FRAME, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), };