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