Fork me on GitHub
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Typedefs | Enumerations | Functions
janus_videoroom.c File Reference

Janus VideoRoom plugin. More...

#include "plugin.h"
#include <jansson.h>
#include <sofia-sip/sdp.h>
#include "../debug.h"
#include "../apierror.h"
#include "../config.h"
#include "../mutex.h"
#include "../rtp.h"
#include "../rtcp.h"
#include "../record.h"
#include "../utils.h"
#include <sys/types.h>
#include <sys/socket.h>
Include dependency graph for janus_videoroom.c:

Data Structures

struct  janus_videoroom_message
struct  janus_videoroom
struct  janus_videoroom_session
struct  rtp_forwarder
struct  janus_videoroom_participant
struct  janus_videoroom_listener_context
struct  janus_videoroom_listener
struct  janus_videoroom_listener_muxed
struct  janus_videoroom_rtp_relay_packet
struct  janus_videoroom_data_relay_packet

Macros

#define JANUS_VIDEOROOM_VERSION   6
#define JANUS_VIDEOROOM_VERSION_STRING   "0.0.6"
#define JANUS_VIDEOROOM_DESCRIPTION   "This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router."
#define JANUS_VIDEOROOM_NAME   "JANUS VideoRoom plugin"
#define JANUS_VIDEOROOM_AUTHOR   "Meetecho s.r.l."
#define JANUS_VIDEOROOM_PACKAGE   "janus.plugin.videoroom"
#define OPUS_PT   111
#define VP8_PT   100
#define sdp_template
#define sdp_a_template
#define sdp_v_template
#define sdp_d_template
#define JANUS_VIDEOROOM_ERROR_UNKNOWN_ERROR   499
#define JANUS_VIDEOROOM_ERROR_NO_MESSAGE   421
#define JANUS_VIDEOROOM_ERROR_INVALID_JSON   422
#define JANUS_VIDEOROOM_ERROR_INVALID_REQUEST   423
#define JANUS_VIDEOROOM_ERROR_JOIN_FIRST   424
#define JANUS_VIDEOROOM_ERROR_ALREADY_JOINED   425
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_ROOM   426
#define JANUS_VIDEOROOM_ERROR_ROOM_EXISTS   427
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_FEED   428
#define JANUS_VIDEOROOM_ERROR_MISSING_ELEMENT   429
#define JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT   430
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP_TYPE   431
#define JANUS_VIDEOROOM_ERROR_PUBLISHERS_FULL   432
#define JANUS_VIDEOROOM_ERROR_UNAUTHORIZED   433
#define JANUS_VIDEOROOM_ERROR_ALREADY_PUBLISHED   434
#define JANUS_VIDEOROOM_ERROR_NOT_PUBLISHED   435
#define JANUS_VIDEOROOM_ERROR_ID_EXISTS   436
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP   437

Typedefs

typedef enum janus_videoroom_p_type janus_videoroom_p_type
typedef struct
janus_videoroom_message 
janus_videoroom_message
typedef struct janus_videoroom janus_videoroom
typedef struct
janus_videoroom_session 
janus_videoroom_session
typedef struct rtp_forwarder rtp_forwarder
typedef struct
janus_videoroom_participant 
janus_videoroom_participant
typedef struct
janus_videoroom_listener_context 
janus_videoroom_listener_context
typedef struct
janus_videoroom_listener 
janus_videoroom_listener
typedef struct
janus_videoroom_listener_muxed 
janus_videoroom_listener_muxed
typedef struct
janus_videoroom_rtp_relay_packet 
janus_videoroom_rtp_relay_packet
typedef struct
janus_videoroom_data_relay_packet 
janus_videoroom_data_relay_packet

Enumerations

enum  janus_videoroom_p_type { janus_videoroom_p_type_none = 0, janus_videoroom_p_type_subscriber, janus_videoroom_p_type_subscriber_muxed, janus_videoroom_p_type_publisher }

Functions

