Gstreamer RTSP 客户端超时问题
Gstreamer RTSP client timeout issues
我在使用 Gstreamer 的 RTSP 客户端时遇到一些问题。所以我有一个客户端程序,我希望它在 RTSP 客户端 receives/sends 一条消息或 returns 一个错误等时从看门狗功能给我适当的响应,如果有的话,相应地退出代码一个错误。所以我做的就是这个,
- 我只是在我的机器上使用 VLC 创建一个 RTSP 服务器,然后连接到该服务器。我显然可以成功创建连接。
- 我通过简单地关闭 VLC 来停止服务器。所以现在看门狗功能应该收到正确的错误代码并将其打印到屏幕上。但它永远不会那样做。在 Gstreamer 的 RTSP 文档中,有一个名为
gst_rtsp_connection_connect
的函数,它接受一个连接和一个超时值,并且在文档中指出,如果超时为 NULL,则该函数可以永远阻塞。所以我虽然因为我把 NULL 放在超时字段中,它永远不会超时并相信它仍然连接到服务器,因此永远不会进入任何看门狗功能。但是,当我申请时,比如 5 秒超时,然后它会在 5-7 秒后直接终止连接并进入一些看门狗功能。我不希望我的代码立即给出错误,即使有正确的连接并且服务器仍在工作,我只希望它在服务器实际关闭并且超时时间已经过去时给出一些错误。我该如何解决这个问题?
这是我的完整代码,包括和库在代码的顶部:
/*
* INCLUDES
* /usr/include/gstreamer-1.0
* /usr/include/glib-2.0
* /usr/lib/x86_64-linux-gnu/glib-2.0/include
* /usr/include/gstreamer-1.0/gst/rtsp
*
* LIBRARIES
* gstreamer-1.0
* gstrtsp-1.0
* gobject-2.0
* glib-2.0
*
* MISC.
* -std=c99
*
*
*
* */
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtsptransport.h>
#include <gst/rtsp/gstrtspconnection.h>
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
static GstRTSPStatusCode
tunnel_start (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_start\n");
return GST_RTSP_STS_OK;
}
static GstRTSPResult
tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_complete\n");
return GST_RTSP_OK;
}
static GstRTSPResult
tunnel_lost (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_lost\n");
return GST_RTSP_OK;
}
static GstRTSPResult
closed (GstRTSPWatch * watch, gpointer user_data)
{
g_print("closed\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_sent (GstRTSPWatch * watch, guint id, gpointer user_data)
{
g_print("message_sent\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_received (GstRTSPWatch *watch, GstRTSPMessage *message, gpointer user_data) {
g_print("message_received\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error (GstRTSPWatch *watch, GstRTSPResult result, gpointer user_data) {
g_print("error\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error_full (GstRTSPWatch *watch, GstRTSPResult result, GstRTSPMessage *message, guint id, gpointer user_data) {
g_print("error_full\n");
return GST_RTSP_OK;
}
static GstRTSPWatchFuncs watch_funcs = {
message_received,
message_sent,
closed,
error,
tunnel_start,
tunnel_complete,
error_full,
tunnel_lost
};
/* main method */
int main (int argc, char *argv[]) {
GMainLoop *loop;
loop = g_main_loop_new (NULL, FALSE);
GstRTSPUrl *url = NULL;
GstRTSPConnection *conn = NULL;
GstRTSPResult res;
GstRTSPWatch *watch;
GTimeVal *timeout;
timeout->tv_sec = 5;
timeout->tv_usec = 5000000;
res = gst_rtsp_url_parse ("rtsp://localhost:5000/test", &url);
res = gst_rtsp_connection_create (url, &conn);
if (res == GST_RTSP_OK) {
g_print("Connection created.\n");
}
res = gst_rtsp_connection_connect (conn, timeout);
if (res == GST_RTSP_OK) {
g_print("Connection connected.\n");
} else {
g_printerr("Connection not connected. Exiting with code 500.\n");
exit(500);
}
watch = gst_rtsp_watch_new (conn, &watch_funcs, loop, NULL);
if (watch == NULL) {
g_print("Failed to create watch.\n");
}
gst_rtsp_watch_attach (watch, NULL);
gst_rtsp_url_free (url);
g_main_loop_run (loop);
return 0;
}
此代码按预期运行。我做错了类型的测试。
我 "stopped" rtsp 服务器的方式只是按下 VLC 的 "stop" 按钮。这不会破坏服务器,服务器仍然存在,只是没有制作任何类型的流,并且客户端仍然毫无问题地连接到服务器,因为服务器仍然存在。当我关闭 VLC 而不是破坏服务器时,它进入了正确的看门狗功能。
我在使用 Gstreamer 的 RTSP 客户端时遇到一些问题。所以我有一个客户端程序,我希望它在 RTSP 客户端 receives/sends 一条消息或 returns 一个错误等时从看门狗功能给我适当的响应,如果有的话,相应地退出代码一个错误。所以我做的就是这个,
- 我只是在我的机器上使用 VLC 创建一个 RTSP 服务器,然后连接到该服务器。我显然可以成功创建连接。
- 我通过简单地关闭 VLC 来停止服务器。所以现在看门狗功能应该收到正确的错误代码并将其打印到屏幕上。但它永远不会那样做。在 Gstreamer 的 RTSP 文档中,有一个名为
gst_rtsp_connection_connect
的函数,它接受一个连接和一个超时值,并且在文档中指出,如果超时为 NULL,则该函数可以永远阻塞。所以我虽然因为我把 NULL 放在超时字段中,它永远不会超时并相信它仍然连接到服务器,因此永远不会进入任何看门狗功能。但是,当我申请时,比如 5 秒超时,然后它会在 5-7 秒后直接终止连接并进入一些看门狗功能。我不希望我的代码立即给出错误,即使有正确的连接并且服务器仍在工作,我只希望它在服务器实际关闭并且超时时间已经过去时给出一些错误。我该如何解决这个问题?
这是我的完整代码,包括和库在代码的顶部:
/*
* INCLUDES
* /usr/include/gstreamer-1.0
* /usr/include/glib-2.0
* /usr/lib/x86_64-linux-gnu/glib-2.0/include
* /usr/include/gstreamer-1.0/gst/rtsp
*
* LIBRARIES
* gstreamer-1.0
* gstrtsp-1.0
* gobject-2.0
* glib-2.0
*
* MISC.
* -std=c99
*
*
*
* */
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtsptransport.h>
#include <gst/rtsp/gstrtspconnection.h>
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
static GstRTSPStatusCode
tunnel_start (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_start\n");
return GST_RTSP_STS_OK;
}
static GstRTSPResult
tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_complete\n");
return GST_RTSP_OK;
}
static GstRTSPResult
tunnel_lost (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_lost\n");
return GST_RTSP_OK;
}
static GstRTSPResult
closed (GstRTSPWatch * watch, gpointer user_data)
{
g_print("closed\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_sent (GstRTSPWatch * watch, guint id, gpointer user_data)
{
g_print("message_sent\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_received (GstRTSPWatch *watch, GstRTSPMessage *message, gpointer user_data) {
g_print("message_received\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error (GstRTSPWatch *watch, GstRTSPResult result, gpointer user_data) {
g_print("error\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error_full (GstRTSPWatch *watch, GstRTSPResult result, GstRTSPMessage *message, guint id, gpointer user_data) {
g_print("error_full\n");
return GST_RTSP_OK;
}
static GstRTSPWatchFuncs watch_funcs = {
message_received,
message_sent,
closed,
error,
tunnel_start,
tunnel_complete,
error_full,
tunnel_lost
};
/* main method */
int main (int argc, char *argv[]) {
GMainLoop *loop;
loop = g_main_loop_new (NULL, FALSE);
GstRTSPUrl *url = NULL;
GstRTSPConnection *conn = NULL;
GstRTSPResult res;
GstRTSPWatch *watch;
GTimeVal *timeout;
timeout->tv_sec = 5;
timeout->tv_usec = 5000000;
res = gst_rtsp_url_parse ("rtsp://localhost:5000/test", &url);
res = gst_rtsp_connection_create (url, &conn);
if (res == GST_RTSP_OK) {
g_print("Connection created.\n");
}
res = gst_rtsp_connection_connect (conn, timeout);
if (res == GST_RTSP_OK) {
g_print("Connection connected.\n");
} else {
g_printerr("Connection not connected. Exiting with code 500.\n");
exit(500);
}
watch = gst_rtsp_watch_new (conn, &watch_funcs, loop, NULL);
if (watch == NULL) {
g_print("Failed to create watch.\n");
}
gst_rtsp_watch_attach (watch, NULL);
gst_rtsp_url_free (url);
g_main_loop_run (loop);
return 0;
}
此代码按预期运行。我做错了类型的测试。
我 "stopped" rtsp 服务器的方式只是按下 VLC 的 "stop" 按钮。这不会破坏服务器,服务器仍然存在,只是没有制作任何类型的流,并且客户端仍然毫无问题地连接到服务器,因为服务器仍然存在。当我关闭 VLC 而不是破坏服务器时,它进入了正确的看门狗功能。