X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fflacenc.c;h=89d40d5ac24fe20eeda779aa77ac7016764bab8b;hb=4311ff776b4f887ceb526a9b611f627bbb527c80;hp=9e5036bee30869ca3348c136b4b88d132b1695eb;hpb=d5202e4fda3d6e3d63e032328b7626f779572e76;p=ffmpeg diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 9e5036bee30..89d40d5ac24 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -1,6 +1,6 @@ /** * FLAC audio encoder - * Copyright (c) 2006 Justin Ruggles + * Copyright (c) 2006 Justin Ruggles * * This file is part of FFmpeg. * @@ -19,39 +19,21 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/crc.h" +#include "libavutil/md5.h" #include "avcodec.h" -#include "bitstream.h" -#include "crc.h" +#include "get_bits.h" #include "dsputil.h" #include "golomb.h" -#include "lls.h" - -#define FLAC_MAX_CH 8 -#define FLAC_MIN_BLOCKSIZE 16 -#define FLAC_MAX_BLOCKSIZE 65535 +#include "lpc.h" +#include "flac.h" +#include "flacdata.h" #define FLAC_SUBFRAME_CONSTANT 0 #define FLAC_SUBFRAME_VERBATIM 1 #define FLAC_SUBFRAME_FIXED 8 #define FLAC_SUBFRAME_LPC 32 -#define FLAC_CHMODE_NOT_STEREO 0 -#define FLAC_CHMODE_LEFT_RIGHT 1 -#define FLAC_CHMODE_LEFT_SIDE 8 -#define FLAC_CHMODE_RIGHT_SIDE 9 -#define FLAC_CHMODE_MID_SIDE 10 - -#define ORDER_METHOD_EST 0 -#define ORDER_METHOD_2LEVEL 1 -#define ORDER_METHOD_4LEVEL 2 -#define ORDER_METHOD_8LEVEL 3 -#define ORDER_METHOD_SEARCH 4 -#define ORDER_METHOD_LOG 5 - -#define FLAC_STREAMINFO_SIZE 34 - -#define MIN_LPC_ORDER 1 -#define MAX_LPC_ORDER 32 #define MAX_FIXED_ORDER 4 #define MAX_PARTITION_ORDER 8 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) @@ -89,7 +71,7 @@ typedef struct FlacSubframe { } FlacSubframe; typedef struct FlacFrame { - FlacSubframe subframes[FLAC_MAX_CH]; + FlacSubframe subframes[FLAC_MAX_CHANNELS]; int blocksize; int bs_code[2]; uint8_t crc8; @@ -99,31 +81,22 @@ typedef struct FlacFrame { typedef struct FlacEncodeContext { PutBitContext pb; int channels; - int ch_code; int samplerate; int sr_code[2]; + int max_blocksize; + int min_framesize; int max_framesize; + int max_encoded_framesize; uint32_t frame_count; + uint64_t sample_count; + uint8_t md5sum[16]; FlacFrame frame; CompressionOptions options; AVCodecContext *avctx; DSPContext dsp; + struct AVMD5 *md5ctx; } FlacEncodeContext; -static const int flac_samplerates[16] = { - 0, 0, 0, 0, - 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, - 0, 0, 0, 0 -}; - -static const int flac_blocksizes[16] = { - 0, - 192, - 576, 1152, 2304, 4608, - 0, 0, - 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 -}; - /** * Writes streaminfo metadata block to byte array */ @@ -135,16 +108,18 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header) init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE); /* streaminfo metadata block */ - put_bits(&pb, 16, s->avctx->frame_size); - put_bits(&pb, 16, s->avctx->frame_size); - put_bits(&pb, 24, 0); + put_bits(&pb, 16, s->max_blocksize); + put_bits(&pb, 16, s->max_blocksize); + put_bits(&pb, 24, s->min_framesize); put_bits(&pb, 24, s->max_framesize); put_bits(&pb, 20, s->samplerate); put_bits(&pb, 3, s->channels-1); put_bits(&pb, 5, 15); /* bits per sample - 1 */ + /* write 36-bit sample count in 2 put_bits() calls */ + put_bits(&pb, 24, (s->sample_count & 0xFFFFFF000LL) >> 12); + put_bits(&pb, 12, s->sample_count & 0x000000FFFLL); flush_put_bits(&pb); - /* total samples = 0 */ - /* MD5 signature = 0 */ + memcpy(&header[18], s->md5sum, 16); } /** @@ -158,11 +133,11 @@ static int select_blocksize(int samplerate, int block_time_ms) int blocksize; assert(samplerate > 0); - blocksize = flac_blocksizes[1]; + blocksize = ff_flac_blocksize_table[1]; target = (samplerate * block_time_ms) / 1000; for(i=0; i<16; i++) { - if(target >= flac_blocksizes[i] && flac_blocksizes[i] > blocksize) { - blocksize = flac_blocksizes[i]; + if(target >= ff_flac_blocksize_table[i] && ff_flac_blocksize_table[i] > blocksize) { + blocksize = ff_flac_blocksize_table[i]; } } return blocksize; @@ -184,18 +159,17 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) return -1; } - if(channels < 1 || channels > FLAC_MAX_CH) { + if(channels < 1 || channels > FLAC_MAX_CHANNELS) { return -1; } s->channels = channels; - s->ch_code = s->channels-1; /* find samplerate in table */ if(freq < 1) return -1; for(i=4; i<12; i++) { - if(freq == flac_samplerates[i]) { - s->samplerate = flac_samplerates[i]; + if(freq == ff_flac_sample_rate_table[i]) { + s->samplerate = ff_flac_sample_rate_table[i]; s->sr_code[0] = i; s->sr_code[1] = 0; break; @@ -353,6 +327,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) } else { s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms); } + s->max_blocksize = s->avctx->frame_size; av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", s->avctx->frame_size); /* set LPC precision */ @@ -371,11 +346,14 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) s->options.lpc_coeff_precision); /* set maximum encoded frame size in verbatim mode */ - if(s->channels == 2) { - s->max_framesize = 14 + ((s->avctx->frame_size * 33 + 7) >> 3); - } else { - s->max_framesize = 14 + (s->avctx->frame_size * s->channels * 2); - } + s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size, + s->channels, 16); + + /* initialize MD5 context */ + s->md5ctx = av_malloc(av_md5_size); + if(!s->md5ctx) + return AVERROR(ENOMEM); + av_md5_init(s->md5ctx); streaminfo = av_malloc(FLAC_STREAMINFO_SIZE); write_streaminfo(s, streaminfo); @@ -383,6 +361,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) avctx->extradata_size = FLAC_STREAMINFO_SIZE; s->frame_count = 0; + s->min_framesize = s->max_framesize; avctx->coded_frame = avcodec_alloc_frame(); avctx->coded_frame->key_frame = 1; @@ -398,8 +377,8 @@ static void init_frame(FlacEncodeContext *s) frame = &s->frame; for(i=0; i<16; i++) { - if(s->avctx->frame_size == flac_blocksizes[i]) { - frame->blocksize = flac_blocksizes[i]; + if(s->avctx->frame_size == ff_flac_blocksize_table[i]) { + frame->blocksize = ff_flac_blocksize_table[i]; frame->bs_code[0] = i; frame->bs_code[1] = 0; break; @@ -573,248 +552,6 @@ static uint32_t calc_rice_params_lpc(RiceContext *rc, int pmin, int pmax, return bits; } -/** - * Apply Welch window function to audio block - */ -static void apply_welch_window(const int32_t *data, int len, double *w_data) -{ - int i, n2; - double w; - double c; - - assert(!(len&1)); //the optimization in r11881 does not support odd len - //if someone wants odd len extend the change in r11881 - - n2 = (len >> 1); - c = 2.0 / (len - 1.0); - - w_data+=n2; - data+=n2; - for(i=0; i> 1); - lpc_tmp[i] = r; - for(j=0; j qmax) && (sh > 0)) { - sh--; - } - - /* since negative shift values are unsupported in decoder, scale down - coefficients instead */ - if(sh == 0 && cmax > qmax) { - double scale = ((double)qmax) / cmax; - for(i=0; i=0; i--) { - if(ref[i] > 0.10) { - est = i+1; - break; - } - } - return est; -} - -/** - * Calculate LPC coefficients for multiple orders - */ -static int lpc_calc_coefs(FlacEncodeContext *s, - const int32_t *samples, int blocksize, int max_order, - int precision, int32_t coefs[][MAX_LPC_ORDER], - int *shift, int use_lpc, int omethod) -{ - double autoc[MAX_LPC_ORDER+1]; - double ref[MAX_LPC_ORDER]; - double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; - int i, j, pass; - int opt_order; - - assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER); - - if(use_lpc == 1){ - s->dsp.flac_compute_autocorr(samples, blocksize, max_order, autoc); - - compute_lpc_coefs(autoc, max_order, lpc, ref); - }else{ - LLSModel m[2]; - double var[MAX_LPC_ORDER+1], weight; - - for(pass=0; pass>pass) + fabs(eval - var[0]); - inv = 1/eval; - rinv = sqrt(inv); - for(j=0; j<=max_order; j++) - var[j] *= rinv; - weight += inv; - }else - weight++; - - av_update_lls(&m[pass&1], var, 1.0); - } - av_solve_lls(&m[pass&1], 0.001, 0); - } - - for(i=0; i0; i--) - ref[i] = ref[i-1] - ref[i]; - } - opt_order = max_order; - - if(omethod == ORDER_METHOD_EST) { - opt_order = estimate_best_order(ref, max_order); - i = opt_order-1; - quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i]); - } else { - for(i=0; i 0); @@ -946,7 +683,7 @@ static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n, for(i=0; ioptions.use_lpc, omethod); + opt_order = ff_lpc_calc_coefs(&ctx->dsp, smp, n, min_order, max_order, + precision, coefs, shift, ctx->options.use_lpc, + omethod, MAX_LPC_SHIFT, 0); if(omethod == ORDER_METHOD_2LEVEL || omethod == ORDER_METHOD_4LEVEL || @@ -1180,7 +919,7 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) } } if(best == 0) { - return FLAC_CHMODE_LEFT_RIGHT; + return FLAC_CHMODE_INDEPENDENT; } else if(best == 1) { return FLAC_CHMODE_LEFT_SIDE; } else if(best == 2) { @@ -1205,14 +944,14 @@ static void channel_decorrelation(FlacEncodeContext *ctx) right = frame->subframes[1].samples; if(ctx->channels != 2) { - frame->ch_mode = FLAC_CHMODE_NOT_STEREO; + frame->ch_mode = FLAC_CHMODE_INDEPENDENT; return; } frame->ch_mode = estimate_stereo_mode(left, right, n); /* perform decorrelation and adjust bits-per-sample */ - if(frame->ch_mode == FLAC_CHMODE_LEFT_RIGHT) { + if(frame->ch_mode == FLAC_CHMODE_INDEPENDENT) { return; } if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) { @@ -1236,13 +975,6 @@ static void channel_decorrelation(FlacEncodeContext *ctx) } } -static void put_sbits(PutBitContext *pb, int bits, int32_t val) -{ - assert(bits >= 0 && bits <= 31); - - put_bits(pb, bits, val & ((1<pb, 16, 0xFFF8); put_bits(&s->pb, 4, frame->bs_code[0]); put_bits(&s->pb, 4, s->sr_code[0]); - if(frame->ch_mode == FLAC_CHMODE_NOT_STEREO) { - put_bits(&s->pb, 4, s->ch_code); + if(frame->ch_mode == FLAC_CHMODE_INDEPENDENT) { + put_bits(&s->pb, 4, s->channels-1); } else { put_bits(&s->pb, 4, frame->ch_mode); } @@ -1427,6 +1159,19 @@ static void output_frame_footer(FlacEncodeContext *s) flush_put_bits(&s->pb); } +static void update_md5_sum(FlacEncodeContext *s, int16_t *samples) +{ +#if HAVE_BIGENDIAN + int i; + for(i = 0; i < s->frame.blocksize*s->channels; i++) { + int16_t smp = le2me_16(samples[i]); + av_md5_update(s->md5ctx, (uint8_t *)&smp, 2); + } +#else + av_md5_update(s->md5ctx, (uint8_t *)samples, s->frame.blocksize*s->channels*2); +#endif +} + static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data) { @@ -1434,9 +1179,23 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, FlacEncodeContext *s; int16_t *samples = data; int out_bytes; + int reencoded=0; s = avctx->priv_data; + if(buf_size < s->max_framesize*2) { + av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); + return 0; + } + + /* when the last block is reached, update the header in extradata */ + if (!data) { + s->max_framesize = s->max_encoded_framesize; + av_md5_final(s->md5ctx, s->md5sum); + write_streaminfo(s, avctx->extradata); + return 0; + } + init_frame(s); copy_samples(s, samples); @@ -1446,36 +1205,46 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, for(ch=0; chchannels; ch++) { encode_residual(s, ch); } + +write_frame: init_put_bits(&s->pb, frame, buf_size); output_frame_header(s); output_subframes(s); output_frame_footer(s); out_bytes = put_bits_count(&s->pb) >> 3; - if(out_bytes > s->max_framesize || out_bytes >= buf_size) { - /* frame too large. use verbatim mode */ - for(ch=0; chchannels; ch++) { - encode_residual_v(s, ch); - } - init_put_bits(&s->pb, frame, buf_size); - output_frame_header(s); - output_subframes(s); - output_frame_footer(s); - out_bytes = put_bits_count(&s->pb) >> 3; - - if(out_bytes > s->max_framesize || out_bytes >= buf_size) { + if(out_bytes > s->max_framesize) { + if(reencoded) { /* still too large. must be an error. */ av_log(avctx, AV_LOG_ERROR, "error encoding frame\n"); return -1; } + + /* frame too large. use verbatim mode */ + for(ch=0; chchannels; ch++) { + encode_residual_v(s, ch); + } + reencoded = 1; + goto write_frame; } s->frame_count++; + s->sample_count += avctx->frame_size; + update_md5_sum(s, samples); + if (out_bytes > s->max_encoded_framesize) + s->max_encoded_framesize = out_bytes; + if (out_bytes < s->min_framesize) + s->min_framesize = out_bytes; + return out_bytes; } static av_cold int flac_encode_close(AVCodecContext *avctx) { + if (avctx->priv_data) { + FlacEncodeContext *s = avctx->priv_data; + av_freep(&s->md5ctx); + } av_freep(&avctx->extradata); avctx->extradata_size = 0; av_freep(&avctx->coded_frame); @@ -1484,13 +1253,14 @@ static av_cold int flac_encode_close(AVCodecContext *avctx) AVCodec flac_encoder = { "flac", - CODEC_TYPE_AUDIO, + AVMEDIA_TYPE_AUDIO, CODEC_ID_FLAC, sizeof(FlacEncodeContext), flac_encode_init, flac_encode_frame, flac_encode_close, NULL, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME, - .long_name = "FLAC (Free Lossless Audio Codec)", + .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, + .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), };