This section includes the following sample programs for RTP:

  • sender.c

    When the user requests, the sender.c program sends an RTP packet.

  • recver.c

    When the user requests, the recver.c program polls for an RTP packet and receives the packet.

The usage of these programs is as follows:

./sender [-a local-address] [-p local-rtp-port] [-d dest-addr] [-r remote-rtp-port]

./recver [-a local-address] [-p local-rtp-port] [-d dest-addr] [-r remote-rtp-port]

Example:

./sender

or

./sender -p 8200 -r 7100

./recver

or

./recver -p 7100 -r 8200

 

The sender.c Program

The sender.c program is as follows:

/*
 *  HP MSP-RTP Sample application
 *  (c) Copyright 2003  Hewlett-Packard Company All Rights Reserved
 *
 */

#include <netinet/in.h>
#include <rtp.h>

/*
 * This Application uses the interfaces provided by the
 * RTP library to transmit data
 *
 */

/* Macros for handling time as double */
#define tv2dbl(tv) ((tv).tv_sec + (tv).tv_usec / 1000000.0)

#define dbl2prnt(x)  ((int)((long)(x))) \

,((int)(((int)(1000000.0*((double)(x))))%((int)1000000)))

/* function to print Usage for this program */
Usage(char *prg)
{
    fprintf(stderr, "Usage: %s [-a local-address] [-p local-rtp-port]"
                                    " [-d dest-addr] [-r remote-rtp-port]\n",prg);
}


/* The main routine */

int main(int argc, char **argv)
{

char c;
/*
 * by default:
 *              IPv4 is to be handled unless specified
 *              local ports 28000 for RTP and 28001 for RTCP are used
 *              loop back addresses are used
 */
int RTPport=28000,RTCPport;
int remRTPport=17000,remRTCPport;
char *caddr="127.0.0.1",*destaddr="127.0.0.1";
struct sockaddr_in addr[2];
int rd;
int ret;
struct sockaddr_in sin;
int i=0,x;
char ec='y';

while ((c = getopt(argc, argv, "6a:p:d:r:"))!=EOF)
{

    switch(c)
    {
        case 'a':
            caddr=optarg;
            break;
        case 'p':
            RTPport=atoi(optarg);
            break;
        case 'r':
            remRTPport=atoi(optarg);
            break;
        case 'd':
            destaddr=optarg;
            break;
                default:
                {
                        Usage(argv[1]);
                        exit(1);
                }
    }
}

        RTCPport = RTPport + 1;

    addr[0].sin_family=AF_INET;
    inet_pton(AF_INET,caddr,&addr[0].sin_addr.s_addr);
        addr[0].sin_port=RTPport;

    addr[1].sin_family=AF_INET;
    inet_pton(AF_INET,caddr,&addr[1].sin_addr.s_addr);
    addr[1].sin_port=RTCPport;

        rd = rtp_open((char*)addr, (char*)(addr+1));

        if(rd>0)
        {
                printf("\tOpened RTP descriptor %d\n"
                        "\tReceiving RTP packets on port %d\n"
                           "\tand RTCP packets on port %d\n"
                           ,rd
                           ,addr[0].sin_port
                           ,addr[1].sin_port
                          );
        }
        else
        {
                fprintf(stderr,"rtp_open() failed\n");
                exit(1);
        }

        remRTCPport=remRTPport+1;

        sin.sin_family=AF_INET;
        sin.sin_port=remRTPport;
        sin.sin_addr.s_addr=inet_addr(destaddr);

        if(sin.sin_addr.s_addr < 0)
        {
                fprintf(stderr,"The destination address %s is not valid\n",destaddr);
                exit(1);
        }

        ret = rtp_ioctl(rd,RTP_SSENDTOADDR,&sin);
        if(ret<0)
        {
                fprintf(stderr,"could not add %s to the RTP SENDTO list\n",destaddr);
        }
        else

                printf("\tDestination %s:%d addded to RTP SENDTO list\n"
                                ,destaddr
                                ,remRTPport
                          );

        sin.sin_port=remRTCPport;
        ret = rtp_ioctl(rd,RTCP_SSENDTOADDR,&sin);
        if(ret<0)
        {
                fprintf(stderr,"could not add %s to the RTCP SENDTO list\n",destaddr);
        }
        else

                printf("\tDestination %s:%d addded to RTCP SENDTO list\n"
                                ,destaddr
                                ,remRTCPport
                          );

        /*
         * constructing an RTP packet
         * The RTP packet which we construct does not contain
         * actual media data, but contains alphabets.
         * Media streaming applications would replace this
         * with actual media packets.
         */
        rtp_pkt_t  pkt ;
        pkt.v=2;
        pkt.p=0;
        pkt.x=0;
        pkt.cc=0;
        pkt.m=1;
        pkt.pt=7;

        pkt.seq=1;
        struct timeval  tv;
        struct timezone tzp;

        gettimeofday(&tv,&tzp);
        pkt.ts=tv2dbl(tv);
        pkt.csrcp=0;
        pkt.xtnhdrp=0;
        pkt.datap=(char*)malloc(9);
        strcpy(pkt.datap,"abcdefgh",8);
        pkt.datalen=8;

        i=0;

        printf("send an RTP packet? ");
        fflush(stdin);
        scanf("%c",&ec);

        /*
         * The library automatically generates RTCP packets.
         */

        while((ec=='y')||(ec=='Y'))
        {
                i++;
                if((ret= rtp_send(rd,&pkt))<0) break;
                printf("send another packet? ");
                fflush(stdin);
                scanf("%c",&ec);
        }
        if(ret<0)
                printf("rtp_send failed \n");
        else
                printf("%d RTP packet(s) sent\n",i);

}
 

