annotate ffmpeg/libavutil/audio_fifo.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * Audio FIFO
yading@11 3 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
yading@11 4 *
yading@11 5 * This file is part of Libav.
yading@11 6 *
yading@11 7 * Libav is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * Libav is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with Libav; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 /**
yading@11 23 * @file
yading@11 24 * Audio FIFO
yading@11 25 */
yading@11 26
yading@11 27 #include "avutil.h"
yading@11 28 #include "audio_fifo.h"
yading@11 29 #include "common.h"
yading@11 30 #include "fifo.h"
yading@11 31 #include "mem.h"
yading@11 32 #include "samplefmt.h"
yading@11 33
yading@11 34 struct AVAudioFifo {
yading@11 35 AVFifoBuffer **buf; /**< single buffer for interleaved, per-channel buffers for planar */
yading@11 36 int nb_buffers; /**< number of buffers */
yading@11 37 int nb_samples; /**< number of samples currently in the FIFO */
yading@11 38 int allocated_samples; /**< current allocated size, in samples */
yading@11 39
yading@11 40 int channels; /**< number of channels */
yading@11 41 enum AVSampleFormat sample_fmt; /**< sample format */
yading@11 42 int sample_size; /**< size, in bytes, of one sample in a buffer */
yading@11 43 };
yading@11 44
yading@11 45 void av_audio_fifo_free(AVAudioFifo *af)
yading@11 46 {
yading@11 47 if (af) {
yading@11 48 if (af->buf) {
yading@11 49 int i;
yading@11 50 for (i = 0; i < af->nb_buffers; i++) {
yading@11 51 if (af->buf[i])
yading@11 52 av_fifo_free(af->buf[i]);
yading@11 53 }
yading@11 54 av_free(af->buf);
yading@11 55 }
yading@11 56 av_free(af);
yading@11 57 }
yading@11 58 }
yading@11 59
yading@11 60 AVAudioFifo *av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels,
yading@11 61 int nb_samples)
yading@11 62 {
yading@11 63 AVAudioFifo *af;
yading@11 64 int buf_size, i;
yading@11 65
yading@11 66 /* get channel buffer size (also validates parameters) */
yading@11 67 if (av_samples_get_buffer_size(&buf_size, channels, nb_samples, sample_fmt, 1) < 0)
yading@11 68 return NULL;
yading@11 69
yading@11 70 af = av_mallocz(sizeof(*af));
yading@11 71 if (!af)
yading@11 72 return NULL;
yading@11 73
yading@11 74 af->channels = channels;
yading@11 75 af->sample_fmt = sample_fmt;
yading@11 76 af->sample_size = buf_size / nb_samples;
yading@11 77 af->nb_buffers = av_sample_fmt_is_planar(sample_fmt) ? channels : 1;
yading@11 78
yading@11 79 af->buf = av_mallocz(af->nb_buffers * sizeof(*af->buf));
yading@11 80 if (!af->buf)
yading@11 81 goto error;
yading@11 82
yading@11 83 for (i = 0; i < af->nb_buffers; i++) {
yading@11 84 af->buf[i] = av_fifo_alloc(buf_size);
yading@11 85 if (!af->buf[i])
yading@11 86 goto error;
yading@11 87 }
yading@11 88 af->allocated_samples = nb_samples;
yading@11 89
yading@11 90 return af;
yading@11 91
yading@11 92 error:
yading@11 93 av_audio_fifo_free(af);
yading@11 94 return NULL;
yading@11 95 }
yading@11 96
yading@11 97 int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples)
yading@11 98 {
yading@11 99 int i, ret, buf_size;
yading@11 100
yading@11 101 if ((ret = av_samples_get_buffer_size(&buf_size, af->channels, nb_samples,
yading@11 102 af->sample_fmt, 1)) < 0)
yading@11 103 return ret;
yading@11 104
yading@11 105 for (i = 0; i < af->nb_buffers; i++) {
yading@11 106 if ((ret = av_fifo_realloc2(af->buf[i], buf_size)) < 0)
yading@11 107 return ret;
yading@11 108 }
yading@11 109 af->allocated_samples = nb_samples;
yading@11 110 return 0;
yading@11 111 }
yading@11 112
yading@11 113 int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
yading@11 114 {
yading@11 115 int i, ret, size;
yading@11 116
yading@11 117 /* automatically reallocate buffers if needed */
yading@11 118 if (av_audio_fifo_space(af) < nb_samples) {
yading@11 119 int current_size = av_audio_fifo_size(af);
yading@11 120 /* check for integer overflow in new size calculation */
yading@11 121 if (INT_MAX / 2 - current_size < nb_samples)
yading@11 122 return AVERROR(EINVAL);
yading@11 123 /* reallocate buffers */
yading@11 124 if ((ret = av_audio_fifo_realloc(af, 2 * (current_size + nb_samples))) < 0)
yading@11 125 return ret;
yading@11 126 }
yading@11 127
yading@11 128 size = nb_samples * af->sample_size;
yading@11 129 for (i = 0; i < af->nb_buffers; i++) {
yading@11 130 ret = av_fifo_generic_write(af->buf[i], data[i], size, NULL);
yading@11 131 if (ret != size)
yading@11 132 return AVERROR_BUG;
yading@11 133 }
yading@11 134 af->nb_samples += nb_samples;
yading@11 135
yading@11 136 return nb_samples;
yading@11 137 }
yading@11 138
yading@11 139 int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
yading@11 140 {
yading@11 141 int i, ret, size;
yading@11 142
yading@11 143 if (nb_samples < 0)
yading@11 144 return AVERROR(EINVAL);
yading@11 145 nb_samples = FFMIN(nb_samples, af->nb_samples);
yading@11 146 if (!nb_samples)
yading@11 147 return 0;
yading@11 148
yading@11 149 size = nb_samples * af->sample_size;
yading@11 150 for (i = 0; i < af->nb_buffers; i++) {
yading@11 151 if ((ret = av_fifo_generic_read(af->buf[i], data[i], size, NULL)) < 0)
yading@11 152 return AVERROR_BUG;
yading@11 153 }
yading@11 154 af->nb_samples -= nb_samples;
yading@11 155
yading@11 156 return nb_samples;
yading@11 157 }
yading@11 158
yading@11 159 int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
yading@11 160 {
yading@11 161 int i, size;
yading@11 162
yading@11 163 if (nb_samples < 0)
yading@11 164 return AVERROR(EINVAL);
yading@11 165 nb_samples = FFMIN(nb_samples, af->nb_samples);
yading@11 166
yading@11 167 if (nb_samples) {
yading@11 168 size = nb_samples * af->sample_size;
yading@11 169 for (i = 0; i < af->nb_buffers; i++)
yading@11 170 av_fifo_drain(af->buf[i], size);
yading@11 171 af->nb_samples -= nb_samples;
yading@11 172 }
yading@11 173 return 0;
yading@11 174 }
yading@11 175
yading@11 176 void av_audio_fifo_reset(AVAudioFifo *af)
yading@11 177 {
yading@11 178 int i;
yading@11 179
yading@11 180 for (i = 0; i < af->nb_buffers; i++)
yading@11 181 av_fifo_reset(af->buf[i]);
yading@11 182
yading@11 183 af->nb_samples = 0;
yading@11 184 }
yading@11 185
yading@11 186 int av_audio_fifo_size(AVAudioFifo *af)
yading@11 187 {
yading@11 188 return af->nb_samples;
yading@11 189 }
yading@11 190
yading@11 191 int av_audio_fifo_space(AVAudioFifo *af)
yading@11 192 {
yading@11 193 return af->allocated_samples - af->nb_samples;
yading@11 194 }