Also it is important for a Multimedia framework to have the ability to support different transports and be able to plug and configure them dynamically and statically .For example, a wireless link based application may want to use the Wireless link protocol to stream the data. RTP is gaining wide significance as the Transport protocol for streaming Audio and Video Data over the Internet. Our framework provides an implementation of RTP/RTCP for the audio/video profile. RTP is internet-centric and doesn't provide facilities to transport IDL-defined flows. SFP is a Simple Flow Protocol specified by the OMG for A/V Streaming and it can be mapped to different transports like UDP, RTP and ATM AAL5. Our framework provides an implementation of SFP that runs over UDP and multicast UDP.
The OMG specification defines the flow specification syntax that is
to be used for the bind_devs calls for connection establishment. It defines
the protocol names and also the syntax for specifying the transport/flow
protocol information but it doesn't define any interfaces for the protocol
implementation as such. Our framework bridges this gap by defining a uniform
API for the different flow protocols like RTP and SFP while taking
care of the variations using a Policy interface. We solve this with our
Pluggable Protocol Framework using design patterns like Layer,
Acceptor, Connector, Facade and Abstract Factory. Please look at this
paper
for more documentation on the TAO AV Service Pluggable Protocol Framework.
The pluggable transport protocol implementation should inherit from the following abstract classes declared in <orbsvcs/orbsvcs/AV/Transport.h>:
/**
* @class TAO_AV_Acceptor
* @brief
*/
class TAO_AV_Export TAO_AV_Acceptor
{
public:
TAO_AV_Acceptor (void);
virtual ~TAO_AV_Acceptor (void);
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
TAO_AV_Flow_Protocol_Factory *factory) = 0;
virtual int open_default (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_FlowSpec_Entry *entry,
TAO_AV_Flow_Protocol_Factory *factory) = 0;
const char *flowname ();
virtual int close (void) = 0;
protected:
ACE_CString flowname_;
TAO_AV_Core *av_core_;
ACE_Addr *address_;
};
/**
* @class TAO_AV_Connector
* @brief
*/
class TAO_AV_Export TAO_AV_Connector
{
public:
TAO_AV_Connector (void);
virtual ~TAO_AV_Connector (void);
const char *flowname (void);
virtual int open (TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Core *av_core,
TAO_AV_Flow_Protocol_Factory *factory) = 0;
virtual int connect (TAO_FlowSpec_Entry *entry,
TAO_AV_Transport *&transport) = 0;
virtual int close (void) = 0;
protected:
ACE_CString flowname_;
};
The pluggable transport protocol implementation should inherit from the following abstract classes declared in <orbsvcs/orbsvcs/AV/Transport.h>:
/**
* @class TAO_AV_Transport
* @brief A Base class for the different transport protocols.
* All the different
transports should derive and implement
* the open,close,send
and recv methods.
*/
class TAO_AV_Export TAO_AV_Transport
{
public:
TAO_AV_Transport (void);
virtual ~TAO_AV_Transport (void);
virtual int open (ACE_Addr *address) = 0;
virtual int close (void) = 0;
virtual int mtu (void) = 0;
virtual ACE_Addr *get_peer_addr (void) = 0;
virtual ACE_Addr *get_local_addr (void);
virtual ssize_t send (const ACE_Message_Block *mblk,
ACE_Time_Value *s = 0) = 0;
/// Write the contents of the buffer of length len to the connection.
virtual ssize_t send (const char *buf,
size_t len,
ACE_Time_Value *s = 0) = 0;
/// Write the contents of iovcnt iovec's to the connection.
virtual ssize_t send (const iovec *iov,
int iovcnt,
ACE_Time_Value *s = 0) = 0;
/// Read len bytes from into buf.
virtual ssize_t recv (char *buf,
size_t len,
ACE_Time_Value *s = 0) = 0;
/// Read len bytes from into buf using flags.
virtual ssize_t recv (char *buf,
size_t len,
int flags,
ACE_Time_Value *s = 0) = 0;
/// Read received data into the iovec buffers.
virtual ssize_t recv (iovec *iov,
int iovcnt,
ACE_Time_Value *s = 0) = 0;
};
/**
* @class TAO_AV_Transport_Factory
* @brief
*/
class TAO_AV_Export TAO_AV_Transport_Factory : public ACE_Service_Object
{
public:
/// Initialization hook.
TAO_AV_Transport_Factory (void);
virtual ~TAO_AV_Transport_Factory (void);
virtual int init (int argc, char *argv[]);
virtual int match_protocol (const char *protocol_string);
virtual TAO_AV_Acceptor *make_acceptor (void);
virtual TAO_AV_Connector *make_connector (void);
};
The pluggable transport protocol implementation should inherit from the following abstract class declared in <orbsvcs/orbsvcs/AV/Transport.h>:
/**
* @class TAO_AV_Flow_Handler
* @brief
*/
class TAO_AV_Export TAO_AV_Flow_Handler
{
public:
/// Constructor.
TAO_AV_Flow_Handler (void);
/// Start/stop the flow handler.
virtual int start (TAO_FlowSpec_Entry::Role role);
virtual int stop (TAO_FlowSpec_Entry::Role role);
/// Schedule timer. Uses the get_timeout method on the callback.
virtual int schedule_timer (void);
/// get the transport.
TAO_AV_Transport *transport (void);
/// set/get protocol_object.
TAO_AV_Protocol_Object* protocol_object (void);
void protocol_object (TAO_AV_Protocol_Object *protocol_object);
/// set the callback.
void callback (TAO_AV_Callback *callback);
/// Handle timeout. called from reactor.
int handle_timeout (const ACE_Time_Value &tv, const void
*arg = 0);
/// set the remote address.
virtual int set_remote_address (ACE_Addr *address);
/// get the underlying event handler. To be overridden by the
derived clases.
virtual ACE_Event_Handler* event_handler (void) = 0;
virtual int change_qos (AVStreams::QoS);
protected:
TAO_AV_Transport *transport_;
TAO_AV_Callback *callback_;
TAO_AV_Protocol_Object *protocol_object_;
long timer_id_;
ACE_Reactor *reactor_;
void *timeout_arg_;
};
The pluggable flow protocol implementation should inherit from the following abstract class declared in <orbsvcs/orbsvcs/AV/Protocol_Factory>:
/**
* @class TAO_AV_Flow_Protocol_Factory
* @brief
*/
class TAO_AV_Export TAO_AV_Flow_Protocol_Factory : public ACE_Service_Object
{
public:
/// Initialization hook.
TAO_AV_Flow_Protocol_Factory (void);
virtual ~TAO_AV_Flow_Protocol_Factory (void);
virtual int init (int argc, char *argv[]);
virtual int match_protocol (const char *flow_string);
virtual TAO_AV_Protocol_Object* make_protocol_object (TAO_FlowSpec_Entry
*entry,
TAO_Base_StreamEndPoint *endpoint,
TAO_AV_Flow_Handler *handler,
TAO_AV_Transport *transport);
virtual const char *control_flow_factory (void);
};
The pluggable flow protocol implementation should inherit from the following abstract class declared in <orbsvcs/orbsvcs/AV/Protocol_Factory>:
/**
* @class TAO_AV_Protocol_Object
* @brief
*/
class TAO_AV_Export TAO_AV_Protocol_Object
{
public:
TAO_AV_Protocol_Object (void);
/// constructor.
TAO_AV_Protocol_Object (TAO_AV_Callback *callback,
TAO_AV_Transport *transport);
/// Destructor
virtual ~TAO_AV_Protocol_Object (void);
virtual int open (TAO_AV_Callback *callback,
TAO_AV_Transport *transport);
virtual int handle_input (void) = 0;
/// Called on a control object.
virtual int handle_control_input (ACE_Message_Block *control_frame,
const ACE_Addr &peer_address);
/// set/get policies.
virtual int set_policies (const TAO_AV_PolicyList &policy_list);
virtual TAO_AV_PolicyList get_policies (void);
/// start/stop the flow.
virtual int start (void);
virtual int stop (void);
/// send a data frame.
virtual int send_frame (ACE_Message_Block *frame,
TAO_AV_frame_info *frame_info = 0) = 0;
/// send a frame in iovecs.
virtual int send_frame (const iovec *iov,
int iovcnt,
TAO_AV_frame_info *frame_info = 0) = 0;
virtual int send_frame (const char *buf,
size_t len) = 0;
/// end the stream.
virtual void control_object (TAO_AV_Protocol_Object *object);
virtual int destroy (void) = 0;
TAO_AV_Transport *transport (void);
protected:
TAO_AV_Transport *transport_;
TAO_AV_PolicyList policy_list_;
TAO_AV_Callback *callback_;
};
For an example of how all the above components are implemented refer to the implementation of the UDP transport <orbsvcs/orbsvcs/AV/UDP.h> and <orbsvcs/orbsvcs/AV/UDP.cpp>
A typical svc.conf will look like this:
dynamic TAO_AV_Resource_Factory Service_Object * TAO_AV:_make_TAO_AV_Resource_Factory()
""
dynamic ATM_Factory Service_Object * TAO_AV:_make_TAO_AV_ATM_Factory()
""
static TAO_AV_Resource_Factory "-AVTransportFactory ATM_Factory"
dynamic SFP_Factory Service_Object * TAO_AV:_make_TAO_AV_SFP_Factory()
""
static TAO_AV_Resource_Factory "-AVFlowProtocolFactory SFP_Factory"
The TAO_AV_Resource_Factory is a the default resource factory that helps to load the different transport and flow protocols to the corresponding factory sets.
NOTE: The TAO_AV_Resource_Factory must be loaded in order to load the pluggable protocols, ie. the first statement shown above is mandatory to load the protocols.
The above entries show how to add a transport factory eg. ATM Factory and a flow protocol factory eg. SFP Factory. The -AVTransportFactory option causes the specified transport protocol factory to be loaded into the AV Core and the -AVFlowProtocolFactory option causes the specified flow protocol factory to be loaded into the AV Core.