The recver.c Program

The recver.c program is as follows:

/*
 *  HP MSP-RTP Sample application
 *  (c) Copyright 2003  Hewlett-Packard Company  All Rights Reserved.
 *
 */

#include <netinet/in.h>
#include <rtp.h>

/*
 * This Application uses the interfaces provided by the
 * RTP library to transmit data
 *
 */

/* Macros for handling time as double */
#define tv2dbl(tv) ((tv).tv_sec + (tv).tv_usec / 1000000.0)

#define dbl2prnt(x)  ((int)((long)(x))) \

,((int)(((int)(1000000.0*((double)(x))))%((int)1000000)))

/* function to print Usage for this program */
Usage(char *prg)
{
    fprintf(stderr, "Usage: %s [-a local-address] [-p local-rtp-port]"
                                    " [-d dest-addr] [-r remote-rtp-port]\n",prg);
}


/* The main routine */

int main(int argc, char **argv)
{

char c;
/*
 * by default:
 *              IPv4 is to be handled unless specified
 *              local ports 17000 for RTP and 17001 for RTCP are used
 *              loop back addresses are used
 */
int RTPport=17000,RTCPport;
int remRTPport=28000,remRTCPport;
char *caddr="127.0.0.1",*destaddr="127.0.0.1";
struct sockaddr_in addr[2];
int rd;
int ret;
struct sockaddr_in sin;
int i=0,x;
char ec='y';
struct rtp_pollrd rfds[1];
char buf[1024],*ptr=buf;

while ((c = getopt(argc, argv, "6a:p:d:r:"))!=EOF)
{

    switch(c)
    {
        case 'a':
            caddr=optarg;
            break;
        case 'p':
            RTPport=atoi(optarg);
            break;
        case 'r':
            remRTPport=atoi(optarg);
            break;
        case 'd':
            destaddr=optarg;
            break;
                default:
                {
                        Usage(argv[1]);
                        exit(1);
                }
    }
}

        RTCPport = RTPport + 1;

    addr[0].sin_family=AF_INET;
    inet_pton(AF_INET,caddr,&addr[0].sin_addr.s_addr);
        addr[0].sin_port=RTPport;

    addr[1].sin_family=AF_INET;
    inet_pton(AF_INET,caddr,&addr[1].sin_addr.s_addr);
    addr[1].sin_port=RTCPport;

        rd = rtp_open((char*)addr, (char*)(addr+1));

        if(rd>0)
        {
                printf("\tOpened RTP descriptor %d\n"
                           "\tReceiving RTP packets on port %d\n"
                           "\tand RTCP packets on port %d\n"
                           ,rd
                           ,addr[0].sin_port
                           ,addr[1].sin_port
                          );
        }
        else
        {
                fprintf(stderr,"rtp_open() failed\n");
                exit(1);
        }

        remRTCPport=remRTPport+1;

        sin.sin_family=AF_INET;
        sin.sin_port=remRTPport;
        sin.sin_addr.s_addr=inet_addr(destaddr);

        if(sin.sin_addr.s_addr < 0)
        {
                fprintf(stderr,"The destination address %s is not valid\n",destaddr);
                exit(1);
        }

        ret = rtp_ioctl(rd,RTP_SSENDTOADDR,&sin);
        if(ret<0)
        {
                fprintf(stderr,"could not add %s to the RTP SENDTO list\n",destaddr);
        }
        else

                printf("\tDestination %s:%d addded to RTP SENDTO list\n"
                                ,destaddr
                                ,remRTPport
                          );

        sin.sin_port=remRTCPport;
        ret = rtp_ioctl(rd,RTCP_SSENDTOADDR,&sin);
        if(ret<0)
        {
                fprintf(stderr,"could not add %s to the RTCP SENDTO list\n",destaddr);
        }
        else

                printf("\tDestination %s:%d addded to RTCP SENDTO list\n"
                                ,destaddr
                                ,remRTCPport
                          );

        /*
         * The library automatically generates RTCP packets.
         */

        /* poll for an RTP packet */

printf("polling for an RTP packet...\n");

        rfds[0].rd=rd;
        rfds[0].events=RTP_PIN;

        if((ret=rtp_poll(rfds,1,-1))<0)
    {
        fprintf(stderr,"rtp_poll() failed\n");
        exit(1);
    }
        printf("An RTP packet is ready to be received \n"
                   "Receive it now?");
        fflush(stdin);
        scanf("%c",&ec);

        i=0;

        int buflen;
        while((ec!='n')&&(ec!='N'))
        {
                i++;
                buflen=sizeof buf;
/*
 * receiving an RTP packet
 * if ptr points to NULL instead of buf the
 * library would automatically allocate the
 * required memory for the RTP packet.
 */

                if((ret= rtp_recv(rd,(rtp_pkt_t *)NULL,&ptr,&buflen))<0) break;
                printf("receive another packet? ");
                fflush(stdin);
                scanf("%c",&ec);
        }
        if(ret<0)
        {
/*
 * if memory were requested from the library
 * a check for RTP_EMOREDATA would have been
 * redundant
 */

                if(ret==RTP_EMOREDATA)
                        fprintf(stderr,"The buffer passed to rtp_recv() was small\n");
                else
                        fprintf(stderr,"rtp_recv() failed \n");
        }
        else
                printf("%d RTP packet(s) received\n",i);

}
 

Make File

The make file for RTP is as follows:

all : sender recver
sender: sender.c
    cc -O sender.c -o sender -l rtp
recver: recver.c
    cc -O recver.c -o recver -l rtp
 

Compiling the Sample RTP Program

This section describes how to compile the sample RTP program.

Before compiling the program, ensure that the rtp.h header file and the librtp library that come with HP-UX MSP are available on the machine. The rtp.h header file is assumed to be in the /usr/include directory and the librtp library in the /usr/lib directory.To compile, issue the following commands:

$ cc recver.c -o recver -lrtp

$ cc sender.c -o sender -lrtp

Alternatively, you can use the make file to compile the RTP programs as follows:

$ make all

or

$ make sender

$ make recver