janus_plugincreate (void)
int janus_videoroom_init (janus_callbacks *callback, const char *config_path)
void janus_videoroom_destroy (void)
int janus_videoroom_get_api_compatibility (void)
int janus_videoroom_get_version (void)
const char * janus_videoroom_get_version_string (void)
const char * janus_videoroom_get_description (void)
const char * janus_videoroom_get_name (void)
const char * janus_videoroom_get_author (void)
const char * janus_videoroom_get_package (void)
void janus_videoroom_create_session (janus_plugin_session *handle, int *error)
struct janus_plugin_resultjanus_videoroom_handle_message (janus_plugin_session *handle, char *transaction, char *message, char *sdp_type, char *sdp)
void janus_videoroom_setup_media (janus_plugin_session *handle)
void janus_videoroom_incoming_rtp (janus_plugin_session *handle, int video, char *buf, int len)
void janus_videoroom_incoming_rtcp (janus_plugin_session *handle, int video, char *buf, int len)
void janus_videoroom_incoming_data (janus_plugin_session *handle, char *buf, int len)
void janus_videoroom_slow_link (janus_plugin_session *handle, int uplink, int video)
void janus_videoroom_hangup_media (janus_plugin_session *handle)
void janus_videoroom_destroy_session (janus_plugin_session *handle, int *error)
char * janus_videoroom_query_session (janus_plugin_session *handle)
int janus_videoroom_muxed_subscribe (janus_videoroom_listener_muxed *muxed_listener, GList *feeds, char *transaction)
int janus_videoroom_muxed_unsubscribe (janus_videoroom_listener_muxed *muxed_listener, GList *feeds, char *transaction)
int janus_videoroom_muxed_offer (janus_videoroom_listener_muxed *muxed_listener, char *transaction, char *event_text)
void * janus_videoroom_watchdog (void *data)

Detailed Description

Janus VideoRoom plugin.

Author
Lorenzo Miniero loren.nosp@m.zo@m.nosp@m.eetec.nosp@m.ho.c.nosp@m.om

This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router. This means that the plugin implements a virtual conferencing room peers can join and leave at any time. This room is based on a Publish/Subscribe pattern. Each peer can publish his/her own live audio/video feeds: this feed becomes an available stream in the room the other participants can attach to. This means that this plugin allows the realization of several different scenarios, ranging from a simple webinar (one speaker, several listeners) to a fully meshed video conference (each peer sending and receiving to and from all the others).

For what concerns the subscriber side, there are two different ways to attach to a publisher's feed: a generic 'listener', which can attach to a single feed, and a more complex 'Multiplexed listener', which instead can attach to more feeds using the same PeerConnection. The generic 'listener' is the default, which means that if you want to watch more feeds at the same time, you'll need to create multiple 'listeners' to attach at any of them. The 'Multiplexed listener', instead, is a more complex alternative that exploits the so called RTCWEB 'Plan B', which multiplexes more streams on a single PeerConnection and in the SDP: while more efficient in terms of resources, though, this approach is experimental, and currently only available on Google Chrome, so use it wisely.

Note
As of now, work on Plan B is still going on, and as such its support in Janus is flaky to say the least. Don't try to attach as a Multiplexed listener or bad things will probably happen!

