Commit 79d30321 authored by Michael Niedermayer's avatar Michael Niedermayer

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 537ef8be 31b2262d
...@@ -479,31 +479,28 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, ...@@ -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. * 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; int ch;
const int sinc = s->channels; int end = 2048 + (frame ? frame->nb_samples : 0);
const uint8_t *channel_map = aac_chan_maps[sinc - 1]; const uint8_t *channel_map = aac_chan_maps[s->channels - 1];
/* deinterleave and remap input samples */ /* copy and remap input samples */
for (ch = 0; ch < sinc; ch++) { for (ch = 0; ch < s->channels; ch++) {
/* copy last 1024 samples of previous frame to the start of the current frame */ /* 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])); memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0]));
/* deinterleave */ /* copy new samples and zero any remaining samples */
i = 2048;
if (frame) { if (frame) {
const float *sptr = ((const float *)frame->data[0]) + channel_map[ch]; memcpy(&s->planar_samples[ch][2048],
for (; i < 2048 + frame->nb_samples; i++) { frame->extended_data[channel_map[ch]],
s->planar_samples[ch][i] = *sptr; frame->nb_samples * sizeof(s->planar_samples[0][0]));
sptr += sinc;
}
} }
memset(&s->planar_samples[ch][i], 0, memset(&s->planar_samples[ch][end], 0,
(3072 - i) * sizeof(s->planar_samples[0][0])); (3072 - end) * sizeof(s->planar_samples[0][0]));
} }
} }
...@@ -526,7 +523,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ...@@ -526,7 +523,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
return ret; return ret;
} }
deinterleave_input_samples(s, frame); copy_input_samples(s, frame);
if (s->psypp) if (s->psypp)
ff_psy_preprocess(s->psypp, s->planar_samples, s->channels); ff_psy_preprocess(s->psypp, s->planar_samples, s->channels);
...@@ -827,7 +824,7 @@ AVCodec ff_aac_encoder = { ...@@ -827,7 +824,7 @@ AVCodec ff_aac_encoder = {
.supported_samplerates = avpriv_mpeg4audio_sample_rates, .supported_samplerates = avpriv_mpeg4audio_sample_rates,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY |
CODEC_CAP_EXPERIMENTAL, 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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
.priv_class = &aacenc_class, .priv_class = &aacenc_class,
......
...@@ -160,7 +160,7 @@ AVCodec ff_ac3_fixed_encoder = { ...@@ -160,7 +160,7 @@ AVCodec ff_ac3_fixed_encoder = {
.init = ac3_fixed_encode_init, .init = ac3_fixed_encode_init,
.encode2 = ff_ac3_fixed_encode_frame, .encode2 = ff_ac3_fixed_encode_frame,
.close = ff_ac3_encode_close, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class, .priv_class = &ac3enc_class,
......
...@@ -158,7 +158,7 @@ AVCodec ff_ac3_encoder = { ...@@ -158,7 +158,7 @@ AVCodec ff_ac3_encoder = {
.init = ff_ac3_encode_init, .init = ff_ac3_encode_init,
.encode2 = ff_ac3_float_encode_frame, .encode2 = ff_ac3_float_encode_frame,
.close = ff_ac3_encode_close, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class, .priv_class = &ac3enc_class,
......
...@@ -4,20 +4,20 @@ ...@@ -4,20 +4,20 @@
* Copyright (c) 2006-2011 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2006-2011 Justin Ruggles <justin.ruggles@gmail.com>
* Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> * 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 * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * 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 * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
...@@ -68,30 +68,23 @@ alloc_fail: ...@@ -68,30 +68,23 @@ alloc_fail:
/* /*
* Deinterleave input samples. * Copy input samples.
* Channels are reordered from FFmpeg's default order to AC-3 order. * Channels are reordered from FFmpeg's default order to AC-3 order.
*/ */
static void deinterleave_input_samples(AC3EncodeContext *s, static void copy_input_samples(AC3EncodeContext *s, SampleType **samples)
const SampleType *samples)
{ {
int ch, i; int ch;
/* deinterleave and remap input samples */ /* copy and remap input samples */
for (ch = 0; ch < s->channels; ch++) { 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 */ /* 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], 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])); AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
/* deinterleave */ /* copy new samples for current frame */
sinc = s->channels; memcpy(&s->planar_samples[ch][AC3_BLOCK_SIZE],
sptr = samples + s->channel_map[ch]; samples[s->channel_map[ch]],
for (i = AC3_BLOCK_SIZE; i < AC3_BLOCK_SIZE * (s->num_blocks + 1); i++) { AC3_BLOCK_SIZE * s->num_blocks * sizeof(s->planar_samples[0][0]));
s->planar_samples[ch][i] = *sptr;
sptr += sinc;
}
} }
} }
...@@ -395,7 +388,6 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, ...@@ -395,7 +388,6 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr) const AVFrame *frame, int *got_packet_ptr)
{ {
AC3EncodeContext *s = avctx->priv_data; AC3EncodeContext *s = avctx->priv_data;
const SampleType *samples = (const SampleType *)frame->data[0];
int ret; int ret;
if (s->options.allow_per_frame_metadata) { if (s->options.allow_per_frame_metadata) {
...@@ -407,7 +399,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt, ...@@ -407,7 +399,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
if (s->bit_alloc.sr_code == 1 || s->eac3) if (s->bit_alloc.sr_code == 1 || s->eac3)
ff_ac3_adjust_frame_size(s); ff_ac3_adjust_frame_size(s);
deinterleave_input_samples(s, samples); copy_input_samples(s, (SampleType **)frame->extended_data);
apply_mdct(s); apply_mdct(s);
......
This diff is collapsed.
...@@ -258,7 +258,7 @@ AVCodec ff_eac3_encoder = { ...@@ -258,7 +258,7 @@ AVCodec ff_eac3_encoder = {
.init = ff_ac3_encode_init, .init = ff_ac3_encode_init,
.encode2 = ff_ac3_float_encode_frame, .encode2 = ff_ac3_float_encode_frame,
.close = ff_ac3_encode_close, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"), .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"),
.priv_class = &eac3enc_class, .priv_class = &eac3enc_class,
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "avcodec.h" #include "avcodec.h"
#include "audio_frame_queue.h" #include "audio_frame_queue.h"
#include "dsputil.h"
#include "internal.h" #include "internal.h"
#include "mpegaudio.h" #include "mpegaudio.h"
#include "mpegaudiodecheader.h" #include "mpegaudiodecheader.h"
...@@ -46,8 +47,9 @@ typedef struct LAMEContext { ...@@ -46,8 +47,9 @@ typedef struct LAMEContext {
uint8_t buffer[BUFFER_SIZE]; uint8_t buffer[BUFFER_SIZE];
int buffer_index; int buffer_index;
int reservoir; int reservoir;
void *planar_samples[2]; float *samples_flt[2];
AudioFrameQueue afq; AudioFrameQueue afq;
DSPContext dsp;
} LAMEContext; } LAMEContext;
...@@ -58,8 +60,8 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx) ...@@ -58,8 +60,8 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
#if FF_API_OLD_ENCODE_AUDIO #if FF_API_OLD_ENCODE_AUDIO
av_freep(&avctx->coded_frame); av_freep(&avctx->coded_frame);
#endif #endif
av_freep(&s->planar_samples[0]); av_freep(&s->samples_flt[0]);
av_freep(&s->planar_samples[1]); av_freep(&s->samples_flt[1]);
ff_af_queue_close(&s->afq); ff_af_queue_close(&s->afq);
...@@ -127,93 +129,63 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) ...@@ -127,93 +129,63 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx)
} }
#endif #endif
/* sample format */ /* allocate float sample buffers */
if (avctx->sample_fmt == AV_SAMPLE_FMT_S32 || if (avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
int ch; int ch;
for (ch = 0; ch < avctx->channels; ch++) { for (ch = 0; ch < avctx->channels; ch++) {
s->planar_samples[ch] = av_malloc(avctx->frame_size * s->samples_flt[ch] = av_malloc(avctx->frame_size *
av_get_bytes_per_sample(avctx->sample_fmt)); sizeof(*s->samples_flt[ch]));
if (!s->planar_samples[ch]) { if (!s->samples_flt[ch]) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto error; goto error;
} }
} }
} }
ff_dsputil_init(&s->dsp, avctx);
return 0; return 0;
error: error:
mp3lame_encode_close(avctx); mp3lame_encode_close(avctx);
return ret; return ret;
} }
#define DEINTERLEAVE(type, scale) do { \ #define ENCODE_BUFFER(func, buf_type, buf_name) do { \
int ch, i; \ lame_result = func(s->gfp, \
for (ch = 0; ch < s->avctx->channels; ch++) { \ (const buf_type *)buf_name[0], \
const type *input = samples; \ (const buf_type *)buf_name[1], frame->nb_samples, \
type *output = s->planar_samples[ch]; \ s->buffer + s->buffer_index, \
input += ch; \ BUFFER_SIZE - s->buffer_index); \
for (i = 0; i < nb_samples; i++) { \
output[i] = *input * scale; \
input += s->avctx->channels; \
} \
} \
} while (0) } 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, static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr) const AVFrame *frame, int *got_packet_ptr)
{ {
LAMEContext *s = avctx->priv_data; LAMEContext *s = avctx->priv_data;
MPADecodeHeader hdr; MPADecodeHeader hdr;
int len, ret; int len, ret, ch;
int lame_result; int lame_result;
if (frame) { if (frame) {
switch (avctx->sample_fmt) { switch (avctx->sample_fmt) {
case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S16P:
lame_result = encode_frame_int16(s, frame->data[0], frame->nb_samples); ENCODE_BUFFER(lame_encode_buffer, int16_t, frame->data);
break; break;
case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_S32P:
lame_result = encode_frame_int32(s, frame->data[0], frame->nb_samples); ENCODE_BUFFER(lame_encode_buffer_int, int32_t, frame->data);
break; break;
case AV_SAMPLE_FMT_FLT: case AV_SAMPLE_FMT_FLTP:
lame_result = encode_frame_float(s, frame->data[0], frame->nb_samples); 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; break;
default: default:
return AVERROR_BUG; return AVERROR_BUG;
...@@ -299,9 +271,9 @@ AVCodec ff_libmp3lame_encoder = { ...@@ -299,9 +271,9 @@ AVCodec ff_libmp3lame_encoder = {
.encode2 = mp3lame_encode_frame, .encode2 = mp3lame_encode_frame,
.close = mp3lame_encode_close, .close = mp3lame_encode_close,
.capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE },
.supported_samplerates = libmp3lame_sample_rates, .supported_samplerates = libmp3lame_sample_rates,
.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
......
...@@ -290,18 +290,16 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ...@@ -290,18 +290,16 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
/* send samples to libvorbis */ /* send samples to libvorbis */
if (frame) { if (frame) {
const float *audio = (const float *)frame->data[0];
const int samples = frame->nb_samples; const int samples = frame->nb_samples;
float **buffer; float **buffer;
int c, channels = s->vi.channels; int c, channels = s->vi.channels;
buffer = vorbis_analysis_buffer(&s->vd, samples); buffer = vorbis_analysis_buffer(&s->vd, samples);
for (c = 0; c < channels; c++) { for (c = 0; c < channels; c++) {
int i;
int co = (channels > 8) ? c : int co = (channels > 8) ? c :
ff_vorbis_encoding_channel_layout_offsets[channels - 1][c]; ff_vorbis_encoding_channel_layout_offsets[channels - 1][c];
for (i = 0; i < samples; i++) memcpy(buffer[c], frame->extended_data[co],
buffer[c][i] = audio[i * channels + co]; samples * sizeof(*buffer[c]));
} }
if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) { if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n");
...@@ -383,7 +381,7 @@ AVCodec ff_libvorbis_encoder = { ...@@ -383,7 +381,7 @@ AVCodec ff_libvorbis_encoder = {
.encode2 = oggvorbis_encode_frame, .encode2 = oggvorbis_encode_frame,
.close = oggvorbis_encode_close, .close = oggvorbis_encode_close,
.capabilities = CODEC_CAP_DELAY, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("libvorbis"), .long_name = NULL_IF_CONFIG_SMALL("libvorbis"),
.priv_class = &class, .priv_class = &class,
......
...@@ -963,10 +963,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, ...@@ -963,10 +963,10 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc,
return 0; return 0;
} }
static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *audio, static int apply_window_and_mdct(vorbis_enc_context *venc,
int samples) float **audio, int samples)
{ {
int i, j, channel; int i, channel;
const float * win = venc->win[0]; const float * win = venc->win[0];
int window_len = 1 << (venc->log2_blocksize[0] - 1); int window_len = 1 << (venc->log2_blocksize[0] - 1);
float n = (float)(1 << venc->log2_blocksize[0]) / 4.; 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 ...@@ -988,9 +988,8 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a
if (samples) { if (samples) {
for (channel = 0; channel < venc->channels; channel++) { for (channel = 0; channel < venc->channels; channel++) {
float * offset = venc->samples + channel*window_len*2 + window_len; float * offset = venc->samples + channel*window_len*2 + window_len;
j = channel; for (i = 0; i < samples; i++)
for (i = 0; i < samples; i++, j += venc->channels) offset[i] = audio[channel][i] / n * win[window_len - i - 1];
offset[i] = audio[j] / 32768. / n * win[window_len - i - 1];
} }
} else { } else {
for (channel = 0; channel < venc->channels; channel++) 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 ...@@ -1005,9 +1004,8 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a
if (samples) { if (samples) {
for (channel = 0; channel < venc->channels; channel++) { for (channel = 0; channel < venc->channels; channel++) {
float *offset = venc->saved + channel * window_len; float *offset = venc->saved + channel * window_len;
j = channel; for (i = 0; i < samples; i++)
for (i = 0; i < samples; i++, j += venc->channels) offset[i] = audio[channel][i] / n * win[i];
offset[i] = audio[j] / 32768. / n * win[i];
} }
venc->have_saved = 1; venc->have_saved = 1;
} else { } else {
...@@ -1020,7 +1018,7 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt, ...@@ -1020,7 +1018,7 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr) const AVFrame *frame, int *got_packet_ptr)
{ {
vorbis_enc_context *venc = avccontext->priv_data; 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; int samples = frame ? frame->nb_samples : 0;
vorbis_enc_mode *mode; vorbis_enc_mode *mode;
vorbis_enc_mapping *mapping; vorbis_enc_mapping *mapping;
...@@ -1213,7 +1211,7 @@ AVCodec ff_vorbis_encoder = { ...@@ -1213,7 +1211,7 @@ AVCodec ff_vorbis_encoder = {
.encode2 = vorbis_encode_frame, .encode2 = vorbis_encode_frame,
.close = vorbis_encode_close, .close = vorbis_encode_close,
.capabilities = CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
}; };
...@@ -89,6 +89,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) ...@@ -89,6 +89,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
ff_dsputil_init(&s->dsp, avctx); ff_dsputil_init(&s->dsp, avctx);
ff_fmt_convert_init(&s->fmt_conv, 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) { if (avctx->codec->id == AV_CODEC_ID_WMAV1) {
s->version = 1; s->version = 1;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#ifndef AVCODEC_WMA_H #ifndef AVCODEC_WMA_H
#define AVCODEC_WMA_H #define AVCODEC_WMA_H
#include "libavutil/float_dsp.h"
#include "get_bits.h" #include "get_bits.h"
#include "put_bits.h" #include "put_bits.h"
#include "dsputil.h" #include "dsputil.h"
...@@ -137,6 +138,7 @@ typedef struct WMACodecContext { ...@@ -137,6 +138,7 @@ typedef struct WMACodecContext {
float lsp_pow_m_table2[(1 << LSP_POW_BITS)]; float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
DSPContext dsp; DSPContext dsp;
FmtConvertContext fmt_conv; FmtConvertContext fmt_conv;
AVFloatDSPContext fdsp;
#ifdef TRACE #ifdef TRACE
int frame_count; int frame_count;
......
...@@ -93,23 +93,24 @@ static int encode_init(AVCodecContext * avctx){ ...@@ -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; 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; int window_index= s->frame_len_bits - s->block_len_bits;
FFTContext *mdct = &s->mdct_ctx[window_index]; FFTContext *mdct = &s->mdct_ctx[window_index];
int i, j, channel; int ch;
const float * win = s->windows[window_index]; const float * win = s->windows[window_index];
int window_len = 1 << s->block_len_bits; int window_len = 1 << s->block_len_bits;
float n = window_len/2; float n = 2.0 * 32768.0 / window_len;
for (channel = 0; channel < avctx->channels; channel++) { for (ch = 0; ch < avctx->channels; ch++) {
memcpy(s->output, s->frame_out[channel], sizeof(float)*window_len); memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output));
j = channel; s->dsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
for (i = 0; i < len; i++, j += avctx->channels){ s->dsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
s->output[i+window_len] = audio[j] / n * win[window_len - i - 1]; s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
s->frame_out[channel][i] = audio[j] / n * win[i]; mdct->mdct_calc(mdct, s->coefs[ch], s->output);
}
mdct->mdct_calc(mdct, s->coefs[channel], s->output);
} }
} }
...@@ -345,13 +346,12 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, ...@@ -345,13 +346,12 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr) const AVFrame *frame, int *got_packet_ptr)
{ {
WMACodecContext *s = avctx->priv_data; WMACodecContext *s = avctx->priv_data;
const int16_t *samples = (const int16_t *)frame->data[0];
int i, total_gain, ret, error; int i, total_gain, ret, error;
s->block_len_bits= s->frame_len_bits; //required by non variable block len s->block_len_bits= s->frame_len_bits; //required by non variable block len
s->block_len = 1 << s->block_len_bits; 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) { if (s->ms_stereo) {
float a, b; float a, b;
...@@ -404,7 +404,7 @@ AVCodec ff_wmav1_encoder = { ...@@ -404,7 +404,7 @@ AVCodec ff_wmav1_encoder = {
.init = encode_init, .init = encode_init,
.encode2 = encode_superframe, .encode2 = encode_superframe,
.close = ff_wma_end, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
}; };
...@@ -418,7 +418,7 @@ AVCodec ff_wmav2_encoder = { ...@@ -418,7 +418,7 @@ AVCodec ff_wmav2_encoder = {
.init = encode_init, .init = encode_init,
.encode2 = encode_superframe, .encode2 = encode_superframe,
.close = ff_wma_end, .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 }, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
}; };
......
...@@ -360,7 +360,6 @@ static int ffm_read_header(AVFormatContext *s) ...@@ -360,7 +360,6 @@ static int ffm_read_header(AVFormatContext *s)
codec->sample_rate = avio_rb32(pb); codec->sample_rate = avio_rb32(pb);
codec->channels = avio_rl16(pb); codec->channels = avio_rl16(pb);
codec->frame_size = avio_rl16(pb); codec->frame_size = avio_rl16(pb);
codec->sample_fmt = (int16_t) avio_rl16(pb);
break; break;
default: default:
goto fail; goto fail;
......
...@@ -169,7 +169,6 @@ static int ffm_write_header(AVFormatContext *s) ...@@ -169,7 +169,6 @@ static int ffm_write_header(AVFormatContext *s)
avio_wb32(pb, codec->sample_rate); avio_wb32(pb, codec->sample_rate);
avio_wl16(pb, codec->channels); avio_wl16(pb, codec->channels);
avio_wl16(pb, codec->frame_size); avio_wl16(pb, codec->frame_size);
avio_wl16(pb, codec->sample_fmt);
break; break;
default: default:
return -1; return -1;
......
This diff is collapsed.
...@@ -389,7 +389,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, ...@@ -389,7 +389,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
} }
if (tail) { if (tail) {
unsigned long int alpha; double alpha;
const char *alpha_string = tail; const char *alpha_string = tail;
if (!strncmp(alpha_string, "0x", 2)) { if (!strncmp(alpha_string, "0x", 2)) {
alpha = strtoul(alpha_string, &tail, 16); alpha = strtoul(alpha_string, &tail, 16);
...@@ -401,7 +401,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, ...@@ -401,7 +401,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
alpha = 255 * norm_alpha; alpha = 255 * norm_alpha;
} }
if (tail == alpha_string || *tail || alpha > 255) { if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) {
av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n", av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
alpha_string, color_string); alpha_string, color_string);
return AVERROR(EINVAL); return AVERROR(EINVAL);
......
e6d8254af2b1ad1f58d60da4d80c6e96 *./tests/data/lavf/lavf.ffm c76e8f9a9bcd04379dfa3239e272d049 *./tests/data/lavf/lavf.ffm
376832 ./tests/data/lavf/lavf.ffm 376832 ./tests/data/lavf/lavf.ffm
./tests/data/lavf/lavf.ffm CRC=0x5b136bb1 ./tests/data/lavf/lavf.ffm CRC=0x5b136bb1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment