Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP-UX Multimedia Streaming Protocols (MSP) Programmer's Guide: HP-UX 11i v1 and HP-UX 11i v2 > Chapter 5 Sample Programs

RTSP Sample Program

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

You can use the sampleclient.c program, a minimal RTSP client, to send RTSP messages to a server.The program is interactive and allows you to choose the type of RTSP message to be sent to a server. Based on the RTSP message type, you may be prompted to enter additional information.

The following is a sample program for the RTSP module of the MSP suite of libraries:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtsp.h>

/*
* connect2server :
* Parse the url string and create a RTSP
* Connection to the server identified by the url.
*/

rtsp_conn_t *
connect2server(char *mediaurl)
{
    rtsp_error_t    err;
    rtsp_conn_t     *rtspconn = NULL;
    rtsp_url_t      rtspurl;

    /* Parse the url string and fill up rtspurl */
    err = rtsp_parse_url(mediaurl, &rtspurl);
    if( err!=RTSP_SUCCESS )
    {
        printf(“Error parsing media url %s\n”, mediaurl);
        return rtspconn;
    }
    printf(“Connecting to server ... “);

    /* Create a RTSP Connection */
    err = rtsp_open(&rtspurl, RTSP_CFLAG_CS, &rtspconn);
    if( err!=RTSP_SUCCESS )
    {
        printf(“Error\n”);
        return rtspconn;
    }
    printf(“Success\n”);
    return rtspconn;
}

void
display_msg_menu()
{
    printf(“\nAvailable RTSP Messages : \n”
           “1. DESCRIBE\n2. SETUP\n3. PLAY\n”
           “4. PAUSE\n5. TEARDOWN\n6. EXIT\n” 
           “Choose one [1-6]: “);
}

/*
* The basic flow of operations for the process_* routines
* is as follows :
*
* Create and Initialize the request message.
* Set the header information in the request message.
* Send the request message to the server
* Free the request message
* Receive the response message from the server.
* Retrieve header information from the response message.
* Retrieve message body from the response message.
* Free the response message
*
* In all the process_* routines, the following variables 
* are used.
*
* req_msg => The RTSP Request Message
* rsp_msg => The RTSP Response Message
* err => error number returned by RTSP APIs
* rtspconn => The RTSP Connection over which messages
* are sent and received.
*
*/

/*
* process_describe :
* Creates and sends a DESCRIBE Request message to the
* server. Receives and processes the response message.
*/

rtsp_error_t
process_describe(rtsp_conn_t *rtspconn, char *mediaurl)
{
    rtsp_msg_t      *reqmsg = NULL;
    rtsp_msg_t      *rspmsg = NULL;
    rtsp_error_t    err;
    char            accepttype[] = “application/sdp”;
    uint8_t         *sdpbuf;
    uint16_t        sdpbuflen;

    /* Create a DESCRIBE RTSP Request Message */
    err = rtsp_init_request_msg(RTSP_DESCRIBE, mediaurl,
                                &reqmsg);
    if( err!=RTSP_SUCCESS )
        return err;

    /* Specify the Accept RTSP Header in the Request Message */
    err = rtsp_set_msg_hdr(reqmsg, RTSP_ACCEPT_HDR, accepttype,
                            strlen(accepttype));
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(reqmsg);
        return err;
    }

    /* Send the Request Message */
    err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0);
    rtsp_free_msg(reqmsg);
    if( err<0 )
        return err;

    /* Receive the response for the request Message. We pass
     * NULL for channel and size argument since we are sure we 
     * would be receiving only a RTSP Message and not an 
     * interleaved media stream.
     */
    err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL);
    if( err<0 )
        return err;

    /* Retrieve the Content-Length Header information */
    err = rtsp_get_msg_hdr(rspmsg, RTSP_CONTENT_LENGTH_HDR,
                            &sdpbuflen, NULL);
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    /* Allocate a buffer to hold the message body 
     * (i.e) SDP Description */
    sdpbuf = malloc(sdpbuflen*sizeof(uint8_t));
    if( !sdpbuf )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    /* Get the body of the Response Message */
    err = rtsp_get_msg_body(rspmsg, (uint8_t *)sdpbuf,
                            &sdpbuflen);
    if( err!=RTSP_SUCCESS )
    {
        free(sdpbuf);
        rtsp_free_msg(rspmsg);
        return err;
    }

    printf(“SDP Description for %s is : \n”
           “%.*s\n”, mediaurl, (int)sdpbuflen, sdpbuf);

    free(sdpbuf);

    /* Free the resources allocated for the RTSP Message */
    rtsp_free_msg(rspmsg);

    return RTSP_SUCCESS;
}

