<html><head></head><body>Hi,<br><br>I reject any new code that invokes vlc_object_parent(). Breaks encapsulation.<br><br><div class="gmail_quote">Le 14 août 2020 15:18:03 GMT+02:00, Thomas Guillem <thomas@gllm.fr> a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail"><hr> configure.ac                      |   5 +<br> modules/audio_filter/Makefile.am  |   9 +-<br> modules/audio_filter/libebur128.c | 290 ++++++++++++++++++++++++++++++<br> 3 files changed, 303 insertions(+), 1 deletion(-)<br> create mode 100644 modules/audio_filter/libebur128.c<br><br>diff --git a/configure.ac b/configure.ac<br>index 149c7c926b4..862546e49f3 100644<br>--- a/configure.ac<br>+++ b/configure.ac<br>@@ -3919,6 +3919,11 @@ dnl  soxr module<br> dnl<br> PKG_ENABLE_MODULES_VLC([SOXR], [], [soxr >= 0.1.2], [SoX Resampler library], [auto])<br> <br>+dnl<br>+dnl  libebur128 module<br>+dnl<br>+PKG_ENABLE_MODULES_VLC([EBUR128], [], [libebur128 >= 1.2.4], [EBU R 128 standard for loudness normalisation], [auto])<br>+<br> dnl<br> dnl  OS/2 KAI plugin<br> dnl<br>diff --git a/modules/audio_filter/Makefile.am b/modules/audio_filter/Makefile.am<br>index 279be02040f..028b188bfe2 100644<br>--- a/modules/audio_filter/Makefile.am<br>+++ b/modules/audio_filter/Makefile.am<br>@@ -125,14 +125,21 @@ libsoxr_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(SOXR_CFLAGS)<br> libsoxr_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(audio_filterdir)'<br> libsoxr_plugin_la_LIBADD = $(SOXR_LIBS) $(LIBM)<br> <br>+libebur128_plugin_la_SOURCES = audio_filter/libebur128.c<br>+libebur128_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(EBUR128_CFLAGS)<br>+libebur128_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(audio_filterdir)'<br>+libebur128_plugin_la_LIBADD = $(EBUR128_LIBS)<br>+<br> audio_filter_LTLIBRARIES += \<br>    $(LTLIBsamplerate) \<br>  $(LTLIBsoxr) \<br>+       $(LTLIBebur128) \<br>     libugly_resampler_plugin.la<br> EXTRA_LTLIBRARIES += \<br>  libbandlimited_resampler_plugin.la \<br>  libsamplerate_plugin.la \<br>-    libsoxr_plugin.la<br>+    libsoxr_plugin.la \<br>+  libebur128_plugin.la<br> <br> libspeex_resampler_plugin_la_SOURCES = audio_filter/resampler/speex.c<br> libspeex_resampler_plugin_la_CFLAGS = $(AM_CFLAGS) $(SPEEXDSP_CFLAGS)<br>diff --git a/modules/audio_filter/libebur128.c b/modules/audio_filter/libebur128.c<br>new file mode 100644<br>index 00000000000..bd5464dc6d1<br>--- /dev/null<br>+++ b/modules/audio_filter/libebur128.c<br>@@ -0,0 +1,290 @@<br>+/*****************************************************************************<br>+ * libebur128.c : libebur128 filter<br>+ *****************************************************************************<br>+ * Copyright © 2020 Videolabs<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify it<br>+ * under the terms of the GNU Lesser General Public License as published by<br>+ * the Free Software Foundation; either version 2.1 of the License, or<br>+ * (at your option) any later version.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>+ * GNU Lesser General Public License for more details.<br>+ *<br>+ * You should have received a copy of the GNU Lesser General Public License<br>+ * along with this program; if not, write to the Free Software Foundation,<br>+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<br>+ *****************************************************************************/<br>+<br>+#ifdef HAVE_CONFIG_H<br>+# include "config.h"<br>+#endif<br>+<br>+#include <vlc_common.h><br>+#include <vlc_aout.h><br>+#include <vlc_filter.h><br>+#include <vlc_modules.h><br>+#include <vlc_plugin.h><br>+<br>+#include <ebur128.h><br>+<br>+#define UPDATE_INTERVAL VLC_TICK_FROM_MS(400)<br>+<br>+struct filter_sys<br>+{<br>+    ebur128_state *state;<br>+    vlc_tick_t last_update;<br>+    bool new_frames;<br>+};<br>+<br>+static ebur128_state *<br>+CreateEbuR128State(filter_t *filter)<br>+{<br>+    int mode = var_InheritBool(filter, "ebur128-fullmeter")<br>+             ? EBUR128_MODE_TRUE_PEAK|EBUR128_MODE_LRA : EBUR128_MODE_M;<br>+<br>+    ebur128_state *state =<br>+        ebur128_init(filter->fmt_in.audio.i_channels, filter->fmt_in.audio.i_rate, mode);<br>+    if (state == NULL)<br>+        return NULL;<br>+<br>+    /* TODO: improve */<br>+    unsigned channels_set = 2;<br>+    int error;<br>+    if (filter->fmt_in.audio.i_physical_channels == AOUT_CHANS_5_1<br>+     || filter->fmt_in.audio.i_physical_channels == AOUT_CHANS_7_1)<br>+    {<br>+        error = ebur128_set_channel(state, 2, EBUR128_LEFT_SURROUND);<br>+        if (error != EBUR128_SUCCESS)<br>+            goto error;<br>+        ebur128_set_channel(state, 3, EBUR128_RIGHT_SURROUND);<br>+        if (error != EBUR128_SUCCESS)<br>+            goto error;<br>+        ebur128_set_channel(state, 4, EBUR128_CENTER);<br>+        if (error != EBUR128_SUCCESS)<br>+            goto error;<br>+<br>+        channels_set += 3;<br>+    }<br>+<br>+    for (unsigned i = channels_set; i < filter->fmt_in.audio.i_channels; ++i)<br>+    {<br>+        error = ebur128_set_channel(state, i, EBUR128_UNUSED);<br>+        if (error != EBUR128_SUCCESS)<br>+            goto error;<br>+    }<br>+<br>+    return state;<br>+error:<br>+    ebur128_destroy(&state);<br>+    return NULL;<br>+}<br>+<br>+static int<br>+SendLoudnessMeter(filter_t *filter)<br>+{<br>+    struct filter_sys *sys = filter->p_sys;<br>+<br>+    int error;<br>+    struct vlc_audio_loudness_meter meter = { 0, 0, 0, 0, 0 };<br>+<br>+    error = ebur128_loudness_momentary(sys->state, &meter.loudness_momentary);<br>+    if (error != EBUR128_SUCCESS)<br>+        return error;<br>+<br>+    if ((sys->state->mode & EBUR128_MODE_S) == EBUR128_MODE_S)<br>+    {<br>+        error = ebur128_loudness_shortterm(sys->state, &meter.loudness_shortterm);<br>+        if (error != EBUR128_SUCCESS)<br>+            return error;<br>+    }<br>+    if ((sys->state->mode & EBUR128_MODE_I) == EBUR128_MODE_I)<br>+    {<br>+        error = ebur128_loudness_global(sys->state, &meter.loudness_integrated);<br>+        if (error != EBUR128_SUCCESS)<br>+            return error;<br>+<br>+    }<br>+    if ((sys->state->mode & EBUR128_MODE_LRA) == EBUR128_MODE_LRA)<br>+    {<br>+        error = ebur128_loudness_range(sys->state, &meter.loudness_range);<br>+        if (error != EBUR128_SUCCESS)<br>+            return error;<br>+    }<br>+    if ((sys->state->mode & EBUR128_MODE_TRUE_PEAK) == EBUR128_MODE_TRUE_PEAK)<br>+    {<br>+        for (unsigned i = 0; i < filter->fmt_in.audio.i_channels; ++i)<br>+        {<br>+            double truepeak;<br>+            error = ebur128_true_peak(sys->state, 0, &truepeak);<br>+            if (error != EBUR128_SUCCESS)<br>+                return error;<br>+            if (truepeak > meter.truepeak)<br>+                meter.truepeak = truepeak;<br>+        }<br>+    }<br>+<br>+    var_SetAddress(vlc_object_parent(VLC_OBJECT(filter)), "loudness-meter", &meter);<br>+<br>+    return EBUR128_SUCCESS;<br>+}<br>+<br>+static block_t *<br>+Process(filter_t *filter, block_t *block)<br>+{<br>+    struct filter_sys *sys = filter->p_sys;<br>+    int error;<br>+    block_t *out = block;<br>+<br>+    if (unlikely(sys->state == NULL))<br>+    {<br>+        /* Can happen after a flush */<br>+        sys->state = CreateEbuR128State(filter);<br>+        if (sys->state == NULL)<br>+            return out;<br>+    }<br>+<br>+    switch (filter->fmt_in.i_codec)<br>+    {<br>+        case VLC_CODEC_U8:<br>+        {<br>+            /* Convert to S16N */<br>+            block_t *block_s16 = block_Alloc(block->i_buffer * 2);<br>+            if (unlikely(block_s16 == NULL))<br>+                return out;<br>+<br>+            block_CopyProperties(block_s16, block);<br>+            uint8_t *src = (uint8_t *)block->p_buffer;<br>+            int16_t *dst = (int16_t *)block_s16->p_buffer;<br>+            for (size_t i = block->i_buffer; i--;)<br>+                *dst++ = ((*src++) << 8) - 0x8000;<br>+<br>+            block = block_s16;<br>+        }<br>+        /* Fallthrough */<br>+        case VLC_CODEC_S16N:<br>+            error = ebur128_add_frames_short(sys->state,<br>+                                             (const short *)block->p_buffer,<br>+                                             block->i_nb_samples);<br>+            break;<br>+        case VLC_CODEC_S32N:<br>+            error = ebur128_add_frames_int(sys->state,<br>+                                           (const int *) block->p_buffer,<br>+                                           block->i_nb_samples);<br>+            break;<br>+        case VLC_CODEC_FL32:<br>+            error = ebur128_add_frames_float(sys->state,<br>+                                             (const float *) block->p_buffer,<br>+                                             block->i_nb_samples);<br>+            break;<br>+        case VLC_CODEC_FL64:<br>+            error = ebur128_add_frames_double(sys->state,<br>+                                              (const double *) block->p_buffer,<br>+                                              block->i_nb_samples);<br>+            break;<br>+        default: vlc_assert_unreachable();<br>+    }<br>+<br>+    if (error != EBUR128_SUCCESS)<br>+    {<br>+        msg_Warn(filter, "ebur128_add_frames_*() failed: %d\n", error);<br>+        return out;<br>+    }<br>+<br>+    if (sys->last_update == VLC_TICK_INVALID)<br>+        sys->last_update = out->i_pts;<br>+<br>+    if (out->i_pts + out->i_length - sys->last_update >= UPDATE_INTERVAL)<br>+    {<br>+        error = SendLoudnessMeter(filter);<br>+        if (error == EBUR128_SUCCESS)<br>+        {<br>+            sys->last_update = out->i_pts + out->i_length;<br>+            sys->new_frames = false;<br>+        }<br>+    }<br>+    else<br>+        sys->new_frames = true;<br>+<br>+    return out;<br>+}<br>+<br>+static void<br>+Flush(filter_t *filter)<br>+{<br>+    struct filter_sys *sys = filter->p_sys;<br>+<br>+    if (sys->state != NULL)<br>+    {<br>+        if (sys->new_frames)<br>+        {<br>+            SendLoudnessMeter(filter);<br>+            sys->new_frames = false;<br>+        }<br>+        sys->last_update = VLC_TICK_INVALID;<br>+<br>+        ebur128_destroy(&sys->state);<br>+    }<br>+}<br>+<br>+static int Open(vlc_object_t *this)<br>+{<br>+    filter_t *filter = (filter_t *) this;<br>+<br>+    switch (filter->fmt_in.i_codec)<br>+    {<br>+        case VLC_CODEC_U8:<br>+        case VLC_CODEC_S16N:<br>+        case VLC_CODEC_S32N:<br>+        case VLC_CODEC_FL32:<br>+        case VLC_CODEC_FL64:<br>+            break;<br>+        default:<br>+            return VLC_EGENERIC;<br>+    }<br>+<br>+    if (var_Type(vlc_object_parent(this), "loudness-meter") != VLC_VAR_ADDRESS)<br>+        return VLC_EGENERIC;<br>+<br>+    struct filter_sys *sys = malloc(sizeof(*sys));<br>+    if (sys == NULL)<br>+        return VLC_ENOMEM;<br>+<br>+    sys->last_update = VLC_TICK_INVALID;<br>+    sys->new_frames = false;<br>+    sys->state = CreateEbuR128State(filter);<br>+    if (sys->state == NULL)<br>+    {<br>+        free(sys);<br>+        return VLC_EGENERIC;<br>+    }<br>+<br>+    filter->p_sys = sys;<br>+    filter->fmt_out.audio = filter->fmt_in.audio;<br>+    filter->pf_audio_filter = Process;<br>+    filter->pf_flush = Flush;<br>+    return VLC_SUCCESS;<br>+}<br>+<br>+static void<br>+Close(vlc_object_t *this)<br>+{<br>+    filter_t *filter = (filter_t*) this;<br>+    struct filter_sys *sys = filter->p_sys;<br>+<br>+    if (sys->state != NULL)<br>+        ebur128_destroy(&sys->state);<br>+    free(filter->p_sys);<br>+}<br>+<br>+vlc_module_begin()<br>+    set_shortname("EBU R 128")<br>+    set_description("EBU R128 standard for loudness normalisation")<br>+    set_category(CAT_AUDIO)<br>+    set_subcategory(SUBCAT_AUDIO_AFILTER)<br>+    add_bool("ebur128-fullmeter", false, NULL, NULL, false)<br>+    set_capability("audio meter", 0)<br>+    set_callbacks(Open, Close)<br>+vlc_module_end()</pre></blockquote></div><br>-- <br>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.</body></html>