|
|
|
@ -21,6 +21,7 @@ |
|
|
|
|
|
|
|
|
|
#include "libavutil/crc.h" |
|
|
|
|
#include "libavutil/lls.h" |
|
|
|
|
#include "libavutil/md5.h" |
|
|
|
|
#include "avcodec.h" |
|
|
|
|
#include "bitstream.h" |
|
|
|
|
#include "dsputil.h" |
|
|
|
@ -97,10 +98,12 @@ typedef struct FlacEncodeContext { |
|
|
|
|
int max_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] = { |
|
|
|
@ -139,7 +142,7 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header) |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -372,6 +375,12 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
|
s->max_framesize = 14 + (s->avctx->frame_size * s->channels * 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* 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 = streaminfo; |
|
|
|
@ -1238,6 +1247,19 @@ static void output_frame_footer(FlacEncodeContext *s) |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
@ -1256,6 +1278,7 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
|
|
|
|
|
|
|
|
|
/* when the last block is reached, update the header in extradata */ |
|
|
|
|
if (!data) { |
|
|
|
|
av_md5_final(s->md5ctx, s->md5sum); |
|
|
|
|
write_streaminfo(s, avctx->extradata); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -1294,12 +1317,17 @@ write_frame: |
|
|
|
|
|
|
|
|
|
s->frame_count++; |
|
|
|
|
s->sample_count += avctx->frame_size; |
|
|
|
|
update_md5_sum(s, samples); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|