Search code examples
c++streamingvideo-streaminggstreamerrtsp

GStreamer and URI query parameters extraction for each new client


I have created rtsp/h264/mjpeg server. It works well. But now I have to get query for each new connected client. For example I have to get requested resolution from client query: rtsp://192.116.10.20:8554/stream?width=1920&height=1280

I have tryed to do it using the following code:

 ....
gulong clientConnectedConfigureId = g_signal_connect(m_server, "client-connected", (GCallback)ClientConnected, this);
 ....

static void ClientConnected(GstRTSPServer *gstrtspserver, GstRTSPClient *arg1, gpointer user_data)
    {
        GstRTSPConnection *connection = gst_rtsp_client_get_connection(arg1);

        if(!connection)
        {
            return;
        }

        GstRTSPUrl *uri = gst_rtsp_connection_get_url(connection);

        if(!uri)
        {
            return;
        }

        gchar *urlString = gst_rtsp_url_get_request_uri (uri);

        std::stringstream ssTemp;
        ssTemp << "ClientConnected - urlString = " << urlString;
        InternalLog::Debug(ssTemp.str());

        g_free(urlString); 
    }

GstRTSPUrl contains the following members: //rtsp[u]://[user:passwd@]host[:port]/abspath[?query]

After connection from VLC with query rtsp://192.116.10.20:8554/stream?width=1920&height=1280 the result is the follows:

ClientConnected - urlString = rtsp://192.116.10.20:61099(null)

GstRTSPUrl contains only host=192.116.10.20 and port=61099. Other fields like "abspath" or "query" are equal to NULL.

In netstat utility I see that port 61099 is a client port of VLC application. It is connected to port 8554.

How can I receive rtsp query for client with "query" filled to "width=1920&height=1280" ?


Solution

  • I have found the solution

    ...
    gulong clientConnectedConfigureId = g_signal_connect(m_server, "client-connected", (GCallback)ClientConnected, this);
    ...
    
    static void ClientConnected(GstRTSPServer *gstrtspserver, GstRTSPClient *arg1, gpointer user_data)
    {
        gulong describeConfigureId = g_signal_connect(arg1, "describe-request", (GCallback)DescribeRequest, user_data);
    
        //Do not forget about g_signal_handler_disconnect
    }
    
    void DescribeRequest(GstRTSPClient  *gstrtspclient, GstRTSPContext *arg1, gpointer user_data)
    {
        gchar *urlString = gst_rtsp_url_get_request_uri(arg1->uri);
    
        std::stringstream ssTemp;
        ssTemp << "DescribeRequest - urlString = " << urlString;
        InternalLog::Debug(ssTemp.str());
    
        g_free(urlString);  
    }
    

    If you using gst_rtsp_media_factory_set_shared(m_factory, TRUE); then you have to redefine method default_gen_key. Because URL used as a key to determine the need for creation of new media.You can do it using the following code:

    static gchar *
    default_gen_key (GstRTSPMediaFactory * factory, const GstRTSPUrl * url)
    {
      gchar *result =
          g_strdup_printf ("%u%s", url->port, url->abspath);
    
      return result;
    }
    
    ...
    m_factory = gst_rtsp_media_factory_new();
    GstRTSPMediaFactoryClass *klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (m_factory);
    klass->gen_key = default_gen_key;
    gst_rtsp_media_factory_set_shared(m_factory, TRUE);
    ...