Considering that this plugin allows for several different WebRTC PeerConnections to be on at the same time for the same peer (specifically, each peer potentially has 1 PeerConnection on for publishing and N on for subscriptions from other peers), each peer may need to attach several times to the same plugin for every stream: this means that each peer needs to have at least one handle active for managing its relation with the plugin (joining a room, leaving a room, muting/unmuting, publishing, receiving events), and needs to open a new one each time he/she wants to subscribe to a feed from another participant (or a single one in case a 'Multiplexed listener is used). The handle used for a subscription, however, would be logically a "slave" to the master one used for managing the room: this means that it cannot be used, for instance, to unmute in the room, as its only purpose would be to provide a context in which creating the sendonly PeerConnection for the subscription to the active participant.

Rooms to make available are listed in the plugin configuration file. A pre-filled configuration file is provided in conf/janus.plugin.videoroom.cfg and includes a demo room for testing. The same plugin is also used dynamically (that is, with rooms created on the fly via API) in the Screen Sharing demo as well.

To add more rooms or modify the existing one, you can use the following syntax:

[<unique room ID>]
description = This is my awesome room
is_private = yes|no (private rooms don't appear when you do a 'list' request)
secret = <password needed for manipulating (e.g. destroying) the room>
publishers = <max number of concurrent senders> (e.g., 6 for a video
             conference or 1 for a webinar)
bitrate = <max video bitrate for senders> (e.g., 128000)
fir_freq = <send a FIR to publishers every fir_freq seconds> (0=disable)
record = true|false (whether this room should be recorded, default=false)
rec_dir = <folder where recordings should be stored, when enabled>

Video Room API

The Video Room API supports several requests, some of which are synchronous and some asynchronous. There are some situations, though, (invalid JSON, invalid request) which will always result in a synchronous error response even for asynchronous requests.

create , destroy , exists, list and listparticipants are synchronous requests, which means you'll get a response directly within the context of the transaction. create allows you to create a new video room dynamically, as an alternative to using the configuration file; destroy removes a video room and destroys it, kicking all the users out as part of the process; exists allows you to check whether a specific video room exists; finally, list lists all the available rooms, while listparticipants lists all the participants of a specific room and their details.

The join , joinandconfigure , configure , publish , unpublish , start , pause , switch , stop , add , remove and leave requests instead are all asynchronous, which means you'll get a notification about their success or failure in an event. join allows you to join a specific video room, specifying whether that specific PeerConnection will be used for publishing or watching; configure can be used to modify some of the participation settings (e.g., bitrate cap); joinandconfigure combines the previous two requests in a single one (just for publishers); publish can be used to start sending media to broadcast to the other participants, while unpublish does the opposite; start allows you to start receiving media from a publisher you've subscribed to previously by means of a join , while pause pauses the delivery of the media; the switch request can be used to change the source of the media flowing over a specific PeerConnection (e.g., I was watching Alice, I want to watch Bob now) without having to create a new handle for that; stop interrupts a viewer instance; add and remove are just used when involving "Plan B", and are used to add or remove publishers to be muxed in the single viewer PeerConnection; finally, leave allows you to leave a video room for good.

Actual API docs: TBD.

Plugins

Macro Definition Documentation

#define JANUS_VIDEOROOM_AUTHOR   "Meetecho s.r.l."
#define JANUS_VIDEOROOM_DESCRIPTION   "This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router."
#define JANUS_VIDEOROOM_ERROR_ALREADY_JOINED   425
#define JANUS_VIDEOROOM_ERROR_ALREADY_PUBLISHED   434
#define JANUS_VIDEOROOM_ERROR_ID_EXISTS   436
#define JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT   430
#define JANUS_VIDEOROOM_ERROR_INVALID_JSON   422
#define JANUS_VIDEOROOM_ERROR_INVALID_REQUEST   423
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP   437
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP_TYPE   431
#define JANUS_VIDEOROOM_ERROR_JOIN_FIRST   424
#define JANUS_VIDEOROOM_ERROR_MISSING_ELEMENT   429
#define JANUS_VIDEOROOM_ERROR_NO_MESSAGE   421
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_FEED   428
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_ROOM   426
#define JANUS_VIDEOROOM_ERROR_NOT_PUBLISHED   435
#define JANUS_VIDEOROOM_ERROR_PUBLISHERS_FULL   432
#define JANUS_VIDEOROOM_ERROR_ROOM_EXISTS   427
#define JANUS_VIDEOROOM_ERROR_UNAUTHORIZED   433
#define JANUS_VIDEOROOM_ERROR_UNKNOWN_ERROR   499
#define JANUS_VIDEOROOM_NAME   "JANUS VideoRoom plugin"
#define JANUS_VIDEOROOM_PACKAGE   "janus.plugin.videoroom"
#define JANUS_VIDEOROOM_VERSION   6
#define JANUS_VIDEOROOM_VERSION_STRING   "0.0.6"
#define OPUS_PT   111
#define sdp_a_template
Value:
"m=audio 1 RTP/SAVPF %d\r\n" /* Opus payload type */ \
"c=IN IP4 1.1.1.1\r\n" \
"a=%s\r\n" /* Media direction */ \
"a=rtpmap:%d opus/48000/2\r\n" /* Opus payload type */
#define sdp_d_template
Value:
"m=application 1 DTLS/SCTP 5000\r\n" \
"c=IN IP4 1.1.1.1\r\n" \
"a=sctpmap:5000 webrtc-datachannel 16\r\n"
#define sdp_template
Value:
"v=0\r\n" \
"o=- %"SCNu64" %"SCNu64" IN IP4 127.0.0.1\r\n" /* We need current time here */ \
"s=%s\r\n" /* Video room name */ \
"t=0 0\r\n" \
"%s%s%s" /* Audio, video and/or data channel m-lines */
#define sdp_v_template
Value:
"m=video 1 RTP/SAVPF %d\r\n" /* VP8 payload type */ \
"c=IN IP4 1.1.1.1\r\n" \
"b=AS:%d\r\n" /* Bandwidth */ \
"a=%s\r\n" /* Media direction */ \
"a=rtpmap:%d VP8/90000\r\n" /* VP8 payload type */ \
"a=rtcp-fb:%d ccm fir\r\n" /* VP8 payload type */ \
"a=rtcp-fb:%d nack\r\n" /* VP8 payload type */ \
"a=rtcp-fb:%d nack pli\r\n" /* VP8 payload type */ \
"a=rtcp-fb:%d goog-remb\r\n" /* VP8 payload type */
#define VP8_PT   100

Typedef Documentation

typedef struct rtp_forwarder rtp_forwarder

Enumeration Type Documentation

Enumerator:
janus_videoroom_p_type_none 
janus_videoroom_p_type_subscriber 
janus_videoroom_p_type_subscriber_muxed 
janus_videoroom_p_type_publisher 

Function Documentation

janus_plugin* create ( void  )
void janus_videoroom_create_session ( janus_plugin_session handle,
int *  error 
)
void janus_videoroom_destroy ( void  )
void janus_videoroom_destroy_session ( janus_plugin_session handle,
int *  error 
)
int janus_videoroom_get_api_compatibility ( void  )
const char * janus_videoroom_get_author ( void  )
const char * janus_videoroom_get_description ( void  )
const char * janus_videoroom_get_name ( void  )
const char * janus_videoroom_get_package ( void  )
int janus_videoroom_get_version ( void  )
const char * janus_videoroom_get_version_string ( void  )
struct janus_plugin_result * janus_videoroom_handle_message ( janus_plugin_session handle,
char *  transaction,
char *  message,
char *  sdp_type,
char *  sdp 
)
read
void janus_videoroom_hangup_media ( janus_plugin_session handle)
void janus_videoroom_incoming_data ( janus_plugin_session handle,
char *  buf,
int  len 
)
void janus_videoroom_incoming_rtcp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
void janus_videoroom_incoming_rtp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
int janus_videoroom_init ( janus_callbacks callback,
const char *  config_path 
)
int janus_videoroom_muxed_offer ( janus_videoroom_listener_muxed muxed_listener,
char *  transaction,
char *  event_text 
)
int janus_videoroom_muxed_subscribe ( janus_videoroom_listener_muxed muxed_listener,
GList *  feeds,
char *  transaction 
)
int janus_videoroom_muxed_unsubscribe ( janus_videoroom_listener_muxed muxed_listener,
GList *  feeds,
char *  transaction 
)
char * janus_videoroom_query_session ( janus_plugin_session handle)
void janus_videoroom_setup_media ( janus_plugin_session handle)
void janus_videoroom_slow_link ( janus_plugin_session handle,
int  uplink,
int  video 
)
void * janus_videoroom_watchdog ( void *  data)