我需要将klv元数据复用到h264流中。我创建了应用程序。但只要插入klv数据,流就会播放。当我停止推送klv-data时,整个流停止。 通过mpegtsmux复用异步klv数据的正确方法是什么?
需要将Klv数据插入以下工作管道:
v4l2src input-src=Camera ! videorate drop-only=true ! 'video/x-raw, format=(string)NV12, width=1920, height=1088, framerate=25/1' ! ce_h264enc target-bitrate=6000000 idrinterval=25 intraframe-interval=60 ! queue ! mpegtsmux alignment=7 ! udpsink host=192.168.0.1 port=3000 -v
此管道在应用程序中收集。要创建插入klv-metedata appsrc:
appSrc = gst_element_factory_make("appsrc", nullptr);
gst_app_src_set_caps (GST_APP_SRC (appSrc), gst_caps_new_simple("meta/x-klv", "parsed", G_TYPE_BOOLEAN, TRUE, "sparse", G_TYPE_BOOLEAN, TRUE, nullptr));
g_object_set(appSrc, "format", GST_FORMAT_TIME, nullptr);
然后,appsrc链接到管道:
gst_bin_add(GST_BIN(pipeline), appSrc);
gst_element_link(appSrc, mpegtsmux);
这是推送功能:
void AppSrc::pushData(const std::string &data)
{
GstBuffer *buffer = gst_buffer_new_allocate(nullptr, data.size(), nullptr);
GstMapInfo map;
GstClock *clock;
GstClockTime abs_time, base_time;
gst_buffer_map (buffer, &map, GST_MAP_WRITE);
memcpy(map.data, data.data(), data.size());
gst_buffer_unmap (buffer, &map);
GST_OBJECT_LOCK (element);
clock = GST_ELEMENT_CLOCK (element);
base_time = GST_ELEMENT (element)->base_time;
gst_object_ref (clock);
GST_OBJECT_UNLOCK (element);
abs_time = gst_clock_get_time (clock);
gst_object_unref (clock);
GST_BUFFER_PTS (buffer) = abs_time - base_time;
GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int (1, GST_SECOND, 1);
gst_app_src_push_buffer(GST_APP_SRC(element), buffer);
}
Gstreamer版本是1.6.1。
我的代码有什么问题?我很感激你的帮助。
我可以推送虚拟klv包来维护视频流。但我不想污染upcomming流,我相信应该有更精细的解决方案。
我发现我可以发送GST_STREAM_FLAG_SPARSE的事件,这应该适合字幕。但结果我根本没有输出。
GstEvent* stream_start = gst_event_new_stream_start("klv-04");
gst_event_set_stream_flags(stream_start, GST_STREAM_FLAG_SPARSE);
GstPad* pad = gst_element_get_static_pad(GST_ELEMENT(element), "src");
gst_pad_push_event (pad, stream_start);
调试时我发现在将以下补丁应用到gstreamer并使用GST_STREAM_FLAG_SPARSE之后,当appsrc停止推送数据包时,流不会停止。
diff --git a/libs/gst/base/gstcollectpads.c b/libs/gst/base/gstcollectpads.c
index 8edfe41..14f9926 100644
--- a/libs/gst/base/gstcollectpads.c
+++ b/libs/gst/base/gstcollectpads.c
@@ -1440,7 +1440,8 @@ gst_collect_pads_recalculate_waiting (GstCollectPads * pads)
if (!GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_WAITING)) {
/* start waiting */
gst_collect_pads_set_waiting (pads, data, TRUE);
- result = TRUE;
+ if (!GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_LOCKED))
+ result = TRUE;
}
}
}
无论如何,接收器在最后一个klv包后10秒停止更新屏幕。
答案 0 :(得分:0)
这是一个旧线程,但是,
根据我的经验,如果appsrc和muxer之间没有队列,你会得到这种行为。我会改变你的:
gst_element_link(appSrc, mpegtsmux);
对此:
gst_element_link(appSrc, appSrcQueue);
gst_element_link(appSrcQueue, mpegtsmux);
我不确定mpegtsmux是否具有该功能,但我们使用的多路复用器具有一个名为do-timestamping
的属性,当设置为TRUE
时我们有一个更好的经验。
我要给出的另一个提示是使用gst-inspect
工具查看每个元素有哪些选项。