Search code examples
cclientgstreamerrtsp

Gstreamer RTSP client timeout issues


I am having some problems with the Gstreamer's RTSP client. So I have a client program and I want it to give proper responses to me from a watch dog function whenever the RTSP client receives/sends a message or returns an error etc. and exit the code accordingly if there is an error. So what I do is this,

  1. I simply create an RTSP server using VLC on my machine and I connect to this server. I can create the connection successfully apparently.
  2. I stop the server by simply closing the VLC. So now the watch dog function should receive proper error code and print it to the screen. But it never does that. In the RTSP documentation of Gstreamer there is a function called gst_rtsp_connection_connect which takes a connection and a timeout value and in the documentation it is stated that if the timeout is NULL, this function can block forever. So I though since I put NULL in the timeout field, it never times out and believes it is still connected to the server and thus never gets inside any of the watch dog functions. However, when I applied, say a 5 second timeout, then it directly kills the connection after 5-7 seconds and gets inside some of the watch dog functions. I don't want my code to give an error immediately even though there is a proper connection and the server is still up working, I just want it to give some errors when the server is actually down and some timeout time has passed. How can I fix this?

Here is my complete code, includes and libraries are at the top of the code:

/*
 * 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;
}

Solution

  • This code is working as intended. I was making wrong type of tests.

    The way I "stopped" the rtsp server was just pressing the "stop" button of VLC. This does not destroy the server, server is still there, just not making any kind of stream and client is still connected to the server without problem because server still exists. When I close the VLC instead to destroy the server, it gets into the right watch dog function.