Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  28. typedef struct ChanDelay {
  29.     int delay;
  30.     unsigned delay_index;
  31.     unsigned index;
  32.     uint8_t *samples;
  33. } ChanDelay;
  34.  
  35. typedef 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.  
  51. static 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.  
  56. AVFILTER_DEFINE_CLASS(adelay);
  57.  
  58. static 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.     int ret;
  68.  
  69.     layouts = ff_all_channel_layouts();
  70.     if (!layouts)
  71.         return AVERROR(ENOMEM);
  72.     ret = ff_set_common_channel_layouts(ctx, layouts);
  73.     if (ret < 0)
  74.         return ret;
  75.  
  76.     formats = ff_make_format_list(sample_fmts);
  77.     if (!formats)
  78.         return AVERROR(ENOMEM);
  79.     ret = ff_set_common_formats(ctx, formats);
  80.     if (ret < 0)
  81.         return ret;
  82.  
  83.     formats = ff_all_samplerates();
  84.     if (!formats)
  85.         return AVERROR(ENOMEM);
  86.     return ff_set_common_samplerates(ctx, formats);
  87. }
  88.  
  89. #define DELAY(name, type, fill)                                           \
  90. static void delay_channel_## name ##p(ChanDelay *d, int nb_samples,       \
  91.                                       const uint8_t *ssrc, uint8_t *ddst) \
  92. {                                                                         \
  93.     const type *src = (type *)ssrc;                                       \
  94.     type *dst = (type *)ddst;                                             \
  95.     type *samples = (type *)d->samples;                                   \
  96.                                                                           \
  97.     while (nb_samples) {                                                  \
  98.         if (d->delay_index < d->delay) {                                  \
  99.             const int len = FFMIN(nb_samples, d->delay - d->delay_index); \
  100.                                                                           \
  101.             memcpy(&samples[d->delay_index], src, len * sizeof(type));    \
  102.             memset(dst, fill, len * sizeof(type));                        \
  103.             d->delay_index += len;                                        \
  104.             src += len;                                                   \
  105.             dst += len;                                                   \
  106.             nb_samples -= len;                                            \
  107.         } else {                                                          \
  108.             *dst = samples[d->index];                                     \
  109.             samples[d->index] = *src;                                     \
  110.             nb_samples--;                                                 \
  111.             d->index++;                                                   \
  112.             src++, dst++;                                                 \
  113.             d->index = d->index >= d->delay ? 0 : d->index;               \
  114.         }                                                                 \
  115.     }                                                                     \
  116. }
  117.  
  118. DELAY(u8,  uint8_t, 0x80)
  119. DELAY(s16, int16_t, 0)
  120. DELAY(s32, int32_t, 0)
  121. DELAY(flt, float,   0)
  122. DELAY(dbl, double,  0)
  123.  
  124. static int config_input(AVFilterLink *inlink)
  125. {
  126.     AVFilterContext *ctx = inlink->dst;
  127.     AudioDelayContext *s = ctx->priv;
  128.     char *p, *arg, *saveptr = NULL;
  129.     int i;
  130.  
  131.     s->chandelay = av_calloc(inlink->channels, sizeof(*s->chandelay));
  132.     if (!s->chandelay)
  133.         return AVERROR(ENOMEM);
  134.     s->nb_delays = inlink->channels;
  135.     s->block_align = av_get_bytes_per_sample(inlink->format);
  136.  
  137.     p = s->delays;
  138.     for (i = 0; i < s->nb_delays; i++) {
  139.         ChanDelay *d = &s->chandelay[i];
  140.         float delay;
  141.  
  142.         if (!(arg = av_strtok(p, "|", &saveptr)))
  143.             break;
  144.  
  145.         p = NULL;
  146.         sscanf(arg, "%f", &delay);
  147.  
  148.         d->delay = delay * inlink->sample_rate / 1000.0;
  149.         if (d->delay < 0) {
  150.             av_log(ctx, AV_LOG_ERROR, "Delay must be non negative number.\n");
  151.             return AVERROR(EINVAL);
  152.         }
  153.     }
  154.  
  155.     for (i = 0; i < s->nb_delays; i++) {
  156.         ChanDelay *d = &s->chandelay[i];
  157.  
  158.         if (!d->delay)
  159.             continue;
  160.  
  161.         d->samples = av_malloc_array(d->delay, s->block_align);
  162.         if (!d->samples)
  163.             return AVERROR(ENOMEM);
  164.  
  165.         s->max_delay = FFMAX(s->max_delay, d->delay);
  166.     }
  167.  
  168.     if (!s->max_delay) {
  169.         av_log(ctx, AV_LOG_ERROR, "At least one delay >0 must be specified.\n");
  170.         return AVERROR(EINVAL);
  171.     }
  172.  
  173.     switch (inlink->format) {
  174.     case AV_SAMPLE_FMT_U8P : s->delay_channel = delay_channel_u8p ; break;
  175.     case AV_SAMPLE_FMT_S16P: s->delay_channel = delay_channel_s16p; break;
  176.     case AV_SAMPLE_FMT_S32P: s->delay_channel = delay_channel_s32p; break;
  177.     case AV_SAMPLE_FMT_FLTP: s->delay_channel = delay_channel_fltp; break;
  178.     case AV_SAMPLE_FMT_DBLP: s->delay_channel = delay_channel_dblp; break;
  179.     }
  180.  
  181.     return 0;
  182. }
  183.  
  184. static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
  185. {
  186.     AVFilterContext *ctx = inlink->dst;
  187.     AudioDelayContext *s = ctx->priv;
  188.     AVFrame *out_frame;
  189.     int i;
  190.  
  191.     if (ctx->is_disabled || !s->delays)
  192.         return ff_filter_frame(ctx->outputs[0], frame);
  193.  
  194.     out_frame = ff_get_audio_buffer(inlink, frame->nb_samples);
  195.     if (!out_frame)
  196.         return AVERROR(ENOMEM);
  197.     av_frame_copy_props(out_frame, frame);
  198.  
  199.     for (i = 0; i < s->nb_delays; i++) {
  200.         ChanDelay *d = &s->chandelay[i];
  201.         const uint8_t *src = frame->extended_data[i];
  202.         uint8_t *dst = out_frame->extended_data[i];
  203.  
  204.         if (!d->delay)
  205.             memcpy(dst, src, frame->nb_samples * s->block_align);
  206.         else
  207.             s->delay_channel(d, frame->nb_samples, src, dst);
  208.     }
  209.  
  210.     s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base);
  211.     av_frame_free(&frame);
  212.     return ff_filter_frame(ctx->outputs[0], out_frame);
  213. }
  214.  
  215. static int request_frame(AVFilterLink *outlink)
  216. {
  217.     AVFilterContext *ctx = outlink->src;
  218.     AudioDelayContext *s = ctx->priv;
  219.     int ret;
  220.  
  221.     ret = ff_request_frame(ctx->inputs[0]);
  222.     if (ret == AVERROR_EOF && !ctx->is_disabled && s->max_delay) {
  223.         int nb_samples = FFMIN(s->max_delay, 2048);
  224.         AVFrame *frame;
  225.  
  226.         frame = ff_get_audio_buffer(outlink, nb_samples);
  227.         if (!frame)
  228.             return AVERROR(ENOMEM);
  229.         s->max_delay -= nb_samples;
  230.  
  231.         av_samples_set_silence(frame->extended_data, 0,
  232.                                frame->nb_samples,
  233.                                outlink->channels,
  234.                                frame->format);
  235.  
  236.         frame->pts = s->next_pts;
  237.         if (s->next_pts != AV_NOPTS_VALUE)
  238.             s->next_pts += av_rescale_q(nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
  239.  
  240.         ret = filter_frame(ctx->inputs[0], frame);
  241.     }
  242.  
  243.     return ret;
  244. }
  245.  
  246. static av_cold void uninit(AVFilterContext *ctx)
  247. {
  248.     AudioDelayContext *s = ctx->priv;
  249.     int i;
  250.  
  251.     for (i = 0; i < s->nb_delays; i++)
  252.         av_freep(&s->chandelay[i].samples);
  253.     av_freep(&s->chandelay);
  254. }
  255.  
  256. static const AVFilterPad adelay_inputs[] = {
  257.     {
  258.         .name         = "default",
  259.         .type         = AVMEDIA_TYPE_AUDIO,
  260.         .config_props = config_input,
  261.         .filter_frame = filter_frame,
  262.     },
  263.     { NULL }
  264. };
  265.  
  266. static const AVFilterPad adelay_outputs[] = {
  267.     {
  268.         .name          = "default",
  269.         .request_frame = request_frame,
  270.         .type          = AVMEDIA_TYPE_AUDIO,
  271.     },
  272.     { NULL }
  273. };
  274.  
  275. AVFilter ff_af_adelay = {
  276.     .name          = "adelay",
  277.     .description   = NULL_IF_CONFIG_SMALL("Delay one or more audio channels."),
  278.     .query_formats = query_formats,
  279.     .priv_size     = sizeof(AudioDelayContext),
  280.     .priv_class    = &adelay_class,
  281.     .uninit        = uninit,
  282.     .inputs        = adelay_inputs,
  283.     .outputs       = adelay_outputs,
  284.     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
  285. };
  286.