2016-05-26 105 views
0

我在使用Gstreamer的RTSP客戶端時遇到了一些問題。所以我有一個客戶端程序,並且我希望當RTSP客戶端收到/發送消息或返回錯誤等時,它會從看門狗功能給予適當的響應,並在出現錯誤時相應地退出代碼。所以我做的是這個,Gstreamer RTSP客戶端超時問題

  1. 我只是在我的機器上使用VLC創建一個RTSP服務器,並且我連接到了這臺服務器。我可以很明顯地成功建立連接。
  2. 我通過簡單地關閉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; 
} 

回答

1

此代碼如預期運行。我做了錯誤的測試。

我「停止」rtsp服務器的方式只是按下VLC的「停止」按鈕。這不會破壞服務器,服務器仍然存在,只是沒有做出任何類型的流,而且客戶端仍然沒有問題地連接到服務器,因爲服務器仍然存在。當我關閉VLC而不是銷燬服務器時,它會進入正確的看門狗功能。