/*
* process_setup :
* Creates and sends a SETUP Request message to the
* server. Receives and processes the response message.
*/

rtsp_error_t
process_setup(rtsp_conn_t *rtspconn, char *setupurl, 
int crtpport, int crtcpport)
{
    rtsp_msg_t      *reqmsg = NULL;
    rtsp_msg_t      *rspmsg = NULL;
    rtsp_error_t    err;
    rtsp_xport_spec_t xspec, *serverxspec=NULL;
    char            *sessionid;
    int             sessionidlen;

    /* Create a SETUP RTSP Request Message */
    err = rtsp_init_request_msg(RTSP_SETUP, setupurl, &reqmsg);
    if( err!=RTSP_SUCCESS )
        return err;

    /* Initialize and fill up the Transport Header */
    rtsp_init_xport_spec(&xspec);
    xspec.xport_id  = (uint8_t *)”RTP/AVP”;
    xspec.ncast     = RTSP_TRANSMIT_UNICAST;
    xspec.cport.rtp = crtpport;
    xspec.cport.rtcp = crtcpport;

    /* Set the Transport RTSP Header in the Request Message */
    err = rtsp_set_msg_hdr(reqmsg, RTSP_TRANSPORT_HDR, 
                            &xspec, 0);
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(reqmsg);
        return err;
    }

    /* Send the Request Message */
    err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0);

    /* Free the resources allocated for the request message */
    rtsp_free_msg(reqmsg);

    /* Check for rtsp_send_msg errors */
    if( err<0 )
        return err;

    /* Receive the response for the request Message. We pass
     * NULL for channel and size argument since we are sure we 
     * would be receiving only a RTSP Message and not an 
     * interleaved media stream.
     */
    err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL);
    if( err<0 )
        return err;

    /* Get Transport Header information from the Response */
    err = rtsp_get_msg_hdr(rspmsg, RTSP_TRANSPORT_HDR,
                            &serverxspec, NULL);
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    printf(“\nServer RTP and RTCP ports are %d %d\n”,
        (int)serverxspec->sport.rtp,
        (int)serverxspec->sport.rtcp);

    /* Free the resources allocated to the entire linked
     * list of rtsp_xport_spec_t structures
     */
    rtsp_free_xport_spec(serverxspec);

    /* Retrieve Session Header information from message */
    err = rtsp_get_msg_hdr(rspmsg, RTSP_SESSION_HDR,
                            &sessionid, &sessionidlen);
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    printf(“Session ID is %.*s\n”, sessionidlen, sessionid);
    free(sessionid);

    /* Free the resources allocated for the response Message */
    rtsp_free_msg(rspmsg);

    return RTSP_SUCCESS;
}

/*
* process_play :
* Creates and sends a PLAY Request message to the server.
* Receives and process the response message for PLAY.
*/

