1/* 2 * Copyright (c) 2013 Paul B Mahol 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "libavutil/avstring.h" 22#include "libavutil/opt.h" 23#include "libavutil/samplefmt.h" 24#include "avfilter.h" 25#include "audio.h" 26#include "internal.h" 27 28typedef struct ChanDelay { 29 int delay; 30 unsigned delay_index; 31 unsigned index; 32 uint8_t *samples; 33} ChanDelay; 34 35typedef struct AudioDelayContext { 36 const AVClass *class; 37 char *delays; 38 ChanDelay *chandelay; 39 int nb_delays; 40 int block_align; 41 unsigned max_delay; 42 int64_t next_pts; 43 44 void (*delay_channel)(ChanDelay *d, int nb_samples, 45 const uint8_t *src, uint8_t *dst); 46} AudioDelayContext; 47 48#define OFFSET(x) offsetof(AudioDelayContext, x) 49#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM 50 51static const AVOption adelay_options[] = { 52 { "delays", "set list of delays for each channel", OFFSET(delays), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, A }, 53 { NULL } 54}; 55 56AVFILTER_DEFINE_CLASS(adelay); 57 58static int query_formats(AVFilterContext *ctx) 59{ 60 AVFilterChannelLayouts *layouts; 61 AVFilterFormats *formats; 62 static const enum AVSampleFormat sample_fmts[] = { 63 AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, 64 AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_DBLP, 65 AV_SAMPLE_FMT_NONE 66 }; 67 68 layouts = ff_all_channel_layouts(); 69 if (!layouts) 70 return AVERROR(ENOMEM); 71 ff_set_common_channel_layouts(ctx, layouts); 72 73 formats = ff_make_format_list(sample_fmts); 74 if (!formats) 75 return AVERROR(ENOMEM); 76 ff_set_common_formats(ctx, formats); 77 78 formats = ff_all_samplerates(); 79 if (!formats) 80 return AVERROR(ENOMEM); 81 ff_set_common_samplerates(ctx, formats); 82 83 return 0; 84} 85 86#define DELAY(name, type, fill) \ 87static void delay_channel_## name ##p(ChanDelay *d, int nb_samples, \ 88 const uint8_t *ssrc, uint8_t *ddst) \ 89{ \ 90 const type *src = (type *)ssrc; \ 91 type *dst = (type *)ddst; \ 92 type *samples = (type *)d->samples; \ 93 \ 94 while (nb_samples) { \ 95 if (d->delay_index < d->delay) { \ 96 const int len = FFMIN(nb_samples, d->delay - d->delay_index); \ 97 \ 98 memcpy(&samples[d->delay_index], src, len * sizeof(type)); \ 99 memset(dst, fill, len * sizeof(type)); \ 100 d->delay_index += len; \ 101 src += len; \ 102 dst += len; \ 103 nb_samples -= len; \ 104 } else { \ 105 *dst = samples[d->index]; \ 106 samples[d->index] = *src; \ 107 nb_samples--; \ 108 d->index++; \ 109 src++, dst++; \ 110 d->index = d->index >= d->delay ? 0 : d->index; \ 111 } \ 112 } \ 113} 114 115DELAY(u8, uint8_t, 0x80) 116DELAY(s16, int16_t, 0) 117DELAY(s32, int32_t, 0) 118DELAY(flt, float, 0) 119DELAY(dbl, double, 0) 120 121static int config_input(AVFilterLink *inlink) 122{ 123 AVFilterContext *ctx = inlink->dst; 124 AudioDelayContext *s = ctx->priv; 125 char *p, *arg, *saveptr = NULL; 126 int i; 127 128 s->chandelay = av_calloc(inlink->channels, sizeof(*s->chandelay)); 129 if (!s->chandelay) 130 return AVERROR(ENOMEM); 131 s->nb_delays = inlink->channels; 132 s->block_align = av_get_bytes_per_sample(inlink->format); 133 134 p = s->delays; 135 for (i = 0; i < s->nb_delays; i++) { 136 ChanDelay *d = &s->chandelay[i]; 137 float delay; 138 139 if (!(arg = av_strtok(p, "|", &saveptr))) 140 break; 141 142 p = NULL; 143 sscanf(arg, "%f", &delay); 144 145 d->delay = delay * inlink->sample_rate / 1000.0; 146 if (d->delay < 0) { 147 av_log(ctx, AV_LOG_ERROR, "Delay must be non negative number.\n"); 148 return AVERROR(EINVAL); 149 } 150 } 151 152 for (i = 0; i < s->nb_delays; i++) { 153 ChanDelay *d = &s->chandelay[i]; 154 155 if (!d->delay) 156 continue; 157 158 d->samples = av_malloc_array(d->delay, s->block_align); 159 if (!d->samples) 160 return AVERROR(ENOMEM); 161 162 s->max_delay = FFMAX(s->max_delay, d->delay); 163 } 164 165 if (!s->max_delay) { 166 av_log(ctx, AV_LOG_ERROR, "At least one delay >0 must be specified.\n"); 167 return AVERROR(EINVAL); 168 } 169 170 switch (inlink->format) { 171 case AV_SAMPLE_FMT_U8P : s->delay_channel = delay_channel_u8p ; break; 172 case AV_SAMPLE_FMT_S16P: s->delay_channel = delay_channel_s16p; break; 173 case AV_SAMPLE_FMT_S32P: s->delay_channel = delay_channel_s32p; break; 174 case AV_SAMPLE_FMT_FLTP: s->delay_channel = delay_channel_fltp; break; 175 case AV_SAMPLE_FMT_DBLP: s->delay_channel = delay_channel_dblp; break; 176 } 177 178 return 0; 179} 180 181static int filter_frame(AVFilterLink *inlink, AVFrame *frame) 182{ 183 AVFilterContext *ctx = inlink->dst; 184 AudioDelayContext *s = ctx->priv; 185 AVFrame *out_frame; 186 int i; 187 188 if (ctx->is_disabled || !s->delays) 189 return ff_filter_frame(ctx->outputs[0], frame); 190 191 out_frame = ff_get_audio_buffer(inlink, frame->nb_samples); 192 if (!out_frame) 193 return AVERROR(ENOMEM); 194 av_frame_copy_props(out_frame, frame); 195 196 for (i = 0; i < s->nb_delays; i++) { 197 ChanDelay *d = &s->chandelay[i]; 198 const uint8_t *src = frame->extended_data[i]; 199 uint8_t *dst = out_frame->extended_data[i]; 200 201 if (!d->delay) 202 memcpy(dst, src, frame->nb_samples * s->block_align); 203 else 204 s->delay_channel(d, frame->nb_samples, src, dst); 205 } 206 207 s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base); 208 av_frame_free(&frame); 209 return ff_filter_frame(ctx->outputs[0], out_frame); 210} 211 212static int request_frame(AVFilterLink *outlink) 213{ 214 AVFilterContext *ctx = outlink->src; 215 AudioDelayContext *s = ctx->priv; 216 int ret; 217 218 ret = ff_request_frame(ctx->inputs[0]); 219 if (ret == AVERROR_EOF && !ctx->is_disabled && s->max_delay) { 220 int nb_samples = FFMIN(s->max_delay, 2048); 221 AVFrame *frame; 222 223 frame = ff_get_audio_buffer(outlink, nb_samples); 224 if (!frame) 225 return AVERROR(ENOMEM); 226 s->max_delay -= nb_samples; 227 228 av_samples_set_silence(frame->extended_data, 0, 229 frame->nb_samples, 230 outlink->channels, 231 frame->format); 232 233 frame->pts = s->next_pts; 234 if (s->next_pts != AV_NOPTS_VALUE) 235 s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base); 236 237 ret = filter_frame(ctx->inputs[0], frame); 238 } 239 240 return ret; 241} 242 243static av_cold void uninit(AVFilterContext *ctx) 244{ 245 AudioDelayContext *s = ctx->priv; 246 int i; 247 248 for (i = 0; i < s->nb_delays; i++) 249 av_free(s->chandelay[i].samples); 250 av_freep(&s->chandelay); 251} 252 253static const AVFilterPad adelay_inputs[] = { 254 { 255 .name = "default", 256 .type = AVMEDIA_TYPE_AUDIO, 257 .config_props = config_input, 258 .filter_frame = filter_frame, 259 }, 260 { NULL } 261}; 262 263static const AVFilterPad adelay_outputs[] = { 264 { 265 .name = "default", 266 .request_frame = request_frame, 267 .type = AVMEDIA_TYPE_AUDIO, 268 }, 269 { NULL } 270}; 271 272AVFilter ff_af_adelay = { 273 .name = "adelay", 274 .description = NULL_IF_CONFIG_SMALL("Delay one or more audio channels."), 275 .query_formats = query_formats, 276 .priv_size = sizeof(AudioDelayContext), 277 .priv_class = &adelay_class, 278 .uninit = uninit, 279 .inputs = adelay_inputs, 280 .outputs = adelay_outputs, 281 .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, 282}; 283