// 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 __RTS_THREAD_H__
#define __RTS_THREAD_H__
#ifndef __APE_THREAD_H__
#include <APE/thread.h>
#endif
#ifndef __RTS_AUDIO_H__
#include <RTS/audio.h>
#endif
#ifdef WIN32
class __EXPORT RTSThread;
class __EXPORT RTSSendThread;
class __EXPORT RTSRecvThread;
#endif
/**
* The RT service thread is the base class for realtime send and receive servicing.
* An internal buffer is provided for assembling realtime 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 RTSThread : public Thread
{
private:
struct timeval _tv;
timeout_t _timeout;
int _startup;
protected:
/**
* Working buffer for rtp data packets.
*/
unsigned char rtpdata[1500];
/**
* Set the thread timeout.
*
* @param timeout for this realtime service thread in milliseconds.
*/
void setTimeout(timeout_t timer)
{_timeout = timer;};
/**
* Add to current service thread startup delay.
*
* @param number of timeouts to add to the current startup.
*/
void setServiceDelay(int number)
{_startup += number;};
/**
* Test for and update service delay timer.
*
* @return true if service delay in effect.
*/
bool isServiceDelay(void);
/**
* 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);
/**
* Compute the amount of time that has transpired since the last
* time sync mark was computed. This can be used to determine if
* a blocking operation has caused frame delays.
*
* @return used time in milliseconds.
*/
timeout_t getTimeUsed(void);
/**
* Adjust current time marker for this thread. This can be used
* in place of pausing when updating for delays that have already
* occured.
*
* @param timeout to adjust start time by.
*/
void addTimeUsed(timeout_t timeout);
/**
* Set audio sampling format for this service
* thread. This change is assumed to take effect on the
* next operation.
*
* @param audio sampling format.
*/
virtual void setAudioSampling(unsigned format)
{return;};
public:
/**
* Get the timeout for this service thread.
*
* @return service thread timeout in milliseconds.
*/
timeout_t getTimeout(void)
{return _timeout;};
/**
* 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.
*/
RTSThread(Semaphore *start = NULL, int pri = 0);
/**
* Destroy an realtime service thread. Wait for any remaining time
* synchronization and exit.
*/
virtual ~RTSThread();
/**
* Determine audio format being supported by
* the service thread for the specified payload
* identifier currently in effect.
*
* @param payload identifier.
* @return 0 on error.
*/
virtual unsigned getAudioSampling(unsigned payload)
{return RTS_AUDIO_UNSUPPORTED;};
/**
* Get audio encoding codec to use for processing this
* realtime service stream based on the current payload
* identifier in effect.
*
* @param payload identifier.
* @return audio codec (base) to use or NULL if none.
*/
virtual AudioCodec *getAudioEncoding(unsigned format)
{return NULL;};
};
/**
* The service thread used to send real-time packets. This
* virtual service thread provides the core functionality for streaming
* of outbound media packets. In fact, streaming includes abstract I/O
* services that are implemented on a per protocol bases which allows
* RTSSendThread to drive IPX "RTP" sockets or even VAT sessions.
*
* @short Service thread for real-time streaming input.
* @author David Sugar (dyfet@ostel.com)
*/
class RTSSendThread : public RTSThread
{
private:
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);
/**
* Send realtime data from the service thread into the derived
* socket layer protocol.
*
* @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 RTSSend(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 RTSFetch(unsigned char *buf, timeout_t timer) = 0;
/**
* Update the time stamp for the next sent packet in the derived
* protocol for the service thread.
*/
virtual void RTSUpdate(void);
/**
* Error handler for derived class.
*/
virtual void RTSSendError(void);
public:
/**
* Construct realtime 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.
*/
RTSSendThread(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 ~RTSSendThread();
/**
* 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
* RTSRecvThread to drive IPX "RTP" sockets or even VAT sessions.
*
* @short Service thread for real-time streaming input.
* @author David Sugar (dyfet@ostel.com)
*/
class RTSRecvThread : public RTSThread
{
private:
unsigned long _starting;
void Run(void)
{RunReceiver();};
void Initial(void)
{InitReceiver();};
void Final(void)
{ExitReceiver();};
protected:
/**
* Set starting timestamp for the current window.
* This starting time stamp is used to compute the
* relative offset of the received packet for posting into
* a pending delivery queue with RTSPost.
*
* @param value of starting time stamp for frame buffer.
*/
void setStarting(unsigned long value);
/**
* The RTSOutput() method must use addStartup() to adjust
* the timestamp for the next packets received once real-
* time data has been retrieved.
*
* @param offset timestamp by specified samples.
* @return new base timestamp in effect.
*/
unsigned long addStarting(unsigned long offset);
/**
* 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 realtime 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 encoding sample format of received packet (after codec).
* @param timestamp of received packet.
*/
virtual ssize_t RTSRecv(unsigned char *buf, unsigned short *encoding, unsigned long *timestamp) = 0;
/**
* Process an output frame for timed playback. Posting is assumed to
* post data into a buffer queue buffer. Playback may also
* simply update the 'timing' window of the current frame.
*
* @param timeout of audio frames.
*/
virtual void RTSOutput(timeout_t timeout)
{addStarting(8 * timeout);};
/**
* Wait for the specified timeout duration for data to appear at the
* socket and then do a blind "internal" peek of the message header
* so that getPeerHeader() will be functional.
*
* @return 0 if data available, -1 on failure.
* @param timeout of current session in milliseconds.
*/
virtual int RTSWait(timeout_t timeout);
/**
* 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 encoding sample format of last read packet.
* @param time stamp of this packet.
*/
virtual size_t RTSPost(unsigned char *buf, unsigned short encoding, unsigned long timestamp, size_t len) = 0;
/**
* Error processing routine for receive failures.
*/
virtual void RTSRecvError(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 RTS service thread for receiving packets.
*
* @param start semaphore to use for synchronized startup.
* @param pri level of this thread relative to parent.
* @param timer for synchronizing frames, default 20ms audio.
*/
RTSRecvThread(Semaphore *start = NULL, int pri = 0, timeout_t timer = 20);
/**
* Terminate the receiving thread service.
*/
virtual ~RTSRecvThread()
{Terminate();};
/**
* Compute offset in pending queue for the specified packet
* based on it's timestamp.
*
* @return adjusted timestamp based on window offset.
* @param timestamp of received packet.
*/
unsigned long getStarting(unsigned long stamp);
};
#endif
Documentation generated by dyfet@home.tycho.com on Fri Jul 2 11:43:56 EDT 1999