|
|
|
@@ -32,6 +32,7 @@ |
|
|
|
#include "lpc.h" |
|
|
|
#include "flac.h" |
|
|
|
#include "flacdata.h" |
|
|
|
#include "flacdsp.h" |
|
|
|
|
|
|
|
#define FLAC_SUBFRAME_CONSTANT 0 |
|
|
|
#define FLAC_SUBFRAME_VERBATIM 1 |
|
|
|
@@ -43,7 +44,11 @@ |
|
|
|
#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) |
|
|
|
#define MAX_LPC_PRECISION 15 |
|
|
|
#define MAX_LPC_SHIFT 15 |
|
|
|
#define MAX_RICE_PARAM 14 |
|
|
|
|
|
|
|
enum CodingMode { |
|
|
|
CODING_MODE_RICE = 4, |
|
|
|
CODING_MODE_RICE2 = 5, |
|
|
|
}; |
|
|
|
|
|
|
|
typedef struct CompressionOptions { |
|
|
|
int compression_level; |
|
|
|
@@ -60,6 +65,7 @@ typedef struct CompressionOptions { |
|
|
|
} CompressionOptions; |
|
|
|
|
|
|
|
typedef struct RiceContext { |
|
|
|
enum CodingMode coding_mode; |
|
|
|
int porder; |
|
|
|
int params[MAX_PARTITIONS]; |
|
|
|
} RiceContext; |
|
|
|
@@ -92,6 +98,7 @@ typedef struct FlacEncodeContext { |
|
|
|
int channels; |
|
|
|
int samplerate; |
|
|
|
int sr_code[2]; |
|
|
|
int bps_code; |
|
|
|
int max_blocksize; |
|
|
|
int min_framesize; |
|
|
|
int max_framesize; |
|
|
|
@@ -107,6 +114,7 @@ typedef struct FlacEncodeContext { |
|
|
|
uint8_t *md5_buffer; |
|
|
|
unsigned int md5_buffer_size; |
|
|
|
DSPContext dsp; |
|
|
|
FLACDSPContext flac_dsp; |
|
|
|
} FlacEncodeContext; |
|
|
|
|
|
|
|
|
|
|
|
@@ -127,7 +135,7 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header) |
|
|
|
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 */ |
|
|
|
put_bits(&pb, 5, s->avctx->bits_per_raw_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); |
|
|
|
@@ -227,8 +235,18 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
s->avctx = avctx; |
|
|
|
|
|
|
|
if (avctx->sample_fmt != AV_SAMPLE_FMT_S16) |
|
|
|
return -1; |
|
|
|
switch (avctx->sample_fmt) { |
|
|
|
case AV_SAMPLE_FMT_S16: |
|
|
|
avctx->bits_per_raw_sample = 16; |
|
|
|
s->bps_code = 4; |
|
|
|
break; |
|
|
|
case AV_SAMPLE_FMT_S32: |
|
|
|
if (avctx->bits_per_raw_sample != 24) |
|
|
|
av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n"); |
|
|
|
avctx->bits_per_raw_sample = 24; |
|
|
|
s->bps_code = 6; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (channels < 1 || channels > FLAC_MAX_CHANNELS) |
|
|
|
return -1; |
|
|
|
@@ -358,7 +376,8 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
/* set maximum encoded frame size in verbatim mode */ |
|
|
|
s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size, |
|
|
|
s->channels, 16); |
|
|
|
s->channels, |
|
|
|
s->avctx->bits_per_raw_sample); |
|
|
|
|
|
|
|
/* initialize MD5 context */ |
|
|
|
s->md5ctx = av_md5_alloc(); |
|
|
|
@@ -408,6 +427,8 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON); |
|
|
|
|
|
|
|
ff_dsputil_init(&s->dsp, avctx); |
|
|
|
ff_flacdsp_init(&s->flac_dsp, avctx->sample_fmt, |
|
|
|
avctx->bits_per_raw_sample); |
|
|
|
|
|
|
|
dprint_compression_options(s); |
|
|
|
|
|
|
|
@@ -442,8 +463,15 @@ static void init_frame(FlacEncodeContext *s, int nb_samples) |
|
|
|
} |
|
|
|
|
|
|
|
for (ch = 0; ch < s->channels; ch++) { |
|
|
|
frame->subframes[ch].wasted = 0; |
|
|
|
frame->subframes[ch].obits = 16; |
|
|
|
FlacSubframe *sub = &frame->subframes[ch]; |
|
|
|
|
|
|
|
sub->wasted = 0; |
|
|
|
sub->obits = s->avctx->bits_per_raw_sample; |
|
|
|
|
|
|
|
if (sub->obits > 16) |
|
|
|
sub->rc.coding_mode = CODING_MODE_RICE2; |
|
|
|
else |
|
|
|
sub->rc.coding_mode = CODING_MODE_RICE; |
|
|
|
} |
|
|
|
|
|
|
|
frame->verbatim_only = 0; |
|
|
|
@@ -453,15 +481,25 @@ static void init_frame(FlacEncodeContext *s, int nb_samples) |
|
|
|
/** |
|
|
|
* Copy channel-interleaved input samples into separate subframes. |
|
|
|
*/ |
|
|
|
static void copy_samples(FlacEncodeContext *s, const int16_t *samples) |
|
|
|
static void copy_samples(FlacEncodeContext *s, const void *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]; |
|
|
|
int shift = av_get_bytes_per_sample(s->avctx->sample_fmt) * 8 - |
|
|
|
s->avctx->bits_per_raw_sample; |
|
|
|
|
|
|
|
#define COPY_SAMPLES(bits) do { \ |
|
|
|
const int ## bits ## _t *samples0 = samples; \ |
|
|
|
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] = samples0[j] >> shift; \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
if (s->avctx->sample_fmt == AV_SAMPLE_FMT_S16) |
|
|
|
COPY_SAMPLES(16); |
|
|
|
else |
|
|
|
COPY_SAMPLES(32); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@@ -515,7 +553,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub, |
|
|
|
part_end = psize; |
|
|
|
for (p = 0; p < 1 << porder; p++) { |
|
|
|
int k = sub->rc.params[p]; |
|
|
|
count += 4; |
|
|
|
count += sub->rc.coding_mode; |
|
|
|
count += rice_count_exact(&sub->residual[i], part_end - i, k); |
|
|
|
i = part_end; |
|
|
|
part_end = FFMIN(s->frame.blocksize, part_end + psize); |
|
|
|
@@ -531,7 +569,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub, |
|
|
|
/** |
|
|
|
* Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0. |
|
|
|
*/ |
|
|
|
static int find_optimal_param(uint64_t sum, int n) |
|
|
|
static int find_optimal_param(uint64_t sum, int n, int max_param) |
|
|
|
{ |
|
|
|
int k; |
|
|
|
uint64_t sum2; |
|
|
|
@@ -540,7 +578,7 @@ static int find_optimal_param(uint64_t sum, int n) |
|
|
|
return 0; |
|
|
|
sum2 = sum - (n >> 1); |
|
|
|
k = av_log2(av_clipl_int32(sum2 / n)); |
|
|
|
return FFMIN(k, MAX_RICE_PARAM); |
|
|
|
return FFMIN(k, max_param); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@@ -548,15 +586,17 @@ static uint64_t calc_optimal_rice_params(RiceContext *rc, int porder, |
|
|
|
uint64_t *sums, int n, int pred_order) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int k, cnt, part; |
|
|
|
int k, cnt, part, max_param; |
|
|
|
uint64_t all_bits; |
|
|
|
|
|
|
|
max_param = (1 << rc->coding_mode) - 2; |
|
|
|
|
|
|
|
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); |
|
|
|
k = find_optimal_param(sums[i], cnt, max_param); |
|
|
|
rc->params[i] = k; |
|
|
|
all_bits += rice_encode_count(sums[i], cnt, k); |
|
|
|
cnt = n >> porder; |
|
|
|
@@ -609,6 +649,8 @@ static uint64_t calc_rice_params(RiceContext *rc, int pmin, int pmax, |
|
|
|
av_assert1(pmax >= 0 && pmax <= MAX_PARTITION_ORDER); |
|
|
|
av_assert1(pmin <= pmax); |
|
|
|
|
|
|
|
tmp_rc.coding_mode = rc->coding_mode; |
|
|
|
|
|
|
|
udata = av_malloc(n * sizeof(uint32_t)); |
|
|
|
for (i = 0; i < n; i++) |
|
|
|
udata[i] = (2*data[i]) ^ (data[i]>>31); |
|
|
|
@@ -647,7 +689,7 @@ static uint64_t find_subframe_rice_params(FlacEncodeContext *s, |
|
|
|
int pmax = get_max_p_order(s->options.max_partition_order, |
|
|
|
s->frame.blocksize, pred_order); |
|
|
|
|
|
|
|
uint64_t bits = 8 + pred_order * sub->obits + 2 + 4; |
|
|
|
uint64_t bits = 8 + pred_order * sub->obits + 2 + sub->rc.coding_mode; |
|
|
|
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, |
|
|
|
@@ -707,110 +749,6 @@ static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#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; |
|
|
|
@@ -892,7 +830,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) |
|
|
|
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]); |
|
|
|
s->flac_dsp.lpc_encode(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; |
|
|
|
@@ -906,7 +845,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) |
|
|
|
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]); |
|
|
|
s->flac_dsp.lpc_encode(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; |
|
|
|
@@ -924,7 +863,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) |
|
|
|
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]); |
|
|
|
s->flac_dsp.lpc_encode(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; |
|
|
|
@@ -939,7 +878,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) |
|
|
|
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); |
|
|
|
s->flac_dsp.lpc_encode(res, smp, n, sub->order, sub->coefs, sub->shift); |
|
|
|
|
|
|
|
find_subframe_rice_params(s, sub, sub->order); |
|
|
|
|
|
|
|
@@ -1025,12 +964,18 @@ static void remove_wasted_bits(FlacEncodeContext *s) |
|
|
|
|
|
|
|
sub->wasted = v; |
|
|
|
sub->obits -= v; |
|
|
|
|
|
|
|
/* for 24-bit, check if removing wasted bits makes the range better |
|
|
|
suited for using RICE instead of RICE2 for entropy coding */ |
|
|
|
if (sub->obits <= 17) |
|
|
|
sub->rc.coding_mode = CODING_MODE_RICE; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) |
|
|
|
static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n, |
|
|
|
int max_rice_param) |
|
|
|
{ |
|
|
|
int i, best; |
|
|
|
int32_t lt, rt; |
|
|
|
@@ -1050,7 +995,7 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) |
|
|
|
} |
|
|
|
/* estimate bit counts */ |
|
|
|
for (i = 0; i < 4; i++) { |
|
|
|
k = find_optimal_param(2 * sum[i], n); |
|
|
|
k = find_optimal_param(2 * sum[i], n, max_rice_param); |
|
|
|
sum[i] = rice_encode_count( 2 * sum[i], n, k); |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1089,9 +1034,10 @@ static void channel_decorrelation(FlacEncodeContext *s) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (s->options.ch_mode < 0) |
|
|
|
frame->ch_mode = estimate_stereo_mode(left, right, n); |
|
|
|
else |
|
|
|
if (s->options.ch_mode < 0) { |
|
|
|
int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2; |
|
|
|
frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param); |
|
|
|
} else |
|
|
|
frame->ch_mode = s->options.ch_mode; |
|
|
|
|
|
|
|
/* perform decorrelation and adjust bits-per-sample */ |
|
|
|
@@ -1140,7 +1086,7 @@ static void write_frame_header(FlacEncodeContext *s) |
|
|
|
else |
|
|
|
put_bits(&s->pb, 4, frame->ch_mode + FLAC_MAX_CHANNELS - 1); |
|
|
|
|
|
|
|
put_bits(&s->pb, 3, 4); /* bits-per-sample code */ |
|
|
|
put_bits(&s->pb, 3, s->bps_code); |
|
|
|
put_bits(&s->pb, 1, 0); |
|
|
|
write_utf8(&s->pb, s->frame_count); |
|
|
|
|
|
|
|
@@ -1200,7 +1146,7 @@ static void write_subframes(FlacEncodeContext *s) |
|
|
|
} |
|
|
|
|
|
|
|
/* rice-encoded block */ |
|
|
|
put_bits(&s->pb, 2, 0); |
|
|
|
put_bits(&s->pb, 2, sub->rc.coding_mode - 4); |
|
|
|
|
|
|
|
/* partition order */ |
|
|
|
porder = sub->rc.porder; |
|
|
|
@@ -1211,7 +1157,7 @@ static void write_subframes(FlacEncodeContext *s) |
|
|
|
part_end = &sub->residual[psize]; |
|
|
|
for (p = 0; p < 1 << porder; p++) { |
|
|
|
int k = sub->rc.params[p]; |
|
|
|
put_bits(&s->pb, 4, k); |
|
|
|
put_bits(&s->pb, sub->rc.coding_mode, k); |
|
|
|
while (res < part_end) |
|
|
|
set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0); |
|
|
|
part_end = FFMIN(frame_end, part_end + psize); |
|
|
|
@@ -1242,23 +1188,38 @@ static int write_frame(FlacEncodeContext *s, AVPacket *avpkt) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int update_md5_sum(FlacEncodeContext *s, const int16_t *samples) |
|
|
|
static int update_md5_sum(FlacEncodeContext *s, const void *samples) |
|
|
|
{ |
|
|
|
const uint8_t *buf; |
|
|
|
int buf_size = s->frame.blocksize * s->channels * 2; |
|
|
|
int buf_size = s->frame.blocksize * s->channels * |
|
|
|
((s->avctx->bits_per_raw_sample + 7) / 8); |
|
|
|
|
|
|
|
if (HAVE_BIGENDIAN) { |
|
|
|
if (s->avctx->bits_per_raw_sample > 16 || HAVE_BIGENDIAN) { |
|
|
|
av_fast_malloc(&s->md5_buffer, &s->md5_buffer_size, buf_size); |
|
|
|
if (!s->md5_buffer) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} |
|
|
|
|
|
|
|
buf = (const uint8_t *)samples; |
|
|
|
if (s->avctx->bits_per_raw_sample <= 16) { |
|
|
|
buf = (const uint8_t *)samples; |
|
|
|
#if HAVE_BIGENDIAN |
|
|
|
s->dsp.bswap16_buf((uint16_t *)s->md5_buffer, |
|
|
|
(const uint16_t *)samples, buf_size / 2); |
|
|
|
buf = s->md5_buffer; |
|
|
|
s->dsp.bswap16_buf((uint16_t *)s->md5_buffer, |
|
|
|
(const uint16_t *)samples, buf_size / 2); |
|
|
|
buf = s->md5_buffer; |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
int i; |
|
|
|
const int32_t *samples0 = samples; |
|
|
|
uint8_t *tmp = s->md5_buffer; |
|
|
|
|
|
|
|
for (i = 0; i < s->frame.blocksize * s->channels; i++) { |
|
|
|
int32_t v = samples0[i] >> 8; |
|
|
|
*tmp++ = (v ) & 0xFF; |
|
|
|
*tmp++ = (v >> 8) & 0xFF; |
|
|
|
*tmp++ = (v >> 16) & 0xFF; |
|
|
|
} |
|
|
|
buf = s->md5_buffer; |
|
|
|
} |
|
|
|
av_md5_update(s->md5ctx, buf, buf_size); |
|
|
|
|
|
|
|
return 0; |
|
|
|
@@ -1269,7 +1230,6 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
const AVFrame *frame, int *got_packet_ptr) |
|
|
|
{ |
|
|
|
FlacEncodeContext *s; |
|
|
|
const int16_t *samples; |
|
|
|
int frame_bytes, out_bytes, ret; |
|
|
|
|
|
|
|
s = avctx->priv_data; |
|
|
|
@@ -1281,17 +1241,17 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
write_streaminfo(s, avctx->extradata); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
samples = (const int16_t *)frame->data[0]; |
|
|
|
|
|
|
|
/* change max_framesize for small final frame */ |
|
|
|
if (frame->nb_samples < s->frame.blocksize) { |
|
|
|
s->max_framesize = ff_flac_get_max_frame_size(frame->nb_samples, |
|
|
|
s->channels, 16); |
|
|
|
s->channels, |
|
|
|
avctx->bits_per_raw_sample); |
|
|
|
} |
|
|
|
|
|
|
|
init_frame(s, frame->nb_samples); |
|
|
|
|
|
|
|
copy_samples(s, samples); |
|
|
|
copy_samples(s, frame->data[0]); |
|
|
|
|
|
|
|
channel_decorrelation(s); |
|
|
|
|
|
|
|
@@ -1317,7 +1277,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
|
|
|
|
s->frame_count++; |
|
|
|
s->sample_count += frame->nb_samples; |
|
|
|
if ((ret = update_md5_sum(s, samples)) < 0) { |
|
|
|
if ((ret = update_md5_sum(s, frame->data[0])) < 0) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Error updating MD5 checksum\n"); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
@@ -1394,6 +1354,7 @@ AVCodec ff_flac_encoder = { |
|
|
|
.close = flac_encode_close, |
|
|
|
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_LOSSLESS, |
|
|
|
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, |
|
|
|
AV_SAMPLE_FMT_S32, |
|
|
|
AV_SAMPLE_FMT_NONE }, |
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), |
|
|
|
.priv_class = &flac_encoder_class, |
|
|
|
|