gstreamermm, Gst::AudioSink

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

gstreamermm, Gst::AudioSink

Ankur Deep Jaiswal
Hi,

 I'm trying to create a custom audio sink plugin for gstreamer using the
Gst::AudioSink as a base class.,
i have gone through a previous mail on april and created a sample plugin.

but plugin fails by audiobasesink gstaudiobasesink.c:1193:gst_audio_base_sink_preroll:<customaudiosink0> [00m error: sink not negotiated.

i have looked into gstaudiobasesink.c
it fails at !gst_audio_ring_buffer_is_acquired.

am i missing something here.

i am including the sample here

--------- .h

#include <gstreamermm.h>
#include <gstreamermm/audiosink.h>
#include <gstreamermm/private/audiosink_p.h>
#include <iostream>

class CustomAudioSink: public Gst::AudioSink {
public:
    explicit CustomAudioSink(GstAudioSink * gobj);
    virtual ~CustomAudioSink();

    static void class_init(Gst::ElementClass<CustomAudioSink> *klass);
    static bool register_element(Glib::RefPtr<Gst::Plugin> plugin);

    bool open_vfunc() override;
    bool close_vfunc() override;
    int write_vfunc(gpointer data, guint length) override;
    guint get_delay_vfunc() const override;

    Glib::RefPtr<Gst::AudioRingBuffer> create_ring_buffer_vfunc() override
    {
        const auto base = static_cast<BaseClassType*>(g_type_class_peek_parent(
                G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
                );

        const auto newbase = (_GstAudioBaseSinkClass *) base;

        if (newbase && newbase->create_ringbuffer) {
            Glib::RefPtr<Gst::AudioRingBuffer> retval(
                    Glib::wrap(
                            (*newbase->create_ringbuffer)(
                                    (_GstAudioBaseSink *) gobj()), true));
            return retval;
        }

        using RType = Glib::RefPtr<Gst::AudioRingBuffer>;
        return RType();
    }
};

---------- .cpp

#include "CustomAudioSink.h"
#include <iostream>

CustomAudioSink::CustomAudioSink(GstAudioSink * gobj) :
        Glib::ObjectBase(typeid(CustomAudioSink)), Gst::AudioSink(gobj) {

}

CustomAudioSink::~CustomAudioSink() {
    // TODO Auto-generated destructor stub
}

void CustomAudioSink::class_init(Gst::ElementClass<CustomAudioSink> *klass) {
    klass->set_metadata("foo_longname", "foo_classification",
            "foo_detail_description", "foo_detail_author"); //channel-mask=(bitmask)0x1,layout=(string)interleaved
    klass->add_pad_template(
            Gst::PadTemplate::create("sink", Gst::PadDirection::PAD_SINK,
                    Gst::PAD_ALWAYS, Gst::Caps::create_any()));
}

bool CustomAudioSink::register_element(Glib::RefPtr<Gst::Plugin> plugin) {
    Gst::ElementFactory::register_element(plugin, "customaudiosink", 0,
            Gst::register_mm_type<CustomAudioSink>("customaudiosink"));
    return true;
}

bool CustomAudioSink::open_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
bool CustomAudioSink::close_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
int CustomAudioSink::write_vfunc(gpointer data, guint length) {
    std::cout << "Writing Audio : " << length << std::endl;
    return length;
}
guint CustomAudioSink::get_delay_vfunc() const {
    return 0;
}

------ main.cpp

#include <gstreamermm.h>
#include <giomm.h>
#include <iostream>
#include "CustomAudioSink.h"

using namespace std;

bool on_bus_message(const Glib::RefPtr<Gst::Bus> & bus, const Glib::RefPtr<Gst::Message> & message)
{
  std::cout << "Bus Message :  " << message->get_message_type() << ":" << GST_MESSAGE_TYPE_NAME(message.get())
      << std::endl;
  return true;
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Gst::init();
    Gio::init();
    auto mainloop = Glib::MainLoop::create();

    Gst::Plugin::register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR,
            "customaudiosink", "customaudiosink",
            sigc::ptr_fun(&CustomAudioSink::register_element), "0.123",
            "LGPL", "source?", "package?", "abcd.com");

    std::string description =
            "audiotestsrc blocksize=16000 num-buffers=100 ! audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1 ! customaudiosink";
    auto bin = Gst::Parse::create_bin(description, true);
    auto pipeline = Gst::Pipeline::create();
    pipeline->get_bus()->add_watch(sigc::ptr_fun(&on_bus_message));
    pipeline->add(bin);

    pipeline->set_state(Gst::State::STATE_PLAYING);
    mainloop->run();
    pipeline->set_state(Gst::State::STATE_NULL);

    return 0;
}

--
Regards
Ankur Deep Jaiswal


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: gstreamermm, Gst::AudioSink

Ankur Deep Jaiswal
Hi,

got it,
we also have to override prepare_audiosink_vfunc
example .

    bool prepare_audiosink_vfunc(Gst::AudioRingBufferSpec& spec) override
    {
        auto srccaps = Gst::Caps::create_from_string("audio/x-raw, format=(string)S16LE, rate=(int)16000,channels=(int)1,channel-mask=(bitmask)0x1,layout=(string)interleaved");
        spec.set_caps(srccaps);
        return true;
    }



On Mon, Jun 18, 2018 at 7:03 PM, Ankur Deep Jaiswal <[hidden email]> wrote:
Hi,

 I'm trying to create a custom audio sink plugin for gstreamer using the
Gst::AudioSink as a base class.,
i have gone through a previous mail on april and created a sample plugin.

but plugin fails by audiobasesink gstaudiobasesink.c:1193:gst_audio_base_sink_preroll:<customaudiosink0> [00m error: sink not negotiated.

i have looked into gstaudiobasesink.c
it fails at !gst_audio_ring_buffer_is_acquired.

am i missing something here.

i am including the sample here

--------- .h

#include <gstreamermm.h>
#include <gstreamermm/audiosink.h>
#include <gstreamermm/private/audiosink_p.h>
#include <iostream>

class CustomAudioSink: public Gst::AudioSink {
public:
    explicit CustomAudioSink(GstAudioSink * gobj);
    virtual ~CustomAudioSink();

    static void class_init(Gst::ElementClass<CustomAudioSink> *klass);
    static bool register_element(Glib::RefPtr<Gst::Plugin> plugin);

    bool open_vfunc() override;
    bool close_vfunc() override;
    int write_vfunc(gpointer data, guint length) override;
    guint get_delay_vfunc() const override;

    Glib::RefPtr<Gst::AudioRingBuffer> create_ring_buffer_vfunc() override
    {
        const auto base = static_cast<BaseClassType*>(g_type_class_peek_parent(
                G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
                );

        const auto newbase = (_GstAudioBaseSinkClass *) base;

        if (newbase && newbase->create_ringbuffer) {
            Glib::RefPtr<Gst::AudioRingBuffer> retval(
                    Glib::wrap(
                            (*newbase->create_ringbuffer)(
                                    (_GstAudioBaseSink *) gobj()), true));
            return retval;
        }

        using RType = Glib::RefPtr<Gst::AudioRingBuffer>;
        return RType();
    }
};

---------- .cpp

#include "CustomAudioSink.h"
#include <iostream>

CustomAudioSink::CustomAudioSink(GstAudioSink * gobj) :
        Glib::ObjectBase(typeid(CustomAudioSink)), Gst::AudioSink(gobj) {

}

CustomAudioSink::~CustomAudioSink() {
    // TODO Auto-generated destructor stub
}

void CustomAudioSink::class_init(Gst::ElementClass<CustomAudioSink> *klass) {
    klass->set_metadata("foo_longname", "foo_classification",
            "foo_detail_description", "foo_detail_author"); //channel-mask=(bitmask)0x1,layout=(string)interleaved
    klass->add_pad_template(
            Gst::PadTemplate::create("sink", Gst::PadDirection::PAD_SINK,
                    Gst::PAD_ALWAYS, Gst::Caps::create_any()));
}

bool CustomAudioSink::register_element(Glib::RefPtr<Gst::Plugin> plugin) {
    Gst::ElementFactory::register_element(plugin, "customaudiosink", 0,
            Gst::register_mm_type<CustomAudioSink>("customaudiosink"));
    return true;
}

bool CustomAudioSink::open_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
bool CustomAudioSink::close_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
int CustomAudioSink::write_vfunc(gpointer data, guint length) {
    std::cout << "Writing Audio : " << length << std::endl;
    return length;
}
guint CustomAudioSink::get_delay_vfunc() const {
    return 0;
}

------ main.cpp

#include <gstreamermm.h>
#include <giomm.h>
#include <iostream>
#include "CustomAudioSink.h"

using namespace std;

bool on_bus_message(const Glib::RefPtr<Gst::Bus> & bus, const Glib::RefPtr<Gst::Message> & message)
{
  std::cout << "Bus Message :  " << message->get_message_type() << ":" << GST_MESSAGE_TYPE_NAME(message.get())
      << std::endl;
  return true;
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Gst::init();
    Gio::init();
    auto mainloop = Glib::MainLoop::create();

    Gst::Plugin::register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR,
            "customaudiosink", "customaudiosink",
            sigc::ptr_fun(&CustomAudioSink::register_element), "0.123",
            "LGPL", "source?", "package?", "abcd.com");

    std::string description =
            "audiotestsrc blocksize=16000 num-buffers=100 ! audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1 ! customaudiosink";
    auto bin = Gst::Parse::create_bin(description, true);
    auto pipeline = Gst::Pipeline::create();
    pipeline->get_bus()->add_watch(sigc::ptr_fun(&on_bus_message));
    pipeline->add(bin);

    pipeline->set_state(Gst::State::STATE_PLAYING);
    mainloop->run();
    pipeline->set_state(Gst::State::STATE_NULL);

    return 0;
}

--
Regards
Ankur Deep Jaiswal




--
Regards

Ankur Deep Jaiswal
Software Architect
Techgentsia Software Technologies Private Limited
Ernakulam

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: gstreamermm, Gst::AudioSink

Ankur Deep Jaiswal
Hi,

the audiosink/audiosrc is now working,
but there is an unexpected bug while stopping the pipeline.

** (test_audio_plugin:11726): [1;35mCRITICAL [0m **: [34m20:48:28.984 [0m: Resources for ring buffer 0x555555a40040 still acquired

Thread #1 [test_audio_plug] 11726 [core: 1] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)   
    0x7ffff7582c41   
    g_logv() at 0x7ffff7583f2b   
    g_log() at 0x7ffff758407f   
    gst_audio_ring_buffer_close_device() at 0x7ffff4adcc9b   
    0x7ffff4affc8e   
    Gst::Element_Class::change_state_vfunc_callback() at 0x7ffff7258281   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    Gst::Element_Class::set_state_vfunc_callback() at 0x7ffff72581e1   
    gst_bin_element_set_state() at gstbin.c:2,602 0x7ffff7ad6942   
    gst_bin_change_state_func() at gstbin.c:2,944 0x7ffff7ad6942   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    gst_bin_element_set_state() at gstbin.c:2,602 0x7ffff7ad6942   
    gst_bin_change_state_func() at gstbin.c:2,944 0x7ffff7ad6942   
    gst_pipeline_change_state() at gstpipeline.c:508 0x7ffff7b1eac2   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_continue_state() at gstelement.c:2,660 0x7ffff7af95ef   
    gst_element_change_state() at gstelement.c:2,991 0x7ffff7af8eb5   
    gst_element_continue_state() at gstelement.c:2,660 0x7ffff7af95ef   
    gst_element_change_state() at gstelement.c:2,998 0x7ffff7af8c26   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    main() at test_audio_plugin.cpp:51 0x55555555d1e2   


i had to override create_ring_buffer_vfunc        

Glib::RefPtr<Gst::AudioRingBuffer> create_ring_buffer_vfunc() override
    {
        const auto base = static_cast<BaseClassType*>(g_type_class_peek_parent(
                G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
                );

        const auto newbase = (_GstAudioBaseSrcClass *) base;

        if (newbase && newbase->create_ringbuffer) {
           auto retval = Glib::wrap(
                    (*newbase->create_ringbuffer)(
                            (_GstAudioBaseSrc *) gobj()),true);
            return retval;
        }

        using RType = Glib::RefPtr<Gst::AudioRingBuffer>;
        return RType();
    }
the default behavior was causing (test_audio_plugin:11956): GStreamer-CRITICAL **: 20:55:06.510: gst_object_set_parent: assertion 'GST_IS_OBJECT (object)' failed

Thread #1 [test_audio_plug] 11987 [core: 4] (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)   
    0x7ffff7582c41   
    g_logv() at 0x7ffff7583f2b   
    g_log() at 0x7ffff758407f   
    gst_object_set_parent() at gstobject.c:670 0x7ffff7acbeaa   
    gst_audio_base_src_create_ringbuffer() at 0x7ffff4aff82d   
    0x7ffff4aff94c   
    Gst::Element_Class::change_state_vfunc_callback() at 0x7ffff7258281   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    Gst::Element_Class::set_state_vfunc_callback() at 0x7ffff72581e1   
    gst_bin_element_set_state() at gstbin.c:2,602 0x7ffff7ad6942   
    gst_bin_change_state_func() at gstbin.c:2,944 0x7ffff7ad6942   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    gst_bin_element_set_state() at gstbin.c:2,602 0x7ffff7ad6942   
    gst_bin_change_state_func() at gstbin.c:2,944 0x7ffff7ad6942   
    gst_element_change_state() at gstelement.c:2,952 0x7ffff7af8bce   
    gst_element_set_state_func() at gstelement.c:2,906 0x7ffff7af9309   
    main() at test_audio_plugin.cpp:49 0x55555555cf7a   



On Mon, Jun 18, 2018 at 7:49 PM, Ankur Deep Jaiswal <[hidden email]> wrote:
Hi,

got it,
we also have to override prepare_audiosink_vfunc
example .

    bool prepare_audiosink_vfunc(Gst::AudioRingBufferSpec& spec) override
    {
        auto srccaps = Gst::Caps::create_from_string("audio/x-raw, format=(string)S16LE, rate=(int)16000,channels=(int)1,channel-mask=(bitmask)0x1,layout=(string)interleaved");
        spec.set_caps(srccaps);
        return true;
    }



On Mon, Jun 18, 2018 at 7:03 PM, Ankur Deep Jaiswal <[hidden email]> wrote:
Hi,

 I'm trying to create a custom audio sink plugin for gstreamer using the
Gst::AudioSink as a base class.,
i have gone through a previous mail on april and created a sample plugin.

but plugin fails by audiobasesink gstaudiobasesink.c:1193:gst_audio_base_sink_preroll:<customaudiosink0> [00m error: sink not negotiated.

i have looked into gstaudiobasesink.c
it fails at !gst_audio_ring_buffer_is_acquired.

am i missing something here.

i am including the sample here

--------- .h

#include <gstreamermm.h>
#include <gstreamermm/audiosink.h>
#include <gstreamermm/private/audiosink_p.h>
#include <iostream>

class CustomAudioSink: public Gst::AudioSink {
public:
    explicit CustomAudioSink(GstAudioSink * gobj);
    virtual ~CustomAudioSink();

    static void class_init(Gst::ElementClass<CustomAudioSink> *klass);
    static bool register_element(Glib::RefPtr<Gst::Plugin> plugin);

    bool open_vfunc() override;
    bool close_vfunc() override;
    int write_vfunc(gpointer data, guint length) override;
    guint get_delay_vfunc() const override;

    Glib::RefPtr<Gst::AudioRingBuffer> create_ring_buffer_vfunc() override
    {
        const auto base = static_cast<BaseClassType*>(g_type_class_peek_parent(
                G_OBJECT_GET_CLASS(gobject_)) // Get the parent class of the object class (The original underlying C class).
                );

        const auto newbase = (_GstAudioBaseSinkClass *) base;

        if (newbase && newbase->create_ringbuffer) {
            Glib::RefPtr<Gst::AudioRingBuffer> retval(
                    Glib::wrap(
                            (*newbase->create_ringbuffer)(
                                    (_GstAudioBaseSink *) gobj()), true));
            return retval;
        }

        using RType = Glib::RefPtr<Gst::AudioRingBuffer>;
        return RType();
    }
};

---------- .cpp

#include "CustomAudioSink.h"
#include <iostream>

CustomAudioSink::CustomAudioSink(GstAudioSink * gobj) :
        Glib::ObjectBase(typeid(CustomAudioSink)), Gst::AudioSink(gobj) {

}

CustomAudioSink::~CustomAudioSink() {
    // TODO Auto-generated destructor stub
}

void CustomAudioSink::class_init(Gst::ElementClass<CustomAudioSink> *klass) {
    klass->set_metadata("foo_longname", "foo_classification",
            "foo_detail_description", "foo_detail_author"); //channel-mask=(bitmask)0x1,layout=(string)interleaved
    klass->add_pad_template(
            Gst::PadTemplate::create("sink", Gst::PadDirection::PAD_SINK,
                    Gst::PAD_ALWAYS, Gst::Caps::create_any()));
}

bool CustomAudioSink::register_element(Glib::RefPtr<Gst::Plugin> plugin) {
    Gst::ElementFactory::register_element(plugin, "customaudiosink", 0,
            Gst::register_mm_type<CustomAudioSink>("customaudiosink"));
    return true;
}

bool CustomAudioSink::open_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
bool CustomAudioSink::close_vfunc() {
    std::cout << "*** CustomAudioSink: " << __FUNCTION__ << " Called ***"
            << std::endl;
    return true;
}
int CustomAudioSink::write_vfunc(gpointer data, guint length) {
    std::cout << "Writing Audio : " << length << std::endl;
    return length;
}
guint CustomAudioSink::get_delay_vfunc() const {
    return 0;
}

------ main.cpp

#include <gstreamermm.h>
#include <giomm.h>
#include <iostream>
#include "CustomAudioSink.h"

using namespace std;

bool on_bus_message(const Glib::RefPtr<Gst::Bus> & bus, const Glib::RefPtr<Gst::Message> & message)
{
  std::cout << "Bus Message :  " << message->get_message_type() << ":" << GST_MESSAGE_TYPE_NAME(message.get())
      << std::endl;
  return true;
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Gst::init();
    Gio::init();
    auto mainloop = Glib::MainLoop::create();

    Gst::Plugin::register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR,
            "customaudiosink", "customaudiosink",
            sigc::ptr_fun(&CustomAudioSink::register_element), "0.123",
            "LGPL", "source?", "package?", "abcd.com");

    std::string description =
            "audiotestsrc blocksize=16000 num-buffers=100 ! audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1 ! customaudiosink";
    auto bin = Gst::Parse::create_bin(description, true);
    auto pipeline = Gst::Pipeline::create();
    pipeline->get_bus()->add_watch(sigc::ptr_fun(&on_bus_message));
    pipeline->add(bin);

    pipeline->set_state(Gst::State::STATE_PLAYING);
    mainloop->run();
    pipeline->set_state(Gst::State::STATE_NULL);

    return 0;
}

--
Regards
Ankur Deep Jaiswal




--
Regards

Ankur Deep Jaiswal
Software Architect
Techgentsia Software Technologies Private Limited
Ernakulam



--
Regards

Ankur Deep Jaiswal

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: gstreamermm, Gst::AudioSink

Ankur Deep Jaiswal
In reply to this post by Ankur Deep Jaiswal

Hi ,

i was able to solve the issue by implementing unprepare_vfunc and adding a ref to gst_caps

    bool prepare_audiosink_vfunc(Gst::AudioRingBufferSpec& spec) override
    {
         //auto srccaps = Gst::Caps::create_from_string();
        // spec.set_caps(srccaps);

         auto bufferspec = spec.gobj();
         bufferspec->caps = gst_caps_ref(gst_caps_from_string("audio/x-raw, format=(string)S16LE, rate=(int)16000,channels=(int)1,layout=(string)interleaved"));
         return true;
    }
    bool unprepare_vfunc() override
    {
        return true;
    }

--
Regards

Ankur Deep Jaiswal

_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list