appsrc, push buffer by external event when I need

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

appsrc, push buffer by external event when I need

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



_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: appsrc, push buffer by external event when I need

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

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: appsrc, push buffer by external event when I need

Denis Shienkov
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
>>
>>
>

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: appsrc, push buffer by external event when I need

Olivier Crête-3
Hi,

Indeed you don't need to wait for the callback. If you set the block property to TRUE,  then the push function will block if the queue is full. But if you leave it at false, then the only way to know if it's full is to listen to the callbacks.

Olivier

On December 13, 2017 5:22:28 AM EST, Denis Shienkov <[hidden email]> wrote:

>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
>>>
>>>
>>
>
>_______________________________________________
>gstreamer-devel mailing list
>[hidden email]
>https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

--
Olivier Crête
[hidden email]
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: appsrc, push buffer by external event when I need

Denis Shienkov
Yes, thanks,

Seems, I already solved this:

https://stackoverflow.com/questions/47793422/how-to-use-use-the-gst-app-src-push-buffer-manually-with-custom-event

BR, Denis


17.12.2017 18:45, Olivier Crête пишет:

> Hi,
>
> Indeed you don't need to wait for the callback. If you set the block property to TRUE,  then the push function will block if the queue is full. But if you leave it at false, then the only way to know if it's full is to listen to the callbacks.
>
> Olivier
>
> On December 13, 2017 5:22:28 AM EST, Denis Shienkov <[hidden email]> wrote:
>> 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
>>>>
>>>>
>> _______________________________________________
>> gstreamer-devel mailing list
>> [hidden email]
>> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel