作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 gstreamer 的 appsrc 元素将图像作为视频流发送到 gstreamer 的管道。我查看了 appsrc 示例,其中使用了基于时间的流格式。每个缓冲区的时间戳步长为 0.5 秒,“需要数据”回调每 0.5 秒调用一次。
但就我而言,我不需要此功能,我需要在图像准备好发送时直接使用 gst_app_src_push_buffer()(据我所知)。
我使用以下初始化代码(简化的伪代码):
void Foo::initializeGst()
{
// Init gstreamer.
::gst_init(nullptr, nullptr);
// Configure appsrc element.
m_appsrc = ::gst_element_factory_make(
"appsrc", "source");
::g_object_set(G_OBJECT(m_appsrc),
"stream-type", GST_APP_STREAM_TYPE_STREAM,
"is-live", true,
nullptr);
// 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.
const auto status = ::gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
qDebug() << "Status:" << status;
}
}
以及以下缓冲区访问代码(简化的伪代码):
void Foo::setImage(const QImage &image)
{
GstBuffer *buffer = gst_buffer_new_and_alloc(m_image.byteCount());
const auto bytesCopied = ::gst_buffer_fill(
buffer, 0, m_image.constBits(), m_image.byteCount());
const auto result = ::gst_app_src_push_buffer(
GST_APP_SRC(m_appsrc), buffer);
qDebug() << "Push result" << result << "for copied bytes"
<< bytesCopied;
}
但是,没有任何反应,我没有看到视频流,例如使用 VLC 播放器(带有 SDP 文件),一段时间后,应用程序崩溃。
但是,如果我使用“需要数据”信号和 GST_FORMAT_TIME 选项:
::g_object_set(G_OBJECT(appsrc),
"stream-type", 0,
"is-live", TRUE,
"format", GST_FORMAT_TIME,
nullptr);
g_signal_connect(appsrc, "need-data", G_CALLBACK(need_data_cb), nullptr);
static void need_data_cb(GstElement *appsrc, guint unused_size, gpointer user_data)
{
static gboolean white = FALSE;
static GstClockTime timestamp = 0;
const guint size = 800 * 600 * 4;
GstBuffer *buffer = ::gst_buffer_new_allocate(nullptr, size, nullptr);
// This makes the image black/white.
::gst_buffer_memset(buffer, 0, white ? 0xff : 0x0, size);
white = !white;
GST_BUFFER_PTS(buffer) = timestamp;
GST_BUFFER_DURATION(buffer) = ::gst_util_uint64_scale_int (1, GST_SECOND, 20);
timestamp += GST_BUFFER_DURATION(buffer);
GstFlowReturn ret;
::g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret);
::gst_buffer_unref(buffer);
}
然后就可以了...
我完全不明白,我需要更改什么才能使其在没有时间戳和 GST_FORMAT_TIME 选项的情况下工作。
有人可以帮我吗?
BR,丹尼斯
最佳答案
啊..对不起,我傻了
设置 GST_FORMAT_TIME 就足够了:
::g_object_set(G_OBJECT(appsrc),
"stream-type", 0,
"is-live", TRUE,
"format", GST_FORMAT_TIME,
nullptr);
在缓冲区创建时,只需将缓冲区 pts 字段设置为当前时间戳值,例如使用 QElapsedTimer:
void Foo::setImage(const QImage &image)
{
GstBuffer *buffer = gst_buffer_new_and_alloc(m_image.byteCount());
const auto bytesCopied = ::gst_buffer_fill(
buffer, 0, m_image.constBits(), m_image.byteCount());
GST_BUFFER_PTS(buffer) = m_timer.nsecsElapsed();
const auto result = ::gst_app_src_push_buffer(
GST_APP_SRC(m_appsrc), buffer);
qDebug() << "Push result" << result << "for copied bytes"
<< bytesCopied;
}
现在,一切正常,yeehaa.. :)
关于qt - 如何使用自定义事件手动使用 gst_app_src_push_buffer(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47793422/
我想使用 gstreamer 的 appsrc 元素将图像作为视频流发送到 gstreamer 的管道。我查看了 appsrc 示例,其中使用了基于时间的流格式。每个缓冲区的时间戳步长为 0.5 秒,
我是一名优秀的程序员,十分优秀!