我想制作GStreamer android应用程序,既能够接收RTP流,又能够检测流何时关闭。
该应用程序使用默认屏幕(videotestsrc)进行初始化,但是当我想切换到流屏幕时,我无法链接垃圾箱的按钮。当管道处于 PLAYING 状态
时,就会发生此过程为此,我使用了三个垃圾箱并将它们添加到管道中。
应用程序使用与显示接收器箱连接的默认源箱进行初始化,因为没有信号,因此应用上显示了默认的蓝屏,而流式源箱等待rtp流(为此,我添加了一个块/ buffer探针)。
当检测到rtp流时,会将默认源容器从管道中删除(还将该容器与显示接收器容器断开链接),并将流式源容器链接到显示接收器容器。
当我尝试将默认源bin更改为流媒体源bin时,会出现问题,因为当我删除默认源bin且我想将流媒体源bin链接到show sink bin时,我得到了<强烈的> GST_PAD_LINK_NO_FORMAT 错误。
这是我用来创建垃圾箱的代码。
gchar streaming_src_bin_string[300];
strcpy(streaming_src_bin_string, "udpsrc port=5000 timeout=100000000 ! ");
strcat(streaming_src_bin_string, "application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264 ! ");
strcat(streaming_src_bin_string, "queue ! rtph264depay ! avdec_h264 name=decoder");
data->streaming_src_bin = gst_parse_bin_from_description(streaming_src_bin_string,
FALSE,
NULL);
gchar default_src_bin_string[300];
strcpy(default_src_bin_string, "videotestsrc pattern=6 ! ");
strcat(default_src_bin_string, "capsfilter name=defaultcaps caps=video/x-raw,width=(int)1280,");
strcat(default_src_bin_string, "height=(int)800,pixel-aspect-ratio=(fraction)1/1,framerate=(fraction)5/1");
data->default_src_bin = gst_parse_bin_from_description(default_src_bin_string,
FALSE,
NULL);
gchar show_sink_bin_string[1024];
strcpy(show_sink_bin_string, "textoverlay name=top-left valignment=top halignment=left font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=top-center valignment=top halignment=center font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=top-right valignment=top halignment=right font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=center-center valignment=center halignment=center font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=bottom-left valignment=bottom halignment=left font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=bottom-center valignment=bottom halignment=center font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "textoverlay name=bottom-right valignment=bottom halignment=right font-desc=\"courier 12px\" text=\"Testing\" ! ");
strcat(show_sink_bin_string, "glimagesink sync=false");
data->show_sink_bin = gst_parse_bin_from_description(show_sink_bin_string, FALSE, NULL);
这是我用来切换垃圾箱的代码:
/* Method that changes the input bin to the streaming source bin
* when the pad is IDLE */
static GstPadProbeReturn
change_input_on_idle_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
CustomData *data = (CustomData *) user_data;
GST_DEBUG ("Default src caps is IDLE, changing to streaming src bin");
gst_bin_remove (GST_BIN (data->pipeline), data->default_src_bin);
GST_DEBUG ("Linking streaming src with show sink");
GstPadLinkReturn ret = gst_pad_link (data->streaming_src_bin_pad, data->show_sink_bin_pad);
switch (ret) {
case GST_PAD_LINK_OK: GST_DEBUG ("Pads linked"); break;
case GST_PAD_LINK_WRONG_HIERARCHY: GST_ERROR ("Can't link pads, GST_PAD_LINK_WRONG_HIERARCHY"); break;
case GST_PAD_LINK_WAS_LINKED: GST_ERROR ("Can't link pads, GST_PAD_LINK_WAS_LINKED"); break;
case GST_PAD_LINK_WRONG_DIRECTION: GST_ERROR ("Can't link pads, GST_PAD_LINK_WRONG_DIRECTION"); break;
case GST_PAD_LINK_NOFORMAT: GST_ERROR ("Can't link pads, GST_PAD_LINK_NOFORMAT"); break;
case GST_PAD_LINK_NOSCHED: GST_ERROR ("Can't link pads, GST_PAD_LINK_NOSCHED"); break;
case GST_PAD_LINK_REFUSED: GST_ERROR ("Can't link pads, GST_PAD_LINK_REFUSED"); break;
default: GST_DEBUG ("Unhandled exception");
}
GST_DEBUG ("Link completed, removing idle probe");
data->is_streaming = TRUE;
return GST_PAD_PROBE_REMOVE;
}
/* Method that adds an idle probe on stream detection
* and waits for streaming src bin to be linked before
* removing the probe attached to the streaming src bin */
static GstPadProbeReturn
data_received_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
if (gst_buffer_has_flags(buffer, GST_BUFFER_FLAG_DISCONT) ||
gst_buffer_has_flags(buffer, GST_BUFFER_FLAG_CORRUPTED)) {
return GST_PAD_PROBE_DROP;
}
GST_DEBUG ("Frame received");
GST_DEBUG ("UDP stream detected, adding idle probe to default src caps");
CustomData *data = (CustomData *) user_data;
gst_pad_add_probe(data->default_src_bin_pad, GST_PAD_PROBE_TYPE_IDLE, change_input_on_idle_cb,
user_data, NULL);
GST_DEBUG ("Linking completed, removing data received probe");
return GST_PAD_PROBE_REMOVE;
}
这没有任何意义,因为当我在python中测试相同的东西并完美运行时,我仅在android上收到此错误。所以我没有任何线索可以解决这个问题。