diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | apps/app_agent_pool.c | 1 | ||||
-rw-r--r-- | apps/app_confbridge.c | 1 | ||||
-rw-r--r-- | apps/app_originate.c | 12 | ||||
-rw-r--r-- | apps/confbridge/conf_config_parser.c | 14 | ||||
-rw-r--r-- | apps/confbridge/include/confbridge.h | 1 | ||||
-rw-r--r-- | channels/chan_pjsip.c | 10 | ||||
-rw-r--r-- | configs/samples/confbridge.conf.sample | 4 | ||||
-rwxr-xr-x | configure | 269 | ||||
-rw-r--r-- | configure.ac | 56 | ||||
-rw-r--r-- | include/asterisk/bridge.h | 9 | ||||
-rw-r--r-- | include/asterisk/res_pjsip.h | 4 | ||||
-rw-r--r-- | include/asterisk/rtp_engine.h | 2 | ||||
-rw-r--r-- | main/bridge.c | 7 | ||||
-rw-r--r-- | res/res_pjsip.c | 30 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 134 |
16 files changed, 235 insertions, 326 deletions
@@ -17,6 +17,13 @@ app_fax * The app_fax module is now deprecated, users should migrate to the replacement module res_fax. +app_originate +------------------ + * An 'a' option has been added to the Originate dialplan application which + will execute the originate in an asynchronous fashion. If set then the + application will return immediately without waiting for the originated + channel to answer. + Build System ------------------ * MALLOC_DEBUG no longer has an effect on Asterisk's ABI. Asterisk built diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c index 3c2ea3870..805c403f5 100644 --- a/apps/app_agent_pool.c +++ b/apps/app_agent_pool.c @@ -438,6 +438,7 @@ static void *agent_cfg_alloc(const char *name) cfg = ao2_alloc_options(sizeof(*cfg), agent_cfg_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!cfg || ast_string_field_init(cfg, 64)) { + ao2_cleanup(cfg); return NULL; } ast_string_field_set(cfg, username, name); diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index 4f1108e6b..d8407d857 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -1543,6 +1543,7 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_SFU)) { ast_bridge_set_sfu_video_mode(conference->bridge); ast_bridge_set_video_update_discard(conference->bridge, conference->b_profile.video_update_discard); + ast_bridge_set_remb_send_interval(conference->bridge, conference->b_profile.remb_send_interval); } /* Link it into the conference bridges container */ diff --git a/apps/app_originate.c b/apps/app_originate.c index 30fa565be..107be846d 100644 --- a/apps/app_originate.c +++ b/apps/app_originate.c @@ -74,6 +74,10 @@ static const char app_originate[] = "Originate"; </parameter> <parameter name="options" required="false"> <optionlist> + <option name="a"> + <para>Originate asynchronously. In other words, continue in the dialplan + without waiting for the originated channel to answer.</para> + </option> <option name="b" argsep="^"> <para>Before originating the outgoing call, Gosub to the specified location using the newly created channel.</para> @@ -123,6 +127,7 @@ static const char app_originate[] = "Originate"; enum { OPT_PREDIAL_CALLEE = (1 << 0), OPT_PREDIAL_CALLER = (1 << 1), + OPT_ASYNC = (1 << 2), }; enum { @@ -133,6 +138,7 @@ enum { }; AST_APP_OPTIONS(originate_exec_options, BEGIN_OPTIONS + AST_APP_OPTION('a', OPT_ASYNC), AST_APP_OPTION_ARG('b', OPT_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE), AST_APP_OPTION_ARG('B', OPT_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER), END_OPTIONS ); @@ -250,7 +256,8 @@ static int originate_exec(struct ast_channel *chan, const char *data) res = ast_pbx_outgoing_exten_predial(chantech, cap_slin, chandata, timeout * 1000, args.arg1, exten, priority, &outgoing_status, - AST_OUTGOING_WAIT, NULL, NULL, NULL, NULL, NULL, 0, NULL, + ast_test_flag64(&opts, OPT_ASYNC) ? AST_OUTGOING_NO_WAIT : AST_OUTGOING_WAIT, + NULL, NULL, NULL, NULL, NULL, 0, NULL, predial_callee); } else { ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n", @@ -258,7 +265,8 @@ static int originate_exec(struct ast_channel *chan, const char *data) res = ast_pbx_outgoing_app_predial(chantech, cap_slin, chandata, timeout * 1000, args.arg1, args.arg2, &outgoing_status, - AST_OUTGOING_WAIT, NULL, NULL, NULL, NULL, NULL, NULL, + ast_test_flag64(&opts, OPT_ASYNC) ? AST_OUTGOING_NO_WAIT : AST_OUTGOING_WAIT, + NULL, NULL, NULL, NULL, NULL, NULL, predial_callee); } diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index 71da80206..f9d74831c 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -458,6 +458,18 @@ video update requests from clients. </para></description> </configOption> + <configOption name="remb_send_interval" default="0"> + <synopsis>Sets the interval in milliseconds that a combined REMB frame will be sent to video sources</synopsis> + <description><para> + Sets the interval in milliseconds that a combined REMB frame will be sent + to video sources. This is done by taking all REMB frames that have been + received since the last REMB frame was sent, making a combined value, + and sending it to the source. A REMB frame contains receiver estimated + maximum bitrate information. By creating a combined REMB frame the + sender of video can be influenced on the bitrate they choose, allowing + better quality for all receivers. + </para></description> + </configOption> <configOption name="template"> <synopsis>When using the CONFBRIDGE dialplan function, use a bridge profile as a template for creating a new temporary profile</synopsis> </configOption> @@ -1661,6 +1673,7 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e, } ast_cli(a->fd,"Video Update Discard: %u\n", b_profile.video_update_discard); + ast_cli(a->fd,"REMB Send Interval: %u\n", b_profile.remb_send_interval); ast_cli(a->fd,"sound_only_person: %s\n", conf_get_sound(CONF_SOUND_ONLY_PERSON, b_profile.sounds)); ast_cli(a->fd,"sound_only_one: %s\n", conf_get_sound(CONF_SOUND_ONLY_ONE, b_profile.sounds)); @@ -2231,6 +2244,7 @@ int conf_load_config(void) aco_option_register(&cfg_info, "language", ACO_EXACT, bridge_types, "en", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct bridge_profile, language)); aco_option_register_custom(&cfg_info, "sound_", ACO_PREFIX, bridge_types, NULL, sound_option_handler, 0); aco_option_register(&cfg_info, "video_update_discard", ACO_EXACT, bridge_types, "2000", OPT_UINT_T, 0, FLDSET(struct bridge_profile, video_update_discard)); + aco_option_register(&cfg_info, "remb_send_interval", ACO_EXACT, bridge_types, "0", OPT_UINT_T, 0, FLDSET(struct bridge_profile, remb_send_interval)); /* This option should only be used with the CONFBRIDGE dialplan function */ aco_option_register_custom(&cfg_info, "template", ACO_EXACT, bridge_types, NULL, bridge_template_handler, 0); diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h index 044ab4003..c2f8f9a58 100644 --- a/apps/confbridge/include/confbridge.h +++ b/apps/confbridge/include/confbridge.h @@ -222,6 +222,7 @@ struct bridge_profile { struct bridge_profile_sounds *sounds; char regcontext[AST_MAX_CONTEXT]; unsigned int video_update_discard; /*!< Amount of time after sending a video update request that subsequent requests should be discarded */ + unsigned int remb_send_interval; /*!< Interval at which a combined REMB frame is sent to video sources */ }; /*! \brief The structure that represents a conference bridge */ diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 5cb52a5b2..6b2664819 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -966,6 +966,16 @@ static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, stru case AST_FRAME_CNG: break; case AST_FRAME_RTCP: + /* We only support writing out feedback */ + if (frame->subclass.integer != AST_RTP_RTCP_PSFB || !media) { + return 0; + } else if (media->type != AST_MEDIA_TYPE_VIDEO) { + ast_debug(3, "Channel %s stream %d is of type '%s', not video! Unable to write RTCP feedback.\n", + ast_channel_name(ast), stream_num, ast_codec_media_type2str(media->type)); + return 0; + } else if (media->write_callback) { + res = media->write_callback(session, media, frame); + } break; default: ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype); diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample index e2d8a620d..4028593d2 100644 --- a/configs/samples/confbridge.conf.sample +++ b/configs/samples/confbridge.conf.sample @@ -235,6 +235,10 @@ type=bridge ; the video stream. Since a full frame can be large limiting how often they occur can ; reduce bandwidth usage at the cost of increasing how long it may take a newly joined ; channel to receive the video stream. +;remb_send_interval=1000 ; Interval (in milliseconds) at which a combined REMB frame will be sent to sources of video. + ; A REMB frame contains receiver estimated maximum bitrate information. By creating a combined + ; frame and sending it to the sources of video the sender can be influenced on what bitrate + ; they choose allowing a better experience for the receivers. This defaults to 0, or disabled. ; All sounds in the conference are customizable using the bridge profile options below. ; Simply state the option followed by the filename or full path of the filename after @@ -7792,7 +7792,7 @@ if test "${WGET}" != ":" ; then DOWNLOAD=${WGET} DOWNLOAD_TO_STDOUT="${WGET} -q -O-" DOWNLOAD_TIMEOUT='--timeout=$1' -else if test "${CURL}" != ":" ; then +elif test "${CURL}" != ":" ; then DOWNLOAD="${CURL} -O --progress-bar -w \"%{url_effective}\n\"" DOWNLOAD_TO_STDOUT="${CURL} -Ls" DOWNLOAD_TIMEOUT='--max-time $(or $2,$1)' @@ -7844,7 +7844,6 @@ fi DOWNLOAD_TIMEOUT='--timeout=$(or $2,$1)' fi fi -fi @@ -19202,15 +19201,15 @@ if test $ac_cv_sizeof_int = $ac_cv_sizeof_fd_set_fds_bits; then $as_echo "#define TYPEOF_FD_SET_FDS_BITS int" >>confdefs.h -else if test $ac_cv_sizeof_long = $ac_cv_sizeof_fd_set_fds_bits; then +elif test $ac_cv_sizeof_long = $ac_cv_sizeof_fd_set_fds_bits; then $as_echo "#define TYPEOF_FD_SET_FDS_BITS long" >>confdefs.h -else if test $ac_cv_sizeof_long_long = $ac_cv_sizeof_fd_set_fds_bits; then +elif test $ac_cv_sizeof_long_long = $ac_cv_sizeof_fd_set_fds_bits; then $as_echo "#define TYPEOF_FD_SET_FDS_BITS long long" >>confdefs.h -fi ; fi ; fi +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dladdr in dlfcn.h" >&5 $as_echo_n "checking for dladdr in dlfcn.h... " >&6; } @@ -20374,15 +20373,13 @@ cat >>confdefs.h <<_ACEOF _ACEOF GSM_OK=1 - else - if test "${GSM_GSM_HEADER_FOUND}" = "1" ; then + elif test "${GSM_GSM_HEADER_FOUND}" = "1" ; then cat >>confdefs.h <<_ACEOF #define HAVE_GSM_GSM_HEADER 1 _ACEOF - GSM_OK=1 - fi + GSM_OK=1 fi if test "${GSM_OK}" = "1" ; then GSM_LIB="-lgsm" @@ -28898,6 +28895,7 @@ fi +for ver in 5.3 5.2 5.1; do if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then pbxlibdir="" @@ -28912,117 +28910,14 @@ if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then ast_ext_lib_check_save_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} " - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.3" >&5 -$as_echo_n "checking for luaL_newstate in -llua5.3... " >&6; } -if ${ac_cv_lib_lua5_3_luaL_newstate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llua5.3 ${pbxlibdir} -lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char luaL_newstate (); -int -main () -{ -return luaL_newstate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lua5_3_luaL_newstate=yes -else - ac_cv_lib_lua5_3_luaL_newstate=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_3_luaL_newstate" >&5 -$as_echo "$ac_cv_lib_lua5_3_luaL_newstate" >&6; } -if test "x$ac_cv_lib_lua5_3_luaL_newstate" = xyes; then : - AST_LUA_FOUND=yes -else - AST_LUA_FOUND=no -fi - - CFLAGS="${ast_ext_lib_check_save_CFLAGS}" - - - # now check for the header. - if test "${AST_LUA_FOUND}" = "yes"; then - LUA_LIB="${pbxlibdir} -llua5.3 -lm" - # if --with-LUA=DIR has been specified, use it. - if test "x${LUA_DIR}" != "x"; then - LUA_INCLUDE="-I${LUA_DIR}/include" - fi - LUA_INCLUDE="${LUA_INCLUDE} " - - # check for the header - ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}" - CPPFLAGS="${CPPFLAGS} ${LUA_INCLUDE}" - ac_fn_c_check_header_mongrel "$LINENO" "lua5.3/lua.h" "ac_cv_header_lua5_3_lua_h" "$ac_includes_default" -if test "x$ac_cv_header_lua5_3_lua_h" = xyes; then : - LUA_HEADER_FOUND=1 -else - LUA_HEADER_FOUND=0 -fi - - - CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}" - - if test "x${LUA_HEADER_FOUND}" = "x0" ; then - LUA_LIB="" - LUA_INCLUDE="" - else - - PBX_LUA=1 - cat >>confdefs.h <<_ACEOF -#define HAVE_LUA 1 -_ACEOF - - fi - fi -fi - - -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.3" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.3" - fi -fi - - -if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then - pbxlibdir="" - # if --with-LUA=DIR has been specified, use it. - if test "x${LUA_DIR}" != "x"; then - if test -d ${LUA_DIR}/lib; then - pbxlibdir="-L${LUA_DIR}/lib" - else - pbxlibdir="-L${LUA_DIR}" - fi - fi - - ast_ext_lib_check_save_CFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} " - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.2" >&5 -$as_echo_n "checking for luaL_newstate in -llua5.2... " >&6; } -if ${ac_cv_lib_lua5_2_luaL_newstate+:} false; then : + as_ac_Lib=`$as_echo "ac_cv_lib_lua${ver}''_luaL_newstate" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua${ver}" >&5 +$as_echo_n "checking for luaL_newstate in -llua${ver}... " >&6; } +if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-llua5.2 ${pbxlibdir} -lm $LIBS" +LIBS="-llua${ver} ${pbxlibdir} -lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -29042,121 +28937,18 @@ return luaL_newstate (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lua5_2_luaL_newstate=yes + eval "$as_ac_Lib=yes" else - ac_cv_lib_lua5_2_luaL_newstate=no + eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_2_luaL_newstate" >&5 -$as_echo "$ac_cv_lib_lua5_2_luaL_newstate" >&6; } -if test "x$ac_cv_lib_lua5_2_luaL_newstate" = xyes; then : - AST_LUA_FOUND=yes -else - AST_LUA_FOUND=no -fi - - CFLAGS="${ast_ext_lib_check_save_CFLAGS}" - - - # now check for the header. - if test "${AST_LUA_FOUND}" = "yes"; then - LUA_LIB="${pbxlibdir} -llua5.2 -lm" - # if --with-LUA=DIR has been specified, use it. - if test "x${LUA_DIR}" != "x"; then - LUA_INCLUDE="-I${LUA_DIR}/include" - fi - LUA_INCLUDE="${LUA_INCLUDE} " - - # check for the header - ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}" - CPPFLAGS="${CPPFLAGS} ${LUA_INCLUDE}" - ac_fn_c_check_header_mongrel "$LINENO" "lua5.2/lua.h" "ac_cv_header_lua5_2_lua_h" "$ac_includes_default" -if test "x$ac_cv_header_lua5_2_lua_h" = xyes; then : - LUA_HEADER_FOUND=1 -else - LUA_HEADER_FOUND=0 -fi - - - CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}" - - if test "x${LUA_HEADER_FOUND}" = "x0" ; then - LUA_LIB="" - LUA_INCLUDE="" - else - - PBX_LUA=1 - cat >>confdefs.h <<_ACEOF -#define HAVE_LUA 1 -_ACEOF - - fi - fi -fi - - -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.2" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.2" - fi -fi - - -if test "x${PBX_LUA}" != "x1" -a "${USE_LUA}" != "no"; then - pbxlibdir="" - # if --with-LUA=DIR has been specified, use it. - if test "x${LUA_DIR}" != "x"; then - if test -d ${LUA_DIR}/lib; then - pbxlibdir="-L${LUA_DIR}/lib" - else - pbxlibdir="-L${LUA_DIR}" - fi - fi - - ast_ext_lib_check_save_CFLAGS="${CFLAGS}" - CFLAGS="${CFLAGS} " - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for luaL_newstate in -llua5.1" >&5 -$as_echo_n "checking for luaL_newstate in -llua5.1... " >&6; } -if ${ac_cv_lib_lua5_1_luaL_newstate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llua5.1 ${pbxlibdir} -lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char luaL_newstate (); -int -main () -{ -return luaL_newstate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lua5_1_luaL_newstate=yes -else - ac_cv_lib_lua5_1_luaL_newstate=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lua5_1_luaL_newstate" >&5 -$as_echo "$ac_cv_lib_lua5_1_luaL_newstate" >&6; } -if test "x$ac_cv_lib_lua5_1_luaL_newstate" = xyes; then : +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : AST_LUA_FOUND=yes else AST_LUA_FOUND=no @@ -29167,7 +28959,7 @@ fi # now check for the header. if test "${AST_LUA_FOUND}" = "yes"; then - LUA_LIB="${pbxlibdir} -llua5.1 -lm" + LUA_LIB="${pbxlibdir} -llua${ver} -lm" # if --with-LUA=DIR has been specified, use it. if test "x${LUA_DIR}" != "x"; then LUA_INCLUDE="-I${LUA_DIR}/include" @@ -29177,8 +28969,9 @@ fi # check for the header ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} ${LUA_INCLUDE}" - ac_fn_c_check_header_mongrel "$LINENO" "lua5.1/lua.h" "ac_cv_header_lua5_1_lua_h" "$ac_includes_default" -if test "x$ac_cv_header_lua5_1_lua_h" = xyes; then : + as_ac_Header=`$as_echo "ac_cv_header_lua${ver}/lua.h" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "lua${ver}/lua.h" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : LUA_HEADER_FOUND=1 else LUA_HEADER_FOUND=0 @@ -29202,13 +28995,15 @@ _ACEOF fi -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.1" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.1" + if test "x${PBX_LUA}" = "x1" ; then + if test x"${LUA_DIR}" = x; then + LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua${ver}" + else + LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua${ver}" + fi + break; fi -fi +done # Some distributions (like openSUSE and NetBSD) remove the 5.x suffix. @@ -35772,9 +35567,9 @@ fi ${ac_cv_path_EGREP} 'CURSES|GTK2|OSARCH|NEWT' makeopts > makeopts.acbak2 if test "x${ac_cv_path_CMP}" = "x:"; then ( cd `pwd`/menuselect && ./configure ) -else if ${ac_cv_path_CMP} -s makeopts.acbak makeopts.acbak2; then : ; else +elif ${ac_cv_path_CMP} -s makeopts.acbak makeopts.acbak2; then : ; else ( cd `pwd`/menuselect && ./configure ) -fi ; fi +fi rm makeopts.acbak makeopts.acbak2 diff --git a/configure.ac b/configure.ac index 702ff4f97..128b0a0f8 100644 --- a/configure.ac +++ b/configure.ac @@ -293,7 +293,7 @@ if test "${WGET}" != ":" ; then DOWNLOAD=${WGET} DOWNLOAD_TO_STDOUT="${WGET} -q -O-" DOWNLOAD_TIMEOUT='--timeout=$1' -else if test "${CURL}" != ":" ; then +elif test "${CURL}" != ":" ; then DOWNLOAD="${CURL} -O --progress-bar -w \"%{url_effective}\n\"" DOWNLOAD_TO_STDOUT="${CURL} -Ls" DOWNLOAD_TIMEOUT='--max-time $(or $2,$1)' @@ -305,7 +305,6 @@ else DOWNLOAD_TIMEOUT='--timeout=$(or $2,$1)' fi fi -fi AC_SUBST(DOWNLOAD) AC_SUBST(DOWNLOAD_TO_STDOUT) AC_SUBST(DOWNLOAD_TIMEOUT) @@ -1426,11 +1425,11 @@ AC_CHECK_SIZEOF(fd_set.fds_bits) # correctly if the size is wrong. if test $ac_cv_sizeof_int = $ac_cv_sizeof_fd_set_fds_bits; then AC_DEFINE([TYPEOF_FD_SET_FDS_BITS], [int], [Define to a type of the same size as fd_set.fds_bits[[0]]]) -else if test $ac_cv_sizeof_long = $ac_cv_sizeof_fd_set_fds_bits; then +elif test $ac_cv_sizeof_long = $ac_cv_sizeof_fd_set_fds_bits; then AC_DEFINE([TYPEOF_FD_SET_FDS_BITS], [long], [Define to a type of the same size as fd_set.fds_bits[[0]]]) -else if test $ac_cv_sizeof_long_long = $ac_cv_sizeof_fd_set_fds_bits; then +elif test $ac_cv_sizeof_long_long = $ac_cv_sizeof_fd_set_fds_bits; then AC_DEFINE([TYPEOF_FD_SET_FDS_BITS], [long long], [Define to a type of the same size as fd_set.fds_bits[[0]]]) -fi ; fi ; fi +fi AC_MSG_CHECKING(for dladdr in dlfcn.h) PBX_DLADDR=0 @@ -1542,11 +1541,9 @@ if test "${USE_GSM}" != "no"; then if test "${GSM_HEADER_FOUND}" = "1" ; then AC_DEFINE_UNQUOTED([HAVE_GSM_HEADER], 1, [Define to indicate that gsm.h has no prefix for its location]) GSM_OK=1 - else - if test "${GSM_GSM_HEADER_FOUND}" = "1" ; then - AC_DEFINE_UNQUOTED([HAVE_GSM_GSM_HEADER], 1, [Define to indicate that gsm.h is in gsm/gsm.h]) - GSM_OK=1 - fi + elif test "${GSM_GSM_HEADER_FOUND}" = "1" ; then + AC_DEFINE_UNQUOTED([HAVE_GSM_GSM_HEADER], 1, [Define to indicate that gsm.h is in gsm/gsm.h]) + GSM_OK=1 fi if test "${GSM_OK}" = "1" ; then GSM_LIB="-lgsm" @@ -2357,32 +2354,17 @@ if test -z "$__opus_include" -o x"$__opus_include" = x" " ; then fi AST_EXT_LIB_CHECK([OPUSFILE], [opusfile], [op_open_callbacks], [opus/opusfile.h], [], [$__opus_include]) -AST_EXT_LIB_CHECK([LUA], [lua5.3], [luaL_newstate], [lua5.3/lua.h], [-lm]) -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.3" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.3" - fi -fi - -AST_EXT_LIB_CHECK([LUA], [lua5.2], [luaL_newstate], [lua5.2/lua.h], [-lm]) -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.2" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.2" - fi -fi - -AST_EXT_LIB_CHECK([LUA], [lua5.1], [luaL_newstate], [lua5.1/lua.h], [-lm]) -if test "x${PBX_LUA}" = "x1" ; then - if test x"${LUA_DIR}" = x; then - LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua5.1" - else - LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua5.1" +for ver in 5.3 5.2 5.1; do + AST_EXT_LIB_CHECK([LUA], lua${ver}, [luaL_newstate], lua${ver}/lua.h, [-lm]) + if test "x${PBX_LUA}" = "x1" ; then + if test x"${LUA_DIR}" = x; then + LUA_INCLUDE="${LUA_INCLUDE} -I/usr/include/lua${ver}" + else + LUA_INCLUDE="${LUA_INCLUDE} -I${LUA_DIR}/lua${ver}" + fi + break; fi -fi +done # Some distributions (like openSUSE and NetBSD) remove the 5.x suffix. AST_EXT_LIB_CHECK([LUA], [lua], [luaL_newstate], [lua.h], [-lm]) @@ -2733,9 +2715,9 @@ AC_OUTPUT ${ac_cv_path_EGREP} 'CURSES|GTK2|OSARCH|NEWT' makeopts > makeopts.acbak2 if test "x${ac_cv_path_CMP}" = "x:"; then ( cd `pwd`/menuselect && ./configure ) -else if ${ac_cv_path_CMP} -s makeopts.acbak makeopts.acbak2; then : ; else +elif ${ac_cv_path_CMP} -s makeopts.acbak makeopts.acbak2; then : ; else ( cd `pwd`/menuselect && ./configure ) -fi ; fi +fi rm makeopts.acbak makeopts.acbak2 diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h index 8d5c50211..b23255844 100644 --- a/include/asterisk/bridge.h +++ b/include/asterisk/bridge.h @@ -135,6 +135,7 @@ struct ast_bridge_video_mode { struct ast_bridge_video_talker_src_data talker_src_data; } mode_data; unsigned int video_update_discard; + unsigned int remb_send_interval; }; /*! @@ -912,6 +913,14 @@ void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge); void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard); /*! + * \brief Set the interval at which a combined REMB frame will be sent to video sources + * + * \param bridge Bridge to set the REMB send interval on + * \param remb_send_interval The REMB send interval + */ +void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval); + +/*! * \brief Update information about talker energy for talker src video mode. */ void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame); diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index c017e62db..26439986b 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -263,7 +263,7 @@ struct ast_sip_contact { struct timeval expiration_time; /*! Frequency to send OPTIONS requests to contact. 0 is disabled. */ unsigned int qualify_frequency; - /*! If true authenticate the qualify if needed */ + /*! If true authenticate the qualify challenge response if needed */ int authenticate_qualify; /*! Qualify timeout. 0 is diabled. */ double qualify_timeout; @@ -346,7 +346,7 @@ struct ast_sip_aor { unsigned int default_expiration; /*! Frequency to send OPTIONS requests to AOR contacts. 0 is disabled. */ unsigned int qualify_frequency; - /*! If true authenticate the qualify if needed */ + /*! If true authenticate the qualify challenge response if needed */ int authenticate_qualify; /*! Maximum number of external contacts, 0 to disable */ unsigned int max_contacts; diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h index b552948d2..8f044ce17 100644 --- a/include/asterisk/rtp_engine.h +++ b/include/asterisk/rtp_engine.h @@ -296,6 +296,8 @@ struct ast_rtp_payload_type { #define AST_RTP_RTCP_PSFB 206 /* Common RTCP feedback message types */ +/*! Picture loss indication (From RFC4585) */ +#define AST_RTP_RTCP_FMT_PLI 1 /*! Full INTRA-frame Request (From RFC5104) */ #define AST_RTP_RTCP_FMT_FIR 4 /*! REMB Information (From draft-alvestrand-rmcat-remb-03) */ diff --git a/main/bridge.c b/main/bridge.c index 1109c4b76..93c53dd15 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -3850,6 +3850,13 @@ void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int ast_bridge_unlock(bridge); } +void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval) +{ + ast_bridge_lock(bridge); + bridge->softmix.video_mode.remb_send_interval = remb_send_interval; + ast_bridge_unlock(bridge); +} + void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe) { struct ast_bridge_video_talker_src_data *data; diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 935a5598e..7c9929740 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1366,12 +1366,17 @@ If <literal>0</literal> no timeout. Time in fractional seconds. </para></description> </configOption> - <configOption name="authenticate_qualify" default="no"> - <synopsis>Authenticates a qualify request if needed</synopsis> - <description><para> - If true and a qualify request receives a challenge or authenticate response + <configOption name="authenticate_qualify"> + <synopsis>Authenticates a qualify challenge response if needed</synopsis> + <description> + <para>If true and a qualify request receives a challenge response then authentication is attempted before declaring the contact available. - </para></description> + </para> + <note><para>This option does nothing as we will always complete + the challenge response authentication if the qualify request is + challenged. + </para></note> + </description> </configOption> <configOption name="outbound_proxy"> <synopsis>Outbound proxy used when sending OPTIONS request</synopsis> @@ -1565,12 +1570,17 @@ If <literal>0</literal> no timeout. Time in fractional seconds. </para></description> </configOption> - <configOption name="authenticate_qualify" default="no"> - <synopsis>Authenticates a qualify request if needed</synopsis> - <description><para> - If true and a qualify request receives a challenge or authenticate response + <configOption name="authenticate_qualify"> + <synopsis>Authenticates a qualify challenge response if needed</synopsis> + <description> + <para>If true and a qualify request receives a challenge response then authentication is attempted before declaring the contact available. - </para></description> + </para> + <note><para>This option does nothing as we will always complete + the challenge response authentication if the qualify request is + challenged. + </para></note> + </description> </configOption> <configOption name="outbound_proxy"> <synopsis>Outbound proxy used when sending OPTIONS request</synopsis> diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index b010f6c51..c88903777 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -4473,6 +4473,94 @@ static struct ast_frame *red_t140_to_red(struct rtp_red *red) return &red->t140red; } +static void rtp_write_rtcp_fir(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *remote_address) +{ + unsigned int *rtcpheader; + char bdata[1024]; + int len = 20; + int ice; + int res; + + if (!rtp || !rtp->rtcp) { + return; + } + + if (ast_sockaddr_isnull(&rtp->rtcp->them) || rtp->rtcp->schedid < 0) { + /* + * RTCP was stopped. + */ + return; + } + + if (!rtp->themssrc_valid) { + /* We don't know their SSRC value so we don't know who to update. */ + return; + } + + /* Prepare RTCP FIR (PT=206, FMT=4) */ + rtp->rtcp->firseq++; + if(rtp->rtcp->firseq == 256) { + rtp->rtcp->firseq = 0; + } + + rtcpheader = (unsigned int *)bdata; + rtcpheader[0] = htonl((2 << 30) | (4 << 24) | (RTCP_PT_PSFB << 16) | ((len/4)-1)); + rtcpheader[1] = htonl(rtp->ssrc); + rtcpheader[2] = htonl(rtp->themssrc); + rtcpheader[3] = htonl(rtp->themssrc); /* FCI: SSRC */ + rtcpheader[4] = htonl(rtp->rtcp->firseq << 24); /* FCI: Sequence number */ + res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice); + if (res < 0) { + ast_log(LOG_ERROR, "RTCP FIR transmission error: %s\n", strerror(errno)); + } +} + +static void rtp_write_rtcp_psfb(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_frame *frame, struct ast_sockaddr *remote_address) +{ + struct ast_rtp_rtcp_feedback *feedback = frame->data.ptr; + unsigned int *rtcpheader; + char bdata[1024]; + int len = 24; + int ice; + int res; + + if (feedback->fmt != AST_RTP_RTCP_FMT_REMB) { + ast_debug(1, "Provided an RTCP feedback frame of format %d to write on RTP instance '%p' but only REMB is supported\n", + feedback->fmt, instance); + return; + } + + if (!rtp || !rtp->rtcp) { + return; + } + + /* If REMB support is not enabled don't send this RTCP packet */ + if (!ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_REMB)) { + ast_debug(1, "Provided an RTCP feedback REMB report to write on RTP instance '%p' but REMB support not enabled\n", + instance); + return; + } + + if (ast_sockaddr_isnull(&rtp->rtcp->them) || rtp->rtcp->schedid < 0) { + /* + * RTCP was stopped. + */ + return; + } + + rtcpheader = (unsigned int *)bdata; + rtcpheader[0] = htonl((2 << 30) | (AST_RTP_RTCP_FMT_REMB << 24) | (RTCP_PT_PSFB << 16) | ((len/4)-1)); + rtcpheader[1] = htonl(rtp->ssrc); + rtcpheader[2] = htonl(0); /* Per the draft this should always be 0 */ + rtcpheader[3] = htonl(('R' << 24) | ('E' << 16) | ('M' << 8) | ('B')); /* Unique identifier 'R' 'E' 'M' 'B' */ + rtcpheader[4] = htonl((1 << 24) | (feedback->remb.br_exp << 18) | (feedback->remb.br_mantissa)); /* Number of SSRCs / BR Exp / BR Mantissa */ + rtcpheader[5] = htonl(rtp->ssrc); /* The SSRC this feedback message applies to */ + res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice); + if (res < 0) { + ast_log(LOG_ERROR, "RTCP PSFB transmission error: %s\n", strerror(errno)); + } +} + /*! \pre instance is locked */ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame) { @@ -4491,42 +4579,11 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr /* VP8: is this a request to send a RTCP FIR? */ if (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_VIDUPDATE) { - unsigned int *rtcpheader; - char bdata[1024]; - int len = 20; - int ice; - int res; - - if (!rtp || !rtp->rtcp) { - return 0; - } - - if (ast_sockaddr_isnull(&rtp->rtcp->them) || rtp->rtcp->schedid < 0) { - /* - * RTCP was stopped. - */ - return 0; - } - if (!rtp->themssrc_valid) { - /* We don't know their SSRC value so we don't know who to update. */ - return 0; - } - - /* Prepare RTCP FIR (PT=206, FMT=4) */ - rtp->rtcp->firseq++; - if(rtp->rtcp->firseq == 256) { - rtp->rtcp->firseq = 0; - } - - rtcpheader = (unsigned int *)bdata; - rtcpheader[0] = htonl((2 << 30) | (4 << 24) | (RTCP_PT_PSFB << 16) | ((len/4)-1)); - rtcpheader[1] = htonl(rtp->ssrc); - rtcpheader[2] = htonl(rtp->themssrc); - rtcpheader[3] = htonl(rtp->themssrc); /* FCI: SSRC */ - rtcpheader[4] = htonl(rtp->rtcp->firseq << 24); /* FCI: Sequence number */ - res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, rtp->bundled ? &remote_address : &rtp->rtcp->them, &ice); - if (res < 0) { - ast_log(LOG_ERROR, "RTCP FIR transmission error: %s\n", strerror(errno)); + rtp_write_rtcp_fir(instance, rtp, &remote_address); + return 0; + } else if (frame->frametype == AST_FRAME_RTCP) { + if (frame->subclass.integer == AST_RTP_RTCP_PSFB) { + rtp_write_rtcp_psfb(instance, rtp, frame, &remote_address); } return 0; } @@ -5185,7 +5242,7 @@ static const char *rtcp_payload_type2str(unsigned int pt) #define RTCP_SR_BLOCK_WORD_LENGTH 5 #define RTCP_RR_BLOCK_WORD_LENGTH 6 #define RTCP_HEADER_SSRC_LENGTH 2 -#define RTCP_FB_REMB_BLOCK_WORD_LENGTH 5 +#define RTCP_FB_REMB_BLOCK_WORD_LENGTH 4 static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr) { @@ -5525,10 +5582,11 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c f = &transport_rtp->f; break; case RTCP_PT_FUR: - /* Handle RTCP FUR as FIR by setting the format to 4 */ + /* Handle RTCP FUR as FIR by setting the format to 4 */ rc = AST_RTP_RTCP_FMT_FIR; case RTCP_PT_PSFB: switch (rc) { + case AST_RTP_RTCP_FMT_PLI: case AST_RTP_RTCP_FMT_FIR: if (rtcp_debug_test_addr(addr)) { ast_verbose("Received an RTCP Fast Update Request\n"); |