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