mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
59eb12faff
* qatar/master: (30 commits) AVOptions: make default_val a union, as proposed in AVOption2. arm/h264pred: add missing argument type. h264dsp_mmx: place bracket outside #if/#endif block. lavf/utils: fix ff_interleave_compare_dts corner case. fate: add 10-bit H264 tests. h264: do not print "too many references" warning for intra-only. Enable decoding of high bit depth h264. Adds 8-, 9- and 10-bit versions of some of the functions used by the h264 decoder. Add support for higher QP values in h264. Add the notion of pixel size in h264 related functions. Make the h264 loop filter bit depth aware. Template dsputil_template.c with respect to pixel size, etc. Template h264idct_template.c with respect to pixel size, etc. Preparatory patch for high bit depth h264 decoding support. Move some functions in dsputil.c into a new file dsputil_template.c. Move the functions in h264idct into a new file h264idct_template.c. Move the functions in h264pred.c into a new file h264pred_template.c. Preparatory patch for high bit depth h264 decoding support. Add pixel formats for 9- and 10-bit yuv420p. Choose h264 chroma dc dequant function dynamically. ... Conflicts: doc/APIchanges ffmpeg.c ffplay.c libavcodec/alpha/dsputil_alpha.c libavcodec/arm/dsputil_init_arm.c libavcodec/arm/dsputil_init_armv6.c libavcodec/arm/dsputil_init_neon.c libavcodec/arm/dsputil_iwmmxt.c libavcodec/arm/h264pred_init_arm.c libavcodec/bfin/dsputil_bfin.c libavcodec/dsputil.c libavcodec/h264.c libavcodec/h264.h libavcodec/h264_cabac.c libavcodec/h264_cavlc.c libavcodec/h264_loopfilter.c libavcodec/h264_ps.c libavcodec/h264_refs.c libavcodec/h264dsp.c libavcodec/h264idct.c libavcodec/h264pred.c libavcodec/mlib/dsputil_mlib.c libavcodec/options.c libavcodec/ppc/dsputil_altivec.c libavcodec/ppc/dsputil_ppc.c libavcodec/ppc/h264_altivec.c libavcodec/ps2/dsputil_mmi.c libavcodec/sh4/dsputil_align.c libavcodec/sh4/dsputil_sh4.c libavcodec/sparc/dsputil_vis.c libavcodec/utils.c libavcodec/version.h libavcodec/x86/dsputil_mmx.c libavformat/options.c libavformat/utils.c libavutil/pixfmt.h libswscale/swscale.c libswscale/swscale_internal.h libswscale/swscale_template.c tests/ref/seek/lavf_avi Merged-by: Michael Niedermayer <michaelni@gmx.at>
1395 lines
44 KiB
C
1395 lines
44 KiB
C
/**
|
|
* FLAC audio encoder
|
|
* Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com>
|
|
*
|
|
* This file is part of FFmpeg.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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 FFmpeg; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "libavutil/crc.h"
|
|
#include "libavutil/md5.h"
|
|
#include "libavutil/opt.h"
|
|
#include "avcodec.h"
|
|
#include "get_bits.h"
|
|
#include "golomb.h"
|
|
#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 MAX_FIXED_ORDER 4
|
|
#define MAX_PARTITION_ORDER 8
|
|
#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
|
|
#define MAX_LPC_PRECISION 15
|
|
#define MAX_LPC_SHIFT 15
|
|
#define MAX_RICE_PARAM 14
|
|
|
|
typedef struct CompressionOptions {
|
|
int compression_level;
|
|
int block_time_ms;
|
|
enum FFLPCType lpc_type;
|
|
int lpc_passes;
|
|
int lpc_coeff_precision;
|
|
int min_prediction_order;
|
|
int max_prediction_order;
|
|
int prediction_order_method;
|
|
int min_partition_order;
|
|
int max_partition_order;
|
|
} CompressionOptions;
|
|
|
|
typedef struct RiceContext {
|
|
int porder;
|
|
int params[MAX_PARTITIONS];
|
|
} RiceContext;
|
|
|
|
typedef struct FlacSubframe {
|
|
int type;
|
|
int type_code;
|
|
int obits;
|
|
int order;
|
|
int32_t coefs[MAX_LPC_ORDER];
|
|
int shift;
|
|
RiceContext rc;
|
|
int32_t samples[FLAC_MAX_BLOCKSIZE];
|
|
int32_t residual[FLAC_MAX_BLOCKSIZE+1];
|
|
} FlacSubframe;
|
|
|
|
typedef struct FlacFrame {
|
|
FlacSubframe subframes[FLAC_MAX_CHANNELS];
|
|
int blocksize;
|
|
int bs_code[2];
|
|
uint8_t crc8;
|
|
int ch_mode;
|
|
int verbatim_only;
|
|
} FlacFrame;
|
|
|
|
typedef struct FlacEncodeContext {
|
|
AVClass *class;
|
|
PutBitContext pb;
|
|
int channels;
|
|
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;
|
|
LPCContext lpc_ctx;
|
|
struct AVMD5 *md5ctx;
|
|
} FlacEncodeContext;
|
|
|
|
|
|
/**
|
|
* Write streaminfo metadata block to byte array.
|
|
*/
|
|
static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
|
|
{
|
|
PutBitContext pb;
|
|
|
|
memset(header, 0, FLAC_STREAMINFO_SIZE);
|
|
init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE);
|
|
|
|
/* streaminfo metadata block */
|
|
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);
|
|
memcpy(&header[18], s->md5sum, 16);
|
|
}
|
|
|
|
|
|
/**
|
|
* Set blocksize based on samplerate.
|
|
* Choose the closest predefined blocksize >= BLOCK_TIME_MS milliseconds.
|
|
*/
|
|
static int select_blocksize(int samplerate, int block_time_ms)
|
|
{
|
|
int i;
|
|
int target;
|
|
int blocksize;
|
|
|
|
assert(samplerate > 0);
|
|
blocksize = ff_flac_blocksize_table[1];
|
|
target = (samplerate * block_time_ms) / 1000;
|
|
for (i = 0; i < 16; i++) {
|
|
if (target >= ff_flac_blocksize_table[i] &&
|
|
ff_flac_blocksize_table[i] > blocksize) {
|
|
blocksize = ff_flac_blocksize_table[i];
|
|
}
|
|
}
|
|
return blocksize;
|
|
}
|
|
|
|
|
|
static av_cold void dprint_compression_options(FlacEncodeContext *s)
|
|
{
|
|
AVCodecContext *avctx = s->avctx;
|
|
CompressionOptions *opt = &s->options;
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", opt->compression_level);
|
|
|
|
switch (opt->lpc_type) {
|
|
case FF_LPC_TYPE_NONE:
|
|
av_log(avctx, AV_LOG_DEBUG, " lpc type: None\n");
|
|
break;
|
|
case FF_LPC_TYPE_FIXED:
|
|
av_log(avctx, AV_LOG_DEBUG, " lpc type: Fixed pre-defined coefficients\n");
|
|
break;
|
|
case FF_LPC_TYPE_LEVINSON:
|
|
av_log(avctx, AV_LOG_DEBUG, " lpc type: Levinson-Durbin recursion with Welch window\n");
|
|
break;
|
|
case FF_LPC_TYPE_CHOLESKY:
|
|
av_log(avctx, AV_LOG_DEBUG, " lpc type: Cholesky factorization, %d pass%s\n",
|
|
opt->lpc_passes, opt->lpc_passes == 1 ? "" : "es");
|
|
break;
|
|
}
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n",
|
|
opt->min_prediction_order, opt->max_prediction_order);
|
|
|
|
switch (opt->prediction_order_method) {
|
|
case ORDER_METHOD_EST:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "estimate");
|
|
break;
|
|
case ORDER_METHOD_2LEVEL:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "2-level");
|
|
break;
|
|
case ORDER_METHOD_4LEVEL:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "4-level");
|
|
break;
|
|
case ORDER_METHOD_8LEVEL:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "8-level");
|
|
break;
|
|
case ORDER_METHOD_SEARCH:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "full search");
|
|
break;
|
|
case ORDER_METHOD_LOG:
|
|
av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "log search");
|
|
break;
|
|
}
|
|
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n",
|
|
opt->min_partition_order, opt->max_partition_order);
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", avctx->frame_size);
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n",
|
|
opt->lpc_coeff_precision);
|
|
}
|
|
|
|
|
|
static av_cold int flac_encode_init(AVCodecContext *avctx)
|
|
{
|
|
int freq = avctx->sample_rate;
|
|
int channels = avctx->channels;
|
|
FlacEncodeContext *s = avctx->priv_data;
|
|
int i, level, ret;
|
|
uint8_t *streaminfo;
|
|
|
|
s->avctx = avctx;
|
|
|
|
if (avctx->sample_fmt != AV_SAMPLE_FMT_S16)
|
|
return -1;
|
|
|
|
if (channels < 1 || channels > FLAC_MAX_CHANNELS)
|
|
return -1;
|
|
s->channels = channels;
|
|
|
|
/* find samplerate in table */
|
|
if (freq < 1)
|
|
return -1;
|
|
for (i = 4; i < 12; 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;
|
|
}
|
|
}
|
|
/* if not in table, samplerate is non-standard */
|
|
if (i == 12) {
|
|
if (freq % 1000 == 0 && freq < 255000) {
|
|
s->sr_code[0] = 12;
|
|
s->sr_code[1] = freq / 1000;
|
|
} else if (freq % 10 == 0 && freq < 655350) {
|
|
s->sr_code[0] = 14;
|
|
s->sr_code[1] = freq / 10;
|
|
} else if (freq < 65535) {
|
|
s->sr_code[0] = 13;
|
|
s->sr_code[1] = freq;
|
|
} else {
|
|
return -1;
|
|
}
|
|
s->samplerate = freq;
|
|
}
|
|
|
|
/* set compression option defaults based on avctx->compression_level */
|
|
if (avctx->compression_level < 0)
|
|
s->options.compression_level = 5;
|
|
else
|
|
s->options.compression_level = avctx->compression_level;
|
|
|
|
level = s->options.compression_level;
|
|
if (level > 12) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n",
|
|
s->options.compression_level);
|
|
return -1;
|
|
}
|
|
|
|
s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level];
|
|
|
|
if (s->options.lpc_type == FF_LPC_TYPE_DEFAULT)
|
|
s->options.lpc_type = ((int[]){ FF_LPC_TYPE_FIXED, FF_LPC_TYPE_FIXED, FF_LPC_TYPE_FIXED,
|
|
FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
|
|
FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
|
|
FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
|
|
FF_LPC_TYPE_LEVINSON})[level];
|
|
|
|
s->options.min_prediction_order = ((int[]){ 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})[level];
|
|
s->options.max_prediction_order = ((int[]){ 3, 4, 4, 6, 8, 8, 8, 8, 12, 12, 12, 32, 32})[level];
|
|
|
|
if (s->options.prediction_order_method < 0)
|
|
s->options.prediction_order_method = ((int[]){ ORDER_METHOD_EST, ORDER_METHOD_EST, ORDER_METHOD_EST,
|
|
ORDER_METHOD_EST, ORDER_METHOD_EST, ORDER_METHOD_EST,
|
|
ORDER_METHOD_4LEVEL, ORDER_METHOD_LOG, ORDER_METHOD_4LEVEL,
|
|
ORDER_METHOD_LOG, ORDER_METHOD_SEARCH, ORDER_METHOD_LOG,
|
|
ORDER_METHOD_SEARCH})[level];
|
|
|
|
if (s->options.min_partition_order > s->options.max_partition_order) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n",
|
|
s->options.min_partition_order, s->options.max_partition_order);
|
|
return AVERROR(EINVAL);
|
|
}
|
|
if (s->options.min_partition_order < 0)
|
|
s->options.min_partition_order = ((int[]){ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})[level];
|
|
if (s->options.max_partition_order < 0)
|
|
s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8})[level];
|
|
|
|
/* set compression option overrides from AVCodecContext */
|
|
#if FF_API_FLAC_GLOBAL_OPTS
|
|
if (avctx->lpc_type > FF_LPC_TYPE_DEFAULT) {
|
|
if (avctx->lpc_type > FF_LPC_TYPE_CHOLESKY) {
|
|
av_log(avctx, AV_LOG_ERROR, "unknown lpc type: %d\n", avctx->lpc_type);
|
|
return -1;
|
|
}
|
|
s->options.lpc_type = avctx->lpc_type;
|
|
if (s->options.lpc_type == FF_LPC_TYPE_CHOLESKY) {
|
|
if (avctx->lpc_passes < 0) {
|
|
// default number of passes for Cholesky
|
|
s->options.lpc_passes = 2;
|
|
} else if (avctx->lpc_passes == 0) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid number of lpc passes: %d\n",
|
|
avctx->lpc_passes);
|
|
return -1;
|
|
} else {
|
|
s->options.lpc_passes = avctx->lpc_passes;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
|
|
s->options.min_prediction_order = 0;
|
|
} else if (avctx->min_prediction_order >= 0) {
|
|
if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
|
|
if (avctx->min_prediction_order > MAX_FIXED_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
|
|
avctx->min_prediction_order);
|
|
return -1;
|
|
}
|
|
} else if (avctx->min_prediction_order < MIN_LPC_ORDER ||
|
|
avctx->min_prediction_order > MAX_LPC_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
|
|
avctx->min_prediction_order);
|
|
return -1;
|
|
}
|
|
s->options.min_prediction_order = avctx->min_prediction_order;
|
|
}
|
|
if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
|
|
s->options.max_prediction_order = 0;
|
|
} else if (avctx->max_prediction_order >= 0) {
|
|
if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
|
|
if (avctx->max_prediction_order > MAX_FIXED_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
|
|
avctx->max_prediction_order);
|
|
return -1;
|
|
}
|
|
} else if (avctx->max_prediction_order < MIN_LPC_ORDER ||
|
|
avctx->max_prediction_order > MAX_LPC_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
|
|
avctx->max_prediction_order);
|
|
return -1;
|
|
}
|
|
s->options.max_prediction_order = avctx->max_prediction_order;
|
|
}
|
|
if (s->options.max_prediction_order < s->options.min_prediction_order) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
|
|
s->options.min_prediction_order, s->options.max_prediction_order);
|
|
return -1;
|
|
}
|
|
|
|
#if FF_API_FLAC_GLOBAL_OPTS
|
|
if (avctx->prediction_order_method >= 0) {
|
|
if (avctx->prediction_order_method > ORDER_METHOD_LOG) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid prediction order method: %d\n",
|
|
avctx->prediction_order_method);
|
|
return -1;
|
|
}
|
|
s->options.prediction_order_method = avctx->prediction_order_method;
|
|
}
|
|
|
|
if (avctx->min_partition_order >= 0) {
|
|
if (avctx->min_partition_order > MAX_PARTITION_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid min partition order: %d\n",
|
|
avctx->min_partition_order);
|
|
return -1;
|
|
}
|
|
s->options.min_partition_order = avctx->min_partition_order;
|
|
}
|
|
if (avctx->max_partition_order >= 0) {
|
|
if (avctx->max_partition_order > MAX_PARTITION_ORDER) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid max partition order: %d\n",
|
|
avctx->max_partition_order);
|
|
return -1;
|
|
}
|
|
s->options.max_partition_order = avctx->max_partition_order;
|
|
}
|
|
if (s->options.max_partition_order < s->options.min_partition_order) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n",
|
|
s->options.min_partition_order, s->options.max_partition_order);
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
if (avctx->frame_size > 0) {
|
|
if (avctx->frame_size < FLAC_MIN_BLOCKSIZE ||
|
|
avctx->frame_size > FLAC_MAX_BLOCKSIZE) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n",
|
|
avctx->frame_size);
|
|
return -1;
|
|
}
|
|
} else {
|
|
s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms);
|
|
}
|
|
s->max_blocksize = s->avctx->frame_size;
|
|
|
|
#if FF_API_FLAC_GLOBAL_OPTS
|
|
/* set LPC precision */
|
|
if (avctx->lpc_coeff_precision > 0) {
|
|
if (avctx->lpc_coeff_precision > MAX_LPC_PRECISION) {
|
|
av_log(avctx, AV_LOG_ERROR, "invalid lpc coeff precision: %d\n",
|
|
avctx->lpc_coeff_precision);
|
|
return -1;
|
|
}
|
|
s->options.lpc_coeff_precision = avctx->lpc_coeff_precision;
|
|
}
|
|
#endif
|
|
|
|
/* set maximum encoded frame size in verbatim mode */
|
|
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);
|
|
if (!streaminfo)
|
|
return AVERROR(ENOMEM);
|
|
write_streaminfo(s, streaminfo);
|
|
avctx->extradata = streaminfo;
|
|
avctx->extradata_size = FLAC_STREAMINFO_SIZE;
|
|
|
|
s->frame_count = 0;
|
|
s->min_framesize = s->max_framesize;
|
|
|
|
avctx->coded_frame = avcodec_alloc_frame();
|
|
if (!avctx->coded_frame)
|
|
return AVERROR(ENOMEM);
|
|
|
|
if (channels == 3 &&
|
|
avctx->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) ||
|
|
channels == 4 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_2_2 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_QUAD ||
|
|
channels == 5 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_5POINT0 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_5POINT0_BACK ||
|
|
channels == 6 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_5POINT1 &&
|
|
avctx->channel_layout != AV_CH_LAYOUT_5POINT1_BACK) {
|
|
if (avctx->channel_layout) {
|
|
av_log(avctx, AV_LOG_ERROR, "Channel layout not supported by Flac, "
|
|
"output stream will have incorrect "
|
|
"channel layout.\n");
|
|
} else {
|
|
av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder "
|
|
"will use Flac channel layout for "
|
|
"%d channels.\n", channels);
|
|
}
|
|
}
|
|
|
|
ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
|
|
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
|
|
|
|
dprint_compression_options(s);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static void init_frame(FlacEncodeContext *s)
|
|
{
|
|
int i, ch;
|
|
FlacFrame *frame;
|
|
|
|
frame = &s->frame;
|
|
|
|
for (i = 0; i < 16; 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;
|
|
}
|
|
}
|
|
if (i == 16) {
|
|
frame->blocksize = s->avctx->frame_size;
|
|
if (frame->blocksize <= 256) {
|
|
frame->bs_code[0] = 6;
|
|
frame->bs_code[1] = frame->blocksize-1;
|
|
} else {
|
|
frame->bs_code[0] = 7;
|
|
frame->bs_code[1] = frame->blocksize-1;
|
|
}
|
|
}
|
|
|
|
for (ch = 0; ch < s->channels; ch++)
|
|
frame->subframes[ch].obits = 16;
|
|
|
|
frame->verbatim_only = 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Copy channel-interleaved input samples into separate subframes.
|
|
*/
|
|
static void copy_samples(FlacEncodeContext *s, const int16_t *samples)
|
|
{
|
|
int i, j, ch;
|
|
FlacFrame *frame;
|
|
|
|
frame = &s->frame;
|
|
for (i = 0, j = 0; i < frame->blocksize; i++)
|
|
for (ch = 0; ch < s->channels; ch++, j++)
|
|
frame->subframes[ch].samples[i] = samples[j];
|
|
}
|
|
|
|
|
|
static int rice_count_exact(int32_t *res, int n, int k)
|
|
{
|
|
int i;
|
|
int count = 0;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
int32_t v = -2 * res[i] - 1;
|
|
v ^= v >> 31;
|
|
count += (v >> k) + 1 + k;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
|
|
static int subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub,
|
|
int pred_order)
|
|
{
|
|
int p, porder, psize;
|
|
int i, part_end;
|
|
int count = 0;
|
|
|
|
/* subframe header */
|
|
count += 8;
|
|
|
|
/* subframe */
|
|
if (sub->type == FLAC_SUBFRAME_CONSTANT) {
|
|
count += sub->obits;
|
|
} else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
|
|
count += s->frame.blocksize * sub->obits;
|
|
} else {
|
|
/* warm-up samples */
|
|
count += pred_order * sub->obits;
|
|
|
|
/* LPC coefficients */
|
|
if (sub->type == FLAC_SUBFRAME_LPC)
|
|
count += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
|
|
|
|
/* rice-encoded block */
|
|
count += 2;
|
|
|
|
/* partition order */
|
|
porder = sub->rc.porder;
|
|
psize = s->frame.blocksize >> porder;
|
|
count += 4;
|
|
|
|
/* residual */
|
|
i = pred_order;
|
|
part_end = psize;
|
|
for (p = 0; p < 1 << porder; p++) {
|
|
int k = sub->rc.params[p];
|
|
count += 4;
|
|
count += rice_count_exact(&sub->residual[i], part_end - i, k);
|
|
i = part_end;
|
|
part_end = FFMIN(s->frame.blocksize, part_end + psize);
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
#define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))
|
|
|
|
/**
|
|
* Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0.
|
|
*/
|
|
static int find_optimal_param(uint32_t sum, int n)
|
|
{
|
|
int k;
|
|
uint32_t sum2;
|
|
|
|
if (sum <= n >> 1)
|
|
return 0;
|
|
sum2 = sum - (n >> 1);
|
|
k = av_log2(n < 256 ? FASTDIV(sum2, n) : sum2 / n);
|
|
return FFMIN(k, MAX_RICE_PARAM);
|
|
}
|
|
|
|
|
|
static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder,
|
|
uint32_t *sums, int n, int pred_order)
|
|
{
|
|
int i;
|
|
int k, cnt, part;
|
|
uint32_t all_bits;
|
|
|
|
part = (1 << porder);
|
|
all_bits = 4 * part;
|
|
|
|
cnt = (n >> porder) - pred_order;
|
|
for (i = 0; i < part; i++) {
|
|
k = find_optimal_param(sums[i], cnt);
|
|
rc->params[i] = k;
|
|
all_bits += rice_encode_count(sums[i], cnt, k);
|
|
cnt = n >> porder;
|
|
}
|
|
|
|
rc->porder = porder;
|
|
|
|
return all_bits;
|
|
}
|
|
|
|
|
|
static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order,
|
|
uint32_t sums[][MAX_PARTITIONS])
|
|
{
|
|
int i, j;
|
|
int parts;
|
|
uint32_t *res, *res_end;
|
|
|
|
/* sums for highest level */
|
|
parts = (1 << pmax);
|
|
res = &data[pred_order];
|
|
res_end = &data[n >> pmax];
|
|
for (i = 0; i < parts; i++) {
|
|
uint32_t sum = 0;
|
|
while (res < res_end)
|
|
sum += *(res++);
|
|
sums[pmax][i] = sum;
|
|
res_end += n >> pmax;
|
|
}
|
|
/* sums for lower levels */
|
|
for (i = pmax - 1; i >= pmin; i--) {
|
|
parts = (1 << i);
|
|
for (j = 0; j < parts; j++)
|
|
sums[i][j] = sums[i+1][2*j] + sums[i+1][2*j+1];
|
|
}
|
|
}
|
|
|
|
|
|
static uint32_t calc_rice_params(RiceContext *rc, int pmin, int pmax,
|
|
int32_t *data, int n, int pred_order)
|
|
{
|
|
int i;
|
|
uint32_t bits[MAX_PARTITION_ORDER+1];
|
|
int opt_porder;
|
|
RiceContext tmp_rc;
|
|
uint32_t *udata;
|
|
uint32_t sums[MAX_PARTITION_ORDER+1][MAX_PARTITIONS];
|
|
|
|
assert(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
|
|
assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
|
|
assert(pmin <= pmax);
|
|
|
|
udata = av_malloc(n * sizeof(uint32_t));
|
|
for (i = 0; i < n; i++)
|
|
udata[i] = (2*data[i]) ^ (data[i]>>31);
|
|
|
|
calc_sums(pmin, pmax, udata, n, pred_order, sums);
|
|
|
|
opt_porder = pmin;
|
|
bits[pmin] = UINT32_MAX;
|
|
for (i = pmin; i <= pmax; i++) {
|
|
bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums[i], n, pred_order);
|
|
if (bits[i] <= bits[opt_porder]) {
|
|
opt_porder = i;
|
|
*rc = tmp_rc;
|
|
}
|
|
}
|
|
|
|
av_freep(&udata);
|
|
return bits[opt_porder];
|
|
}
|
|
|
|
|
|
static int get_max_p_order(int max_porder, int n, int order)
|
|
{
|
|
int porder = FFMIN(max_porder, av_log2(n^(n-1)));
|
|
if (order > 0)
|
|
porder = FFMIN(porder, av_log2(n/order));
|
|
return porder;
|
|
}
|
|
|
|
|
|
static uint32_t find_subframe_rice_params(FlacEncodeContext *s,
|
|
FlacSubframe *sub, int pred_order)
|
|
{
|
|
int pmin = get_max_p_order(s->options.min_partition_order,
|
|
s->frame.blocksize, pred_order);
|
|
int pmax = get_max_p_order(s->options.max_partition_order,
|
|
s->frame.blocksize, pred_order);
|
|
|
|
uint32_t bits = 8 + pred_order * sub->obits + 2 + 4;
|
|
if (sub->type == FLAC_SUBFRAME_LPC)
|
|
bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
|
|
bits += calc_rice_params(&sub->rc, pmin, pmax, sub->residual,
|
|
s->frame.blocksize, pred_order);
|
|
return bits;
|
|
}
|
|
|
|
|
|
static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
|
|
int order)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < order; i++)
|
|
res[i] = smp[i];
|
|
|
|
if (order == 0) {
|
|
for (i = order; i < n; i++)
|
|
res[i] = smp[i];
|
|
} else if (order == 1) {
|
|
for (i = order; i < n; i++)
|
|
res[i] = smp[i] - smp[i-1];
|
|
} else if (order == 2) {
|
|
int a = smp[order-1] - smp[order-2];
|
|
for (i = order; i < n; i += 2) {
|
|
int b = smp[i ] - smp[i-1];
|
|
res[i] = b - a;
|
|
a = smp[i+1] - smp[i ];
|
|
res[i+1] = a - b;
|
|
}
|
|
} else if (order == 3) {
|
|
int a = smp[order-1] - smp[order-2];
|
|
int c = smp[order-1] - 2*smp[order-2] + smp[order-3];
|
|
for (i = order; i < n; i += 2) {
|
|
int b = smp[i ] - smp[i-1];
|
|
int d = b - a;
|
|
res[i] = d - c;
|
|
a = smp[i+1] - smp[i ];
|
|
c = a - b;
|
|
res[i+1] = c - d;
|
|
}
|
|
} else {
|
|
int a = smp[order-1] - smp[order-2];
|
|
int c = smp[order-1] - 2*smp[order-2] + smp[order-3];
|
|
int e = smp[order-1] - 3*smp[order-2] + 3*smp[order-3] - smp[order-4];
|
|
for (i = order; i < n; i += 2) {
|
|
int b = smp[i ] - smp[i-1];
|
|
int d = b - a;
|
|
int f = d - c;
|
|
res[i ] = f - e;
|
|
a = smp[i+1] - smp[i ];
|
|
c = a - b;
|
|
e = c - d;
|
|
res[i+1] = e - f;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#define LPC1(x) {\
|
|
int c = coefs[(x)-1];\
|
|
p0 += c * s;\
|
|
s = smp[i-(x)+1];\
|
|
p1 += c * s;\
|
|
}
|
|
|
|
static av_always_inline void encode_residual_lpc_unrolled(int32_t *res,
|
|
const int32_t *smp, int n, int order,
|
|
const int32_t *coefs, int shift, int big)
|
|
{
|
|
int i;
|
|
for (i = order; i < n; i += 2) {
|
|
int s = smp[i-order];
|
|
int p0 = 0, p1 = 0;
|
|
if (big) {
|
|
switch (order) {
|
|
case 32: LPC1(32)
|
|
case 31: LPC1(31)
|
|
case 30: LPC1(30)
|
|
case 29: LPC1(29)
|
|
case 28: LPC1(28)
|
|
case 27: LPC1(27)
|
|
case 26: LPC1(26)
|
|
case 25: LPC1(25)
|
|
case 24: LPC1(24)
|
|
case 23: LPC1(23)
|
|
case 22: LPC1(22)
|
|
case 21: LPC1(21)
|
|
case 20: LPC1(20)
|
|
case 19: LPC1(19)
|
|
case 18: LPC1(18)
|
|
case 17: LPC1(17)
|
|
case 16: LPC1(16)
|
|
case 15: LPC1(15)
|
|
case 14: LPC1(14)
|
|
case 13: LPC1(13)
|
|
case 12: LPC1(12)
|
|
case 11: LPC1(11)
|
|
case 10: LPC1(10)
|
|
case 9: LPC1( 9)
|
|
LPC1( 8)
|
|
LPC1( 7)
|
|
LPC1( 6)
|
|
LPC1( 5)
|
|
LPC1( 4)
|
|
LPC1( 3)
|
|
LPC1( 2)
|
|
LPC1( 1)
|
|
}
|
|
} else {
|
|
switch (order) {
|
|
case 8: LPC1( 8)
|
|
case 7: LPC1( 7)
|
|
case 6: LPC1( 6)
|
|
case 5: LPC1( 5)
|
|
case 4: LPC1( 4)
|
|
case 3: LPC1( 3)
|
|
case 2: LPC1( 2)
|
|
case 1: LPC1( 1)
|
|
}
|
|
}
|
|
res[i ] = smp[i ] - (p0 >> shift);
|
|
res[i+1] = smp[i+1] - (p1 >> shift);
|
|
}
|
|
}
|
|
|
|
|
|
static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n,
|
|
int order, const int32_t *coefs, int shift)
|
|
{
|
|
int i;
|
|
for (i = 0; i < order; i++)
|
|
res[i] = smp[i];
|
|
#if CONFIG_SMALL
|
|
for (i = order; i < n; i += 2) {
|
|
int j;
|
|
int s = smp[i];
|
|
int p0 = 0, p1 = 0;
|
|
for (j = 0; j < order; j++) {
|
|
int c = coefs[j];
|
|
p1 += c * s;
|
|
s = smp[i-j-1];
|
|
p0 += c * s;
|
|
}
|
|
res[i ] = smp[i ] - (p0 >> shift);
|
|
res[i+1] = smp[i+1] - (p1 >> shift);
|
|
}
|
|
#else
|
|
switch (order) {
|
|
case 1: encode_residual_lpc_unrolled(res, smp, n, 1, coefs, shift, 0); break;
|
|
case 2: encode_residual_lpc_unrolled(res, smp, n, 2, coefs, shift, 0); break;
|
|
case 3: encode_residual_lpc_unrolled(res, smp, n, 3, coefs, shift, 0); break;
|
|
case 4: encode_residual_lpc_unrolled(res, smp, n, 4, coefs, shift, 0); break;
|
|
case 5: encode_residual_lpc_unrolled(res, smp, n, 5, coefs, shift, 0); break;
|
|
case 6: encode_residual_lpc_unrolled(res, smp, n, 6, coefs, shift, 0); break;
|
|
case 7: encode_residual_lpc_unrolled(res, smp, n, 7, coefs, shift, 0); break;
|
|
case 8: encode_residual_lpc_unrolled(res, smp, n, 8, coefs, shift, 0); break;
|
|
default: encode_residual_lpc_unrolled(res, smp, n, order, coefs, shift, 1); break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
static int encode_residual_ch(FlacEncodeContext *s, int ch)
|
|
{
|
|
int i, n;
|
|
int min_order, max_order, opt_order, omethod;
|
|
FlacFrame *frame;
|
|
FlacSubframe *sub;
|
|
int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
|
|
int shift[MAX_LPC_ORDER];
|
|
int32_t *res, *smp;
|
|
|
|
frame = &s->frame;
|
|
sub = &frame->subframes[ch];
|
|
res = sub->residual;
|
|
smp = sub->samples;
|
|
n = frame->blocksize;
|
|
|
|
/* CONSTANT */
|
|
for (i = 1; i < n; i++)
|
|
if(smp[i] != smp[0])
|
|
break;
|
|
if (i == n) {
|
|
sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
|
|
res[0] = smp[0];
|
|
return subframe_count_exact(s, sub, 0);
|
|
}
|
|
|
|
/* VERBATIM */
|
|
if (frame->verbatim_only || n < 5) {
|
|
sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
|
|
memcpy(res, smp, n * sizeof(int32_t));
|
|
return subframe_count_exact(s, sub, 0);
|
|
}
|
|
|
|
min_order = s->options.min_prediction_order;
|
|
max_order = s->options.max_prediction_order;
|
|
omethod = s->options.prediction_order_method;
|
|
|
|
/* FIXED */
|
|
sub->type = FLAC_SUBFRAME_FIXED;
|
|
if (s->options.lpc_type == FF_LPC_TYPE_NONE ||
|
|
s->options.lpc_type == FF_LPC_TYPE_FIXED || n <= max_order) {
|
|
uint32_t bits[MAX_FIXED_ORDER+1];
|
|
if (max_order > MAX_FIXED_ORDER)
|
|
max_order = MAX_FIXED_ORDER;
|
|
opt_order = 0;
|
|
bits[0] = UINT32_MAX;
|
|
for (i = min_order; i <= max_order; i++) {
|
|
encode_residual_fixed(res, smp, n, i);
|
|
bits[i] = find_subframe_rice_params(s, sub, i);
|
|
if (bits[i] < bits[opt_order])
|
|
opt_order = i;
|
|
}
|
|
sub->order = opt_order;
|
|
sub->type_code = sub->type | sub->order;
|
|
if (sub->order != max_order) {
|
|
encode_residual_fixed(res, smp, n, sub->order);
|
|
find_subframe_rice_params(s, sub, sub->order);
|
|
}
|
|
return subframe_count_exact(s, sub, sub->order);
|
|
}
|
|
|
|
/* LPC */
|
|
sub->type = FLAC_SUBFRAME_LPC;
|
|
opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, smp, n, min_order, max_order,
|
|
s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
|
|
s->options.lpc_passes, omethod,
|
|
MAX_LPC_SHIFT, 0);
|
|
|
|
if (omethod == ORDER_METHOD_2LEVEL ||
|
|
omethod == ORDER_METHOD_4LEVEL ||
|
|
omethod == ORDER_METHOD_8LEVEL) {
|
|
int levels = 1 << omethod;
|
|
uint32_t bits[1 << ORDER_METHOD_8LEVEL];
|
|
int order;
|
|
int opt_index = levels-1;
|
|
opt_order = max_order-1;
|
|
bits[opt_index] = UINT32_MAX;
|
|
for (i = levels-1; i >= 0; i--) {
|
|
order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1;
|
|
if (order < 0)
|
|
order = 0;
|
|
encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]);
|
|
bits[i] = find_subframe_rice_params(s, sub, order+1);
|
|
if (bits[i] < bits[opt_index]) {
|
|
opt_index = i;
|
|
opt_order = order;
|
|
}
|
|
}
|
|
opt_order++;
|
|
} else if (omethod == ORDER_METHOD_SEARCH) {
|
|
// brute-force optimal order search
|
|
uint32_t bits[MAX_LPC_ORDER];
|
|
opt_order = 0;
|
|
bits[0] = UINT32_MAX;
|
|
for (i = min_order-1; i < max_order; i++) {
|
|
encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
|
|
bits[i] = find_subframe_rice_params(s, sub, i+1);
|
|
if (bits[i] < bits[opt_order])
|
|
opt_order = i;
|
|
}
|
|
opt_order++;
|
|
} else if (omethod == ORDER_METHOD_LOG) {
|
|
uint32_t bits[MAX_LPC_ORDER];
|
|
int step;
|
|
|
|
opt_order = min_order - 1 + (max_order-min_order)/3;
|
|
memset(bits, -1, sizeof(bits));
|
|
|
|
for (step = 16; step; step >>= 1) {
|
|
int last = opt_order;
|
|
for (i = last-step; i <= last+step; i += step) {
|
|
if (i < min_order-1 || i >= max_order || bits[i] < UINT32_MAX)
|
|
continue;
|
|
encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
|
|
bits[i] = find_subframe_rice_params(s, sub, i+1);
|
|
if (bits[i] < bits[opt_order])
|
|
opt_order = i;
|
|
}
|
|
}
|
|
opt_order++;
|
|
}
|
|
|
|
sub->order = opt_order;
|
|
sub->type_code = sub->type | (sub->order-1);
|
|
sub->shift = shift[sub->order-1];
|
|
for (i = 0; i < sub->order; i++)
|
|
sub->coefs[i] = coefs[sub->order-1][i];
|
|
|
|
encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift);
|
|
|
|
find_subframe_rice_params(s, sub, sub->order);
|
|
|
|
return subframe_count_exact(s, sub, sub->order);
|
|
}
|
|
|
|
|
|
static int count_frame_header(FlacEncodeContext *s)
|
|
{
|
|
uint8_t tmp;
|
|
int count;
|
|
|
|
/*
|
|
<14> Sync code
|
|
<1> Reserved
|
|
<1> Blocking strategy
|
|
<4> Block size in inter-channel samples
|
|
<4> Sample rate
|
|
<4> Channel assignment
|
|
<3> Sample size in bits
|
|
<1> Reserved
|
|
*/
|
|
count = 32;
|
|
|
|
/* coded frame number */
|
|
PUT_UTF8(s->frame_count, tmp, count += 8;)
|
|
|
|
/* explicit block size */
|
|
if (s->frame.bs_code[0] == 6)
|
|
count += 8;
|
|
else if (s->frame.bs_code[0] == 7)
|
|
count += 16;
|
|
|
|
/* explicit sample rate */
|
|
count += ((s->sr_code[0] == 12) + (s->sr_code[0] > 12)) * 8;
|
|
|
|
/* frame header CRC-8 */
|
|
count += 8;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int encode_frame(FlacEncodeContext *s)
|
|
{
|
|
int ch, count;
|
|
|
|
count = count_frame_header(s);
|
|
|
|
for (ch = 0; ch < s->channels; ch++)
|
|
count += encode_residual_ch(s, ch);
|
|
|
|
count += (8 - (count & 7)) & 7; // byte alignment
|
|
count += 16; // CRC-16
|
|
|
|
return count >> 3;
|
|
}
|
|
|
|
|
|
static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
|
|
{
|
|
int i, best;
|
|
int32_t lt, rt;
|
|
uint64_t sum[4];
|
|
uint64_t score[4];
|
|
int k;
|
|
|
|
/* calculate sum of 2nd order residual for each channel */
|
|
sum[0] = sum[1] = sum[2] = sum[3] = 0;
|
|
for (i = 2; i < n; i++) {
|
|
lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
|
|
rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
|
|
sum[2] += FFABS((lt + rt) >> 1);
|
|
sum[3] += FFABS(lt - rt);
|
|
sum[0] += FFABS(lt);
|
|
sum[1] += FFABS(rt);
|
|
}
|
|
/* estimate bit counts */
|
|
for (i = 0; i < 4; i++) {
|
|
k = find_optimal_param(2 * sum[i], n);
|
|
sum[i] = rice_encode_count( 2 * sum[i], n, k);
|
|
}
|
|
|
|
/* calculate score for each mode */
|
|
score[0] = sum[0] + sum[1];
|
|
score[1] = sum[0] + sum[3];
|
|
score[2] = sum[1] + sum[3];
|
|
score[3] = sum[2] + sum[3];
|
|
|
|
/* return mode with lowest score */
|
|
best = 0;
|
|
for (i = 1; i < 4; i++)
|
|
if (score[i] < score[best])
|
|
best = i;
|
|
if (best == 0) {
|
|
return FLAC_CHMODE_INDEPENDENT;
|
|
} else if (best == 1) {
|
|
return FLAC_CHMODE_LEFT_SIDE;
|
|
} else if (best == 2) {
|
|
return FLAC_CHMODE_RIGHT_SIDE;
|
|
} else {
|
|
return FLAC_CHMODE_MID_SIDE;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Perform stereo channel decorrelation.
|
|
*/
|
|
static void channel_decorrelation(FlacEncodeContext *s)
|
|
{
|
|
FlacFrame *frame;
|
|
int32_t *left, *right;
|
|
int i, n;
|
|
|
|
frame = &s->frame;
|
|
n = frame->blocksize;
|
|
left = frame->subframes[0].samples;
|
|
right = frame->subframes[1].samples;
|
|
|
|
if (s->channels != 2) {
|
|
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_INDEPENDENT)
|
|
return;
|
|
if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
|
|
int32_t tmp;
|
|
for (i = 0; i < n; i++) {
|
|
tmp = left[i];
|
|
left[i] = (tmp + right[i]) >> 1;
|
|
right[i] = tmp - right[i];
|
|
}
|
|
frame->subframes[1].obits++;
|
|
} else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
|
|
for (i = 0; i < n; i++)
|
|
right[i] = left[i] - right[i];
|
|
frame->subframes[1].obits++;
|
|
} else {
|
|
for (i = 0; i < n; i++)
|
|
left[i] -= right[i];
|
|
frame->subframes[0].obits++;
|
|
}
|
|
}
|
|
|
|
|
|
static void write_utf8(PutBitContext *pb, uint32_t val)
|
|
{
|
|
uint8_t tmp;
|
|
PUT_UTF8(val, tmp, put_bits(pb, 8, tmp);)
|
|
}
|
|
|
|
|
|
static void write_frame_header(FlacEncodeContext *s)
|
|
{
|
|
FlacFrame *frame;
|
|
int crc;
|
|
|
|
frame = &s->frame;
|
|
|
|
put_bits(&s->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_INDEPENDENT)
|
|
put_bits(&s->pb, 4, s->channels-1);
|
|
else
|
|
put_bits(&s->pb, 4, frame->ch_mode);
|
|
|
|
put_bits(&s->pb, 3, 4); /* bits-per-sample code */
|
|
put_bits(&s->pb, 1, 0);
|
|
write_utf8(&s->pb, s->frame_count);
|
|
|
|
if (frame->bs_code[0] == 6)
|
|
put_bits(&s->pb, 8, frame->bs_code[1]);
|
|
else if (frame->bs_code[0] == 7)
|
|
put_bits(&s->pb, 16, frame->bs_code[1]);
|
|
|
|
if (s->sr_code[0] == 12)
|
|
put_bits(&s->pb, 8, s->sr_code[1]);
|
|
else if (s->sr_code[0] > 12)
|
|
put_bits(&s->pb, 16, s->sr_code[1]);
|
|
|
|
flush_put_bits(&s->pb);
|
|
crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, s->pb.buf,
|
|
put_bits_count(&s->pb) >> 3);
|
|
put_bits(&s->pb, 8, crc);
|
|
}
|
|
|
|
|
|
static void write_subframes(FlacEncodeContext *s)
|
|
{
|
|
int ch;
|
|
|
|
for (ch = 0; ch < s->channels; ch++) {
|
|
FlacSubframe *sub = &s->frame.subframes[ch];
|
|
int i, p, porder, psize;
|
|
int32_t *part_end;
|
|
int32_t *res = sub->residual;
|
|
int32_t *frame_end = &sub->residual[s->frame.blocksize];
|
|
|
|
/* subframe header */
|
|
put_bits(&s->pb, 1, 0);
|
|
put_bits(&s->pb, 6, sub->type_code);
|
|
put_bits(&s->pb, 1, 0); /* no wasted bits */
|
|
|
|
/* subframe */
|
|
if (sub->type == FLAC_SUBFRAME_CONSTANT) {
|
|
put_sbits(&s->pb, sub->obits, res[0]);
|
|
} else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
|
|
while (res < frame_end)
|
|
put_sbits(&s->pb, sub->obits, *res++);
|
|
} else {
|
|
/* warm-up samples */
|
|
for (i = 0; i < sub->order; i++)
|
|
put_sbits(&s->pb, sub->obits, *res++);
|
|
|
|
/* LPC coefficients */
|
|
if (sub->type == FLAC_SUBFRAME_LPC) {
|
|
int cbits = s->options.lpc_coeff_precision;
|
|
put_bits( &s->pb, 4, cbits-1);
|
|
put_sbits(&s->pb, 5, sub->shift);
|
|
for (i = 0; i < sub->order; i++)
|
|
put_sbits(&s->pb, cbits, sub->coefs[i]);
|
|
}
|
|
|
|
/* rice-encoded block */
|
|
put_bits(&s->pb, 2, 0);
|
|
|
|
/* partition order */
|
|
porder = sub->rc.porder;
|
|
psize = s->frame.blocksize >> porder;
|
|
put_bits(&s->pb, 4, porder);
|
|
|
|
/* residual */
|
|
part_end = &sub->residual[psize];
|
|
for (p = 0; p < 1 << porder; p++) {
|
|
int k = sub->rc.params[p];
|
|
put_bits(&s->pb, 4, k);
|
|
while (res < part_end)
|
|
set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0);
|
|
part_end = FFMIN(frame_end, part_end + psize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void write_frame_footer(FlacEncodeContext *s)
|
|
{
|
|
int crc;
|
|
flush_put_bits(&s->pb);
|
|
crc = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, s->pb.buf,
|
|
put_bits_count(&s->pb)>>3));
|
|
put_bits(&s->pb, 16, crc);
|
|
flush_put_bits(&s->pb);
|
|
}
|
|
|
|
|
|
static int write_frame(FlacEncodeContext *s, uint8_t *frame, int buf_size)
|
|
{
|
|
init_put_bits(&s->pb, frame, buf_size);
|
|
write_frame_header(s);
|
|
write_subframes(s);
|
|
write_frame_footer(s);
|
|
return put_bits_count(&s->pb) >> 3;
|
|
}
|
|
|
|
|
|
static void update_md5_sum(FlacEncodeContext *s, const int16_t *samples)
|
|
{
|
|
#if HAVE_BIGENDIAN
|
|
int i;
|
|
for (i = 0; i < s->frame.blocksize * s->channels; i++) {
|
|
int16_t smp = av_le2ne16(samples[i]);
|
|
av_md5_update(s->md5ctx, (uint8_t *)&smp, 2);
|
|
}
|
|
#else
|
|
av_md5_update(s->md5ctx, (const 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)
|
|
{
|
|
FlacEncodeContext *s;
|
|
const int16_t *samples = data;
|
|
int frame_bytes, out_bytes;
|
|
|
|
s = avctx->priv_data;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/* change max_framesize for small final frame */
|
|
if (avctx->frame_size < s->frame.blocksize) {
|
|
s->max_framesize = ff_flac_get_max_frame_size(avctx->frame_size,
|
|
s->channels, 16);
|
|
}
|
|
|
|
init_frame(s);
|
|
|
|
copy_samples(s, samples);
|
|
|
|
channel_decorrelation(s);
|
|
|
|
frame_bytes = encode_frame(s);
|
|
|
|
/* fallback to verbatim mode if the compressed frame is larger than it
|
|
would be if encoded uncompressed. */
|
|
if (frame_bytes > s->max_framesize) {
|
|
s->frame.verbatim_only = 1;
|
|
frame_bytes = encode_frame(s);
|
|
}
|
|
|
|
if (buf_size < frame_bytes) {
|
|
av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");
|
|
return 0;
|
|
}
|
|
out_bytes = write_frame(s, frame, buf_size);
|
|
|
|
s->frame_count++;
|
|
avctx->coded_frame->pts = s->sample_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);
|
|
ff_lpc_end(&s->lpc_ctx);
|
|
}
|
|
av_freep(&avctx->extradata);
|
|
avctx->extradata_size = 0;
|
|
av_freep(&avctx->coded_frame);
|
|
return 0;
|
|
}
|
|
|
|
#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
|
|
static const AVOption options[] = {
|
|
{ "lpc_coeff_precision", "LPC coefficient precision", offsetof(FlacEncodeContext, options.lpc_coeff_precision), FF_OPT_TYPE_INT, 15, 0, MAX_LPC_PRECISION, FLAGS },
|
|
{ "lpc_type", "LPC algorithm", offsetof(FlacEncodeContext, options.lpc_type), FF_OPT_TYPE_INT, FF_LPC_TYPE_DEFAULT, FF_LPC_TYPE_DEFAULT, FF_LPC_TYPE_NB-1, FLAGS, "lpc_type" },
|
|
{ "none", NULL, 0, FF_OPT_TYPE_CONST, FF_LPC_TYPE_NONE, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
|
|
{ "fixed", NULL, 0, FF_OPT_TYPE_CONST, FF_LPC_TYPE_FIXED, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
|
|
{ "levinson", NULL, 0, FF_OPT_TYPE_CONST, FF_LPC_TYPE_LEVINSON, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
|
|
{ "cholesky", NULL, 0, FF_OPT_TYPE_CONST, FF_LPC_TYPE_CHOLESKY, INT_MIN, INT_MAX, FLAGS, "lpc_type" },
|
|
{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, FLAGS },
|
|
{ "min_partition_order", NULL, offsetof(FlacEncodeContext, options.min_partition_order), FF_OPT_TYPE_INT, -1, -1, MAX_PARTITION_ORDER, FLAGS },
|
|
{ "max_partition_order", NULL, offsetof(FlacEncodeContext, options.max_partition_order), FF_OPT_TYPE_INT, -1, -1, MAX_PARTITION_ORDER, FLAGS },
|
|
{ "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), FF_OPT_TYPE_INT, -1, -1, ORDER_METHOD_LOG, FLAGS, "predm" },
|
|
{ "estimation", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_EST, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ "2level", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_2LEVEL, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ "4level", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_4LEVEL, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ "8level", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_8LEVEL, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ "search", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_SEARCH, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ "log", NULL, 0, FF_OPT_TYPE_CONST, ORDER_METHOD_LOG, INT_MIN, INT_MAX, FLAGS, "predm" },
|
|
{ NULL },
|
|
};
|
|
|
|
static const AVClass flac_encoder_class = {
|
|
"FLAC encoder",
|
|
av_default_item_name,
|
|
options,
|
|
LIBAVUTIL_VERSION_INT,
|
|
};
|
|
|
|
AVCodec ff_flac_encoder = {
|
|
"flac",
|
|
AVMEDIA_TYPE_AUDIO,
|
|
CODEC_ID_FLAC,
|
|
sizeof(FlacEncodeContext),
|
|
flac_encode_init,
|
|
flac_encode_frame,
|
|
flac_encode_close,
|
|
NULL,
|
|
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
|
|
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
|
|
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
|
|
.priv_class = &flac_encoder_class,
|
|
};
|