From 9e6d2583bd42e3ddd12a4ac137e788ca7ad467e4 Mon Sep 17 00:00:00 2001
From: Kyle Swanson <k@ylo.ph>
Date: Sat, 18 Jun 2016 01:29:02 -0500
Subject: [PATCH 1/2] avfilter: add libebur128 port

Signed-off-by: Kyle Swanson <k@ylo.ph>
---
 libavfilter/ebur128.c | 1058 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavfilter/ebur128.h |  345 ++++++++++++++++
 libavfilter/queue.h   |  592 +++++++++++++++++++++++++++
 3 files changed, 1995 insertions(+)
 create mode 100644 libavfilter/ebur128.c
 create mode 100644 libavfilter/ebur128.h
 create mode 100644 libavfilter/queue.h

diff --git a/libavfilter/ebur128.c b/libavfilter/ebur128.c
new file mode 100644
index 0000000..6fabd73
--- /dev/null
+++ b/libavfilter/ebur128.c
@@ -0,0 +1,1058 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This file uses code from libebur128 which has the following license:
+ *
+ * Copyright (c) 2011 Jan Kokemüller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "ebur128.h"
+
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "libavutil/channel_layout.h"
+#include "libswresample/swresample.h"
+#include "libavutil/opt.h"
+#include "queue.h"
+
+
+#define CHECK_ERROR(condition, errorcode, goto_point)                            \
+    if ((condition)) {                                                           \
+        errcode = (errorcode);                                                   \
+        goto goto_point;                                                         \
+    }
+
+SLIST_HEAD(ebur128_double_queue, ebur128_dq_entry);
+struct ebur128_dq_entry {
+    double z;
+    SLIST_ENTRY(ebur128_dq_entry) entries;
+};
+
+struct ebur128_state_internal {
+    /** Filtered audio data (used as ring buffer). */
+    double* audio_data;
+    /** Size of audio_data array. */
+    size_t audio_data_frames;
+    /** Current index for audio_data. */
+    size_t audio_data_index;
+    /** How many frames are needed for a gating block. Will correspond to 400ms
+     *  of audio at initialization, and 100ms after the first block (75% overlap
+     *  as specified in the 2011 revision of BS1770). */
+    unsigned long needed_frames;
+    /** The channel map. Has as many elements as there are channels. */
+    int* channel_map;
+    /** How many samples fit in 100ms (rounded). */
+    unsigned long samples_in_100ms;
+    /** BS.1770 filter coefficients (nominator). */
+    double b[5];
+    /** BS.1770 filter coefficients (denominator). */
+    double a[5];
+    /** BS.1770 filter state. */
+    double v[5][5];
+    /** Linked list of block energies. */
+    struct ebur128_double_queue block_list;
+    /** Linked list of 3s-block energies, used to calculate LRA. */
+    struct ebur128_double_queue short_term_block_list;
+    int use_histogram;
+    unsigned long *block_energy_histogram;
+    unsigned long *short_term_block_energy_histogram;
+    /** Keeps track of when a new short term block is needed. */
+    size_t short_term_frame_counter;
+    /** Maximum sample peak, one per channel */
+    double* sample_peak;
+    /** Maximum true peak, one per channel */
+    double* true_peak;
+#if CONFIG_SWRESAMPLE
+    SwrContext *resampler;
+#endif
+    size_t oversample_factor;
+    float* resampler_buffer_input;
+    size_t resampler_buffer_input_frames;
+    float* resampler_buffer_output;
+    size_t resampler_buffer_output_frames;
+};
+
+static double relative_gate = -10.0;
+
+/* Those will be calculated when initializing the library */
+static double relative_gate_factor;
+static double minus_twenty_decibels;
+static double histogram_energies[1000];
+static double histogram_energy_boundaries[1001];
+
+static void ebur128_init_filter(ebur128_state* st)
+{
+    int i, j;
+
+    double f0 = 1681.974450955533;
+    double G  =    3.999843853973347;
+    double Q  =    0.7071752369554196;
+
+    double K  = tan(M_PI * f0 / (double) st->samplerate);
+    double Vh = pow(10.0, G / 20.0);
+    double Vb = pow(Vh, 0.4996667741545416);
+
+    double pb[3] = {0.0,  0.0, 0.0};
+    double pa[3] = {1.0,  0.0, 0.0};
+    double rb[3] = {1.0, -2.0, 1.0};
+    double ra[3] = {1.0,  0.0, 0.0};
+
+    double a0 =      1.0 + K / Q + K * K      ;
+    pb[0] =     (Vh + Vb * K / Q + K * K) / a0;
+    pb[1] =           2.0 * (K * K -  Vh) / a0;
+    pb[2] =     (Vh - Vb * K / Q + K * K) / a0;
+    pa[1] =           2.0 * (K * K - 1.0) / a0;
+    pa[2] =         (1.0 - K / Q + K * K) / a0;
+
+    f0 = 38.13547087602444;
+    Q  =  0.5003270373238773;
+    K  = tan(M_PI * f0 / (double) st->samplerate);
+
+    ra[1] =   2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
+    ra[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
+
+    st->d->b[0] = pb[0] * rb[0];
+    st->d->b[1] = pb[0] * rb[1] + pb[1] * rb[0];
+    st->d->b[2] = pb[0] * rb[2] + pb[1] * rb[1] + pb[2] * rb[0];
+    st->d->b[3] = pb[1] * rb[2] + pb[2] * rb[1];
+    st->d->b[4] = pb[2] * rb[2];
+
+    st->d->a[0] = pa[0] * ra[0];
+    st->d->a[1] = pa[0] * ra[1] + pa[1] * ra[0];
+    st->d->a[2] = pa[0] * ra[2] + pa[1] * ra[1] + pa[2] * ra[0];
+    st->d->a[3] = pa[1] * ra[2] + pa[2] * ra[1];
+    st->d->a[4] = pa[2] * ra[2];
+
+    for (i = 0; i < 5; ++i) {
+        for (j = 0; j < 5; ++j) {
+            st->d->v[i][j] = 0.0;
+        }
+    }
+}
+
+static int ebur128_init_channel_map(ebur128_state* st)
+{
+    size_t i;
+    st->d->channel_map = (int*) av_malloc(st->channels * sizeof(int));
+    if (!st->d->channel_map) return EBUR128_ERROR_NOMEM;
+    if (st->channels == 4) {
+        st->d->channel_map[0] = EBUR128_LEFT;
+        st->d->channel_map[1] = EBUR128_RIGHT;
+        st->d->channel_map[2] = EBUR128_LEFT_SURROUND;
+        st->d->channel_map[3] = EBUR128_RIGHT_SURROUND;
+    } else if (st->channels == 5) {
+        st->d->channel_map[0] = EBUR128_LEFT;
+        st->d->channel_map[1] = EBUR128_RIGHT;
+        st->d->channel_map[2] = EBUR128_CENTER;
+        st->d->channel_map[3] = EBUR128_LEFT_SURROUND;
+        st->d->channel_map[4] = EBUR128_RIGHT_SURROUND;
+    } else {
+        for (i = 0; i < st->channels; ++i) {
+            switch (i) {
+                case 0:  st->d->channel_map[i] = EBUR128_LEFT;           break;
+                case 1:  st->d->channel_map[i] = EBUR128_RIGHT;          break;
+                case 2:  st->d->channel_map[i] = EBUR128_CENTER;         break;
+                case 3:  st->d->channel_map[i] = EBUR128_UNUSED;         break;
+                case 4:  st->d->channel_map[i] = EBUR128_LEFT_SURROUND;  break;
+                case 5:  st->d->channel_map[i] = EBUR128_RIGHT_SURROUND; break;
+                default: st->d->channel_map[i] = EBUR128_UNUSED;         break;
+            }
+        }
+    }
+    return EBUR128_SUCCESS;
+}
+
+#if CONFIG_SWRESAMPLE
+static int ebur128_init_resampler(ebur128_state* st)
+{
+    int errcode = EBUR128_SUCCESS;
+    int64_t channel_layout;
+
+    if (st->samplerate < 96000) {
+        st->d->oversample_factor = 4;
+    } else if (st->samplerate < 192000) {
+        st->d->oversample_factor = 2;
+    } else {
+        st->d->oversample_factor = 1;
+        st->d->resampler_buffer_input = NULL;
+        st->d->resampler_buffer_output = NULL;
+        st->d->resampler = NULL;
+    }
+
+    st->d->resampler_buffer_input_frames = st->d->samples_in_100ms * 4;
+    st->d->resampler_buffer_input = av_malloc(st->d->resampler_buffer_input_frames *
+            st->channels *
+            sizeof(float));
+    CHECK_ERROR(!st->d->resampler_buffer_input, EBUR128_ERROR_NOMEM, exit)
+
+        st->d->resampler_buffer_output_frames =
+        st->d->resampler_buffer_input_frames *
+        st->d->oversample_factor;
+    st->d->resampler_buffer_output = av_malloc
+        (st->d->resampler_buffer_output_frames *
+         st->channels *
+         sizeof(float));
+    CHECK_ERROR(!st->d->resampler_buffer_output, EBUR128_ERROR_NOMEM, free_input)
+
+        st->d->resampler = swr_alloc();
+    CHECK_ERROR(!st->d->resampler, EBUR128_ERROR_NOMEM, free_output)
+
+        channel_layout = av_get_default_channel_layout(st->channels);
+
+    av_opt_set_int(st->d->resampler, "in_channel_layout", channel_layout, 0);
+    av_opt_set_int(st->d->resampler, "in_sample_rate", st->samplerate, 0);
+    av_opt_set_sample_fmt(st->d->resampler, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+    av_opt_set_int(st->d->resampler, "out_channel_layout", channel_layout, 0);
+    av_opt_set_int(st->d->resampler, "out_sample_rate", st->samplerate * st->d->oversample_factor, 0);
+    av_opt_set_sample_fmt(st->d->resampler, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+
+    swr_init(st->d->resampler);
+
+    return errcode;
+
+free_output:
+    av_free(st->d->resampler_buffer_output);
+    st->d->resampler_buffer_output = NULL;
+free_input:
+    av_free(st->d->resampler_buffer_input);
+    st->d->resampler_buffer_input = NULL;
+exit:
+    return errcode;
+}
+
+static void ebur128_destroy_resampler(ebur128_state* st)
+{
+    av_free(st->d->resampler_buffer_input);
+    st->d->resampler_buffer_input = NULL;
+    av_free(st->d->resampler_buffer_output);
+    st->d->resampler_buffer_output = NULL;
+    swr_free(&st->d->resampler);
+    st->d->resampler = NULL;
+}
+#endif
+
+ebur128_state* ff_ebur128_init(unsigned int channels, unsigned long samplerate, int mode)
+{
+    int errcode, result;
+    ebur128_state* st;
+    unsigned int i;
+
+    st = (ebur128_state*) av_malloc(sizeof(ebur128_state));
+    CHECK_ERROR(!st, 0, exit)
+        st->d = (struct ebur128_state_internal*)
+        av_malloc(sizeof(struct ebur128_state_internal));
+    CHECK_ERROR(!st->d, 0, free_state)
+        st->channels = channels;
+    errcode = ebur128_init_channel_map(st);
+    CHECK_ERROR(errcode, 0, free_internal)
+
+        st->d->sample_peak = (double*) av_malloc(channels * sizeof(double));
+    CHECK_ERROR(!st->d->sample_peak, 0, free_channel_map)
+        st->d->true_peak = (double*) av_malloc(channels * sizeof(double));
+    CHECK_ERROR(!st->d->true_peak, 0, free_sample_peak)
+        for (i = 0; i < channels; ++i) {
+            st->d->sample_peak[i] = 0.0;
+            st->d->true_peak[i] = 0.0;
+        }
+
+    st->d->use_histogram = mode & EBUR128_MODE_HISTOGRAM ? 1 : 0;
+
+    st->samplerate = samplerate;
+    st->d->samples_in_100ms = (st->samplerate + 5) / 10;
+    st->mode = mode;
+    if ((mode & EBUR128_MODE_S) == EBUR128_MODE_S) {
+        st->d->audio_data_frames = st->d->samples_in_100ms * 30;
+    } else if ((mode & EBUR128_MODE_M) == EBUR128_MODE_M) {
+        st->d->audio_data_frames = st->d->samples_in_100ms * 4;
+    } else {
+        goto free_true_peak;
+    }
+    st->d->audio_data = (double*) av_malloc(st->d->audio_data_frames *
+            st->channels *
+            sizeof(double));
+    CHECK_ERROR(!st->d->audio_data, 0, free_true_peak)
+        ebur128_init_filter(st);
+
+    if (st->d->use_histogram) {
+        st->d->block_energy_histogram = av_malloc(1000 * sizeof(unsigned long));
+        CHECK_ERROR(!st->d->block_energy_histogram, 0, free_audio_data)
+            for (i = 0; i < 1000; ++i) {
+                st->d->block_energy_histogram[i] = 0;
+            }
+    } else {
+        st->d->block_energy_histogram = NULL;
+    }
+    if (st->d->use_histogram) {
+        st->d->short_term_block_energy_histogram = av_malloc(1000 * sizeof(unsigned long));
+        CHECK_ERROR(!st->d->short_term_block_energy_histogram, 0, free_block_energy_histogram)
+            for (i = 0; i < 1000; ++i) {
+                st->d->short_term_block_energy_histogram[i] = 0;
+            }
+    } else {
+        st->d->short_term_block_energy_histogram = NULL;
+    }
+    SLIST_INIT(&st->d->block_list);
+    SLIST_INIT(&st->d->short_term_block_list);
+    st->d->short_term_frame_counter = 0;
+
+#if CONFIG_SWRESAMPLE
+    result = ebur128_init_resampler(st);
+    CHECK_ERROR(result, 0, free_short_term_block_energy_histogram)
+#endif
+
+    /* the first block needs 400ms of audio data */
+    st->d->needed_frames = st->d->samples_in_100ms * 4;
+    /* start at the beginning of the buffer */
+    st->d->audio_data_index = 0;
+
+    /* initialize static constants */
+    relative_gate_factor = pow(10.0, relative_gate / 10.0);
+    minus_twenty_decibels = pow(10.0, -20.0 / 10.0);
+    histogram_energy_boundaries[0] = pow(10.0, (-70.0 + 0.691) / 10.0);
+    if (st->d->use_histogram) {
+        for (i = 0; i < 1000; ++i) {
+            histogram_energies[i] = pow(10.0, ((double) i / 10.0 - 69.95 + 0.691) / 10.0);
+        }
+        for (i = 1; i < 1001; ++i) {
+            histogram_energy_boundaries[i] = pow(10.0, ((double) i / 10.0 - 70.0 + 0.691) / 10.0);
+        }
+    }
+
+    return st;
+
+free_short_term_block_energy_histogram:
+    av_free(st->d->short_term_block_energy_histogram);
+free_block_energy_histogram:
+    av_free(st->d->block_energy_histogram);
+free_audio_data:
+    av_free(st->d->audio_data);
+free_true_peak:
+    av_free(st->d->true_peak);
+free_sample_peak:
+    av_free(st->d->sample_peak);
+free_channel_map:
+    av_free(st->d->channel_map);
+free_internal:
+    av_free(st->d);
+free_state:
+    av_free(st);
+exit:
+    return NULL;
+}
+
+void ff_ebur128_destroy(ebur128_state** st)
+{
+    struct ebur128_dq_entry* entry;
+    av_free((*st)->d->block_energy_histogram);
+    av_free((*st)->d->short_term_block_energy_histogram);
+    av_free((*st)->d->audio_data);
+    av_free((*st)->d->channel_map);
+    av_free((*st)->d->sample_peak);
+    av_free((*st)->d->true_peak);
+    while (!SLIST_EMPTY(&(*st)->d->block_list)) {
+        entry = SLIST_FIRST(&(*st)->d->block_list);
+        SLIST_REMOVE_HEAD(&(*st)->d->block_list, entries);
+        av_free(entry);
+    }
+    while (!SLIST_EMPTY(&(*st)->d->short_term_block_list)) {
+        entry = SLIST_FIRST(&(*st)->d->short_term_block_list);
+        SLIST_REMOVE_HEAD(&(*st)->d->short_term_block_list, entries);
+        av_free(entry);
+    }
+#if CONFIG_SWRESAMPLE
+    ebur128_destroy_resampler(*st);
+#endif
+
+    av_free((*st)->d);
+    av_free(*st);
+    *st = NULL;
+}
+
+static int ebur128_use_swresample(ebur128_state* st)
+{
+#if CONFIG_SWRESAMPLE
+    return ((st->mode & EBUR128_MODE_TRUE_PEAK) == EBUR128_MODE_TRUE_PEAK);
+#else
+    (void) st;
+    return 0;
+#endif
+}
+
+static void ebur128_check_true_peak(ebur128_state* st, size_t frames)
+{
+#if CONFIG_SWRESAMPLE
+    size_t c, i;
+
+    const int in_len  = frames;
+    const int out_len = st->d->resampler_buffer_output_frames;
+    swr_convert(st->d->resampler, (uint8_t **)&st->d->resampler_buffer_output, out_len,
+            (const uint8_t **)&st->d->resampler_buffer_input, in_len);
+
+    for (c = 0; c < st->channels; ++c) {
+        for (i = 0; i < out_len; ++i) {
+            if (st->d->resampler_buffer_output[i * st->channels + c] >
+                    st->d->true_peak[c]) {
+                st->d->true_peak[c] =
+                    st->d->resampler_buffer_output[i * st->channels + c];
+            } else if (-st->d->resampler_buffer_output[i * st->channels + c] >
+                    st->d->true_peak[c]) {
+                st->d->true_peak[c] =
+                    -st->d->resampler_buffer_output[i * st->channels + c];
+            }
+        }
+    }
+#else
+    (void) st; (void) frames;
+#endif
+}
+
+#define EBUR128_FILTER(type, min_scale, max_scale)                                      \
+    static void ebur128_filter_##type(ebur128_state* st, const type* src,               \
+            size_t frames) {                                                            \
+        static double scaling_factor = -((double) min_scale) > (double) max_scale ?     \
+        -((double) min_scale) : (double) max_scale;                                     \
+        double* audio_data = st->d->audio_data + st->d->audio_data_index;               \
+        size_t i, c;                                                                    \
+                                                                                        \
+        if ((st->mode & EBUR128_MODE_SAMPLE_PEAK) == EBUR128_MODE_SAMPLE_PEAK) {        \
+            for (c = 0; c < st->channels; ++c) {                                        \
+                double max = 0.0;                                                       \
+                for (i = 0; i < frames; ++i) {                                          \
+                    if (src[i * st->channels + c] > max) {                              \
+                        max =        src[i * st->channels + c];                         \
+                    } else if (-src[i * st->channels + c] > max) {                      \
+                        max = -1.0 * src[i * st->channels + c];                         \
+                    }                                                                   \
+                }                                                                       \
+                max /= scaling_factor;                                                  \
+                if (max > st->d->sample_peak[c]) st->d->sample_peak[c] = max;           \
+            }                                                                           \
+        }                                                                               \
+        if (ebur128_use_swresample(st)) {                                               \
+            for (c = 0; c < st->channels; ++c) {                                        \
+                for (i = 0; i < frames; ++i) {                                          \
+                    st->d->resampler_buffer_input[i * st->channels + c] =               \
+                    (float) (src[i * st->channels + c] / scaling_factor);               \
+                }                                                                       \
+            }                                                                           \
+            ebur128_check_true_peak(st, frames);                                        \
+        }                                                                               \
+        for (c = 0; c < st->channels; ++c) {                                            \
+            int ci = st->d->channel_map[c] - 1;                                         \
+            if (ci < 0) continue;                                                       \
+            else if (ci == EBUR128_DUAL_MONO - 1) ci = 0; /*dual mono */                \
+            for (i = 0; i < frames; ++i) {                                              \
+                st->d->v[ci][0] = (double) (src[i * st->channels + c] / scaling_factor) \
+                - st->d->a[1] * st->d->v[ci][1]                                         \
+                - st->d->a[2] * st->d->v[ci][2]                                         \
+                - st->d->a[3] * st->d->v[ci][3]                                         \
+                - st->d->a[4] * st->d->v[ci][4];                                        \
+                audio_data[i * st->channels + c] =                                      \
+                st->d->b[0] * st->d->v[ci][0]                                           \
+                + st->d->b[1] * st->d->v[ci][1]                                         \
+                + st->d->b[2] * st->d->v[ci][2]                                         \
+                + st->d->b[3] * st->d->v[ci][3]                                         \
+                + st->d->b[4] * st->d->v[ci][4];                                        \
+                st->d->v[ci][4] = st->d->v[ci][3];                                      \
+                st->d->v[ci][3] = st->d->v[ci][2];                                      \
+                st->d->v[ci][2] = st->d->v[ci][1];                                      \
+                st->d->v[ci][1] = st->d->v[ci][0];                                      \
+            }                                                                           \
+            st->d->v[ci][4] = fabs(st->d->v[ci][4]) < DBL_MIN ? 0.0 : st->d->v[ci][4];  \
+            st->d->v[ci][3] = fabs(st->d->v[ci][3]) < DBL_MIN ? 0.0 : st->d->v[ci][3];  \
+            st->d->v[ci][2] = fabs(st->d->v[ci][2]) < DBL_MIN ? 0.0 : st->d->v[ci][2];  \
+            st->d->v[ci][1] = fabs(st->d->v[ci][1]) < DBL_MIN ? 0.0 : st->d->v[ci][1];  \
+        }                                                                               \
+    }
+EBUR128_FILTER(short, SHRT_MIN, SHRT_MAX)
+EBUR128_FILTER(int, INT_MIN, INT_MAX)
+EBUR128_FILTER(float, -1.0f, 1.0f)
+EBUR128_FILTER(double, -1.0, 1.0)
+
+static double ebur128_energy_to_loudness(double energy)
+{
+    return 10 * (log(energy) / log(10.0)) - 0.691;
+}
+
+static size_t find_histogram_index(double energy)
+{
+    size_t index_min = 0;
+    size_t index_max = 1000;
+    size_t index_mid;
+
+    do {
+        index_mid = (index_min + index_max) / 2;
+        if (energy >= histogram_energy_boundaries[index_mid]) {
+            index_min = index_mid;
+        } else {
+            index_max = index_mid;
+        }
+    } while (index_max - index_min != 1);
+
+    return index_min;
+}
+
+static int ebur128_calc_gating_block(ebur128_state* st, size_t frames_per_block, double* optional_output)
+{
+    size_t i, c;
+    double sum = 0.0;
+    double channel_sum;
+    for (c = 0; c < st->channels; ++c) {
+        if (st->d->channel_map[c] == EBUR128_UNUSED) continue;
+        channel_sum = 0.0;
+        if (st->d->audio_data_index < frames_per_block * st->channels) {
+            for (i = 0; i < st->d->audio_data_index / st->channels; ++i) {
+                channel_sum += st->d->audio_data[i * st->channels + c] *
+                    st->d->audio_data[i * st->channels + c];
+            }
+            for (i = st->d->audio_data_frames -
+                    (frames_per_block -
+                     st->d->audio_data_index / st->channels);
+                    i < st->d->audio_data_frames; ++i) {
+                channel_sum += st->d->audio_data[i * st->channels + c] *
+                    st->d->audio_data[i * st->channels + c];
+            }
+        } else {
+            for (i = st->d->audio_data_index / st->channels - frames_per_block;
+                    i < st->d->audio_data_index / st->channels;
+                    ++i) {
+                channel_sum += st->d->audio_data[i * st->channels + c] *
+                    st->d->audio_data[i * st->channels + c];
+            }
+        }
+        if (st->d->channel_map[c] == EBUR128_Mp110 ||
+                st->d->channel_map[c] == EBUR128_Mm110 ||
+                st->d->channel_map[c] == EBUR128_Mp060 ||
+                st->d->channel_map[c] == EBUR128_Mm060 ||
+                st->d->channel_map[c] == EBUR128_Mp090 ||
+                st->d->channel_map[c] == EBUR128_Mm090) {
+            channel_sum *= 1.41;
+        } else if (st->d->channel_map[c] == EBUR128_DUAL_MONO) {
+            channel_sum *= 2.0;
+        }
+        sum += channel_sum;
+    }
+    sum /= (double) frames_per_block;
+    if (optional_output) {
+        *optional_output = sum;
+        return EBUR128_SUCCESS;
+    } else if (sum >= histogram_energy_boundaries[0]) {
+        if (st->d->use_histogram) {
+            ++st->d->block_energy_histogram[find_histogram_index(sum)];
+        } else {
+            struct ebur128_dq_entry* block;
+            block = (struct ebur128_dq_entry*) av_malloc(sizeof(struct ebur128_dq_entry));
+            if (!block) return EBUR128_ERROR_NOMEM;
+            block->z = sum;
+            SLIST_INSERT_HEAD(&st->d->block_list, block, entries);
+        }
+        return EBUR128_SUCCESS;
+    } else {
+        return EBUR128_SUCCESS;
+    }
+}
+
+int ff_ebur128_set_channel(ebur128_state* st, unsigned int channel_number, int value)
+{
+    if (channel_number >= st->channels) {
+        return 1;
+    }
+    if (value == EBUR128_DUAL_MONO && (st->channels != 1 || channel_number != 0)) {
+        av_log(NULL, AV_LOG_ERROR, "EBUR128_DUAL_MONO only works with mono files!\n");
+        return 1;
+    }
+    st->d->channel_map[channel_number] = value;
+    return 0;
+}
+
+int ff_ebur128_change_parameters(ebur128_state* st, unsigned int channels, unsigned long samplerate)
+{
+    int errcode;
+    if (channels == st->channels &&
+            samplerate == st->samplerate) {
+        return 2;
+    }
+    av_free(st->d->audio_data);
+    st->d->audio_data = NULL;
+
+    if (channels != st->channels) {
+        unsigned int i;
+
+        av_free(st->d->channel_map); st->d->channel_map = NULL;
+        av_free(st->d->sample_peak); st->d->sample_peak = NULL;
+        av_free(st->d->true_peak);   st->d->true_peak = NULL;
+        st->channels = channels;
+
+#if CONFIG_SWRESAMPLE
+        ebur128_destroy_resampler(st);
+        ebur128_init_resampler(st);
+#endif
+
+        errcode = ebur128_init_channel_map(st);
+        CHECK_ERROR(errcode, EBUR128_ERROR_NOMEM, exit)
+
+        st->d->sample_peak = (double*) av_malloc(channels * sizeof(double));
+        CHECK_ERROR(!st->d->sample_peak, EBUR128_ERROR_NOMEM, exit)
+        st->d->true_peak = (double*) av_malloc(channels * sizeof(double));
+        CHECK_ERROR(!st->d->true_peak, EBUR128_ERROR_NOMEM, exit)
+        for (i = 0; i < channels; ++i) {
+            st->d->sample_peak[i] = 0.0;
+            st->d->true_peak[i] = 0.0;
+        }
+    }
+    if (samplerate != st->samplerate) {
+        st->samplerate = samplerate;
+        ebur128_init_filter(st);
+    }
+    if ((st->mode & EBUR128_MODE_S) == EBUR128_MODE_S) {
+        st->d->audio_data_frames = st->d->samples_in_100ms * 30;
+    } else if ((st->mode & EBUR128_MODE_M) == EBUR128_MODE_M) {
+        st->d->audio_data_frames = st->d->samples_in_100ms * 4;
+    } else {
+        return 1;
+    }
+    st->d->audio_data = (double*) av_malloc(st->d->audio_data_frames * st->channels * sizeof(double));
+    CHECK_ERROR(!st->d->audio_data, EBUR128_ERROR_NOMEM, exit)
+
+    /* the first block needs 400ms of audio data */
+    st->d->needed_frames = st->d->samples_in_100ms * 4;
+    /* start at the beginning of the buffer */
+    st->d->audio_data_index = 0;
+    /* reset short term frame counter */
+    st->d->short_term_frame_counter = 0;
+
+    return 0;
+
+exit:
+    return 1;
+}
+
+
+static int ebur128_energy_shortterm(ebur128_state* st, double* out);
+#define EBUR128_ADD_FRAMES(type)                                                              \
+int ff_ebur128_add_frames_##type(ebur128_state* st,                                           \
+        const type* src, size_t frames) {                                                     \
+    size_t src_index = 0;                                                                     \
+    while (frames > 0) {                                                                      \
+        if (frames >= st->d->needed_frames) {                                                 \
+            ebur128_filter_##type(st, src + src_index, st->d->needed_frames);                 \
+            src_index += st->d->needed_frames * st->channels;                                 \
+            frames -= st->d->needed_frames;                                                   \
+            st->d->audio_data_index += st->d->needed_frames * st->channels;                   \
+            /* calculate the new gating block */                                              \
+            if ((st->mode & EBUR128_MODE_I) == EBUR128_MODE_I) {                              \
+                if (ebur128_calc_gating_block(st, st->d->samples_in_100ms * 4, NULL)) {       \
+                    return EBUR128_ERROR_NOMEM;                                               \
+                }                                                                             \
+            }                                                                                 \
+            if ((st->mode & EBUR128_MODE_LRA) == EBUR128_MODE_LRA) {                          \
+                st->d->short_term_frame_counter += st->d->needed_frames;                      \
+                if (st->d->short_term_frame_counter == st->d->samples_in_100ms * 30) {        \
+                    struct ebur128_dq_entry* block;                                           \
+                    double st_energy;                                                         \
+                    ebur128_energy_shortterm(st, &st_energy);                                 \
+                    if (st_energy >= histogram_energy_boundaries[0]) {                        \
+                        if (st->d->use_histogram) {                                           \
+                            ++st->d->short_term_block_energy_histogram[                       \
+                            find_histogram_index(st_energy)];                                 \
+                        } else {                                                              \
+                            block = (struct ebur128_dq_entry*)                                \
+                            av_malloc(sizeof(struct ebur128_dq_entry));                       \
+                            if (!block) return EBUR128_ERROR_NOMEM;                           \
+                            block->z = st_energy;                                             \
+                            SLIST_INSERT_HEAD(&st->d->short_term_block_list, block, entries); \
+                        }                                                                     \
+                    }                                                                         \
+                    st->d->short_term_frame_counter = st->d->samples_in_100ms * 20;           \
+                }                                                                             \
+            }                                                                                 \
+            /* 100ms are needed for all blocks besides the first one */                       \
+            st->d->needed_frames = st->d->samples_in_100ms;                                   \
+            /* reset audio_data_index when buffer full */                                     \
+            if (st->d->audio_data_index == st->d->audio_data_frames * st->channels) {         \
+                st->d->audio_data_index = 0;                                                  \
+            }                                                                                 \
+        } else {                                                                              \
+            ebur128_filter_##type(st, src + src_index, frames);                               \
+            st->d->audio_data_index += frames * st->channels;                                 \
+            if ((st->mode & EBUR128_MODE_LRA) == EBUR128_MODE_LRA) {                          \
+                st->d->short_term_frame_counter += frames;                                    \
+            }                                                                                 \
+            st->d->needed_frames -= frames;                                                   \
+            frames = 0;                                                                       \
+        }                                                                                     \
+    }                                                                                         \
+    return EBUR128_SUCCESS;                                                                   \
+}
+EBUR128_ADD_FRAMES(short)
+EBUR128_ADD_FRAMES(int)
+EBUR128_ADD_FRAMES(float)
+EBUR128_ADD_FRAMES(double)
+
+static int ebur128_calc_relative_threshold(ebur128_state* st, size_t* above_thresh_counter, double* relative_threshold)
+{
+    struct ebur128_dq_entry* it;
+    size_t i;
+    *relative_threshold = 0.0;
+    *above_thresh_counter = 0;
+
+    if (st->d->use_histogram) {
+        for (i = 0; i < 1000; ++i) {
+            *relative_threshold += st->d->block_energy_histogram[i] * histogram_energies[i];
+            *above_thresh_counter += st->d->block_energy_histogram[i];
+        }
+    } else {
+        SLIST_FOREACH(it, &st->d->block_list, entries) {
+            ++*above_thresh_counter;
+            *relative_threshold += it->z;
+        }
+    }
+
+    if (*above_thresh_counter != 0) {
+        *relative_threshold /= (double) *above_thresh_counter;
+        *relative_threshold *= relative_gate_factor;
+    }
+
+    return EBUR128_SUCCESS;
+}
+
+static int ebur128_gated_loudness(ebur128_state** sts, size_t size, double* out)
+{
+    struct ebur128_dq_entry* it;
+    double gated_loudness = 0.0;
+    double relative_threshold;
+    size_t above_thresh_counter;
+    size_t i, j, start_index;
+
+    for (i = 0; i < size; i++) {
+        if (sts[i] && (sts[i]->mode & EBUR128_MODE_I) != EBUR128_MODE_I) {
+            return EBUR128_ERROR_INVALID_MODE;
+        }
+    }
+
+    for (i = 0; i < size; i++) {
+        if (!sts[i]) continue;
+        ebur128_calc_relative_threshold(sts[i], &above_thresh_counter, &relative_threshold);
+    }
+    if (!above_thresh_counter) {
+        *out = -HUGE_VAL;
+        return EBUR128_SUCCESS;
+    }
+
+    above_thresh_counter = 0;
+    if (relative_threshold < histogram_energy_boundaries[0]) {
+        start_index = 0;
+    } else {
+        start_index = find_histogram_index(relative_threshold);
+        if (relative_threshold > histogram_energies[start_index]) {
+            ++start_index;
+        }
+    }
+    for (i = 0; i < size; i++) {
+        if (!sts[i]) continue;
+        if (sts[i]->d->use_histogram) {
+            for (j = start_index; j < 1000; ++j) {
+                gated_loudness += sts[i]->d->block_energy_histogram[j] *
+                    histogram_energies[j];
+                above_thresh_counter += sts[i]->d->block_energy_histogram[j];
+            }
+        } else {
+            SLIST_FOREACH(it, &sts[i]->d->block_list, entries) {
+                if (it->z >= relative_threshold) {
+                    ++above_thresh_counter;
+                    gated_loudness += it->z;
+                }
+            }
+        }
+    }
+    if (!above_thresh_counter) {
+        *out = -HUGE_VAL;
+        return EBUR128_SUCCESS;
+    }
+    gated_loudness /= (double) above_thresh_counter;
+    *out = ebur128_energy_to_loudness(gated_loudness);
+    return EBUR128_SUCCESS;
+}
+
+int ff_ebur128_relative_threshold(ebur128_state* st, double* out)
+{
+    double relative_threshold;
+    size_t above_thresh_counter;
+
+    if (st && (st->mode & EBUR128_MODE_I) != EBUR128_MODE_I)
+        return EBUR128_ERROR_INVALID_MODE;
+
+    ebur128_calc_relative_threshold(st, &above_thresh_counter, &relative_threshold);
+
+    if (!above_thresh_counter) {
+        *out = -70.0;
+        return EBUR128_SUCCESS;
+    }
+
+    *out = ebur128_energy_to_loudness(relative_threshold);
+    return EBUR128_SUCCESS;
+}
+
+int ff_ebur128_loudness_global(ebur128_state* st, double* out)
+{
+    return ebur128_gated_loudness(&st, 1, out);
+}
+
+int ff_ebur128_loudness_global_multiple(ebur128_state** sts, size_t size, double* out)
+{
+    return ebur128_gated_loudness(sts, size, out);
+}
+
+static int ebur128_energy_in_interval(ebur128_state* st, size_t interval_frames, double* out)
+{
+    if (interval_frames > st->d->audio_data_frames) {
+        return EBUR128_ERROR_INVALID_MODE;
+    }
+    ebur128_calc_gating_block(st, interval_frames, out);
+    return EBUR128_SUCCESS;
+}
+
+static int ebur128_energy_shortterm(ebur128_state* st, double* out)
+{
+    return ebur128_energy_in_interval(st, st->d->samples_in_100ms * 30, out);
+}
+
+int ff_ebur128_loudness_momentary(ebur128_state* st, double* out)
+{
+    double energy;
+    int error = ebur128_energy_in_interval(st, st->d->samples_in_100ms * 4,
+            &energy);
+    if (error) {
+        return error;
+    } else if (energy <= 0.0) {
+        *out = -HUGE_VAL;
+        return EBUR128_SUCCESS;
+    }
+    *out = ebur128_energy_to_loudness(energy);
+    return EBUR128_SUCCESS;
+}
+
+int ff_ebur128_loudness_shortterm(ebur128_state* st, double* out)
+{
+    double energy;
+    int error = ebur128_energy_shortterm(st, &energy);
+    if (error) {
+        return error;
+    } else if (energy <= 0.0) {
+        *out = -HUGE_VAL;
+        return EBUR128_SUCCESS;
+    }
+    *out = ebur128_energy_to_loudness(energy);
+    return EBUR128_SUCCESS;
+}
+
+static int ebur128_double_cmp(const void *p1, const void *p2)
+{
+    const double* d1 = (const double*) p1;
+    const double* d2 = (const double*) p2;
+    return (*d1 > *d2) - (*d1 < *d2);
+}
+
+/* EBU - TECH 3342 */
+int ff_ebur128_loudness_range_multiple(ebur128_state** sts, size_t size, double* out)
+{
+    size_t i, j;
+    struct ebur128_dq_entry* it;
+    double* stl_vector;
+    size_t stl_size;
+    double* stl_relgated;
+    size_t stl_relgated_size;
+    double stl_power, stl_integrated;
+    /* High and low percentile energy */
+    double h_en, l_en;
+    int use_histogram = 0;
+
+    for (i = 0; i < size; ++i) {
+        if (sts[i]) {
+            if ((sts[i]->mode & EBUR128_MODE_LRA) != EBUR128_MODE_LRA) {
+                return EBUR128_ERROR_INVALID_MODE;
+            }
+            if (i == 0 && sts[i]->mode & EBUR128_MODE_HISTOGRAM) {
+                use_histogram = 1;
+            } else if (use_histogram != !!(sts[i]->mode & EBUR128_MODE_HISTOGRAM)) {
+                return EBUR128_ERROR_INVALID_MODE;
+            }
+        }
+    }
+
+    if (use_histogram) {
+        unsigned long hist[1000] = { 0 };
+        size_t percentile_low, percentile_high;
+        size_t index;
+
+        stl_size = 0;
+        stl_power = 0.0;
+        for (i = 0; i < size; ++i) {
+            if (!sts[i]) continue;
+            for (j = 0; j < 1000; ++j) {
+                hist[j]   += sts[i]->d->short_term_block_energy_histogram[j];
+                stl_size  += sts[i]->d->short_term_block_energy_histogram[j];
+                stl_power += sts[i]->d->short_term_block_energy_histogram[j]
+                    * histogram_energies[j];
+            }
+        }
+        if (!stl_size) {
+            *out = 0.0;
+            return EBUR128_SUCCESS;
+        }
+
+        stl_power /= stl_size;
+        stl_integrated = minus_twenty_decibels * stl_power;
+
+        if (stl_integrated < histogram_energy_boundaries[0]) {
+            index = 0;
+        } else {
+            index = find_histogram_index(stl_integrated);
+            if (stl_integrated > histogram_energies[index]) {
+                ++index;
+            }
+        }
+        stl_size = 0;
+        for (j = index; j < 1000; ++j) {
+            stl_size += hist[j];
+        }
+        if (!stl_size) {
+            *out = 0.0;
+            return EBUR128_SUCCESS;
+        }
+
+        percentile_low  = (size_t) ((stl_size - 1) * 0.1 + 0.5);
+        percentile_high = (size_t) ((stl_size - 1) * 0.95 + 0.5);
+
+        stl_size = 0;
+        j = index;
+        while (stl_size <= percentile_low) {
+            stl_size += hist[j++];
+        }
+        l_en = histogram_energies[j - 1];
+        while (stl_size <= percentile_high) {
+            stl_size += hist[j++];
+        }
+        h_en = histogram_energies[j - 1];
+        *out = ebur128_energy_to_loudness(h_en) - ebur128_energy_to_loudness(l_en);
+        return EBUR128_SUCCESS;
+
+    } else {
+        stl_size = 0;
+        for (i = 0; i < size; ++i) {
+            if (!sts[i]) continue;
+            SLIST_FOREACH(it, &sts[i]->d->short_term_block_list, entries) {
+                ++stl_size;
+            }
+        }
+        if (!stl_size) {
+            *out = 0.0;
+            return EBUR128_SUCCESS;
+        }
+        stl_vector = (double*) av_malloc(stl_size * sizeof(double));
+        if (!stl_vector)
+            return EBUR128_ERROR_NOMEM;
+
+        for (j = 0, i = 0; i < size; ++i) {
+            if (!sts[i]) continue;
+            SLIST_FOREACH(it, &sts[i]->d->short_term_block_list, entries) {
+                stl_vector[j] = it->z;
+                ++j;
+            }
+        }
+        qsort(stl_vector, stl_size, sizeof(double), ebur128_double_cmp);
+        stl_power = 0.0;
+        for (i = 0; i < stl_size; ++i) {
+            stl_power += stl_vector[i];
+        }
+        stl_power /= (double) stl_size;
+        stl_integrated = minus_twenty_decibels * stl_power;
+
+        stl_relgated = stl_vector;
+        stl_relgated_size = stl_size;
+        while (stl_relgated_size > 0 && *stl_relgated < stl_integrated) {
+            ++stl_relgated;
+            --stl_relgated_size;
+        }
+
+        if (stl_relgated_size) {
+            h_en = stl_relgated[(size_t) ((stl_relgated_size - 1) * 0.95 + 0.5)];
+            l_en = stl_relgated[(size_t) ((stl_relgated_size - 1) * 0.1 + 0.5)];
+            av_free(stl_vector);
+            *out = ebur128_energy_to_loudness(h_en) - ebur128_energy_to_loudness(l_en);
+            return EBUR128_SUCCESS;
+        } else {
+            av_free(stl_vector);
+            *out = 0.0;
+            return EBUR128_SUCCESS;
+        }
+    }
+}
+
+int ff_ebur128_loudness_range(ebur128_state* st, double* out)
+{
+    return ff_ebur128_loudness_range_multiple(&st, 1, out);
+}
+
+int ff_ebur128_sample_peak(ebur128_state* st, unsigned int channel_number, double* out)
+{
+    if ((st->mode & EBUR128_MODE_SAMPLE_PEAK) != EBUR128_MODE_SAMPLE_PEAK) {
+        return EBUR128_ERROR_INVALID_MODE;
+    } else if (channel_number >= st->channels) {
+        return EBUR128_ERROR_INVALID_CHANNEL_INDEX;
+    }
+    *out = st->d->sample_peak[channel_number];
+    return EBUR128_SUCCESS;
+}
+
+#if CONFIG_SWRESAMPLE
+int ff_ebur128_true_peak(ebur128_state* st, unsigned int channel_number, double* out)
+{
+    if ((st->mode & EBUR128_MODE_TRUE_PEAK) != EBUR128_MODE_TRUE_PEAK) {
+        return EBUR128_ERROR_INVALID_MODE;
+    } else if (channel_number >= st->channels) {
+        return EBUR128_ERROR_INVALID_CHANNEL_INDEX;
+    }
+    *out = st->d->true_peak[channel_number] > st->d->sample_peak[channel_number]
+        ? st->d->true_peak[channel_number]
+        : st->d->sample_peak[channel_number];
+    return EBUR128_SUCCESS;
+}
+#endif
diff --git a/libavfilter/ebur128.h b/libavfilter/ebur128.h
new file mode 100644
index 0000000..898a6fd
--- /dev/null
+++ b/libavfilter/ebur128.h
@@ -0,0 +1,345 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * This file uses code from libebur128 which has the following license:
+ *
+ * Copyright (c) 2011 Jan Kokemüller
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef AVFILTER_EBUR128_H
+#define AVFILTER_EBUR128_H
+
+#include <stddef.h>       /* for size_t */
+
+/** \enum channel
+ *  Use these values when setting the channel map with ebur128_set_channel().
+ *  See definitions in ITU R-REC-BS 1770-4
+ */
+enum channel {
+    EBUR128_UNUSED = 0,     /**< unused channel (for example LFE channel) */
+    EBUR128_LEFT,
+    EBUR128_Mp030 = 1,      /**< itu M+030 */
+    EBUR128_RIGHT,
+    EBUR128_Mm030 = 2,      /**< itu M-030 */
+    EBUR128_CENTER,
+    EBUR128_Mp000 = 3,      /**< itu M+000 */
+    EBUR128_LEFT_SURROUND,
+    EBUR128_Mp110 = 4,      /**< itu M+110 */
+    EBUR128_RIGHT_SURROUND,
+    EBUR128_Mm110 = 5,      /**< itu M-110 */
+    EBUR128_DUAL_MONO,      /**< a channel that is counted twice */
+    EBUR128_MpSC,           /**< itu M+SC */
+    EBUR128_MmSC,           /**< itu M-SC */
+    EBUR128_Mp060,          /**< itu M+060 */
+    EBUR128_Mm060,          /**< itu M-060 */
+    EBUR128_Mp090,          /**< itu M+090 */
+    EBUR128_Mm090,          /**< itu M-090 */
+    EBUR128_Mp135,          /**< itu M+135 */
+    EBUR128_Mm135,          /**< itu M-135 */
+    EBUR128_Mp180,          /**< itu M+180 */
+    EBUR128_Up000,          /**< itu U+000 */
+    EBUR128_Up030,          /**< itu U+030 */
+    EBUR128_Um030,          /**< itu U-030 */
+    EBUR128_Up045,          /**< itu U+045 */
+    EBUR128_Um045,          /**< itu U-030 */
+    EBUR128_Up090,          /**< itu U+090 */
+    EBUR128_Um090,          /**< itu U-090 */
+    EBUR128_Up110,          /**< itu U+110 */
+    EBUR128_Um110,          /**< itu U-110 */
+    EBUR128_Up135,          /**< itu U+135 */
+    EBUR128_Um135,          /**< itu U-135 */
+    EBUR128_Up180,          /**< itu U+180 */
+    EBUR128_Tp000,          /**< itu T+000 */
+    EBUR128_Bp000,          /**< itu B+000 */
+    EBUR128_Bp045,          /**< itu B+045 */
+    EBUR128_Bm045           /**< itu B-045 */
+};
+
+/** \enum error
+ *  Error return values.
+ */
+enum error {
+    EBUR128_SUCCESS = 0,
+    EBUR128_ERROR_NOMEM,
+    EBUR128_ERROR_INVALID_MODE,
+    EBUR128_ERROR_INVALID_CHANNEL_INDEX,
+    EBUR128_ERROR_NO_CHANGE
+};
+
+/** \enum mode
+ *  Use these values in ebur128_init (or'ed). Try to use the lowest possible
+ *  modes that suit your needs, as performance will be better.
+ */
+enum mode {
+    /** can call ebur128_loudness_momentary */
+    EBUR128_MODE_M           = (1 << 0),
+    /** can call ebur128_loudness_shortterm */
+    EBUR128_MODE_S           = (1 << 1) | EBUR128_MODE_M,
+    /** can call ebur128_loudness_global_* and ebur128_relative_threshold */
+    EBUR128_MODE_I           = (1 << 2) | EBUR128_MODE_M,
+    /** can call ebur128_loudness_range */
+    EBUR128_MODE_LRA         = (1 << 3) | EBUR128_MODE_S,
+    /** can call ebur128_sample_peak */
+    EBUR128_MODE_SAMPLE_PEAK = (1 << 4) | EBUR128_MODE_M,
+    /** can call ebur128_true_peak */
+    EBUR128_MODE_TRUE_PEAK   = (1 << 5) | EBUR128_MODE_M
+                                        | EBUR128_MODE_SAMPLE_PEAK,
+    /** uses histogram algorithm to calculate loudness */
+    EBUR128_MODE_HISTOGRAM   = (1 << 6)
+};
+
+/** forward declaration of ebur128_state_internal */
+struct ebur128_state_internal;
+
+/** \brief Contains information about the state of a loudness measurement.
+ *
+ *  You should not need to modify this struct directly.
+ */
+typedef struct {
+    int mode;                           /**< The current mode. */
+    unsigned int channels;              /**< The number of channels. */
+    unsigned long samplerate;           /**< The sample rate. */
+    struct ebur128_state_internal* d;   /**< Internal state. */
+} ebur128_state;
+
+/** \brief Initialize library state.
+ *
+ *  @param channels the number of channels.
+ *  @param samplerate the sample rate.
+ *  @param mode see the mode enum for possible values.
+ *  @return an initialized library state.
+ */
+ebur128_state* ff_ebur128_init(unsigned int channels,
+                            unsigned long samplerate,
+                            int mode);
+
+/** \brief Destroy library state.
+ *
+ *  @param st pointer to a library state.
+ */
+void ff_ebur128_destroy(ebur128_state** st);
+
+/** \brief Set channel type.
+ *
+ *  The default is:
+ *  - 0 -> EBUR128_LEFT
+ *  - 1 -> EBUR128_RIGHT
+ *  - 2 -> EBUR128_CENTER
+ *  - 3 -> EBUR128_UNUSED
+ *  - 4 -> EBUR128_LEFT_SURROUND
+ *  - 5 -> EBUR128_RIGHT_SURROUND
+ *
+ *  @param st library state.
+ *  @param channel_number zero based channel index.
+ *  @param value channel type from the "channel" enum.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_CHANNEL_INDEX if invalid channel index.
+ */
+int ff_ebur128_set_channel(ebur128_state* st,
+                        unsigned int channel_number,
+                        int value);
+
+/** \brief Change library parameters.
+ *
+ *  Note that the channel map will be reset when setting a different number of
+ *  channels. The current unfinished block will be lost.
+ *
+ *  @param st library state.
+ *  @param channels new number of channels.
+ *  @param samplerate new sample rate.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_NOMEM on memory allocation error. The state will be
+ *      invalid and must be destroyed.
+ *    - EBUR128_ERROR_NO_CHANGE if channels and sample rate were not changed.
+ */
+int ff_ebur128_change_parameters(ebur128_state* st,
+                              unsigned int channels,
+                              unsigned long samplerate);
+
+/** \brief Add frames to be processed.
+ *
+ *  @param st library state.
+ *  @param src array of source frames. Channels must be interleaved.
+ *  @param frames number of frames. Not number of samples!
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_NOMEM on memory allocation error.
+ */
+int ff_ebur128_add_frames_short(ebur128_state* st,
+                             const short* src,
+                             size_t frames);
+/** \brief See \ref ebur128_add_frames_short */
+int ff_ebur128_add_frames_int(ebur128_state* st,
+                             const int* src,
+                             size_t frames);
+/** \brief See \ref ebur128_add_frames_short */
+int ff_ebur128_add_frames_float(ebur128_state* st,
+                             const float* src,
+                             size_t frames);
+/** \brief See \ref ebur128_add_frames_short */
+int ff_ebur128_add_frames_double(ebur128_state* st,
+                             const double* src,
+                             size_t frames);
+
+/** \brief Get global integrated loudness in LUFS.
+ *
+ *  @param st library state.
+ *  @param out integrated loudness in LUFS. -HUGE_VAL if result is negative
+ *             infinity.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_I" has not been set.
+ */
+int ff_ebur128_loudness_global(ebur128_state* st, double* out);
+/** \brief Get global integrated loudness in LUFS across multiple instances.
+ *
+ *  @param sts array of library states.
+ *  @param size length of sts
+ *  @param out integrated loudness in LUFS. -HUGE_VAL if result is negative
+ *             infinity.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_I" has not been set.
+ */
+int ff_ebur128_loudness_global_multiple(ebur128_state** sts,
+                                     size_t size,
+                                     double* out);
+
+/** \brief Get momentary loudness (last 400ms) in LUFS.
+ *
+ *  @param st library state.
+ *  @param out momentary loudness in LUFS. -HUGE_VAL if result is negative
+ *             infinity.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ */
+int ff_ebur128_loudness_momentary(ebur128_state* st, double* out);
+/** \brief Get short-term loudness (last 3s) in LUFS.
+ *
+ *  @param st library state.
+ *  @param out short-term loudness in LUFS. -HUGE_VAL if result is negative
+ *             infinity.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_S" has not been set.
+ */
+int ff_ebur128_loudness_shortterm(ebur128_state* st, double* out);
+
+/** \brief Get loudness range (LRA) of programme in LU.
+ *
+ *  Calculates loudness range according to EBU 3342.
+ *
+ *  @param st library state.
+ *  @param out loudness range (LRA) in LU. Will not be changed in case of
+ *             error. EBUR128_ERROR_NOMEM or EBUR128_ERROR_INVALID_MODE will be
+ *             returned in this case.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_NOMEM in case of memory allocation error.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_LRA" has not been set.
+ */
+int ff_ebur128_loudness_range(ebur128_state* st, double* out);
+/** \brief Get loudness range (LRA) in LU across multiple instances.
+ *
+ *  Calculates loudness range according to EBU 3342.
+ *
+ *  @param sts array of library states.
+ *  @param size length of sts
+ *  @param out loudness range (LRA) in LU. Will not be changed in case of
+ *             error. EBUR128_ERROR_NOMEM or EBUR128_ERROR_INVALID_MODE will be
+ *             returned in this case.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_NOMEM in case of memory allocation error.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_LRA" has not been set.
+ */
+int ff_ebur128_loudness_range_multiple(ebur128_state** sts,
+                                    size_t size,
+                                    double* out);
+
+/** \brief Get maximum sample peak of selected channel in float format.
+ *
+ *  @param st library state
+ *  @param channel_number channel to analyse
+ *  @param out maximum sample peak in float format (1.0 is 0 dBFS)
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_SAMPLE_PEAK" has not
+ *      been set.
+ *    - EBUR128_ERROR_INVALID_CHANNEL_INDEX if invalid channel index.
+ */
+int ff_ebur128_sample_peak(ebur128_state* st,
+                        unsigned int channel_number,
+                        double* out);
+
+/** \brief Get maximum true peak of selected channel in float format.
+ *
+ *  Uses an implementation defined algorithm to calculate the true peak. Do not
+ *  try to compare resulting values across different versions of the library,
+ *  as the algorithm may change.
+ *
+ *  The current implementation uses the Speex resampler with quality level 8 to
+ *  calculate true peak. Will oversample 4x for sample rates < 96000 Hz, 2x for
+ *  sample rates < 192000 Hz and leave the signal unchanged for 192000 Hz.
+ *
+ *  @param st library state
+ *  @param channel_number channel to analyse
+ *  @param out maximum true peak in float format (1.0 is 0 dBFS)
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_TRUE_PEAK" has not
+ *      been set.
+ *    - EBUR128_ERROR_INVALID_CHANNEL_INDEX if invalid channel index.
+ */
+int ff_ebur128_true_peak(ebur128_state* st,
+                      unsigned int channel_number,
+                      double* out);
+
+/** \brief Get relative threshold in LUFS.
+ *
+ *  @param st library state
+ *  @param out relative threshold in LUFS.
+ *  @return
+ *    - EBUR128_SUCCESS on success.
+ *    - EBUR128_ERROR_INVALID_MODE if mode "EBUR128_MODE_I" has not
+ *      been set.
+ */
+int ff_ebur128_relative_threshold(ebur128_state* st, double* out);
+
+#endif /* AVFILTER_EBUR128_H */
diff --git a/libavfilter/queue.h b/libavfilter/queue.h
new file mode 100644
index 0000000..023be73
--- /dev/null
+++ b/libavfilter/queue.h
@@ -0,0 +1,592 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Copyright (c) 1991, 1993
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *  @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef AVFILTER_QUEUE_H
+#define AVFILTER_QUEUE_H
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list.  Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction.  Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * AN EXisting element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type)                                                \
+struct name {                                                                \
+    struct type *lh_first;  /* first element */                              \
+}
+
+#define LIST_HEAD_INITIALIZER(head)                                          \
+    { NULL }
+
+#define LIST_ENTRY(type)                                                     \
+struct {                                                                     \
+    struct type *le_next;   /* next element */                               \
+    struct type **le_prev;  /* address of previous next element */           \
+}
+
+/*
+ * List functions.
+ */
+#define LIST_INIT(head) do {                                                 \
+    (head)->lh_first = NULL;                                                 \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do {                          \
+    if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)           \
+        (listelm)->field.le_next->field.le_prev =                            \
+            &(elm)->field.le_next;                                           \
+    (listelm)->field.le_next = (elm);                                        \
+    (elm)->field.le_prev = &(listelm)->field.le_next;                        \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do {                         \
+    (elm)->field.le_prev = (listelm)->field.le_prev;                         \
+    (elm)->field.le_next = (listelm);                                        \
+    *(listelm)->field.le_prev = (elm);                                       \
+    (listelm)->field.le_prev = &(elm)->field.le_next;                        \
+} while (/*CONSTCOND*/0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do {                              \
+    if (((elm)->field.le_next = (head)->lh_first) != NULL)                   \
+        (head)->lh_first->field.le_prev = &(elm)->field.le_next;             \
+    (head)->lh_first = (elm);                                                \
+    (elm)->field.le_prev = &(head)->lh_first;                                \
+} while (/*CONSTCOND*/0)
+
+#define LIST_REMOVE(elm, field) do {                                         \
+    if ((elm)->field.le_next != NULL)                                        \
+        (elm)->field.le_next->field.le_prev =                                \
+            (elm)->field.le_prev;                                            \
+    *(elm)->field.le_prev = (elm)->field.le_next;                            \
+} while (/*CONSTCOND*/0)
+
+#define LIST_FOREACH(var, head, field)                                       \
+    for ((var) = ((head)->lh_first);                                         \
+        (var);                                                               \
+        (var) = ((var)->field.le_next))
+
+/*
+ * List access methods.
+ */
+#define LIST_EMPTY(head)        ((head)->lh_first == NULL)
+#define LIST_FIRST(head)        ((head)->lh_first)
+#define LIST_NEXT(elm, field)       ((elm)->field.le_next)
+
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type)                                               \
+struct name {                                                                \
+    struct type *slh_first; /* first element */                              \
+}
+
+#define SLIST_HEAD_INITIALIZER(head)                                         \
+    { NULL }
+
+#define SLIST_ENTRY(type)                                                    \
+struct {                                                                     \
+    struct type *sle_next;  /* next element */                               \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_INIT(head) do {                                                \
+    (head)->slh_first = NULL;                                                \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do {                        \
+    (elm)->field.sle_next = (slistelm)->field.sle_next;                      \
+    (slistelm)->field.sle_next = (elm);                                      \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do {                             \
+    (elm)->field.sle_next = (head)->slh_first;                               \
+    (head)->slh_first = (elm);                                               \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE_HEAD(head, field) do {                                  \
+    (head)->slh_first = (head)->slh_first->field.sle_next;                   \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_REMOVE(head, elm, type, field) do {                            \
+    if ((head)->slh_first == (elm)) {                                        \
+        SLIST_REMOVE_HEAD((head), field);                                    \
+    }                                                                        \
+    else {                                                                   \
+        struct type *curelm = (head)->slh_first;                             \
+        while(curelm->field.sle_next != (elm))                               \
+            curelm = curelm->field.sle_next;                                 \
+        curelm->field.sle_next =                                             \
+            curelm->field.sle_next->field.sle_next;                          \
+    }                                                                        \
+} while (/*CONSTCOND*/0)
+
+#define SLIST_FOREACH(var, head, field)                                      \
+    for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+/*
+ * Singly-linked List access methods.
+ */
+#define SLIST_EMPTY(head)   ((head)->slh_first == NULL)
+#define SLIST_FIRST(head)   ((head)->slh_first)
+#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
+
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define STAILQ_HEAD(name, type)                                              \
+struct name {                                                                \
+    struct type *stqh_first;    /* first element */                          \
+    struct type **stqh_last;    /* addr of last next element */              \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head)                                        \
+    { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type)                                                   \
+struct {                                                                     \
+    struct type *stqe_next; /* next element */                               \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_INIT(head) do {                                               \
+    (head)->stqh_first = NULL;                                               \
+    (head)->stqh_last = &(head)->stqh_first;                                 \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do {                            \
+    if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)               \
+        (head)->stqh_last = &(elm)->field.stqe_next;                         \
+    (head)->stqh_first = (elm);                                              \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do {                            \
+    (elm)->field.stqe_next = NULL;                                           \
+    *(head)->stqh_last = (elm);                                              \
+    (head)->stqh_last = &(elm)->field.stqe_next;                             \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {                  \
+    if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)       \
+        (head)->stqh_last = &(elm)->field.stqe_next;                         \
+    (listelm)->field.stqe_next = (elm);                                      \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE_HEAD(head, field) do {                                 \
+    if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL)  \
+        (head)->stqh_last = &(head)->stqh_first;                             \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do {                           \
+    if ((head)->stqh_first == (elm)) {                                       \
+        STAILQ_REMOVE_HEAD((head), field);                                   \
+    } else {                                                                 \
+        struct type *curelm = (head)->stqh_first;                            \
+        while (curelm->field.stqe_next != (elm))                             \
+            curelm = curelm->field.stqe_next;                                \
+        if ((curelm->field.stqe_next =                                       \
+            curelm->field.stqe_next->field.stqe_next) == NULL)               \
+                (head)->stqh_last = &(curelm)->field.stqe_next;              \
+    }                                                                        \
+} while (/*CONSTCOND*/0)
+
+#define STAILQ_FOREACH(var, head, field)                                     \
+    for ((var) = ((head)->stqh_first);                                       \
+        (var);                                                               \
+        (var) = ((var)->field.stqe_next))
+
+#define STAILQ_CONCAT(head1, head2) do {                                     \
+    if (!STAILQ_EMPTY((head2))) {                                            \
+        *(head1)->stqh_last = (head2)->stqh_first;                           \
+        (head1)->stqh_last = (head2)->stqh_last;                             \
+        STAILQ_INIT((head2));                                                \
+    }                                                                        \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define STAILQ_EMPTY(head)  ((head)->stqh_first == NULL)
+#define STAILQ_FIRST(head)  ((head)->stqh_first)
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+
+/*
+ * Simple queue definitions.
+ */
+#define SIMPLEQ_HEAD(name, type)                                             \
+struct name {                                                                \
+    struct type *sqh_first; /* first element */                              \
+    struct type **sqh_last; /* addr of last next element */                  \
+}
+
+#define SIMPLEQ_HEAD_INITIALIZER(head)                                       \
+    { NULL, &(head).sqh_first }
+
+#define SIMPLEQ_ENTRY(type)                                                  \
+struct {                                                                     \
+    struct type *sqe_next;  /* next element */                               \
+}
+
+/*
+ * Simple queue functions.
+ */
+#define SIMPLEQ_INIT(head) do {                                              \
+    (head)->sqh_first = NULL;                                                \
+    (head)->sqh_last = &(head)->sqh_first;                                   \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {                           \
+    if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)                 \
+        (head)->sqh_last = &(elm)->field.sqe_next;                           \
+    (head)->sqh_first = (elm);                                               \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {                           \
+    (elm)->field.sqe_next = NULL;                                            \
+    *(head)->sqh_last = (elm);                                               \
+    (head)->sqh_last = &(elm)->field.sqe_next;                               \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {                 \
+    if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)         \
+        (head)->sqh_last = &(elm)->field.sqe_next;                           \
+    (listelm)->field.sqe_next = (elm);                                       \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_HEAD(head, field) do {                                \
+    if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)     \
+        (head)->sqh_last = &(head)->sqh_first;                               \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE(head, elm, type, field) do {                          \
+    if ((head)->sqh_first == (elm)) {                                        \
+        SIMPLEQ_REMOVE_HEAD((head), field);                                  \
+    } else {                                                                 \
+        struct type *curelm = (head)->sqh_first;                             \
+        while (curelm->field.sqe_next != (elm))                              \
+            curelm = curelm->field.sqe_next;                                 \
+        if ((curelm->field.sqe_next =                                        \
+            curelm->field.sqe_next->field.sqe_next) == NULL)                 \
+                (head)->sqh_last = &(curelm)->field.sqe_next;                \
+    }                                                                        \
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_FOREACH(var, head, field)                                    \
+    for ((var) = ((head)->sqh_first);                                        \
+        (var);                                                               \
+        (var) = ((var)->field.sqe_next))
+
+/*
+ * Simple queue access methods.
+ */
+#define SIMPLEQ_EMPTY(head)     ((head)->sqh_first == NULL)
+#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
+#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
+
+
+/*
+ * Tail queue definitions.
+ */
+#define _TAILQ_HEAD(name, type, qual)                                        \
+struct name {                                                                \
+    qual type *tqh_first;       /* first element */                          \
+    qual type *qual *tqh_last;  /* addr of last next element */              \
+}
+#define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head)                                         \
+    { NULL, &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual)                                             \
+struct {                                                                     \
+    qual type *tqe_next;        /* next element */                           \
+    qual type *qual *tqe_prev;  /* address of previous next element */       \
+}
+#define TAILQ_ENTRY(type)   _TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_INIT(head) do {                                                \
+    (head)->tqh_first = NULL;                                                \
+    (head)->tqh_last = &(head)->tqh_first;                                   \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do {                             \
+    if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)                 \
+        (head)->tqh_first->field.tqe_prev =                                  \
+            &(elm)->field.tqe_next;                                          \
+    else                                                                     \
+        (head)->tqh_last = &(elm)->field.tqe_next;                           \
+    (head)->tqh_first = (elm);                                               \
+    (elm)->field.tqe_prev = &(head)->tqh_first;                              \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do {                             \
+    (elm)->field.tqe_next = NULL;                                            \
+    (elm)->field.tqe_prev = (head)->tqh_last;                                \
+    *(head)->tqh_last = (elm);                                               \
+    (head)->tqh_last = &(elm)->field.tqe_next;                               \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {                   \
+    if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)         \
+        (elm)->field.tqe_next->field.tqe_prev =                              \
+            &(elm)->field.tqe_next;                                          \
+    else                                                                     \
+        (head)->tqh_last = &(elm)->field.tqe_next;                           \
+    (listelm)->field.tqe_next = (elm);                                       \
+    (elm)->field.tqe_prev = &(listelm)->field.tqe_next;                      \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                        \
+    (elm)->field.tqe_prev = (listelm)->field.tqe_prev;                       \
+    (elm)->field.tqe_next = (listelm);                                       \
+    *(listelm)->field.tqe_prev = (elm);                                      \
+    (listelm)->field.tqe_prev = &(elm)->field.tqe_next;                      \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do {                                  \
+    if (((elm)->field.tqe_next) != NULL)                                     \
+        (elm)->field.tqe_next->field.tqe_prev =                              \
+            (elm)->field.tqe_prev;                                           \
+    else                                                                     \
+        (head)->tqh_last = (elm)->field.tqe_prev;                            \
+    *(elm)->field.tqe_prev = (elm)->field.tqe_next;                          \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_FOREACH(var, head, field)                                      \
+    for ((var) = ((head)->tqh_first);                                        \
+        (var);                                                               \
+        (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field)                    \
+    for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));     \
+        (var);                                                               \
+        (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+#define TAILQ_CONCAT(head1, head2, field) do {                               \
+    if (!TAILQ_EMPTY(head2)) {                                               \
+        *(head1)->tqh_last = (head2)->tqh_first;                             \
+        (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;              \
+        (head1)->tqh_last = (head2)->tqh_last;                               \
+        TAILQ_INIT((head2));                                                 \
+    }                                                                        \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Tail queue access methods.
+ */
+#define TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
+#define TAILQ_FIRST(head)       ((head)->tqh_first)
+#define TAILQ_NEXT(elm, field)      ((elm)->field.tqe_next)
+
+#define TAILQ_LAST(head, headname)                                           \
+    (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field)                                     \
+    (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type)                                             \
+struct name {                                                                \
+    struct type *cqh_first;     /* first element */                          \
+    struct type *cqh_last;      /* last element */                           \
+}
+
+#define CIRCLEQ_HEAD_INITIALIZER(head)                                       \
+    { (void *)&head, (void *)&head }
+
+#define CIRCLEQ_ENTRY(type)                                                  \
+struct {                                                                     \
+    struct type *cqe_next;      /* next element */                           \
+    struct type *cqe_prev;      /* previous element */                       \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_INIT(head) do {                                              \
+    (head)->cqh_first = (void *)(head);                                      \
+    (head)->cqh_last = (void *)(head);                                       \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {                 \
+    (elm)->field.cqe_next = (listelm)->field.cqe_next;                       \
+    (elm)->field.cqe_prev = (listelm);                                       \
+    if ((listelm)->field.cqe_next == (void *)(head))                         \
+        (head)->cqh_last = (elm);                                            \
+    else                                                                     \
+        (listelm)->field.cqe_next->field.cqe_prev = (elm);                   \
+    (listelm)->field.cqe_next = (elm);                                       \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {                \
+    (elm)->field.cqe_next = (listelm);                                       \
+    (elm)->field.cqe_prev = (listelm)->field.cqe_prev;                       \
+    if ((listelm)->field.cqe_prev == (void *)(head))                         \
+        (head)->cqh_first = (elm);                                           \
+    else                                                                     \
+        (listelm)->field.cqe_prev->field.cqe_next = (elm);                   \
+    (listelm)->field.cqe_prev = (elm);                                       \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                           \
+    (elm)->field.cqe_next = (head)->cqh_first;                               \
+    (elm)->field.cqe_prev = (void *)(head);                                  \
+    if ((head)->cqh_last == (void *)(head))                                  \
+        (head)->cqh_last = (elm);                                            \
+    else                                                                     \
+        (head)->cqh_first->field.cqe_prev = (elm);                           \
+    (head)->cqh_first = (elm);                                               \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                           \
+    (elm)->field.cqe_next = (void *)(head);                                  \
+    (elm)->field.cqe_prev = (head)->cqh_last;                                \
+    if ((head)->cqh_first == (void *)(head))                                 \
+        (head)->cqh_first = (elm);                                           \
+    else                                                                     \
+        (head)->cqh_last->field.cqe_next = (elm);                            \
+    (head)->cqh_last = (elm);                                                \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do {                                \
+    if ((elm)->field.cqe_next == (void *)(head))                             \
+        (head)->cqh_last = (elm)->field.cqe_prev;                            \
+    else                                                                     \
+        (elm)->field.cqe_next->field.cqe_prev =                              \
+            (elm)->field.cqe_prev;                                           \
+    if ((elm)->field.cqe_prev == (void *)(head))                             \
+        (head)->cqh_first = (elm)->field.cqe_next;                           \
+    else                                                                     \
+        (elm)->field.cqe_prev->field.cqe_next =                              \
+            (elm)->field.cqe_next;                                           \
+} while (/*CONSTCOND*/0)
+
+#define CIRCLEQ_FOREACH(var, head, field)                                    \
+    for ((var) = ((head)->cqh_first);                                        \
+        (var) != (const void *)(head);                                       \
+        (var) = ((var)->field.cqe_next))
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                            \
+    for ((var) = ((head)->cqh_last);                                         \
+        (var) != (const void *)(head);                                       \
+        (var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define CIRCLEQ_EMPTY(head)     ((head)->cqh_first == (void *)(head))
+#define CIRCLEQ_FIRST(head)     ((head)->cqh_first)
+#define CIRCLEQ_LAST(head)      ((head)->cqh_last)
+#define CIRCLEQ_NEXT(elm, field)    ((elm)->field.cqe_next)
+#define CIRCLEQ_PREV(elm, field)    ((elm)->field.cqe_prev)
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field)                                  \
+    (((elm)->field.cqe_next == (void *)(head))                               \
+        ? ((head)->cqh_first)                                                \
+        : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field)                                  \
+    (((elm)->field.cqe_prev == (void *)(head))                               \
+        ? ((head)->cqh_last)                                                 \
+        : (elm->field.cqe_prev))
+
+#endif /* AVFILTER_QUEUE_H */
-- 
2.5.4 (Apple Git-61)