rtsp_error_t
process_play(rtsp_conn_t *rtspconn, char *mediaurl)
{
    rtsp_msg_t      *reqmsg = NULL;
    rtsp_msg_t      *rspmsg = NULL;
    rtsp_error_t    err;
    rtsp_rtpinfo_t  *rtpinfo = NULL, *prtpinfo;

    /* Create a PLAY RTSP Request Message */
    err = rtsp_init_request_msg(RTSP_PLAY, mediaurl, &reqmsg);
    if( err!=RTSP_SUCCESS )
        return err;

    /* Send the Request Message */
    err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0);

    /* Free the resources allocated for the request message */
    rtsp_free_msg(reqmsg);

    /* Check for rtsp_send_msg errors */
    if( err<0 )
        return err;

    /* Receive the response for the request Message. We pass
     * NULL for channel and size argument since we are sure we 
     * would be receiving only a RTSP Message and not an 
     * interleaved media stream.
     */
    err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL);
    if( err<0 )
        return err;

    /* Retrieve RTP-Info Header information from the message */
    err = rtsp_get_msg_hdr(rspmsg, RTSP_RTP_INFO_HDR, 
                            &rtpinfo, NULL);
    if( err!=RTSP_SUCCESS )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    printf(“\nServer RTP Info : \n”);

    /* 
     * The RTP-Info header can have multiple rtp-info-spec
     * entries. The multiple rtp-info-spec entries are linked
     * together through the next structure member
     */
    for(prtpinfo=rtpinfo; prtpinfo!=NULL;
        prtpinfo=prtpinfo->next)
    {
        printf(“\t”);

        /* If url member is NULL, then URL was not 
         * specified in the rtp-info-spec entry in the header 
         */
        if(prtpinfo->url)
            printf(“URL=%s, “, prtpinfo->url);

        /* If seq member is -1, then sequence number was not
         * specified in the rtp-info-spec entry in the header 
         */
        if(prtpinfo->seq!=-1)
            printf(“seq=%d, “, prtpinfo->seq);

        /* If rtptime member is -1, then RTP Timestamp was not
         * specified in the rtp-info-spec entry in the header 
         */
        if(prtpinfo->rtptime!=-1)
            printf(“rtptime=%lld”, prtpinfo->rtptime);

        printf(“\n”);
    }

    /* Free the resources allocated to the entire linked
     * list of rtsp_rtpinfo_t structures
     */
    rtsp_free_rtpinfo(rtpinfo);

    /* Free the resources allocated for the Response Message */
    rtsp_free_msg(rspmsg);

    return RTSP_SUCCESS;
}

/*
* process_pause :
* Creates and sends a PAUSE Request message to the
* server. Receives and process the response message.
*/

rtsp_error_t
process_pause(rtsp_conn_t *rtspconn, char *mediaurl)
{
    rtsp_msg_t      *reqmsg = NULL;
    rtsp_msg_t      *rspmsg = NULL;
    rtsp_error_t    err;
    int             statuscode;

    /* Create a PAUSE RTSP Request Message */
    err = rtsp_init_request_msg(RTSP_PAUSE, mediaurl, &reqmsg);
    if( err!=RTSP_SUCCESS )
        return err;

    /* Send the Request Message */
    err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0);

    /* Free the resources allocated for the request message */
    rtsp_free_msg(reqmsg);

    /* Check for rtsp_send_msg errors */
    if( err<0 )
        return err;

    /* Receive the response for the request Message. We pass
     * NULL for channel and size argument since we are sure we 
     * would be receiving only a RTSP Message and not an 
     * interleaved media stream.
     */
    err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL);
    if( err<0 )
        return err;

    /* Get the status code of the Response Message */
    statuscode = rtsp_get_msg_response_line(rspmsg, NULL,
                                            NULL);
    if( statuscode!=200 )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    /* Free the resources allocated for the Response Message */
    rtsp_free_msg(rspmsg);

    printf(“\nPAUSE Succeeded\n”);

    return RTSP_SUCCESS;
}

/*
* process_teardown :
* Creates and sends a TEARDOWN Request message to the
* server. Receives and processes the response message for
* TEARDOWN.
*/
rtsp_error_t
process_teardown(rtsp_conn_t *rtspconn, char *mediaurl)
{
    rtsp_msg_t      *reqmsg = NULL;
    rtsp_msg_t      *rspmsg = NULL;
    rtsp_error_t    err;
    int             statuscode;
    rtsp_session_t  *session;

    /* Create a TEARDOWN RTSP Request Message */
    err = rtsp_init_request_msg(RTSP_TEARDOWN, mediaurl,
                                &reqmsg);
    if( err!=RTSP_SUCCESS )
        return err;

    /* Send the Request Message */
    err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0);

    /* Free the resources allocated for the request message */
    rtsp_free_msg(reqmsg);

    /* Check for rtsp_send_msg errors */
    if( err<0 )
        return err;

    /* Receive the response for the request message. We pass
     * NULL for channel and size argument since we are sure we 
     * would be receiving only a RTSP Message and not an 
     * interleaved media stream.
     */
    err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL);
    if( err<0 )
        return err;

    /* Get the status code of the Response Message */
    statuscode = rtsp_get_msg_response_line(rspmsg, NULL,
                                            NULL);
    if( statuscode!=200 )
    {
        rtsp_free_msg(rspmsg);
        return err;
    }

    /* Free the resources allocated for the Response Message */
    rtsp_free_msg(rspmsg);

    printf(“\nTEARDOWN Succeeded\n”);

    return RTSP_SUCCESS;
}

