aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Jones <tdjones879@gmail.com>2017-06-14 14:58:22 -0600
committerRostislav Pehlivanov <atomnuker@gmail.com>2017-06-15 16:42:49 +0100
commit5a2ad7ede33b5d63c1f1b1313a218da62e1c0d48 (patch)
treec0ac2fb2182b09a816af294add9cbf0691dc279e
parent9b667f609c509e84ae6ef496edcfb6c8b83c4a38 (diff)
downloadffmpeg-5a2ad7ede33b5d63c1f1b1313a218da62e1c0d48.tar.gz
vorbisenc: Separate copying audio samples from windowing
Audio samples are shifted around when copying from the frame queue so that analysis can be done without negatively impacting calculation of the MDCT. Window coefficients are applied to the current two overlapped windows simultaneously instead of applying overlap for the next frame ahead of time. This improves readability when applying windows of varying lengths. Signed-off-by: Tyler Jones <tdjones879@gmail.com> Reviewed-by: Rostislav Pehlivanov <atomnuker@gmail.com>
-rw-r--r--libavcodec/vorbisenc.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index afded40da0..9b66d566a4 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -453,7 +453,7 @@ static int create_vorbis_context(vorbis_enc_context *venc,
venc->samples = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]));
venc->floor = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);
venc->coeffs = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);
- venc->scratch = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);
+ venc->scratch = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]));
if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs || !venc->scratch)
return AVERROR(ENOMEM);
@@ -994,8 +994,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc,
return 0;
}
-static int apply_window_and_mdct(vorbis_enc_context *venc,
- float *audio, int samples)
+static int apply_window_and_mdct(vorbis_enc_context *venc, int samples)
{
int channel;
const float * win = venc->win[0];
@@ -1003,46 +1002,19 @@ static int apply_window_and_mdct(vorbis_enc_context *venc,
float n = (float)(1 << venc->log2_blocksize[0]) / 4.0;
AVFloatDSPContext *fdsp = venc->fdsp;
- if (!venc->have_saved && !samples)
- return 0;
+ for (channel = 0; channel < venc->channels; channel++) {
+ float *offset = venc->samples + channel * window_len * 2;
- if (venc->have_saved) {
- for (channel = 0; channel < venc->channels; channel++)
- memcpy(venc->samples + channel * window_len * 2,
- venc->saved + channel * window_len, sizeof(float) * window_len);
- } else {
- for (channel = 0; channel < venc->channels; channel++)
- memset(venc->samples + channel * window_len * 2, 0,
- sizeof(float) * window_len);
- }
+ fdsp->vector_fmul(offset, offset, win, samples);
+ fdsp->vector_fmul_scalar(offset, offset, 1/n, samples);
- if (samples) {
- for (channel = 0; channel < venc->channels; channel++) {
- float *offset = venc->samples + channel * window_len * 2 + window_len;
+ offset += window_len;
- fdsp->vector_fmul_reverse(offset, audio + channel * window_len, win, samples);
- fdsp->vector_fmul_scalar(offset, offset, 1/n, samples);
- }
- } else {
- for (channel = 0; channel < venc->channels; channel++)
- memset(venc->samples + channel * window_len * 2 + window_len,
- 0, sizeof(float) * window_len);
- }
+ fdsp->vector_fmul_reverse(offset, offset, win, samples);
+ fdsp->vector_fmul_scalar(offset, offset, 1/n, samples);
- for (channel = 0; channel < venc->channels; channel++)
venc->mdct[0].mdct_calc(&venc->mdct[0], venc->coeffs + channel * window_len,
venc->samples + channel * window_len * 2);
-
- if (samples) {
- for (channel = 0; channel < venc->channels; channel++) {
- float *offset = venc->saved + channel * window_len;
-
- fdsp->vector_fmul(offset, audio + channel * window_len, win, samples);
- fdsp->vector_fmul_scalar(offset, offset, 1/n, samples);
- }
- venc->have_saved = 1;
- } else {
- venc->have_saved = 0;
}
return 1;
}
@@ -1071,24 +1043,40 @@ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels)
return f;
}
-/* Concatenate audio frames into an appropriately sized array of samples */
-static void move_audio(vorbis_enc_context *venc, float *audio, int *samples, int sf_size)
+/* Set up audio samples for psy analysis and window/mdct */
+static void move_audio(vorbis_enc_context *venc, int *samples, int sf_size)
{
AVFrame *cur = NULL;
int frame_size = 1 << (venc->log2_blocksize[1] - 1);
int subframes = frame_size / sf_size;
+ int sf, ch;
- for (int sf = 0; sf < subframes; sf++) {
+ /* Copy samples from last frame into current frame */
+ if (venc->have_saved)
+ for (ch = 0; ch < venc->channels; ch++)
+ memcpy(venc->samples + 2 * ch * frame_size,
+ venc->saved + ch * frame_size, sizeof(float) * frame_size);
+ else
+ for (ch = 0; ch < venc->channels; ch++)
+ memset(venc->samples + 2 * ch * frame_size, 0, sizeof(float) * frame_size);
+
+ for (sf = 0; sf < subframes; sf++) {
cur = ff_bufqueue_get(&venc->bufqueue);
*samples += cur->nb_samples;
- for (int ch = 0; ch < venc->channels; ch++) {
+ for (ch = 0; ch < venc->channels; ch++) {
+ float *offset = venc->samples + 2 * ch * frame_size + frame_size;
+ float *save = venc->saved + ch * frame_size;
const float *input = (float *) cur->extended_data[ch];
const size_t len = cur->nb_samples * sizeof(float);
- memcpy(audio + ch*frame_size + sf*sf_size, input, len);
+
+ memcpy(offset + sf*sf_size, input, len);
+ memcpy(save + sf*sf_size, input, len); // Move samples for next frame
}
av_frame_free(&cur);
}
+ venc->have_saved = 1;
+ memcpy(venc->scratch, venc->samples, 2 * venc->channels * frame_size);
}
static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
@@ -1129,9 +1117,9 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}
}
- move_audio(venc, venc->scratch, &samples, avctx->frame_size);
+ move_audio(venc, &samples, avctx->frame_size);
- if (!apply_window_and_mdct(venc, venc->scratch, samples))
+ if (!apply_window_and_mdct(venc, samples))
return 0;
if ((ret = ff_alloc_packet2(avctx, avpkt, 8192, 0)) < 0)