Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gst-plugins-good: add audio-level-meta to cutter #1159

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions gvsbuild/patches/gst-plugins-good/cutter-add-audio-level-meta.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
From e7d5f3bfadc656cb0ed5f4f821df178a559ec395 Mon Sep 17 00:00:00 2001
From: Ignazio Pillai <ignazp@amazon.com>
Date: Fri, 1 Dec 2023 14:49:37 +0100
Subject: [PATCH] cutter: add audio-level-meta

Set GstAudioLevelMeta on buffers
---
.../gst/cutter/gstcutter.c | 45 ++++++++++++++++++-
.../gst/cutter/gstcutter.h | 1 +
2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/gst/cutter/gstcutter.c b/gst/cutter/gstcutter.c
index 760a9c9d91..633c77fd46 100644
--- a/gst/cutter/gstcutter.c
+++ b/gst/cutter/gstcutter.c
@@ -54,6 +54,7 @@ GST_DEBUG_CATEGORY_STATIC (cutter_debug);
#define CUTTER_DEFAULT_THRESHOLD_LEVEL 0.1
#define CUTTER_DEFAULT_THRESHOLD_LENGTH (500 * GST_MSECOND)
#define CUTTER_DEFAULT_PRE_LENGTH (200 * GST_MSECOND)
+#define EPSILON 1e-35f

static GstStaticPadTemplate cutter_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
@@ -81,7 +82,8 @@ enum
PROP_THRESHOLD_DB,
PROP_RUN_LENGTH,
PROP_PRE_LENGTH,
- PROP_LEAKY
+ PROP_LEAKY,
+ PROP_AUDIO_LEVEL_META,
};

#define gst_cutter_parent_class parent_class
@@ -135,6 +137,17 @@ gst_cutter_class_init (GstCutterClass * klass)
g_param_spec_boolean ("leaky", "Leaky",
"do we leak buffers when below threshold ?",
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstLevel:audio-level-meta:
+ *
+ * If %TRUE, generate or update GstAudioLevelMeta on output buffers.
+ *
+ * Since: 1.24
+ */
+ g_object_class_install_property (gobject_class, PROP_AUDIO_LEVEL_META,
+ g_param_spec_boolean ("audio-level-meta", "Audio Level Meta",
+ "Set GstAudioLevelMeta on buffers", FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

GST_DEBUG_CATEGORY_INIT (cutter_debug, "cutter", 0, "Audio cutting");

@@ -175,6 +188,7 @@ gst_cutter_init (GstCutter * filter)
filter->pre_run_length = 0 * GST_SECOND;
filter->pre_buffer = NULL;
filter->leaky = FALSE;
+ filter->audio_level_meta = FALSE;
}

static GstMessage *
@@ -293,6 +307,23 @@ gst_cutter_event (GstPad * pad, GstObject * parent, GstEvent * event)
return ret;
}

+static void
+set_audio_level_meta (GstBuffer * buffer, guint8 level)
+{
+ GstAudioLevelMeta *meta;
+
+ /* Update the existing meta, if any, so we can have an upstream element
+ * filling the voice activity part of the meta. */
+ meta = gst_buffer_get_audio_level_meta (buffer);
+ if (meta) {
+ meta->level = level;
+ } else {
+ /* Assume audio does not contain voice, it can be detected by another
+ * downstream element. */
+ gst_buffer_add_audio_level_meta (buffer, level, FALSE);
+ }
+}
+
static GstFlowReturn
gst_cutter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
@@ -355,6 +386,12 @@ gst_cutter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
GST_LOG_OBJECT (filter, "buffer stats: NMS %f, RMS %f, audio length %f", NMS,
RMS, gst_guint64_to_gdouble (duration));

+ if (filter->audio_level_meta) {
+ gdouble RMSdB = 20 * log10 (RMS + EPSILON);
+
+ set_audio_level_meta (buf, -RMSdB);
+ }
+
if (RMS < filter->threshold_level)
filter->silent_run_length += gst_guint64_to_gdouble (duration);
else {
@@ -469,6 +506,9 @@ gst_cutter_set_property (GObject * object, guint prop_id,
/* set if the pre-record buffer is leaky or not */
filter->leaky = g_value_get_boolean (value);
break;
+ case PROP_AUDIO_LEVEL_META:
+ filter->audio_level_meta = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -500,6 +540,9 @@ gst_cutter_get_property (GObject * object, guint prop_id,
case PROP_LEAKY:
g_value_set_boolean (value, filter->leaky);
break;
+ case PROP_AUDIO_LEVEL_META:
+ g_value_set_boolean (value, filter->audio_level_meta);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/gst/cutter/gstcutter.h b/gst/cutter/gstcutter.h
index 3167cea007..d00de4d9f6 100644
--- a/gst/cutter/gstcutter.h
+++ b/gst/cutter/gstcutter.h
@@ -62,6 +62,7 @@ struct _GstCutter
double pre_run_length; /* how long is it currently ? */
GList *pre_buffer; /* list of GstBuffers in pre-record buffer */
gboolean leaky; /* do we leak an overflowing prebuffer ? */
+ gboolean audio_level_meta; /* whether or not generate GstAudioLevelMeta */

GstAudioInfo info;
GstSegment segment;
--
2.38.1.windows.1

3 changes: 3 additions & 0 deletions gvsbuild/projects/gstreamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ def __init__(self):
"gst-plugins-base",
"libvpx",
],
patches=[
"cutter-add-audio-level-meta.patch",
],
)

def build(self):
Expand Down