appsrc, push buffer by external event when I need

Denis Shienkov denis.shienkov at gmail.com
Wed Dec 13 10:22:28 UTC 2017


I have tried this code:

void Foo::initializeGst()
{
     // Init gstreamer.
     ::gst_init(nullptr, nullptr);

     // Configure appsrc element.
     m_appsrc = ::gst_element_factory_make(
                 "appsrc", "source");

     // Configure appsrc caps.
     const auto caps = ::gst_caps_new_simple(
                 "video/x-raw",
                 "format", G_TYPE_STRING, "BGRA",
                 "width", G_TYPE_INT, 800,
                 "height", G_TYPE_INT, 600,
                 "framerate", GST_TYPE_FRACTION, 0, 1,
                 nullptr);

     ::g_object_set(G_OBJECT(m_appsrc),
                    "caps", caps,
                    nullptr);

     // Configure video convertor element.
     const auto conv = ::gst_element_factory_make(
                 "videoconvert", "conv");

     // Configure video encoder element.
     const auto videoenc = ::gst_element_factory_make(
                 "x264enc", "video_encoder");

     // Configure payloader element.
     const auto payloader = ::gst_element_factory_make(
                 "rtph264pay", "payloader");

     ::g_object_set(G_OBJECT(payloader),
                    "config-interval", 60,
                    nullptr);

     // Configure udpsink element.
     const auto udpsink = ::gst_element_factory_make(
                 "udpsink", "udpsink");

     ::g_object_set(G_OBJECT(udpsink),
                    "host", "127.0.0.1",
                    "port", 50666,
                    nullptr);

     // Build pipeline.
     m_pipeline = ::gst_pipeline_new("pipeline");

     ::gst_bin_add_many(GST_BIN(m_pipeline),
                        m_appsrc,
                        conv,
                        videoenc,
                        payloader,
                        udpsink,
                        nullptr);

     const auto result = ::gst_element_link_many(
                 m_appsrc, conv, videoenc, payloader, udpsink, nullptr);

     if (!result) {
         qDebug() << "Unable to initialize the GST";
     } else {
         // Play.
         ::gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
     }
}

void Foo::initializeGst()
{
     // Init gstreamer.
     ::gst_init(nullptr, nullptr);

     // Configure appsrc element.
     m_appsrc = ::gst_element_factory_make(
                 "appsrc", "source");

     // Configure appsrc caps.
     const auto caps = ::gst_caps_new_simple(
                 "video/x-raw",
                 "format", G_TYPE_STRING, "BGRA",
                 "width", G_TYPE_INT, 800,
                 "height", G_TYPE_INT, 600,
                 "framerate", GST_TYPE_FRACTION, 0, 1,
                 nullptr);

     ::g_object_set(G_OBJECT(m_appsrc),
                    "caps", caps,
                    nullptr);

     // Configure video convertor element.
     const auto conv = ::gst_element_factory_make(
                 "videoconvert", "conv");

     // Configure video encoder element.
     const auto videoenc = ::gst_element_factory_make(
                 "x264enc", "video_encoder");

     // Configure payloader element.
     const auto payloader = ::gst_element_factory_make(
                 "rtph264pay", "payloader");

     ::g_object_set(G_OBJECT(payloader),
                    "config-interval", 60,
                    nullptr);

     // Configure udpsink element.
     const auto udpsink = ::gst_element_factory_make(
                 "udpsink", "udpsink");

     ::g_object_set(G_OBJECT(udpsink),
                    "host", "127.0.0.1",
                    "port", 50666,
                    nullptr);

     // Build pipeline.
     m_pipeline = ::gst_pipeline_new("pipeline");

     ::gst_bin_add_many(GST_BIN(m_pipeline),
                        m_appsrc,
                        conv,
                        videoenc,
                        payloader,
                        udpsink,
                        nullptr);

     const auto result = ::gst_element_link_many(
                 m_appsrc, conv, videoenc, payloader, udpsink, nullptr);

     if (!result) {
         qDebug() << "Unable to initialize the GST";
     } else {
         // Play.
         ::gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
     }
}

void Foo::setImage(const QImage &image)
{
     GstBuffer *buffer = ::gst_buffer_new_allocate(
         nullptr, m_image.byteCount(), nullptr);
     gsize offset = 0;
     ::gst_buffer_fill(buffer, offset, m_image.constBits(), 
m_image.byteCount());
     const auto result = 
::gst_app_src_push_buffer(GST_APP_SRC(m_appsrc), buffer);
}

But it does not work at all...

But when I use the:

     ::g_object_set(G_OBJECT(appsrc),
                    "stream-type", 0,
                    "is-live", TRUE,
                    "format", GST_FORMAT_TIME,
                    nullptr);

and:

     g_signal_connect(appsrc, "need-data", G_CALLBACK(need_data_cb), 
nullptr);

then it works (when I fill and push the buffer from the callback),
but I do not need in callback, because I want to push the buffers manually.

Please, help, me. What I need to change in my code? :(

BR,
Denis
12.12.2017 18:19, Denis Shienkov пишет:
> Guys, Is it impossible?
>
>
> 11.12.2017 12:34, Denis Shienkov пишет:
>> Hi developers.
>>
>> I have read this tutorial with appsrs (and even tried it with udpsink):
>>
>> https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html#appsrc-example 
>>
>>
>> where are used the timestamp-based pushing of data buffer.
>>
>> But in my case I need to push a buffer in randomly way (not 
>> periodically, when I want), by some
>> external event (when a data buffer becomes ready from some external 
>> source). A main purpose,
>> as I think, is to minimize the CPU loading, and the udpsink loading 
>> (I want to send a stream to network).
>>
>> So, is it possible to do that? What I need to modify in that source 
>> to push buffers manually?
>>
>> Should I skip the "need-data" signal (e.g. just do not subscribe to 
>> signal) and just to use gst_app_src_push_buffer() directly when I need?
>>
>> BR,
>> Denis
>>
>>
>



More information about the gstreamer-devel mailing list