Kurento:无法应用 GStreamer "audiocheblimit" + "cutter"
Kurento: unable to apply GStreamer "audiocheblimit" + "cutter"
以下是我的代码块,我试图使用它来消除传入媒体管道中的噪音。
VADCustomFilterImpl::VADCustomFilterImpl(const boost::property_tree::ptree & config,std::shared_ptr <MediaPipeline > mediaPipeline) :FilterImpl (config,std::dynamic_pointer_cast <MediaObjectImpl> (mediaPipeline))
{
/* audio cheb limit - to remove noise */
//GST_WARNING("------------------------audiocheblimit");
g_object_set(element, "filter-factory", "audiocheblimit", NULL);
g_object_get(G_OBJECT(element), "filter", &audiocheblimitfilter, NULL);
if (audiocheblimitfilter == NULL) {
throw KurentoException(MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: audiocheblimitfilter");
}
g_object_set(G_OBJECT(audiocheblimitfilter), "mode", "low-pass", NULL);
g_object_set(G_OBJECT(audiocheblimitfilter),"cutoff", 700, NULL);
//GST_WARNING("----------------cutter");
/*Cutter*/
g_object_set(element, "filter-factory", "cutter", NULL);
g_object_get(G_OBJECT(element), "filter", &cutterfilter, NULL);
if (cutterfilter == NULL) {
throw KurentoException(MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: cutterfilter");
}
g_object_set(G_OBJECT(cutterfilter), "threshold-dB", -40.0, NULL);
g_object_set(G_OBJECT(cutterfilter), "run-length", 500000000, NULL);
//GST_WARNING("~~~~~~~~~~~~~~~~~~~~audiocheblimit+cutter");
bus_handler_id = 0;
g_object_unref(audiocheblimitfilter);
g_object_unref(cutterfilter);
}
在 kurento 日志中只有 ------------------------audiocheblimit
正在打印,之后没有日志,在我的 java 服务器控制台中正在打印 Websocket disconnected by WebSocket Read EOF (status code 1006)
崩溃有什么具体原因吗?
可以在kurento中一个接一个的应用两个GStreamer插件吗?
或者我们是否需要创建多个 kurento 自定义过滤器,这些过滤器将在其中使用一个单一的 GStreamer 插件??
编辑 1:
正如@santoscadenas 所指出的,我已经研究了 faceoverlay
项目并在我的代码中进行了相应的更改,
#include "gstvadcustomfilter.h"
#include <gst/gst.h>
#include <glib/gstdio.h>
#include <gst/audio/audio.h>
#include <opencv2/opencv.hpp>
#include <cv.h>
#include <memory>
GST_DEBUG_CATEGORY_STATIC (gst_v_a_d_custom_filter_debug_category);
#define GST_CAT_DEFAULT gst_v_a_d_custom_filter_debug_category
#define PLUGIN_NAME "voicedetector"
#define GST_V_A_D_CUSTOM_FILTER_GET_PRIVATE(obj) ( \
G_TYPE_INSTANCE_GET_PRIVATE ( \
(obj), \
GST_TYPE_V_A_D_CUSTOM_FILTER, \
GstVADCustomFilterPrivate \
) \
)
/* pad templates */
#define AUDIO_SRC_CAPS \
GST_AUDIO_CAPS_MAKE("{ S16LE }")
#define AUDIO_SINK_CAPS \
GST_AUDIO_CAPS_MAKE("{ S16LE }")
/* class initialization */
struct _GstVADCustomFilterPrivate
{
GstElement *audiocheb_limit;
GstElement *cutter_filter;
GstPad *src, *sink;
}priv;
//GstPad *tempsrc , *cuttersrcpad, *audiocheblimitsinkpad;
/* the capabilities of the inputs and outputs. */
GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ( // the capabilities of the padtemplate
AUDIO_SINK_CAPS
)
);
GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS ( // the capabilities of the padtemplate
AUDIO_SRC_CAPS
)
);
//G_DEFINE_TYPE (GstVADCustomFilter, gst_v_a_d_custom_filter, GST_TYPE_BIN);
G_DEFINE_TYPE_WITH_CODE (GstVADCustomFilter, gst_v_a_d_custom_filter,
GST_TYPE_BIN,
GST_DEBUG_CATEGORY_INIT (gst_v_a_d_custom_filter_debug_category,
PLUGIN_NAME, 0,
"debug category for v_a_d_custom_filter element") );
/*static GstFlowReturn
gst_v_a_d_custom_filter_transform_frame_ip (GstVideoFilter *filter,
GstVideoFrame *frame)
{
GST_WARNING("gst_v_a_d_custom_filter_transform_frame_ip");
return GST_FLOW_OK;
}*/
static void
gst_v_a_d_custom_filter_finalize (GObject *object)
{
GST_WARNING("Inside gst_v_a_d_custom_filter_finalize");
}
static void
gst_v_a_d_custom_filter_init (GstVADCustomFilter *v_a_d_custom_filter)
{
GstPadTemplate *templ;
GstPad *target;
GST_ERROR("Inside gst_v_a_d_custom_filter_init");
v_a_d_custom_filter->priv = GST_V_A_D_CUSTOM_FILTER_GET_PRIVATE (v_a_d_custom_filter);
GST_ERROR("audio cheb limit");
v_a_d_custom_filter->priv->audiocheb_limit =
gst_element_factory_make ("audiocheblimit", NULL);
g_object_set (v_a_d_custom_filter->priv->audiocheb_limit, "cutoff",700.0, NULL);
gst_bin_add (GST_BIN (v_a_d_custom_filter), v_a_d_custom_filter->priv->audiocheb_limit);
GST_ERROR("cutter");
/*cutter*/
v_a_d_custom_filter->priv->cutter_filter =
gst_element_factory_make ("cutter", NULL);
g_object_set (v_a_d_custom_filter->priv->cutter_filter, "threshold-dB",-40.0, NULL);
g_object_set (v_a_d_custom_filter->priv->cutter_filter, "run-length",500000000, NULL);
gst_bin_add (GST_BIN (v_a_d_custom_filter), v_a_d_custom_filter->priv->cutter_filter);
GST_ERROR("cutter added to the bus");
target = gst_element_get_static_pad (v_a_d_custom_filter->priv->audiocheb_limit, "sink");
GST_ERROR("sink factory");
templ = gst_static_pad_template_get (&sink_factory);
GST_ERROR("sink , target, templ");
v_a_d_custom_filter->priv->sink =
gst_ghost_pad_new_from_template ("sink", target, templ);
GST_ERROR("g_object_unref");
g_object_unref (templ);
g_object_unref (target);
GST_ERROR("GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->sink");
gst_element_add_pad (GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->sink);
target = gst_element_get_static_pad (v_a_d_custom_filter->priv->cutter_filter, "src");
GST_ERROR("src factory");
templ = gst_static_pad_template_get (&src_factory);
v_a_d_custom_filter->priv->src = gst_ghost_pad_new_from_template ("src", target, templ);
g_object_unref (templ);
g_object_unref (target);
gst_element_add_pad (GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->src);
gst_element_link (v_a_d_custom_filter->priv->audiocheb_limit, v_a_d_custom_filter->priv->cutter_filter);
}
static void
gst_v_a_d_custom_filter_class_init (GstVADCustomFilterClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
//GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, PLUGIN_NAME, 0, PLUGIN_NAME);
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS,
gst_caps_from_string (AUDIO_SRC_CAPS) ) );
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS,
gst_caps_from_string (AUDIO_SINK_CAPS) ) );
gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
"Voice Activity Detector", "Audio/Filter",
"Using GStreamer Cutter Element",
"Author: Sagar Pilkhwal");
gobject_class->finalize = gst_v_a_d_custom_filter_finalize;
//video_filter_class->transform_frame_ip = GST_DEBUG_FUNCPTR (gst_v_a_d_custom_filter_transform_frame_ip);
}
gboolean
gst_v_a_d_custom_filter_plugin_init (GstPlugin *plugin)
{
GST_WARNING("Inside gst_v_a_d_custom_filter_plugin_init");
return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, GST_TYPE_V_A_D_CUSTOM_FILTER);
}
服务器日志:
(kurento-media-server:27765): GLib-GObject-CRITICAL **: g_object_set: assertion 'G_IS_OBJECT (object)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_bin_add: assertion 'GST_IS_ELEMENT (element)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_element_get_static_pad: assertion 'GST_IS_ELEMENT (element)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_ghost_pad_new_from_template: assertion 'GST_IS_PAD (target)' failed
(kurento-media-server:27765): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_element_add_pad: assertion 'GST_IS_PAD (pad)' failed
[31;1mSegmentation fault[0m (thread [33;1m140450597959424[0m, pid [33;1m27765[0m)
问题是filter-factory只能设置一次。将它设置两次是行不通的,我们还没有测试过它并且可能会出现段错误(因为它似乎正在发生)。
如果您需要应用多个 gstreamer 元素,请创建一个包含这两个元素的包装器 (GstBin),并提供与一个简单过滤器(一个接收器和一个 src)相同的垫接口。在 GstBin 中,您可以连接任意数量的元素。
编辑
你可以有一个GstBin封装各种元素的例子here
编辑 2
问题出在这一行:
g_object_set (G_OBJECT (audiocheblimit), "mode", "low-pass", NULL);
"mode"
是一个枚举,可以作为字符串传递,也可以作为整数值传递。
编辑 3
您似乎没有在您需要的 .h
文件中正确声明您的元素:
typedef _GstVADCustomFilter {
GstBin parent;
...
} GstVADCustomFilter;
在您的 .c
文件中:
G_DEFINE_TYPE (GstVADCustomFilter, gst_v_a_d_custom_filter, GST_TYPE_BIN);
以下是我的代码块,我试图使用它来消除传入媒体管道中的噪音。
VADCustomFilterImpl::VADCustomFilterImpl(const boost::property_tree::ptree & config,std::shared_ptr <MediaPipeline > mediaPipeline) :FilterImpl (config,std::dynamic_pointer_cast <MediaObjectImpl> (mediaPipeline))
{
/* audio cheb limit - to remove noise */
//GST_WARNING("------------------------audiocheblimit");
g_object_set(element, "filter-factory", "audiocheblimit", NULL);
g_object_get(G_OBJECT(element), "filter", &audiocheblimitfilter, NULL);
if (audiocheblimitfilter == NULL) {
throw KurentoException(MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: audiocheblimitfilter");
}
g_object_set(G_OBJECT(audiocheblimitfilter), "mode", "low-pass", NULL);
g_object_set(G_OBJECT(audiocheblimitfilter),"cutoff", 700, NULL);
//GST_WARNING("----------------cutter");
/*Cutter*/
g_object_set(element, "filter-factory", "cutter", NULL);
g_object_get(G_OBJECT(element), "filter", &cutterfilter, NULL);
if (cutterfilter == NULL) {
throw KurentoException(MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: cutterfilter");
}
g_object_set(G_OBJECT(cutterfilter), "threshold-dB", -40.0, NULL);
g_object_set(G_OBJECT(cutterfilter), "run-length", 500000000, NULL);
//GST_WARNING("~~~~~~~~~~~~~~~~~~~~audiocheblimit+cutter");
bus_handler_id = 0;
g_object_unref(audiocheblimitfilter);
g_object_unref(cutterfilter);
}
在 kurento 日志中只有 ------------------------audiocheblimit
正在打印,之后没有日志,在我的 java 服务器控制台中正在打印 Websocket disconnected by WebSocket Read EOF (status code 1006)
崩溃有什么具体原因吗? 可以在kurento中一个接一个的应用两个GStreamer插件吗?
或者我们是否需要创建多个 kurento 自定义过滤器,这些过滤器将在其中使用一个单一的 GStreamer 插件??
编辑 1:
正如@santoscadenas 所指出的,我已经研究了 faceoverlay
项目并在我的代码中进行了相应的更改,
#include "gstvadcustomfilter.h"
#include <gst/gst.h>
#include <glib/gstdio.h>
#include <gst/audio/audio.h>
#include <opencv2/opencv.hpp>
#include <cv.h>
#include <memory>
GST_DEBUG_CATEGORY_STATIC (gst_v_a_d_custom_filter_debug_category);
#define GST_CAT_DEFAULT gst_v_a_d_custom_filter_debug_category
#define PLUGIN_NAME "voicedetector"
#define GST_V_A_D_CUSTOM_FILTER_GET_PRIVATE(obj) ( \
G_TYPE_INSTANCE_GET_PRIVATE ( \
(obj), \
GST_TYPE_V_A_D_CUSTOM_FILTER, \
GstVADCustomFilterPrivate \
) \
)
/* pad templates */
#define AUDIO_SRC_CAPS \
GST_AUDIO_CAPS_MAKE("{ S16LE }")
#define AUDIO_SINK_CAPS \
GST_AUDIO_CAPS_MAKE("{ S16LE }")
/* class initialization */
struct _GstVADCustomFilterPrivate
{
GstElement *audiocheb_limit;
GstElement *cutter_filter;
GstPad *src, *sink;
}priv;
//GstPad *tempsrc , *cuttersrcpad, *audiocheblimitsinkpad;
/* the capabilities of the inputs and outputs. */
GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ( // the capabilities of the padtemplate
AUDIO_SINK_CAPS
)
);
GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_REQUEST,
GST_STATIC_CAPS ( // the capabilities of the padtemplate
AUDIO_SRC_CAPS
)
);
//G_DEFINE_TYPE (GstVADCustomFilter, gst_v_a_d_custom_filter, GST_TYPE_BIN);
G_DEFINE_TYPE_WITH_CODE (GstVADCustomFilter, gst_v_a_d_custom_filter,
GST_TYPE_BIN,
GST_DEBUG_CATEGORY_INIT (gst_v_a_d_custom_filter_debug_category,
PLUGIN_NAME, 0,
"debug category for v_a_d_custom_filter element") );
/*static GstFlowReturn
gst_v_a_d_custom_filter_transform_frame_ip (GstVideoFilter *filter,
GstVideoFrame *frame)
{
GST_WARNING("gst_v_a_d_custom_filter_transform_frame_ip");
return GST_FLOW_OK;
}*/
static void
gst_v_a_d_custom_filter_finalize (GObject *object)
{
GST_WARNING("Inside gst_v_a_d_custom_filter_finalize");
}
static void
gst_v_a_d_custom_filter_init (GstVADCustomFilter *v_a_d_custom_filter)
{
GstPadTemplate *templ;
GstPad *target;
GST_ERROR("Inside gst_v_a_d_custom_filter_init");
v_a_d_custom_filter->priv = GST_V_A_D_CUSTOM_FILTER_GET_PRIVATE (v_a_d_custom_filter);
GST_ERROR("audio cheb limit");
v_a_d_custom_filter->priv->audiocheb_limit =
gst_element_factory_make ("audiocheblimit", NULL);
g_object_set (v_a_d_custom_filter->priv->audiocheb_limit, "cutoff",700.0, NULL);
gst_bin_add (GST_BIN (v_a_d_custom_filter), v_a_d_custom_filter->priv->audiocheb_limit);
GST_ERROR("cutter");
/*cutter*/
v_a_d_custom_filter->priv->cutter_filter =
gst_element_factory_make ("cutter", NULL);
g_object_set (v_a_d_custom_filter->priv->cutter_filter, "threshold-dB",-40.0, NULL);
g_object_set (v_a_d_custom_filter->priv->cutter_filter, "run-length",500000000, NULL);
gst_bin_add (GST_BIN (v_a_d_custom_filter), v_a_d_custom_filter->priv->cutter_filter);
GST_ERROR("cutter added to the bus");
target = gst_element_get_static_pad (v_a_d_custom_filter->priv->audiocheb_limit, "sink");
GST_ERROR("sink factory");
templ = gst_static_pad_template_get (&sink_factory);
GST_ERROR("sink , target, templ");
v_a_d_custom_filter->priv->sink =
gst_ghost_pad_new_from_template ("sink", target, templ);
GST_ERROR("g_object_unref");
g_object_unref (templ);
g_object_unref (target);
GST_ERROR("GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->sink");
gst_element_add_pad (GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->sink);
target = gst_element_get_static_pad (v_a_d_custom_filter->priv->cutter_filter, "src");
GST_ERROR("src factory");
templ = gst_static_pad_template_get (&src_factory);
v_a_d_custom_filter->priv->src = gst_ghost_pad_new_from_template ("src", target, templ);
g_object_unref (templ);
g_object_unref (target);
gst_element_add_pad (GST_ELEMENT (v_a_d_custom_filter), v_a_d_custom_filter->priv->src);
gst_element_link (v_a_d_custom_filter->priv->audiocheb_limit, v_a_d_custom_filter->priv->cutter_filter);
}
static void
gst_v_a_d_custom_filter_class_init (GstVADCustomFilterClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
//GstVideoFilterClass *video_filter_class = GST_VIDEO_FILTER_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, PLUGIN_NAME, 0, PLUGIN_NAME);
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
gst_pad_template_new ("src", GST_PAD_SRC,
GST_PAD_ALWAYS,
gst_caps_from_string (AUDIO_SRC_CAPS) ) );
gst_element_class_add_pad_template (GST_ELEMENT_CLASS (klass),
gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS,
gst_caps_from_string (AUDIO_SINK_CAPS) ) );
gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
"Voice Activity Detector", "Audio/Filter",
"Using GStreamer Cutter Element",
"Author: Sagar Pilkhwal");
gobject_class->finalize = gst_v_a_d_custom_filter_finalize;
//video_filter_class->transform_frame_ip = GST_DEBUG_FUNCPTR (gst_v_a_d_custom_filter_transform_frame_ip);
}
gboolean
gst_v_a_d_custom_filter_plugin_init (GstPlugin *plugin)
{
GST_WARNING("Inside gst_v_a_d_custom_filter_plugin_init");
return gst_element_register (plugin, PLUGIN_NAME, GST_RANK_NONE, GST_TYPE_V_A_D_CUSTOM_FILTER);
}
服务器日志:
(kurento-media-server:27765): GLib-GObject-CRITICAL **: g_object_set: assertion 'G_IS_OBJECT (object)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_bin_add: assertion 'GST_IS_ELEMENT (element)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_element_get_static_pad: assertion 'GST_IS_ELEMENT (element)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_ghost_pad_new_from_template: assertion 'GST_IS_PAD (target)' failed
(kurento-media-server:27765): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
(kurento-media-server:27765): GStreamer-CRITICAL **: gst_element_add_pad: assertion 'GST_IS_PAD (pad)' failed
[31;1mSegmentation fault[0m (thread [33;1m140450597959424[0m, pid [33;1m27765[0m)
问题是filter-factory只能设置一次。将它设置两次是行不通的,我们还没有测试过它并且可能会出现段错误(因为它似乎正在发生)。
如果您需要应用多个 gstreamer 元素,请创建一个包含这两个元素的包装器 (GstBin),并提供与一个简单过滤器(一个接收器和一个 src)相同的垫接口。在 GstBin 中,您可以连接任意数量的元素。
编辑
你可以有一个GstBin封装各种元素的例子here
编辑 2
问题出在这一行:
g_object_set (G_OBJECT (audiocheblimit), "mode", "low-pass", NULL);
"mode"
是一个枚举,可以作为字符串传递,也可以作为整数值传递。
编辑 3
您似乎没有在您需要的 .h
文件中正确声明您的元素:
typedef _GstVADCustomFilter {
GstBin parent;
...
} GstVADCustomFilter;
在您的 .c
文件中:
G_DEFINE_TYPE (GstVADCustomFilter, gst_v_a_d_custom_filter, GST_TYPE_BIN);