Subversion Repositories Kolibri OS

Rev

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