<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>