diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-10-07 11:23:29 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-10-07 11:28:38 +0200 |
commit | 79d30321a29dc648d5a475ce5086b2760d5d8c12 (patch) | |
tree | c712b09b56a0937ca08a1c89365addd8e4e33d4b /libavcodec | |
parent | 537ef8bebf8a35aab448db6ec876e275a10f0f15 (diff) | |
parent | 31b2262dca9cc77709d20c45610ec8030e7f9257 (diff) | |
download | ffmpeg-79d30321a29dc648d5a475ce5086b2760d5d8c12.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
wmaenc: use float planar sample format
(e)ac3enc: use planar sample format
aacenc: use planar sample format
adpcmenc: use planar sample format for adpcm_ima_wav and adpcm_ima_qt
adpcmenc: move 'ch' variable to higher scope
adpcmenc: fix 3 instances of variable shadowing
adpcm_ima_wav: simplify encoding
libvorbis: use planar sample format
libmp3lame: use planar sample formats
vorbisenc: use float planar sample format
ffm: do not write or read the audio sample format
parseutils: fix parsing of invalid alpha values
doc/RELEASE_NOTES: update for the 9 release.
smoothstreamingenc: Add a more verbose error message
smoothstreamingenc: Ignore the return value from mkdir
smoothstreamingenc: Try writing a manifest when opening the muxer
smoothstreamingenc: Move the output_chunk_list and write_manifest functions up
smoothstreamingenc: Properly return errors from ism_flush to the caller
smoothstreamingenc: Check the output UrlContext before accessing it
Conflicts:
doc/RELEASE_NOTES
libavcodec/aacenc.c
libavcodec/ac3enc_template.c
libavcodec/wmaenc.c
tests/ref/lavf/ffm
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/aacenc.c | 33 | ||||
-rw-r--r-- | libavcodec/ac3enc_fixed.c | 2 | ||||
-rw-r--r-- | libavcodec/ac3enc_float.c | 2 | ||||
-rw-r--r-- | libavcodec/ac3enc_template.c | 34 | ||||
-rw-r--r-- | libavcodec/adpcmenc.c | 153 | ||||
-rw-r--r-- | libavcodec/eac3enc.c | 2 | ||||
-rw-r--r-- | libavcodec/libmp3lame.c | 104 | ||||
-rw-r--r-- | libavcodec/libvorbisenc.c | 8 | ||||
-rw-r--r-- | libavcodec/vorbisenc.c | 20 | ||||
-rw-r--r-- | libavcodec/wma.c | 1 | ||||
-rw-r--r-- | libavcodec/wma.h | 2 | ||||
-rw-r--r-- | libavcodec/wmaenc.c | 32 |
12 files changed, 172 insertions, 221 deletions
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 383cb5a7c1..9178babda6 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -479,31 +479,28 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, } /* - * Deinterleave input samples. + * Copy input samples. * Channels are reordered from libavcodec's default order to AAC order. */ -static void deinterleave_input_samples(AACEncContext *s, const AVFrame *frame) +static void copy_input_samples(AACEncContext *s, const AVFrame *frame) { - int ch, i; - const int sinc = s->channels; - const uint8_t *channel_map = aac_chan_maps[sinc - 1]; + int ch; + int end = 2048 + (frame ? frame->nb_samples : 0); + const uint8_t *channel_map = aac_chan_maps[s->channels - 1]; - /* deinterleave and remap input samples */ - for (ch = 0; ch < sinc; ch++) { + /* copy and remap input samples */ + for (ch = 0; ch < s->channels; ch++) { /* copy last 1024 samples of previous frame to the start of the current frame */ memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); - /* deinterleave */ - i = 2048; + /* copy new samples and zero any remaining samples */ if (frame) { - const float *sptr = ((const float *)frame->data[0]) + channel_map[ch]; - for (; i < 2048 + frame->nb_samples; i++) { - s->planar_samples[ch][i] = *sptr; - sptr += sinc; - } + memcpy(&s->planar_samples[ch][2048], + frame->extended_data[channel_map[ch]], + frame->nb_samples * sizeof(s->planar_samples[0][0])); } - memset(&s->planar_samples[ch][i], 0, - (3072 - i) * sizeof(s->planar_samples[0][0])); + memset(&s->planar_samples[ch][end], 0, + (3072 - end) * sizeof(s->planar_samples[0][0])); } } @@ -526,7 +523,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return ret; } - deinterleave_input_samples(s, frame); + copy_input_samples(s, frame); if (s->psypp) ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); @@ -827,7 +824,7 @@ AVCodec ff_aac_encoder = { .supported_samplerates = avpriv_mpeg4audio_sample_rates, .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .priv_class = &aacenc_class, diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index fa109f9791..5d8dd5c3f1 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -160,7 +160,7 @@ AVCodec ff_ac3_fixed_encoder = { .init = ac3_fixed_encode_init, .encode2 = ff_ac3_fixed_encode_frame, .close = ff_ac3_encode_close, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .priv_class = &ac3enc_class, diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 5afe0fe2ab..7864f41019 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -158,7 +158,7 @@ AVCodec ff_ac3_encoder = { .init = ff_ac3_encode_init, .encode2 = ff_ac3_float_encode_frame, .close = ff_ac3_encode_close, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .priv_class = &ac3enc_class, diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index e81bfce5a8..904e0bb9ef 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2011 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -68,30 +68,23 @@ alloc_fail: /* - * Deinterleave input samples. + * Copy input samples. * Channels are reordered from FFmpeg's default order to AC-3 order. */ -static void deinterleave_input_samples(AC3EncodeContext *s, - const SampleType *samples) +static void copy_input_samples(AC3EncodeContext *s, SampleType **samples) { - int ch, i; + int ch; - /* deinterleave and remap input samples */ + /* copy and remap input samples */ for (ch = 0; ch < s->channels; ch++) { - const SampleType *sptr; - int sinc; - /* copy last 256 samples of previous frame to the start of the current frame */ memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks], AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0])); - /* deinterleave */ - sinc = s->channels; - sptr = samples + s->channel_map[ch]; - for (i = AC3_BLOCK_SIZE; i < AC3_BLOCK_SIZE * (s->num_blocks + 1); i++) { - s->planar_samples[ch][i] = *sptr; - sptr += sinc; - } + /* copy new samples for current frame */ + memcpy(&s->planar_samples[ch][AC3_BLOCK_SIZE], + samples[s->channel_map[ch]], + AC3_BLOCK_SIZE * s->num_blocks * sizeof(s->planar_samples[0][0])); } } @@ -395,7 +388,6 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { AC3EncodeContext *s = avctx->priv_data; - const SampleType *samples = (const SampleType *)frame->data[0]; int ret; if (s->options.allow_per_frame_metadata) { @@ -407,7 +399,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, if (s->bit_alloc.sr_code == 1 || s->eac3) ff_ac3_adjust_frame_size(s); - deinterleave_input_samples(s, samples); + copy_input_samples(s, (SampleType **)frame->extended_data); apply_mdct(s); diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index a3194abb3c..f016ebd910 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -274,12 +274,11 @@ static inline uint8_t adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, static void adpcm_compress_trellis(AVCodecContext *avctx, const int16_t *samples, uint8_t *dst, - ADPCMChannelStatus *c, int n) + ADPCMChannelStatus *c, int n, int stride) { //FIXME 6% faster if frontier is a compile-time constant ADPCMEncodeContext *s = avctx->priv_data; const int frontier = 1 << avctx->trellis; - const int stride = avctx->channels; const int version = avctx->codec->id; TrellisPath *paths = s->paths, *p; TrellisNode *node_buf = s->node_buf; @@ -481,13 +480,15 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { - int n, i, st, pkt_size, ret; + int n, i, ch, st, pkt_size, ret; const int16_t *samples; + int16_t **samples_p; uint8_t *dst; ADPCMEncodeContext *c = avctx->priv_data; uint8_t *buf; samples = (const int16_t *)frame->data[0]; + samples_p = (int16_t **)frame->extended_data; st = avctx->channels == 2; if (avctx->codec_id == AV_CODEC_ID_ADPCM_SWF) @@ -500,91 +501,71 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, switch(avctx->codec->id) { case AV_CODEC_ID_ADPCM_IMA_WAV: - n = frame->nb_samples / 8; - c->status[0].prev_sample = samples[0]; - /* c->status[0].step_index = 0; - XXX: not sure how to init the state machine */ - bytestream_put_le16(&dst, c->status[0].prev_sample); - *dst++ = c->status[0].step_index; - *dst++ = 0; /* unknown */ - samples++; - if (avctx->channels == 2) { - c->status[1].prev_sample = samples[0]; - /* c->status[1].step_index = 0; */ - bytestream_put_le16(&dst, c->status[1].prev_sample); - *dst++ = c->status[1].step_index; - *dst++ = 0; - samples++; + { + int blocks, j; + + blocks = (frame->nb_samples - 1) / 8; + + for (ch = 0; ch < avctx->channels; ch++) { + ADPCMChannelStatus *status = &c->status[ch]; + status->prev_sample = samples_p[ch][0]; + /* status->step_index = 0; + XXX: not sure how to init the state machine */ + bytestream_put_le16(&dst, status->prev_sample); + *dst++ = status->step_index; + *dst++ = 0; /* unknown */ } - /* stereo: 4 bytes (8 samples) for left, - 4 bytes for right, 4 bytes left, ... */ + /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */ if (avctx->trellis > 0) { - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 8, error); - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n * 8); - if (avctx->channels == 2) - adpcm_compress_trellis(avctx, samples + 1, buf + n * 8, - &c->status[1], n * 8); - for (i = 0; i < n; i++) { - *dst++ = buf[8 * i + 0] | (buf[8 * i + 1] << 4); - *dst++ = buf[8 * i + 2] | (buf[8 * i + 3] << 4); - *dst++ = buf[8 * i + 4] | (buf[8 * i + 5] << 4); - *dst++ = buf[8 * i + 6] | (buf[8 * i + 7] << 4); - if (avctx->channels == 2) { - uint8_t *buf1 = buf + n * 8; - *dst++ = buf1[8 * i + 0] | (buf1[8 * i + 1] << 4); - *dst++ = buf1[8 * i + 2] | (buf1[8 * i + 3] << 4); - *dst++ = buf1[8 * i + 4] | (buf1[8 * i + 5] << 4); - *dst++ = buf1[8 * i + 6] | (buf1[8 * i + 7] << 4); + FF_ALLOC_OR_GOTO(avctx, buf, avctx->channels * blocks * 8, error); + for (ch = 0; ch < avctx->channels; ch++) { + adpcm_compress_trellis(avctx, &samples_p[ch][1], + buf + ch * blocks * 8, &c->status[ch], + blocks * 8, 1); + } + for (i = 0; i < blocks; i++) { + for (ch = 0; ch < avctx->channels; ch++) { + uint8_t *buf1 = buf + ch * blocks * 8 + i * 8; + for (j = 0; j < 8; j += 2) + *dst++ = buf1[j] | (buf1[j + 1] << 4); } } av_free(buf); } else { - for (; n > 0; n--) { - *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]); - *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels ]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]); - *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]); - *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]); - *dst++ |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4; - /* right channel */ - if (avctx->channels == 2) { - *dst = adpcm_ima_compress_sample(&c->status[1], samples[1 ]); - *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[3 ]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[1], samples[5 ]); - *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[7 ]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[1], samples[9 ]); - *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4; - *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]); - *dst++ |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4; + for (i = 0; i < blocks; i++) { + for (ch = 0; ch < avctx->channels; ch++) { + ADPCMChannelStatus *status = &c->status[ch]; + const int16_t *smp = &samples_p[ch][1 + i * 8]; + for (j = 0; j < 8; j += 2) { + *dst++ = adpcm_ima_compress_sample(status, smp[j ]) | + (adpcm_ima_compress_sample(status, smp[j + 1]) << 4); + } } - samples += 8 * avctx->channels; } } break; + } case AV_CODEC_ID_ADPCM_IMA_QT: { - int ch, i; PutBitContext pb; init_put_bits(&pb, dst, pkt_size * 8); for (ch = 0; ch < avctx->channels; ch++) { - put_bits(&pb, 9, (c->status[ch].prev_sample & 0xFFFF) >> 7); - put_bits(&pb, 7, c->status[ch].step_index); + ADPCMChannelStatus *status = &c->status[ch]; + put_bits(&pb, 9, (status->prev_sample & 0xFFFF) >> 7); + put_bits(&pb, 7, status->step_index); if (avctx->trellis > 0) { uint8_t buf[64]; - adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64); + adpcm_compress_trellis(avctx, &samples_p[ch][1], buf, status, + 64, 1); for (i = 0; i < 64; i++) put_bits(&pb, 4, buf[i ^ 1]); } else { for (i = 0; i < 64; i += 2) { int t1, t2; - t1 = adpcm_ima_qt_compress_sample(&c->status[ch], - samples[avctx->channels * (i + 0) + ch]); - t2 = adpcm_ima_qt_compress_sample(&c->status[ch], - samples[avctx->channels * (i + 1) + ch]); + t1 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i ]); + t2 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i + 1]); put_bits(&pb, 4, t2); put_bits(&pb, 4, t1); } @@ -596,7 +577,6 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } case AV_CODEC_ID_ADPCM_SWF: { - int i; PutBitContext pb; init_put_bits(&pb, dst, pkt_size * 8); @@ -617,10 +597,11 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (avctx->trellis > 0) { FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); adpcm_compress_trellis(avctx, samples + avctx->channels, buf, - &c->status[0], n); + &c->status[0], n, avctx->channels); if (avctx->channels == 2) adpcm_compress_trellis(avctx, samples + avctx->channels + 1, - buf + n, &c->status[1], n); + buf + n, &c->status[1], n, + avctx->channels); for (i = 0; i < n; i++) { put_bits(&pb, 4, buf[i]); if (avctx->channels == 2) @@ -661,15 +642,18 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, bytestream_put_le16(&dst, c->status[i].sample2); if (avctx->trellis > 0) { - int n = avctx->block_align - 7 * avctx->channels; + n = avctx->block_align - 7 * avctx->channels; FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); if (avctx->channels == 1) { - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n); + adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, + avctx->channels); for (i = 0; i < n; i += 2) *dst++ = (buf[i] << 4) | buf[i + 1]; } else { - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n); - adpcm_compress_trellis(avctx, samples + 1, buf + n, &c->status[1], n); + adpcm_compress_trellis(avctx, samples, buf, + &c->status[0], n, avctx->channels); + adpcm_compress_trellis(avctx, samples + 1, buf + n, + &c->status[1], n, avctx->channels); for (i = 0; i < n; i++) *dst++ = (buf[i] << 4) | buf[n + i]; } @@ -689,12 +673,15 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error); n *= 2; if (avctx->channels == 1) { - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n); + adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, + avctx->channels); for (i = 0; i < n; i += 2) *dst++ = buf[i] | (buf[i + 1] << 4); } else { - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n); - adpcm_compress_trellis(avctx, samples + 1, buf + n, &c->status[1], n); + adpcm_compress_trellis(avctx, samples, buf, + &c->status[0], n, avctx->channels); + adpcm_compress_trellis(avctx, samples + 1, buf + n, + &c->status[1], n, avctx->channels); for (i = 0; i < n; i++) *dst++ = buf[i] | (buf[n + i] << 4); } @@ -722,7 +709,11 @@ static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; -#define ADPCM_ENCODER(id_, name_, long_name_) \ +static const enum AVSampleFormat sample_fmts_p[] = { + AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE +}; + +#define ADPCM_ENCODER(id_, name_, sample_fmts_, long_name_) \ AVCodec ff_ ## name_ ## _encoder = { \ .name = #name_, \ .type = AVMEDIA_TYPE_AUDIO, \ @@ -731,12 +722,12 @@ AVCodec ff_ ## name_ ## _encoder = { \ .init = adpcm_encode_init, \ .encode2 = adpcm_encode_frame, \ .close = adpcm_encode_close, \ - .sample_fmts = sample_fmts, \ + .sample_fmts = sample_fmts_, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } -ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime"); -ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV"); -ADPCM_ENCODER(AV_CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft"); -ADPCM_ENCODER(AV_CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash"); -ADPCM_ENCODER(AV_CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, "ADPCM IMA QuickTime"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, "ADPCM IMA WAV"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_MS, adpcm_ms, sample_fmts, "ADPCM Microsoft"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_SWF, adpcm_swf, sample_fmts, "ADPCM Shockwave Flash"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, sample_fmts, "ADPCM Yamaha"); diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index c5ac6d1516..bb9ef4fd3e 100644 --- a/libavcodec/eac3enc.c +++ b/libavcodec/eac3enc.c @@ -258,7 +258,7 @@ AVCodec ff_eac3_encoder = { .init = ff_ac3_encode_init, .encode2 = ff_ac3_float_encode_frame, .close = ff_ac3_encode_close, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"), .priv_class = &eac3enc_class, diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 427cacdf8e..ce17e06ef8 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -33,6 +33,7 @@ #include "libavutil/opt.h" #include "avcodec.h" #include "audio_frame_queue.h" +#include "dsputil.h" #include "internal.h" #include "mpegaudio.h" #include "mpegaudiodecheader.h" @@ -46,8 +47,9 @@ typedef struct LAMEContext { uint8_t buffer[BUFFER_SIZE]; int buffer_index; int reservoir; - void *planar_samples[2]; + float *samples_flt[2]; AudioFrameQueue afq; + DSPContext dsp; } LAMEContext; @@ -58,8 +60,8 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx) #if FF_API_OLD_ENCODE_AUDIO av_freep(&avctx->coded_frame); #endif - av_freep(&s->planar_samples[0]); - av_freep(&s->planar_samples[1]); + av_freep(&s->samples_flt[0]); + av_freep(&s->samples_flt[1]); ff_af_queue_close(&s->afq); @@ -127,93 +129,63 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) } #endif - /* sample format */ - if (avctx->sample_fmt == AV_SAMPLE_FMT_S32 || - avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + /* allocate float sample buffers */ + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) { int ch; for (ch = 0; ch < avctx->channels; ch++) { - s->planar_samples[ch] = av_malloc(avctx->frame_size * - av_get_bytes_per_sample(avctx->sample_fmt)); - if (!s->planar_samples[ch]) { + s->samples_flt[ch] = av_malloc(avctx->frame_size * + sizeof(*s->samples_flt[ch])); + if (!s->samples_flt[ch]) { ret = AVERROR(ENOMEM); goto error; } } } + ff_dsputil_init(&s->dsp, avctx); + return 0; error: mp3lame_encode_close(avctx); return ret; } -#define DEINTERLEAVE(type, scale) do { \ - int ch, i; \ - for (ch = 0; ch < s->avctx->channels; ch++) { \ - const type *input = samples; \ - type *output = s->planar_samples[ch]; \ - input += ch; \ - for (i = 0; i < nb_samples; i++) { \ - output[i] = *input * scale; \ - input += s->avctx->channels; \ - } \ - } \ +#define ENCODE_BUFFER(func, buf_type, buf_name) do { \ + lame_result = func(s->gfp, \ + (const buf_type *)buf_name[0], \ + (const buf_type *)buf_name[1], frame->nb_samples, \ + s->buffer + s->buffer_index, \ + BUFFER_SIZE - s->buffer_index); \ } while (0) -static int encode_frame_int16(LAMEContext *s, void *samples, int nb_samples) -{ - if (s->avctx->channels > 1) { - return lame_encode_buffer_interleaved(s->gfp, samples, - nb_samples, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); - } else { - return lame_encode_buffer(s->gfp, samples, NULL, nb_samples, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); - } -} - -static int encode_frame_int32(LAMEContext *s, void *samples, int nb_samples) -{ - DEINTERLEAVE(int32_t, 1); - - return lame_encode_buffer_int(s->gfp, - s->planar_samples[0], s->planar_samples[1], - nb_samples, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); -} - -static int encode_frame_float(LAMEContext *s, void *samples, int nb_samples) -{ - DEINTERLEAVE(float, 32768.0f); - - return lame_encode_buffer_float(s->gfp, - s->planar_samples[0], s->planar_samples[1], - nb_samples, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); -} - static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { LAMEContext *s = avctx->priv_data; MPADecodeHeader hdr; - int len, ret; + int len, ret, ch; int lame_result; if (frame) { switch (avctx->sample_fmt) { - case AV_SAMPLE_FMT_S16: - lame_result = encode_frame_int16(s, frame->data[0], frame->nb_samples); + case AV_SAMPLE_FMT_S16P: + ENCODE_BUFFER(lame_encode_buffer, int16_t, frame->data); break; - case AV_SAMPLE_FMT_S32: - lame_result = encode_frame_int32(s, frame->data[0], frame->nb_samples); + case AV_SAMPLE_FMT_S32P: + ENCODE_BUFFER(lame_encode_buffer_int, int32_t, frame->data); break; - case AV_SAMPLE_FMT_FLT: - lame_result = encode_frame_float(s, frame->data[0], frame->nb_samples); + case AV_SAMPLE_FMT_FLTP: + if (frame->linesize[0] < 4 * FFALIGN(frame->nb_samples, 8)) { + av_log(avctx, AV_LOG_ERROR, "inadequate AVFrame plane padding\n"); + return AVERROR(EINVAL); + } + for (ch = 0; ch < avctx->channels; ch++) { + s->dsp.vector_fmul_scalar(s->samples_flt[ch], + (const float *)frame->data[ch], + 32768.0f, + FFALIGN(frame->nb_samples, 8)); + } + ENCODE_BUFFER(lame_encode_buffer_float, float, s->samples_flt); break; default: return AVERROR_BUG; @@ -299,9 +271,9 @@ AVCodec ff_libmp3lame_encoder = { .encode2 = mp3lame_encode_frame, .close = mp3lame_encode_close, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P, + AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, .supported_samplerates = libmp3lame_sample_rates, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c index b042e0cb4f..6064dd5649 100644 --- a/libavcodec/libvorbisenc.c +++ b/libavcodec/libvorbisenc.c @@ -290,18 +290,16 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* send samples to libvorbis */ if (frame) { - const float *audio = (const float *)frame->data[0]; const int samples = frame->nb_samples; float **buffer; int c, channels = s->vi.channels; buffer = vorbis_analysis_buffer(&s->vd, samples); for (c = 0; c < channels; c++) { - int i; int co = (channels > 8) ? c : ff_vorbis_encoding_channel_layout_offsets[channels - 1][c]; - for (i = 0; i < samples; i++) - buffer[c][i] = audio[i * channels + co]; + memcpy(buffer[c], frame->extended_data[co], + samples * sizeof(*buffer[c])); } if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) { av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); @@ -383,7 +381,7 @@ AVCodec ff_libvorbis_encoder = { .encode2 = oggvorbis_encode_frame, .close = oggvorbis_encode_close, .capabilities = CODEC_CAP_DELAY, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), .priv_class = &class, diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index b88791f274..74d6331ee3 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -963,10 +963,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, return 0; } -static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *audio, - int samples) +static int apply_window_and_mdct(vorbis_enc_context *venc, + float **audio, int samples) { - int i, j, channel; + int i, channel; const float * win = venc->win[0]; int window_len = 1 << (venc->log2_blocksize[0] - 1); float n = (float)(1 << venc->log2_blocksize[0]) / 4.; @@ -988,9 +988,8 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a if (samples) { for (channel = 0; channel < venc->channels; channel++) { float * offset = venc->samples + channel*window_len*2 + window_len; - j = channel; - for (i = 0; i < samples; i++, j += venc->channels) - offset[i] = audio[j] / 32768. / n * win[window_len - i - 1]; + for (i = 0; i < samples; i++) + offset[i] = audio[channel][i] / n * win[window_len - i - 1]; } } else { for (channel = 0; channel < venc->channels; channel++) @@ -1005,9 +1004,8 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a if (samples) { for (channel = 0; channel < venc->channels; channel++) { float *offset = venc->saved + channel * window_len; - j = channel; - for (i = 0; i < samples; i++, j += venc->channels) - offset[i] = audio[j] / 32768. / n * win[i]; + for (i = 0; i < samples; i++) + offset[i] = audio[channel][i] / n * win[i]; } venc->have_saved = 1; } else { @@ -1020,7 +1018,7 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { vorbis_enc_context *venc = avccontext->priv_data; - const int16_t *audio = frame ? (const int16_t *)frame->data[0] : NULL; + float **audio = frame ? (float **)frame->extended_data : NULL; int samples = frame ? frame->nb_samples : 0; vorbis_enc_mode *mode; vorbis_enc_mapping *mapping; @@ -1213,7 +1211,7 @@ AVCodec ff_vorbis_encoder = { .encode2 = vorbis_encode_frame, .close = vorbis_encode_close, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), }; diff --git a/libavcodec/wma.c b/libavcodec/wma.c index d5e66e25b3..c65281711a 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -89,6 +89,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) ff_dsputil_init(&s->dsp, avctx); ff_fmt_convert_init(&s->fmt_conv, avctx); + avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); if (avctx->codec->id == AV_CODEC_ID_WMAV1) { s->version = 1; diff --git a/libavcodec/wma.h b/libavcodec/wma.h index 73734ebc7c..1e7f0e5aba 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -22,6 +22,7 @@ #ifndef AVCODEC_WMA_H #define AVCODEC_WMA_H +#include "libavutil/float_dsp.h" #include "get_bits.h" #include "put_bits.h" #include "dsputil.h" @@ -137,6 +138,7 @@ typedef struct WMACodecContext { float lsp_pow_m_table2[(1 << LSP_POW_BITS)]; DSPContext dsp; FmtConvertContext fmt_conv; + AVFloatDSPContext fdsp; #ifdef TRACE int frame_count; diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 835bc39ce8..63f815c78a 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -93,23 +93,24 @@ static int encode_init(AVCodecContext * avctx){ } -static void apply_window_and_mdct(AVCodecContext * avctx, const signed short * audio, int len) { +static void apply_window_and_mdct(AVCodecContext * avctx, const AVFrame *frame) +{ WMACodecContext *s = avctx->priv_data; + float **audio = (float **)frame->extended_data; + int len = frame->nb_samples; int window_index= s->frame_len_bits - s->block_len_bits; FFTContext *mdct = &s->mdct_ctx[window_index]; - int i, j, channel; + int ch; const float * win = s->windows[window_index]; int window_len = 1 << s->block_len_bits; - float n = window_len/2; - - for (channel = 0; channel < avctx->channels; channel++) { - memcpy(s->output, s->frame_out[channel], sizeof(float)*window_len); - j = channel; - for (i = 0; i < len; i++, j += avctx->channels){ - s->output[i+window_len] = audio[j] / n * win[window_len - i - 1]; - s->frame_out[channel][i] = audio[j] / n * win[i]; - } - mdct->mdct_calc(mdct, s->coefs[channel], s->output); + float n = 2.0 * 32768.0 / window_len; + + for (ch = 0; ch < avctx->channels; ch++) { + memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output)); + s->dsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len); + s->dsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len); + s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len); + mdct->mdct_calc(mdct, s->coefs[ch], s->output); } } @@ -345,13 +346,12 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { WMACodecContext *s = avctx->priv_data; - const int16_t *samples = (const int16_t *)frame->data[0]; int i, total_gain, ret, error; s->block_len_bits= s->frame_len_bits; //required by non variable block len s->block_len = 1 << s->block_len_bits; - apply_window_and_mdct(avctx, samples, frame->nb_samples); + apply_window_and_mdct(avctx, frame); if (s->ms_stereo) { float a, b; @@ -404,7 +404,7 @@ AVCodec ff_wmav1_encoder = { .init = encode_init, .encode2 = encode_superframe, .close = ff_wma_end, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), }; @@ -418,7 +418,7 @@ AVCodec ff_wmav2_encoder = { .init = encode_init, .encode2 = encode_superframe, .close = ff_wma_end, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), }; |