|
|
|
@ -25,6 +25,7 @@ |
|
|
|
|
#include "avcodec.h" |
|
|
|
|
#include "get_bits.h" |
|
|
|
|
#include "golomb.h" |
|
|
|
|
#include "internal.h" |
|
|
|
|
#include "lpc.h" |
|
|
|
|
#include "flac.h" |
|
|
|
|
#include "flacdata.h" |
|
|
|
@ -367,9 +368,11 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
|
s->frame_count = 0; |
|
|
|
|
s->min_framesize = s->max_framesize; |
|
|
|
|
|
|
|
|
|
#if FF_API_OLD_ENCODE_AUDIO |
|
|
|
|
avctx->coded_frame = avcodec_alloc_frame(); |
|
|
|
|
if (!avctx->coded_frame) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size, |
|
|
|
|
s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON); |
|
|
|
@ -380,7 +383,7 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void init_frame(FlacEncodeContext *s) |
|
|
|
|
static void init_frame(FlacEncodeContext *s, int nb_samples) |
|
|
|
|
{ |
|
|
|
|
int i, ch; |
|
|
|
|
FlacFrame *frame; |
|
|
|
@ -388,7 +391,7 @@ static void init_frame(FlacEncodeContext *s) |
|
|
|
|
frame = &s->frame; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < 16; i++) { |
|
|
|
|
if (s->avctx->frame_size == ff_flac_blocksize_table[i]) { |
|
|
|
|
if (nb_samples == ff_flac_blocksize_table[i]) { |
|
|
|
|
frame->blocksize = ff_flac_blocksize_table[i]; |
|
|
|
|
frame->bs_code[0] = i; |
|
|
|
|
frame->bs_code[1] = 0; |
|
|
|
@ -396,7 +399,7 @@ static void init_frame(FlacEncodeContext *s) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (i == 16) { |
|
|
|
|
frame->blocksize = s->avctx->frame_size; |
|
|
|
|
frame->blocksize = nb_samples; |
|
|
|
|
if (frame->blocksize <= 256) { |
|
|
|
|
frame->bs_code[0] = 6; |
|
|
|
|
frame->bs_code[1] = frame->blocksize-1; |
|
|
|
@ -1166,9 +1169,9 @@ static void write_frame_footer(FlacEncodeContext *s) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int write_frame(FlacEncodeContext *s, uint8_t *frame, int buf_size) |
|
|
|
|
static int write_frame(FlacEncodeContext *s, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
init_put_bits(&s->pb, frame, buf_size); |
|
|
|
|
init_put_bits(&s->pb, avpkt->data, avpkt->size); |
|
|
|
|
write_frame_header(s); |
|
|
|
|
write_subframes(s); |
|
|
|
|
write_frame_footer(s); |
|
|
|
@ -1190,30 +1193,31 @@ static void update_md5_sum(FlacEncodeContext *s, const int16_t *samples) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
|
|
|
|
int buf_size, void *data) |
|
|
|
|
static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
|
|
|
const AVFrame *frame, int *got_packet_ptr) |
|
|
|
|
{ |
|
|
|
|
FlacEncodeContext *s; |
|
|
|
|
const int16_t *samples = data; |
|
|
|
|
int frame_bytes, out_bytes; |
|
|
|
|
const int16_t *samples; |
|
|
|
|
int frame_bytes, out_bytes, ret; |
|
|
|
|
|
|
|
|
|
s = avctx->priv_data; |
|
|
|
|
|
|
|
|
|
/* when the last block is reached, update the header in extradata */ |
|
|
|
|
if (!data) { |
|
|
|
|
if (!frame) { |
|
|
|
|
s->max_framesize = s->max_encoded_framesize; |
|
|
|
|
av_md5_final(s->md5ctx, s->md5sum); |
|
|
|
|
write_streaminfo(s, avctx->extradata); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
samples = (const int16_t *)frame->data[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, |
|
|
|
|
if (frame->nb_samples < s->frame.blocksize) { |
|
|
|
|
s->max_framesize = ff_flac_get_max_frame_size(frame->nb_samples, |
|
|
|
|
s->channels, 16); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
init_frame(s); |
|
|
|
|
init_frame(s, frame->nb_samples); |
|
|
|
|
|
|
|
|
|
copy_samples(s, samples); |
|
|
|
|
|
|
|
|
@ -1228,22 +1232,26 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
|
|
|
|
frame_bytes = encode_frame(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (buf_size < frame_bytes) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); |
|
|
|
|
return 0; |
|
|
|
|
if ((ret = ff_alloc_packet(avpkt, frame_bytes))) { |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
out_bytes = write_frame(s, frame, buf_size); |
|
|
|
|
|
|
|
|
|
out_bytes = write_frame(s, avpkt); |
|
|
|
|
|
|
|
|
|
s->frame_count++; |
|
|
|
|
avctx->coded_frame->pts = s->sample_count; |
|
|
|
|
s->sample_count += avctx->frame_size; |
|
|
|
|
s->sample_count += frame->nb_samples; |
|
|
|
|
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; |
|
|
|
|
avpkt->pts = frame->pts; |
|
|
|
|
avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); |
|
|
|
|
avpkt->size = out_bytes; |
|
|
|
|
*got_packet_ptr = 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1256,7 +1264,9 @@ static av_cold int flac_encode_close(AVCodecContext *avctx) |
|
|
|
|
} |
|
|
|
|
av_freep(&avctx->extradata); |
|
|
|
|
avctx->extradata_size = 0; |
|
|
|
|
#if FF_API_OLD_ENCODE_AUDIO |
|
|
|
|
av_freep(&avctx->coded_frame); |
|
|
|
|
#endif |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1294,7 +1304,7 @@ AVCodec ff_flac_encoder = { |
|
|
|
|
.id = CODEC_ID_FLAC, |
|
|
|
|
.priv_data_size = sizeof(FlacEncodeContext), |
|
|
|
|
.init = flac_encode_init, |
|
|
|
|
.encode = flac_encode_frame, |
|
|
|
|
.encode2 = flac_encode_frame, |
|
|
|
|
.close = flac_encode_close, |
|
|
|
|
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, |
|
|
|
|
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, |
|
|
|
|