main(int argc, char *argv[])
{
    /*
     * mediaurl points to the url passed as a
     * command-line argument to the program
    */
    char            *mediaurl;

    /* msgcode identifies the RTSP Method chosen by the user */
    int             msgcode;

    /* rtspconn represents the RTSP Connection to the peer */
    rtsp_conn_t     *rtspconn=NULL;

    /* mapsession represents the mapped session for the 
     * RTSP connection 
     */
    rtsp_session_t  *mapsession=NULL;

    /* err will hold the error numbers returned by RTSP APIs */
    rtsp_error_t    err;

    /*
     * crtpport and crtcpport will hold the client 
     * RTP and RTCP ports for SETUP Request
     */
    int             crtpport, crtcpport;

    /* setupurl holds the URL to be used in SETUP Request */
    char            setupurl[256];
    int             setupurllen;

    /*
     * The mthd variable will hold the enumerated RTSP
     * Method type for the Method chosen by the user
     */
    rtsp_method_t   mthd;

    int             close=0;

    if( argc!=2 )
    {
        printf(“Usage : %s <media url>\n”, argv[0]);
        exit(-1);
    }
    mediaurl = argv[1];

    /* Connect to the server specified by the mediaurl */
    rtspconn = connect2server(mediaurl);
    if( rtspconn==NULL )
        exit(-1);

    do
    {
        display_msg_menu();
        scanf(“%d”, &msgcode);

        switch(msgcode)
        {
        case 1:
            mthd = RTSP_DESCRIBE;
            err = process_describe(rtspconn, mediaurl);
            break;

        case 2:
            mthd = RTSP_SETUP;
            printf(“Enter SETUP URL (max 255 char) : “);
            fflush(stdin);
            fgets(setupurl, 256, stdin);
            setupurllen = strlen(setupurl);
            if( setupurl[setupurllen-1]==’\n’ )
                setupurl[setupurllen-1]=’\0’;

            printf(“Enter Client RTP RTCP Ports : “);
            scanf(“%d %d”, &crtpport, &crtcpport);
            err = process_setup(rtspconn, setupurl,
                                crtpport, crtcpport);
            break;

        case 3:
            mthd = RTSP_PLAY;
            err = process_play(rtspconn, mediaurl);
            break;

        case 4:
            mthd = RTSP_PAUSE;
            err = process_pause(rtspconn, mediaurl);
            break;

        case 5:
            mthd = RTSP_TEARDOWN;
            err = process_teardown(rtspconn, mediaurl);
            close = 1;
            break;

        case 6:
            close = 1;
            err = RTSP_SUCCESS;
            break;

        default:
            err = RTSP_SUCCESS;
            printf(“Invalid value\n”);
            break;
        }

        /* 
         * The rtsp_methods array contains the strings for RTSP
         * Methods. The array index should be an enumerated RTSP 
         * Method type
         */
        if( err!=RTSP_SUCCESS )
            printf(“\nError occurred during %s message “
                   “processing\n”, rtsp_methods[mthd]);

    } while(!close);

    /* Close the RTSP Connection and free the resources */
    rtsp_get_conn_opt(rtspconn, RTSP_OPT_SESSION, 
                        &mapsession, NULL);
    if( mapsession )
        rtsp_free_session(mapsession);
    rtsp_close(rtspconn);

}

The usage of this sample program is as follows:

sampleclient <mediaurl>

Example:

sampleclient rtsp://serveraddress/mediafile

Compiling the Sample RTSP Program

This section describes how to compile the sample RTSP program.

Before compiling the program, enure that the rtsp.h header file and the librtsp library provided by the HP-UX MSP suite are available on the machine. The rtsp.h header file is assumed to be in the /usr/include directory and the librtsp library in the /usr/lib directory.To compile, issue the following command:

$ cc sampleclient.c -o sampleclient -lrtsp

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 2004 Hewlett-Packard Development Company, L.P.