*/
#include "libavutil/crc.h"
-#include "libavutil/lls.h"
+#include "libavutil/md5.h"
#include "avcodec.h"
-#include "bitstream.h"
+#include "get_bits.h"
#include "dsputil.h"
#include "golomb.h"
#include "lpc.h"
-
-#define FLAC_MAX_CH 8
-#define FLAC_MIN_BLOCKSIZE 16
-#define FLAC_MAX_BLOCKSIZE 65535
+#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 FLAC_STREAMINFO_SIZE 34
-
#define MAX_FIXED_ORDER 4
#define MAX_PARTITION_ORDER 8
#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
} FlacSubframe;
typedef struct FlacFrame {
- FlacSubframe subframes[FLAC_MAX_CH];
+ FlacSubframe subframes[FLAC_MAX_CHANNELS];
int blocksize;
int bs_code[2];
uint8_t crc8;
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
*/
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, 24, (s->sample_count & 0xFFFFFF000LL) >> 12);
put_bits(&pb, 12, s->sample_count & 0x000000FFFLL);
flush_put_bits(&pb);
- /* MD5 signature = 0 */
+ memcpy(&header[18], s->md5sum, 16);
}
/**
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;
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;
} 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 */
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_NOMEM;
+ av_md5_init(s->md5ctx);
streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
write_streaminfo(s, streaminfo);
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;
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;
for(j=0; j<lag; j+=2){
double sum0 = 1.0, sum1 = 1.0;
- for(i=0; i<len; i++){
+ for(i=j; i<len; i++){
sum0 += data1[i] * data1[i-j];
sum1 += data1[i] * data1[i-j-1];
}
if(j==lag){
double sum = 1.0;
- for(i=0; i<len; i+=2){
+ for(i=j-1; i<len; i+=2){
sum += data1[i ] * data1[i-j ]
+ data1[i+1] * data1[i-j+1];
}
for(i=0; i<order; i++) {
res[i] = smp[i];
}
-#ifdef CONFIG_SMALL
+#if CONFIG_SMALL
for(i=order; i<n; i+=2) {
int j;
int s = smp[i];
}
}
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) {
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) {
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_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);
}
flush_put_bits(&s->pb);
}
+static void update_md5_sum(FlacEncodeContext *s, int16_t *samples)
+{
+#ifdef WORDS_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)
{
/* 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;
}
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);