// Copyright (C) 1999 Open Source Telecom Corporation.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __APE_RTP_H__
#define __APE_RTP_H__
#ifndef __APE_THREAD_H__
#include <APE/thread.h>
#endif
#ifndef __APE_SOCKET_H__
#include <APE/socket.h>
#endif
enum
{
RTP_SAMPLING_ULAW,
RTP_SAMPLING_8KHZ = RTP_SAMPLING_ULAW,
RTP_SAMPLING_PCM16,
RTP_SAMPLING_CDMONO,
RTP_SAMPLING_CDSTERIO
};
#ifdef WIN32
class __EXPORT RTPThread;
class __EXPORT RTPSendThread;
class __EXPORT RTPRecvThread;
class __EXPORT RTPSocket;
class __EXPORT RTPBroadcast;
#endif
/**
* The RTP thread is the base class for RTP socket send and receive servicing.
* An internal buffer is provided for assembling RTP data packets, and a
* new time synchronization service is offered so that threads can sleep
* intervals that can be adjusted to the passing of actual time to account
* for processing drift.
*
* @short Base thread class for servicing real time queues.
* @author David Sugar (dyfet@ostel.com)
*/
class RTPThread : public Thread
{
private:
struct timeval _tv;
protected:
/**
* Working buffer for rtp data packets.
*/
unsigned char rtpdata[1500];
/**
* Reset the pause timer to the current time of day. This is
* used to initially synchronize the stream timer when time clock
* based "pacing" is required, such as when streaming data that
* is not realtime in origin.
*/
void Reset(void);
/**
* This service provides a time synchronized delay via APE sleep.
* The delay is computed by adjusting the time forward.
*
* @return true if delay needed (after sleeping).
* @param time interval to synchronize on.
*/
bool Pause(timeout_t sync);
public:
/**
* Construct and set initial timer for a new RTP service thread.
*
* @param start starting semaphore for synchronization.
* @param pri thread base priority relative to it's parent.
*/
RTPThread(Semaphore *start = NULL, int pri = 0);
/**
* Destroy an RTP service thread. Wait for any remaining time
* synchronization and exit.
*/
virtual ~RTPThread();
};
/**
* The service thread used to deliver received rtp packets. This
* virtual service thread provides the core functionality for streaming
* of inbound media packets. In fact, streaming includes abstract I/O
* services that are implemented on a per protocol bases which allows
* RTPRecvThread to drive IPX "RTP" sockets or even VAT sessions.
*
* @short Service thread for real-time streaming input.
* @author David Sugar (dyfet@ostel.com)
*/
class RTPSendThread : public RTPThread
{
private:
timeout_t timeout;
void Run(void)
{RunSender();};
void Initial(void)
{InitSender();};
void Final(void)
{ExitSender();};
protected:
/**
* Initial thread service. This is used to support multiple
* inheretance of sending and receiving threads in a single object.
*/
virtual void InitSender(void)
{return;};
/**
* Exit thread service for self destructing objects. This is
* used to support multiple inheretance of sending and receiving
* threads in a single object.
*/
virtual void ExitSender(void)
{return;};
/**
* The default run method of a sending service thread. This is
* used to support multipe inheretance of sending and receiving
* threads in a single object.
*/
virtual void RunSender(void);
/**
* Receive RTP data into an RTP formatted packet using the current
* protocol from the read routine in the derived class. This
* may apply decompression and other codec functions. This
* function normally blocks until a RTP packet is received.
*
* @return actual number of bytes sent on success, -1 on error.
* @param buf pointer to rtpdata buffer.
* @param len of bytes to write.
*/
virtual ssize_t RTPSend(unsigned char *buf, size_t len) = 0;
/**
* Fetch a sample of data in the current sampling format for
* the time interval specified.
*
* @return number of bytes fetched on success, -1 on failure.
* @param buf pointer to rtpdata buffer.
* @param timer for data frame to read.
*/
virtual size_t RTPFetch(unsigned char *buf, timeout_t timer) = 0;
/**
* Update the time stamp for the next sent packet in the derived
* protocol.
*
* @param current sending timeout.
*/
virtual void RTPUpdate(timeout_t timer);
/**
* Error handler for derived class.
*/
virtual void RTPSendError(void);
/**
* Set the effective time frame for sending RTP data. This cal
* should be made within a derived RTPUpdate() method to assure
* it does not occur during processing.
*
* @param new timeout.
*/
inline void setTimeout(timeout_t timer)
{timeout = timer;};
public:
/**
* Construct a RTP service thread for sending packets. We normally
* use 20ms timing frames.
*
* @param start semaphore to use for synchronized startup.
* @param pri level of this thread relative to parent.
*/
RTPSendThread(Semaphore *start = NULL, int pri = 0, timeout_t timer = 20);
/**
* Terminate the sending thread service after timing out until
* the current frame has a chance to be sent.
*/
virtual ~RTPSendThread();
/**
* Allows derived class to retrieve data sampling format. This
* may be useful in conjunction with some codec's. The derived
* RTPFetch() may use this to determine recording format, etc.
*
* @return RTP data sampling format in use.
*/
virtual inline unsigned getSampling(void)
{return RTP_SAMPLING_8KHZ;};
/**
* This may be used to specify a new session id number to use.
*
* @param session id.
*/
virtual void setSession(unsigned long session)
{return;};
};
/**
* The service thread used to deliver received rtp packets. This
* virtual service thread provides the core functionality for streaming
* of inbound media packets. In fact, streaming includes abstract I/O
* services that are implemented on a per protocol bases which allows
* RTPRecvThread to drive IPX "RTP" sockets or even VAT sessions.
*
* @short Service thread for real-time streaming input.
* @author David Sugar (dyfet@ostel.com)
*/
class RTPRecvThread : public RTPThread
{
private:
void Run(void)
{RunReceiver();};
void Initial(void)
{InitReceiver();};
void Final(void)
{ExitReceiver();};
protected:
/**
* Initial thread service. This is used to support multiple
* inheretance of sending and receiving threads in a single object.
*/
virtual void InitReceiver(void)
{return;};
/**
* Exit thread service for self destructing objects. This is
* used to support multiple inheretance of sending and receiving
* threads in a single object.
*/
virtual void ExitReceiver(void)
{return;};
/**
* The default run method of a sending service thread. This is
* used to support multipe inheretance of sending and receiving
* threads in a single object.
*/
virtual void RunReceiver(void);
/**
* Receive RTP data into an RTP formatted packet using the current
* protocol from the read routine in the derived class. This
* may apply decompression and other codec functions. This
* function normally blocks until a RTP packet is received.
*
* @return actual number of bytes read on success, -1 on error.
* @param buf pointer to rtpdata buffer.
* @param seq number of received packet.
* @param timestamp of received packet.
*/
virtual ssize_t RTPRecv(unsigned char *buf, unsigned short *seq, unsigned long *timestamp) = 0;
/**
* Virtual function used to post the last retrieved message. This
* operates by calling the protocol 'derived' class which has
* the header information for the last read packet.
*
* @return number of bytes posted on success, -1 on failure.
* @param buf pointer to rtpdata buffer.
* @param seq number of last read packet.
* @param time stamp of this packet.
*/
virtual size_t RTPPost(unsigned char *buf, unsigned short seq, unsigned long timestamp, size_t len) = 0;
/**
* Error processing routine for receive failures.
*/
virtual void RTPRecvError(void)
{return;};
/**
* Protocol may use this to specify a new session has been initiated.
*
* @param session number of this session.
*/
virtual void SessionId(unsigned long session)
{return;};
public:
/**
* Construct a RTP service thread for receiving packets.
*
* @param start semaphore to use for synchronized startup.
* @param pri level of this thread relative to parent.
*/
RTPRecvThread(Semaphore *start = NULL, int pri = 0);
/**
* Terminate the receiving thread service.
*/
virtual ~RTPRecvThread()
{Terminate();};
/**
* Allows derived class to retrieve data sampling format. This
* may be useful in conjunction with some codec's. The derived
* RTPPost() may use this to determine recording format, etc.
*
* @return RTP data sampling format in use.
*/
virtual inline unsigned getSampled(void)
{return RTP_SAMPLING_8KHZ;};
};
/**
* This abstract class implements the basic support needed for a UDP
* RTP session. It uses both a sending and receiving service thread
* each of which may have derived methods in this new class.
*
* @author David Sugar <dyfet@ostel.com>.
* @short Abstract base class for UDP RTP protocol service.
*/
class RTPSocket : public UDPSocket, public RTPSendThread, public RTPRecvThread
{
private:
Semaphore _start;
#pragma pack(1)
struct
{
unsigned char flags[2];
unsigned short sequence;
unsigned long timestamp;
unsigned long source;
unsigned long conf[15];
} rtprecv, rtpsend;
#pragma pack()
protected:
/**
* Update the time stamp for the next sent packet.
*
* @param current sending timeout.
*/
virtual void RTPUpdate(timeout_t timer);
/**
* Sets the payload id for sending RTP packets. This is
* virtualized so that RTPAudio can also specify sampling
* rates based on the returned value.
*
* @param payload message type (0-127) for sending.
*/
virtual void setPayload(unsigned payload);
/**
* Add a conference id to the RTP send message.
*
* @param source for added conference id.
*/
virtual void addConference(unsigned long source);
/**
* Set this server's stream source id.
*
* @param source id to use for my stream.
*/
inline void setSource(unsigned long source)
{rtpsend.source = source;};
/**
* Write data to the UDP socket. This implements the send
* service thread writer.
*
* @return number of bytes written on success, -1 on failure.
* @param address buffer to write.
* @param len of bytes to write in addition to the header.
*/
ssize_t RTPSend(unsigned char *buf, size_t len);
/**
* read data from the UDP socket. This implements the receive
* service thread reader.
*
* @return number of bytes read on success, -1 on failure.
* @param address buffer to read.
* @param sequence number received.
* @param timestamp received.
*/
ssize_t RTPRecv(unsigned char *buf, unsigned short *seq, unsigned long *timestamp);
public:
/**
* Create and bind an RTP socket to an internet interface address
* and known port number. The sending thread timeout can be
* adjusted with setTimeout() before calling Start() for the sending
* service thread. One might also call setPayload, etc.
*
* @param bind address to bind this socket to.
* @param port address to bind the service under.
* @param pri of service threads relative to parent.
* @param session id for sending under.
*/
RTPSocket(InetAddress &bind, short port, int pri, unsigned long session);
/**
* Starts both service threads. This functions similar to the APE
* thread Start() method and uses the private starting semaphore.
*/
void Start(void);
};
/**
* This abstract class implements the basic support needed for a RTP
* broadcast session using UDP packets. Broadcasts are uni-directional
* and can be used to flood a subnet with real-time streaming. There
* should also be a RTPMulticast added soon.
*
* @author David Sugar <dyfet@ostel.com>.
* @short Abstract base class for UDP RTP subnet broadcast.
*/
class RTPBroadcast : public UDPSocket, public RTPSendThread
{
private:
Semaphore _start;
#pragma pack(1)
struct
{
unsigned char flags[2];
unsigned short sequence;
unsigned long timestamp;
unsigned long source;
unsigned long conf[15];
} rtpsend;
#pragma pack()
protected:
/**
* Update the time stamp for the next sent packet.
*
* @param current sending timeout.
*/
virtual void RTPUpdate(timeout_t timer);
/**
* Sets the payload id for sending RTP packets. This is
* virtualized so that RTPAudio can also specify sampling
* rates based on the returned value.
*
* @param payload message type (0-127) for sending.
*/
virtual void setPayload(unsigned payload);
/**
* Add a conference id to the RTP send message.
*
* @param source for added conference id.
*/
virtual void addConference(unsigned long source);
/**
* Set this server's stream source id.
*
* @param source id to use for my stream.
*/
inline void setSource(unsigned long source)
{rtpsend.source = source;};
/**
* Write data to the UDP socket. This implements the send
* service thread writer.
*
* @return number of bytes written on success, -1 on failure.
* @param address buffer to write.
* @param len of bytes to write in addition to the header.
*/
ssize_t RTPSend(unsigned char *buf, size_t len);
public:
/**
* Create and bind an RTP socket to an internet interface address
* and known port number for the purpose of subnet broadcasting
* with RTP.
*
* @param bind address to bind this socket to.
* @param port address to bind the service under.
* @param pri of service threads relative to parent.
* @param session id for sending under.
*/
RTPBroadcast(BroadcastAddress &bind, short port, int pri, unsigned long session);
};
#endif
Documentation generated by dyfet@centauri.sys on Tue Jun 29 23:36:17 EDT 1999