NVIDIA Iray SDK API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RTMP server

The RTMP server module implements an RTMP server. More...

Classes

class  mi::rtmp::ICall_event_handler
 Superclass of all handlers of call events. More...
 
class  mi::rtmp::IStream_event_handler
 Superclass of all handlers of create stream events. More...
 
class  mi::rtmp::IConnection
 The connection class represents a connection from a client to the server. More...
 
class  mi::rtmp::IConnect_event_handler
 Superclass of all handlers of connect events. More...
 
class  mi::rtmp::IPlay_event_handler
 Superclass of all handlers of play events. More...
 
class  mi::rtmp::IPause_event_handler
 Superclass of all handlers of pause events. More...
 
class  mi::rtmp::IRender_event_handler
 Superclass of all handlers of render events. More...
 
class  mi::rtmp::IFrame_event_handler
 Superclass of all handlers of frame events. More...
 
class  mi::rtmp::IStream
 Representing an RTMP stream. More...
 
class  mi::rtmp::IServer
 The server builds a framework for the handlers. More...
 
class  mi::rtmp::IFactory
 The factory can be used to instantiate the built-in RTMP server. More...
 

Detailed Description

The RTMP server module implements an RTMP server.

It listens for incoming connections and calls the installed connect handlers to see if an incoming connection should be accepted. If it is accepted an RTMP connection is started and upon incoming RTMP commands the installed command handlers will be called.

The server is multithreaded and will start one thread for each connection.

Any number of connect handler classes may be installed to the RTMP server. Each of those handler classes has to implement a handle() function. This function gets the connection. From the connection the handle() function may get the various parameters of the connect packet and if it wants to claim it, it should return true. If all return false, the connection is refused.

To create a server the mi::rtmp::IFactory needs to be obtained from the Iray SDK API using mi::neuraylib::INeuray::get_api_component(). The factory can then be used to create as many RTMP servers as needed.

The handler classes are the only ones that need to be implemented by a user. And then only the ones where the user actually wants to do something. If not implemented, they will simply not be called. The Frame_event_handler runs in a separate thread to avoid that long rendering times affect the framerate.

An example:

void render_a_canvas_and_save() { ... your code ... }
mi::neuraylib::ICanvas* get_the_last_rendered_canvas() { ... your code ... }
// The render loop
class My_render_handler : public mi::Interface_implement<mi::rtmp::IRender_event_handler>
{
public:
bool handle( mi::rtmp::IStream* stream)
{
render_a_canvas_and_save();
return true;
}
};
// The Frame loop, the actual handler where encoded video data is collected. Note that
// it runs in another thread than the Render_event_handler which means the canvas accesses
// need to be synchronized.
class My_frame_handler : public mi::Interface_implement<mi::rtmp::IFrame_event_handler>
{
public:
bool handle(
mi::rtmp::IStream* stream, mi::neuraylib::IVideo_data** out, bool outqueue_is_full)
{
if (outqueue_is_full) // not an error, just no use in encoding a new frame
return true;
mi::base::Handle<mi::neuraylib::ICanvas> canvas( get_the_last_rendered_canvas());
return codec->encode_canvas( canvas.get(), out) == 0;
}
};
// Stream handler
class My_stream_handler : public mi::Interface_implement<mi::rtmp::IStream_event_handler>
{
public:
bool handle(
bool is_create,
const mi::IData* command_arguments)
{
if( is_create) {
new My_render_handler());
stream->register_render_event_handler( render_event_handler.get());
new My_frame_handler());
stream->register_frame_event_handler( frame_event_handler.get());
}
return true;
}
};
// Connect handler
class My_connect_handler : public mi::Interface_implement<mi::rtmp::IConnect_event_handler>
{
public:
bool handle(
bool is_create,
mi::rtmp::IConnection* connection,
const mi::IData* cmd_arguments,
const mi::IData* user_arguments)
{
if( is_create) {
new My_stream_handler());
connection->register_stream_event_handler( stream_event_handler.get());
}
return true;
}
};
neuray->get_api_component<mi::rtmp::IFactory>());
mi::base::Handle<mi::rtmp::IServer> rtmp_server( rtmp_factory->create_server());
mi::base::Handle<mi::rtmp::IConnect_event_handler> connect_handler( new My_connect_handler());
rtmp_server->install( connect_handler.get());
rtmp_server->start( "0.0.0.0:1935");
Note
Some concepts might be easier to understand if having read the Adobe RTMP specification [RTMPSPEC10]