- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个从 rtspsrc 元素中提取视频的 GStreamer 管道。 rtspsrc 元素连接到 rtpjpegdepay 元素。我希望能够即时更改 RTSP URL。到目前为止,我一直在做的是:
1) 取消 rtspsrc 与 depay 元素的链接
2) 使用新的 RTSP URL 创建一个新的源元素
3) 并链接到 depay 元素。
我遇到的问题是新的 RTSP 源元素没有正确链接到 depay 元素,导致段错误。我需要一些帮助来弄清楚如何动态更改 rtspsrc URL(当管道仍在播放时)。
管道创建:
GstBus *bus;
guint busWatchId;
GstElement *src, *depay, *parser, *decoder, *vpe, *filter, *sink;
GstCaps *vpeCaps;
m_loop = g_main_loop_new(NULL, FALSE);
//create pipeline elements
m_cameraStream = gst_pipeline_new("display_pipeline");
src = gst_element_factory_make("rtspsrc", "rtspsrc");
depay = gst_element_factory_make("rtpjpegdepay", "depay");
parser = gst_element_factory_make("jpegparse", NULL);
decoder = gst_element_factory_make("ducatijpegdec", NULL);
vpe = gst_element_factory_make("vpe", NULL);
filter = gst_element_factory_make("capsfilter", NULL);
sink = gst_element_factory_make("waylandsink", NULL);
if(!(m_cameraStream || src || depay || parser || decoder || vpe || filter || sink)){
qFatal("could not create pipeline elements");
exit(1);
}
g_object_set(G_OBJECT(src), "location", "rtsp://192.168.50.29/av0_1", "latency", 0, NULL);
g_signal_connect(src, "pad-added", G_CALLBACK(on_rtsp_pad_added), depay);
//add src caps?
vpeCaps = gst_caps_from_string("video/x-raw, format=NV12, width=800, height=480"); //change this when Tomas' patch hits
if(!vpeCaps){
qFatal("cannot create caps");
exit(1);
}
g_object_set(G_OBJECT(filter), "caps", vpeCaps, NULL);
g_object_set(G_OBJECT(sink), "sync", false, NULL);
//add and link elements to create full pipeline
gst_bin_add_many(GST_BIN(m_cameraStream), src, depay, parser, decoder, vpe, sink, NULL);
if(!gst_element_link_many(depay, parser, decoder, vpe, sink, NULL)){
qFatal("cannot link elements");
exit(1);
}
gst_caps_unref(vpeCaps);
bus = gst_pipeline_get_bus(GST_PIPELINE(m_cameraStream));
busWatchId = gst_bus_add_watch(bus, GstBusFunc(bus_call), m_loop);
gst_object_unref(bus);
rtsp->depay链接回调函数:
gchar *name;
GstElement *depay;
GstCaps *caps;
qDebug("on_rtsp_pad_added");
caps = gst_caps_from_string("application/x-rtp");
name = gst_pad_get_name(pad);
qDebug("on_rtsp_pad_added, rtspsrc pad name: %s", name);
depay = GST_ELEMENT(data);
if(!gst_element_link_pads_filtered(element, name, depay, "sink", caps)){
qFatal("pad_added: failed to link elements");
}
g_free(name);
gst_element_set_state(m_cameraStream, GST_STATE_PLAYING);
g_main_loop_run(m_loop);
源改变函数:
qDebug("slot_changeSource");
//gst_element_set_state(m_cameraStream, GST_STATE_PAUSED); //GST_STATE_NULL: segfault in pad_added
//GST_STATE_PAUSED: pauses, never returns to playing or on_rtsp_pad_added
//GST_STATE_PLAYING(left playing): same as NULL
GstElement* rtspsrc = gst_bin_get_by_name(GST_BIN(m_cameraStream), "rtspsrc");
if(rtspsrc){
qDebug("rtspsrc found");
GstElement* depay = gst_bin_get_by_name(GST_BIN(m_cameraStream), "depay");
if(depay){
qDebug("depay found");
gst_element_unlink(rtspsrc, depay);
gst_bin_remove(GST_BIN(m_cameraStream), rtspsrc);
GstElement* newSource = gst_element_factory_make("rtspsrc", "rtspsrc");
g_object_set(G_OBJECT(newSource), "location", "rtsp://192.168.50.29/av0_1", "latency", 0, NULL);
g_signal_connect(newSource, "pad-added", G_CALLBACK(on_rtsp_pad_added), depay); //needed in the same way as the previous rtspsrc
gst_bin_add(GST_BIN(m_cameraStream), newSource);
gst_element_sync_state_with_parent(newSource);
//gst_element_set_state(m_cameraStream, GST_STATE_PLAYING);
}
gst_element_set_state(rtspsrc, GST_STATE_NULL);
gst_object_unref(rtspsrc);
}
我尝试过的其他事情:
1) 探测rtsp元素的src pad,确保元素中没有任何数据。这似乎是个坏主意,因为 rtsp 元素会在此时重新创建。
2) 将管道设置为 PAUSED 或 NULL,然后更改源元素。这会导致管道永远暂停。
引用资料:
最佳答案
好的,所以我相信我已经找到了答案,我将把它发布在这里,以拯救偶然发现这个问题的人。
答案是创建一对 pad 探针来处理来自管道的数据清除。我通过创建两个 pad 探针回调来做到这一点:一个用于捕获管道以开始刷新过程,另一个用于在管道被刷新后处理 rtspsrc 元素的重新创建。第一个焊盘探针可以放在任何地方,所以我把它放在我的 depay 元件上。第二个焊盘探头必须位于最后一个数据处理 元件的源上。所以不是最终的接收器元素。对于上面的管道,这是“vpe”元素。
我通过将流结束 (EOS) 信号传递到 depay 元素来执行此操作,然后在 vpe 元素的 src pad 处进行 pad 探测回调以在 EOS 退出 VPE 时捕获它。如果 EOS 到达 waylandsink,管道将简单地关闭,您将不得不重新启动整个过程。
vpe = gst_bin_get_by_name(GST_BIN(data), "vpe");
srcPad = gst_element_get_static_pad(vpe, "src");
gst_pad_add_probe(srcPad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, event_probe, data, NULL);
//push EOS into the element, wait for the EOS to appear on the srcpad
depay = gst_bin_get_by_name(GST_BIN(data), "depay");
sinkPad = gst_element_get_static_pad(depay, "sink");
gst_pad_send_event(sinkPad, gst_event_new_eos());
return GST_PAD_PROBE_OK;
以及处理该 EOS 的回调:
static GstPadProbeReturn event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer data){
GstElement *rtspsrcOld, *rtspsrcNew, *depay;
qDebug("event_probe");
if(GST_EVENT_TYPE(GST_PAD_PROBE_INFO_DATA(info)) != GST_EVENT_EOS){
return GST_PAD_PROBE_PASS;
}
gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID(info));
rtspsrcOld = gst_bin_get_by_name(GST_BIN(data), "rtspsrc");
if(rtspsrcOld){
qDebug("found rtspsrcOld");
depay = gst_bin_get_by_name(GST_BIN(data), "depay");
gst_element_unlink(rtspsrcOld, depay);
gst_bin_remove(GST_BIN(data), rtspsrcOld); //remove old rtspsrc from pipeline, should unlink from depay automatically.
rtspsrcNew = gst_element_factory_make("rtspsrc", "rtspsrc");
g_object_set(rtspsrcNew, "location", NEW_URI, "latency", 0, NULL);
g_signal_connect(G_OBJECT(rtspsrcNew), "pad-added", G_CALLBACK(on_rtsp_pad_added), data);
gst_bin_add(GST_BIN(data), rtspsrcNew);
gst_element_set_state(GST_ELEMENT(data), GST_STATE_PLAYING);
return GST_PAD_PROBE_DROP;
}
return GST_PAD_PROBE_DROP;
}
关于c++ - Gstreamer 动态更改源元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50417045/
SO亲爱的 friend 们: 2014 年 3 月 18 日。我正在处理一种情况,在使用 ng-repeat 时,数组内的元素(我从 Json 字符串中获取)更改了原始顺序。 需要明确的是,数组中的
有很多问题询问如何在 JavaScript 单击处理程序中更改 div 的类,例如,此处:Change Div style onclick .我理解得很好(只需更改 .className),并且它有效
我从access导入了一个数据库到mysql,但其中一个表的列名“股数”带有空格,但我尝试更改、替换甚至删除列名,但失败了。任何人都可以帮助解决这一问题 String UpdateQuary = "U
我正在做一个随机的学校元素。 目前,我有一个包含两个 CSS 的页面。一种用于正常 View ,一种用于残障人士 View 。 此页面还包括两个按钮,它们将更改使用的样式表。 function c
我需要使用 javascript 更改 HTML 元素中的文本,但我不知道该怎么做。 ¿有什么帮助吗? 我把它定义成这样: Text I want to change. 我正在尝试这样做: docum
我在它自己的文件 nav_bar.shtml 中有一个主导航栏,每个其他页面都包含该导航栏。这个菜单栏是一个 jQuery 菜单栏(ApyCom 是销售这些导航栏的公司的名称)。导航栏上的元素如何确定
我正在摆弄我的代码,并开始想知道这个变化是否来自: if(array[index] == 0) 对此: if(!array[index] != 0) 可能会影响任何代码,或者它只是做同样的事情而我不需
我一直在想办法调整控制台窗口的大小。这是我正在使用的函数的代码: #include #include #define WIDTH 70 #define HEIGHT 35 HANDLE wHnd;
我有很多情况会导致相同的消息框警报。 有没有比做几个 if 语句更简单/更好的解决方案? PRODUCTS BOX1 BOX2 BOX3
我有一个包含这些元素的 XELEMENT B Bob Petier 19310227 1 我想像这样转换前缀。 B Bob Pet
我使用 MySQL 5.6 遇到了这种情况: 此查询有效并返回预期结果: select * from some_table where a = 'b' and metadata->>"$.countr
我想知道是否有人知道可以检测 R 中日期列格式的任何中断的包或函数,即检测日期向量格式更改的位置,例如: 11/2/90 12/2/90 . . . 15/Feb/1990 16/Feb/1990 .
我希望能够在小部件显示后更改 GtkButton 的标签 char *ButtonStance == "Connect"; GtkWidget *EntryButton = gtk_button_ne
我正在使用 Altera DE2 FPGA 开发板并尝试使用 SD 卡端口和音频线路输出。我正在使用 VHDL 和 C 进行编程,但由于缺乏经验/知识,我在 C 部分遇到了困难。 目前,我可以从 SD
注意到这个链接后: http://www.newscientist.com/blogs/nstv/2010/12/best-videos-of-2010-progress-bar-illusion.h
我想知道在某些情况下,即使剧本任务已成功执行并且 ok=2,ansible 也会显示“changed=0”。使用 Rest API 和 uri 模块时会发生这种情况。我试图找到解释但没有成功。谁能告诉
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: add buttons to push notification alert 是否可以在远程通知显示的警报框中指定有
当您的 TabBarController 中有超过 5 个 View Controller 时,系统会自动为您设置一个“更多” View 。是否可以更改此 View 中导航栏的颜色以匹配我正在使用的颜
如何更改.AndroidStudioBeta文件夹的位置,默认情况下,该文件夹位于Windows中的\ .. \ User \ .AndroidStudioBeta,而不会破坏任何内容? /编辑: 找
我目前正在尝试将更具功能性的编程风格应用于涉及低级(基于 LWJGL)GUI 开发的项目。显然,在这种情况下,需要携带很多状态,这在当前版本中是可变的。我的目标是最终拥有一个完全不可变的状态,以避免状
我是一名优秀的程序员,十分优秀!