cutter: add audio-level-meta

Set GstAudioLevelMeta on buffers

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5771>
This commit is contained in:
Ignazio Pillai 2023-12-01 14:49:37 +01:00 committed by GStreamer Marge Bot
parent 60d9cfc954
commit 34741e1db2
3 changed files with 58 additions and 1 deletions

View file

@ -4293,6 +4293,18 @@
}
},
"properties": {
"audio-level-meta": {
"blurb": "Set GstAudioLevelMeta on buffers",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"leaky": {
"blurb": "do we leak buffers when below threshold ?",
"conditionally-available": false,

View file

@ -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));
/**
* GstCutter: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,13 @@ 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);
buf = gst_buffer_make_writable (buf);
set_audio_level_meta (buf, -RMSdB);
}
if (RMS < filter->threshold_level)
filter->silent_run_length += gst_guint64_to_gdouble (duration);
else {
@ -469,6 +507,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 +541,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;

View file

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