diff --git a/janus/src/client.c b/janus/src/client.c index 526b446..ac686b6 100644 --- a/janus/src/client.c +++ b/janus/src/client.c @@ -103,14 +103,13 @@ static void *_common_thread(void *v_client, bool video) { packet.buffer = (char *)rtp->datagram; packet.length = rtp->used; janus_plugin_rtp_extensions_reset(&packet.extensions); - // FIXME: See rtpv.c - // Это очень эффективный способ уменьшить задержку, но WebRTC стек в хроме и фоксе - // слишком корявый, чтобы обработать это, тз-за чего на кейфреймах начинаются заикания. + // FIXME: Это очень эффективный способ уменьшить задержку, но WebRTC стек в хроме и фоксе + // слишком корявый, чтобы обработать это, из-за чего на кейфреймах начинаются заикания. // - https://github.com/Glimesh/janus-ftl-plugin/issues/101 - /*if (video) { + if (rtp->zero_playout_delay) { packet.extensions.min_delay = 0; packet.extensions.max_delay = 0; - }*/ + } client->gw->relay_rtp(client->session, &packet); } rtp_destroy(rtp); diff --git a/janus/src/config.c b/janus/src/config.c index 1bfef2d..4c6776b 100644 --- a/janus/src/config.c +++ b/janus/src/config.c @@ -24,6 +24,7 @@ static char *_get_value(janus_config *jcfg, const char *section, const char *option); +static bool _get_bool(janus_config *jcfg, const char *section, const char *option, bool def); plugin_config_s *plugin_config_init(const char *config_dir_path) { @@ -50,6 +51,9 @@ plugin_config_s *plugin_config_init(const char *config_dir_path) { JLOG_ERROR("config", "Missing config value: video.sink (ex. memsink.object)"); goto error; } + if ((config->video_zero_playout_delay = _get_bool(jcfg, "video", "zero_playout_delay", false)) == true) { + JLOG_INFO("config", "Enabled the experimental Playout-Delay=0 RTP extension for VIDEO"); + } if ((config->audio_dev_name = _get_value(jcfg, "audio", "device")) != NULL) { JLOG_INFO("config", "Enabled the experimental AUDIO feature"); if ((config->tc358743_dev_path = _get_value(jcfg, "audio", "tc358743")) == NULL) { @@ -85,3 +89,13 @@ static char *_get_value(janus_config *jcfg, const char *section, const char *opt } return strdup(option_obj->value); } + +static bool _get_bool(janus_config *jcfg, const char *section, const char *option, bool def) { + char *tmp = _get_value(jcfg, section, option); + bool value = def; + if (tmp != NULL) { + value = (!strcasecmp(tmp, "1") || !strcasecmp(tmp, "true") || !strcasecmp(tmp, "yes")); + free(tmp); + } + return value; +} diff --git a/janus/src/config.h b/janus/src/config.h index 69668f8..9f9fe5c 100644 --- a/janus/src/config.h +++ b/janus/src/config.h @@ -36,6 +36,8 @@ typedef struct { char *video_sink_name; + bool video_zero_playout_delay; + char *audio_dev_name; char *tc358743_dev_path; } plugin_config_s; diff --git a/janus/src/plugin.c b/janus/src/plugin.c index acfe6f7..da125f9 100644 --- a/janus/src/plugin.c +++ b/janus/src/plugin.c @@ -261,7 +261,7 @@ static int _plugin_init(janus_callbacks *gw, const char *config_dir_path) { _g_gw = gw; _g_video_queue = queue_init(1024); - _g_rtpv = rtpv_init(_relay_rtp_clients); + _g_rtpv = rtpv_init(_relay_rtp_clients, _g_config->video_zero_playout_delay); if (_g_config->audio_dev_name) { _g_rtpa = rtpa_init(_relay_rtp_clients); A_THREAD_CREATE(&_g_audio_tid, _audio_thread, NULL); diff --git a/janus/src/rtp.c b/janus/src/rtp.c index 800d87d..cc11f60 100644 --- a/janus/src/rtp.c +++ b/janus/src/rtp.c @@ -26,11 +26,12 @@ #include "rtp.h" -rtp_s *rtp_init(unsigned payload, bool video) { +rtp_s *rtp_init(unsigned payload, bool video, bool zero_playout_delay) { rtp_s *rtp; A_CALLOC(rtp, 1); rtp->payload = payload; rtp->video = video; + rtp->zero_playout_delay = zero_playout_delay; // See client.c rtp->ssrc = triple_u32(get_now_monotonic_u64()); return rtp; } diff --git a/janus/src/rtp.h b/janus/src/rtp.h index 454224f..45a6d63 100644 --- a/janus/src/rtp.h +++ b/janus/src/rtp.h @@ -39,6 +39,7 @@ typedef struct { unsigned payload; bool video; + bool zero_playout_delay; uint32_t ssrc; uint16_t seq; @@ -49,7 +50,7 @@ typedef struct { typedef void (*rtp_callback_f)(const rtp_s *rtp); -rtp_s *rtp_init(unsigned payload, bool video); +rtp_s *rtp_init(unsigned payload, bool video, bool zero_playout_delay); rtp_s *rtp_dup(const rtp_s *rtp); void rtp_destroy(rtp_s *rtp); diff --git a/janus/src/rtpa.c b/janus/src/rtpa.c index 46e9960..6d18354 100644 --- a/janus/src/rtpa.c +++ b/janus/src/rtpa.c @@ -26,7 +26,7 @@ rtpa_s *rtpa_init(rtp_callback_f callback) { rtpa_s *rtpa; A_CALLOC(rtpa, 1); - rtpa->rtp = rtp_init(111, false); + rtpa->rtp = rtp_init(111, false, false); rtpa->callback = callback; return rtpa; } diff --git a/janus/src/rtpv.c b/janus/src/rtpv.c index 381eb12..ec86088 100644 --- a/janus/src/rtpv.c +++ b/janus/src/rtpv.c @@ -31,10 +31,10 @@ void _rtpv_process_nalu(rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t static ssize_t _find_annexb(const uint8_t *data, size_t size); -rtpv_s *rtpv_init(rtp_callback_f callback) { +rtpv_s *rtpv_init(rtp_callback_f callback, bool zero_playout_delay) { rtpv_s *rtpv; A_CALLOC(rtpv, 1); - rtpv->rtp = rtp_init(96, true); + rtpv->rtp = rtp_init(96, true, zero_playout_delay); rtpv->callback = callback; rtpv->sps = frame_init(); rtpv->pps = frame_init(); @@ -81,14 +81,14 @@ char *rtpv_make_sdp(rtpv_s *rtpv) { "a=rtcp-fb:%u nack pli" RN "a=rtcp-fb:%u goog-remb" RN "a=ssrc:%" PRIu32 " cname:ustreamer" RN - // XXX: See client.c - // "a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay" RN + "%s" // playout-delay "a=sendonly" RN, PAYLOAD, PAYLOAD, PAYLOAD, PAYLOAD, PAYLOAD, sps, PAYLOAD, pps, PAYLOAD, PAYLOAD, PAYLOAD, - rtpv->rtp->ssrc + rtpv->rtp->ssrc, + (rtpv->rtp->zero_playout_delay ? "a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay" RN : "") ); # undef PAYLOAD diff --git a/janus/src/rtpv.h b/janus/src/rtpv.h index 7be712b..53fbea7 100644 --- a/janus/src/rtpv.h +++ b/janus/src/rtpv.h @@ -50,7 +50,7 @@ typedef struct { } rtpv_s; -rtpv_s *rtpv_init(rtp_callback_f callback); +rtpv_s *rtpv_init(rtp_callback_f callback, bool zero_playout_delay); void rtpv_destroy(rtpv_s *rtpv); char *rtpv_make_sdp(rtpv_s *rtpv);