mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-04 09:44:26 +00:00
FS-10088: [freeswitch-core] Backports #resolve
This commit is contained in:
parent
70f4c41184
commit
fa33b30267
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
@ -22,7 +22,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
*
|
||||
@ -30,10 +30,10 @@
|
||||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||
*
|
||||
*/
|
||||
/**
|
||||
/**
|
||||
* @file switch_rtp.h
|
||||
* @brief RTP
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SWITCH_RTP_H
|
||||
@ -162,7 +162,7 @@ typedef enum { /* FMT Values for PSFB Payload Types http://www.iana.org/assignme
|
||||
_RTCP_PSFB_TSTR = 5, /* TSTR: Temporal-Spatial Trade-off Request RFC5104 */
|
||||
_RTCP_PSFB_TSTN = 6, /* TSTN: Temporal-Spatial Trade-off Notification RFC5104 */
|
||||
_RTCP_PSFB_VBCM = 7, /* VBCM: Video Back Channel Message RFC5104 */
|
||||
_RTCP_PSFB_PSLEI = 8, /* PSLEI: Payload-Specific Third-Party Loss Early Indication RFC6642*/
|
||||
_RTCP_PSFB_PSLEI = 8, /* PSLEI: Payload-Specific Third-Party Loss Early Indication RFC6642*/
|
||||
_RTCP_PSFB_AFB = 15 /* AFB Application layer FB */
|
||||
} rtcp_psfb_t;
|
||||
|
||||
@ -180,7 +180,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_get_random(void *buf, uint32_t len);
|
||||
/*!
|
||||
/*!
|
||||
\brief Initilize the RTP System
|
||||
\param pool the memory pool to use for long term allocations
|
||||
\note Generally called by the core_init
|
||||
@ -205,7 +205,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_ssrc(switch_rtp_t *rtp_ses
|
||||
*/
|
||||
SWITCH_DECLARE(switch_port_t) switch_rtp_set_end_port(switch_port_t port);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Request a new port to be used for media
|
||||
\param ip the ip to request a port from
|
||||
\return the new port to use
|
||||
@ -216,7 +216,7 @@ SWITCH_DECLARE(void) switch_rtp_release_port(const char *ip, switch_port_t port)
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_change_interval(switch_rtp_t *rtp_session, uint32_t ms_per_packet, uint32_t samples_per_interval);
|
||||
/*!
|
||||
/*!
|
||||
\brief create a new RTP session handle
|
||||
\param new_rtp_session a poiter to aim at the new session
|
||||
\param payload the IANA payload number
|
||||
@ -260,7 +260,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
|
||||
switch_rtp_flag_t flags[], char *timer_name, const char **err, switch_memory_pool_t *pool);
|
||||
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Assign a remote address to the RTP session
|
||||
\param rtp_session an RTP session to assign the remote address to
|
||||
\param host the ip or fqhn of the remote address
|
||||
@ -279,7 +279,7 @@ SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session);
|
||||
SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Assign a local address to the RTP session
|
||||
\param rtp_session an RTP session to assign the local address to
|
||||
\param host the ip or fqhn of the local address
|
||||
@ -290,7 +290,7 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session);
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Kill the socket on an existing RTP session
|
||||
\param rtp_session an RTP session to kill the socket of
|
||||
*/
|
||||
@ -299,14 +299,14 @@ SWITCH_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session);
|
||||
SWITCH_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session);
|
||||
SWITCH_DECLARE(void) switch_rtp_flush(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Test if an RTP session is ready
|
||||
\param rtp_session an RTP session to test
|
||||
\return a true value if it's ready
|
||||
*/
|
||||
SWITCH_DECLARE(uint8_t) switch_rtp_ready(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Destroy an RTP session
|
||||
\param rtp_session an RTP session to destroy
|
||||
*/
|
||||
@ -314,15 +314,15 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_sync_stats(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Acvite ICE on an RTP session
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
|
||||
const char *password, const char *rpassword, ice_proto_t proto,
|
||||
switch_core_media_ice_type_t type, ice_t *ice_params);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Activate sending RTCP Sender Reports (SR's)
|
||||
\param send_rate interval in milliseconds to send at
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
@ -335,13 +335,13 @@ SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_se
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames, uint32_t max_frames);
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Acvite a jitter buffer on an RTP session
|
||||
\param rtp_session the rtp session
|
||||
\param queue_frames the number of frames to delay
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session,
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session,
|
||||
uint32_t queue_frames,
|
||||
uint32_t max_queue_frames,
|
||||
uint32_t samples_per_packet, uint32_t samples_per_second);
|
||||
@ -379,28 +379,28 @@ SWITCH_DECLARE(uint32_t) switch_rtp_test_flag(switch_rtp_t *rtp_session, switch_
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Retrieve the socket from an existing RTP session
|
||||
\param rtp_session the RTP session to retrieve the socket from
|
||||
\return the socket from the RTP session
|
||||
*/
|
||||
SWITCH_DECLARE(switch_socket_t *) switch_rtp_get_rtp_socket(switch_rtp_t *rtp_session);
|
||||
SWITCH_DECLARE(void) switch_rtp_ping(switch_rtp_t *rtp_session);
|
||||
/*!
|
||||
/*!
|
||||
\brief Get the default samples per interval for a given RTP session
|
||||
\param rtp_session the RTP session to get the samples per interval from
|
||||
\return the default samples per interval of the RTP session
|
||||
*/
|
||||
SWITCH_DECLARE(uint32_t) switch_rtp_get_default_samples_per_interval(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Set the default payload number for a given RTP session
|
||||
\param rtp_session the RTP session to set the payload number on
|
||||
\param payload the new default payload number
|
||||
\param payload the new default payload number
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_default_payload(switch_rtp_t *rtp_session, switch_payload_t payload);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Get the default payload number for a given RTP session
|
||||
\param rtp_session the RTP session to get the payload number from
|
||||
\return the default payload of the RTP session
|
||||
@ -408,15 +408,15 @@ SWITCH_DECLARE(void) switch_rtp_set_default_payload(switch_rtp_t *rtp_session, s
|
||||
SWITCH_DECLARE(uint32_t) switch_rtp_get_default_payload(switch_rtp_t *rtp_session);
|
||||
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Set a callback function to execute when an invalid RTP packet is encountered
|
||||
\param rtp_session the RTP session
|
||||
\param on_invalid the function to set
|
||||
\return
|
||||
\return
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_invalid_handler(switch_rtp_t *rtp_session, switch_rtp_invalid_handler_t on_invalid);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Read data from a given RTP session
|
||||
\param rtp_session the RTP session to read from
|
||||
\param data the data to read
|
||||
@ -429,7 +429,7 @@ SWITCH_DECLARE(void) switch_rtp_set_invalid_handler(switch_rtp_t *rtp_session, s
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void *data, uint32_t *datalen,
|
||||
switch_payload_t *payload_type, switch_frame_flag_t *flags, switch_io_flag_t io_flags);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Queue RFC2833 DTMF data into an RTP Session
|
||||
\param rtp_session the rtp session to use
|
||||
\param dtmf the dtmf digits to queue
|
||||
@ -437,7 +437,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_queue_rfc2833(switch_rtp_t *rtp_session, const switch_dtmf_t *dtmf);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Queue RFC2833 DTMF data into an RTP Session
|
||||
\param rtp_session the rtp session to use
|
||||
\param dtmf the dtmf digits to queue
|
||||
@ -460,7 +460,7 @@ SWITCH_DECLARE(switch_size_t) switch_rtp_has_dtmf(switch_rtp_t *rtp_session);
|
||||
*/
|
||||
SWITCH_DECLARE(switch_size_t) switch_rtp_dequeue_dtmf(switch_rtp_t *rtp_session, switch_dtmf_t *dtmf);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Read data from a given RTP session without copying
|
||||
\param rtp_session the RTP session to read from
|
||||
\param data a pointer to point directly to the RTP read buffer
|
||||
@ -474,7 +474,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi
|
||||
void **data, uint32_t *datalen, switch_payload_t *payload_type, switch_frame_flag_t *flags,
|
||||
switch_io_flag_t io_flags);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Read data from a given RTP session without copying
|
||||
\param rtp_session the RTP session to read from
|
||||
\param frame a frame to populate with information
|
||||
@ -484,7 +484,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags);
|
||||
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Read RTCP data from a given RTP session without copying
|
||||
\param rtp_session the RTP session to read from
|
||||
\param frame an RTCP frame to populate with information
|
||||
@ -512,7 +512,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_enable_vad(switch_rtp_t *rtp_session,
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_disable_vad(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Write data to a given RTP session
|
||||
\param rtp_session the RTP session to write to
|
||||
\param frame the frame to write
|
||||
@ -520,7 +520,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_disable_vad(switch_rtp_t *rtp_session
|
||||
*/
|
||||
SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_frame_t *frame);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Write data with a specified payload and sequence number to a given RTP session
|
||||
\param rtp_session the RTP session to write to
|
||||
\param data data to write
|
||||
@ -536,21 +536,21 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_write_raw(switch_rtp_t *rtp_session, void *data, switch_size_t *bytes, switch_bool_t process_encryption);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Retrieve the SSRC from a given RTP session
|
||||
\param rtp_session the RTP session to retrieve from
|
||||
\return the SSRC
|
||||
*/
|
||||
SWITCH_DECLARE(uint32_t) switch_rtp_get_ssrc(switch_rtp_t *rtp_session);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Associate an arbitrary data pointer with and RTP session
|
||||
\param rtp_session the RTP session to assign the pointer to
|
||||
\param private_data the private data to assign
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *private_data);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Set the payload type to consider RFC2833 DTMF
|
||||
\param rtp_session the RTP session to modify
|
||||
\param te the payload type
|
||||
@ -558,14 +558,14 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri
|
||||
SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te);
|
||||
SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Set the payload type for comfort noise
|
||||
\param rtp_session the RTP session to modify
|
||||
\param pt the payload type
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
\brief Retrieve the private data from a given RTP session
|
||||
\param rtp_session the RTP session to retrieve the data from
|
||||
\return the pointer to the private data
|
||||
|
@ -231,8 +231,8 @@ SWITCH_BEGIN_EXTERN_C
|
||||
#define SWITCH_MAX_TRANS 2000
|
||||
#define SWITCH_CORE_SESSION_MAX_PRIVATES 2
|
||||
#define SWITCH_DEFAULT_VIDEO_SIZE 1200
|
||||
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "5000"
|
||||
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "2000"
|
||||
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "1000"
|
||||
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "1000"
|
||||
|
||||
#define MAX_FMTP_LEN 256
|
||||
|
||||
@ -773,6 +773,7 @@ typedef enum {
|
||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
||||
SWITCH_RTP_FLAG_GEN_TS_MANUAL,
|
||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||
SWITCH_RTP_FLAG_OLD_FIR,
|
||||
SWITCH_RTP_FLAG_INVALID
|
||||
} switch_rtp_flag_t;
|
||||
|
||||
|
@ -3554,6 +3554,8 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
||||
|
||||
if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) {
|
||||
char tmp[80] = "";
|
||||
const char *media_varname = NULL, *port_varname = NULL;
|
||||
|
||||
engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
||||
"setting remote %s ice addr to index %d %s:%d based on candidate\n", type2str(type), engine->ice_in.chosen[0],
|
||||
@ -3570,12 +3572,23 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
||||
smh->mparams->remote_ip = engine->cur_payload_map->remote_sdp_ip;
|
||||
}
|
||||
|
||||
if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||
media_varname = "remote_video_rtp_ip";
|
||||
port_varname = "remote_video_rtp_port";
|
||||
} else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||
media_varname = "remote_audio_rtp_ip";
|
||||
port_varname = "remote_audio_rtp_port";
|
||||
}
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port);
|
||||
switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
||||
switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
||||
switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr);
|
||||
switch_channel_set_variable(smh->session->channel, port_varname, tmp);
|
||||
}
|
||||
|
||||
if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port) {
|
||||
char tmp[80] = "";
|
||||
const char *media_varname = NULL, *port_varname = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
|
||||
"Setting remote rtcp %s addr to %s:%d based on candidate\n", type2str(type),
|
||||
engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
|
||||
@ -3583,6 +3596,20 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
||||
engine->remote_rtcp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
|
||||
|
||||
engine->remote_rtcp_port = engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port;
|
||||
|
||||
|
||||
if (engine->type == SWITCH_MEDIA_TYPE_VIDEO) {
|
||||
media_varname = "remote_video_rtcp_ip";
|
||||
port_varname = "remote_video_rtcp_port";
|
||||
} else if (engine->type == SWITCH_MEDIA_TYPE_AUDIO) {
|
||||
media_varname = "remote_audio_rtcp_ip";
|
||||
port_varname = "remote_audio_rtcp_port";
|
||||
}
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port);
|
||||
switch_channel_set_variable(smh->session->channel, media_varname, engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr);
|
||||
switch_channel_set_variable(smh->session->channel, port_varname, tmp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -5093,7 +5120,33 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
done:
|
||||
|
||||
t38_done:
|
||||
|
||||
|
||||
if (v_engine->rtp_session) {
|
||||
if (v_engine->fir) {
|
||||
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
|
||||
} else {
|
||||
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR);
|
||||
}
|
||||
|
||||
if (v_engine->pli) {
|
||||
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
|
||||
} else {
|
||||
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI);
|
||||
}
|
||||
|
||||
if (v_engine->nack) {
|
||||
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
|
||||
} else {
|
||||
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_NACK);
|
||||
}
|
||||
|
||||
if (v_engine->tmmbr) {
|
||||
switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
|
||||
} else {
|
||||
switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_TMMBR);
|
||||
}
|
||||
}
|
||||
|
||||
if (parser) {
|
||||
sdp_parser_free(parser);
|
||||
}
|
||||
@ -7250,7 +7303,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
if (v_engine->tmmbr) {
|
||||
flags[SWITCH_RTP_FLAG_TMMBR]++;
|
||||
}
|
||||
|
||||
|
||||
v_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip,
|
||||
v_engine->local_sdp_port,
|
||||
v_engine->cur_payload_map->remote_sdp_ip,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
@ -22,7 +22,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* switch_jitterbuffer.c -- Audio/Video Jitter Buffer
|
||||
@ -101,6 +101,8 @@ struct switch_jb_s {
|
||||
switch_jb_type_t type;
|
||||
switch_core_session_t *session;
|
||||
switch_channel_t *channel;
|
||||
uint32_t buffer_lag;
|
||||
uint32_t flush;
|
||||
};
|
||||
|
||||
|
||||
@ -108,7 +110,7 @@ static int node_cmp(const void *l, const void *r)
|
||||
{
|
||||
switch_jb_node_t *a = (switch_jb_node_t *) l;
|
||||
switch_jb_node_t *b = (switch_jb_node_t *) r;
|
||||
|
||||
|
||||
if (!a->visible) return 0;
|
||||
if (!b->visible) return 1;
|
||||
|
||||
@ -175,7 +177,7 @@ switch_jb_node_t *sort_nodes(switch_jb_node_t *list, int (*cmp)(const void *, co
|
||||
|
||||
/* Maintain reverse pointers in a doubly linked list. */
|
||||
e->prev = tail;
|
||||
|
||||
|
||||
tail = e;
|
||||
}
|
||||
|
||||
@ -208,15 +210,15 @@ static inline switch_jb_node_t *new_node(switch_jb_t *jb)
|
||||
}
|
||||
|
||||
if (!np) {
|
||||
|
||||
|
||||
np = switch_core_alloc(jb->pool, sizeof(*np));
|
||||
|
||||
|
||||
np->next = jb->node_list;
|
||||
if (np->next) {
|
||||
np->next->prev = np;
|
||||
}
|
||||
jb->node_list = np;
|
||||
|
||||
|
||||
}
|
||||
|
||||
switch_assert(np);
|
||||
@ -237,7 +239,7 @@ static inline void push_to_top(switch_jb_t *jb, switch_jb_node_t *node)
|
||||
} else if (node->prev) {
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
|
||||
|
||||
if (node->next) {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
@ -318,14 +320,14 @@ static inline void drop_ts(switch_jb_t *jb, uint32_t ts)
|
||||
}
|
||||
|
||||
switch_mutex_unlock(jb->list_mutex);
|
||||
|
||||
|
||||
if (x) jb->complete_frames--;
|
||||
}
|
||||
|
||||
static inline switch_jb_node_t *jb_find_lowest_seq(switch_jb_t *jb, uint32_t ts)
|
||||
{
|
||||
switch_jb_node_t *np, *lowest = NULL;
|
||||
|
||||
|
||||
switch_mutex_lock(jb->list_mutex);
|
||||
for (np = jb->node_list; np; np = np->next) {
|
||||
if (!np->visible) continue;
|
||||
@ -390,7 +392,7 @@ static inline void thin_frames(switch_jb_t *jb, int freq, int max)
|
||||
}
|
||||
|
||||
sort_free_nodes(jb);
|
||||
switch_mutex_unlock(jb->list_mutex);
|
||||
switch_mutex_unlock(jb->list_mutex);
|
||||
}
|
||||
|
||||
|
||||
@ -449,7 +451,7 @@ static inline void jb_hit(switch_jb_t *jb)
|
||||
static void jb_frame_inc_line(switch_jb_t *jb, int i, int line)
|
||||
{
|
||||
uint32_t old_frame_len = jb->frame_len;
|
||||
|
||||
|
||||
if (i == 0) {
|
||||
jb->frame_len = jb->min_frame_len;
|
||||
goto end;
|
||||
@ -509,15 +511,15 @@ static inline int verify_oldest_frame(switch_jb_t *jb)
|
||||
if (!lowest || !(lowest = jb_find_lowest_seq(jb, lowest->packet.header.ts))) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_lock(jb->mutex);
|
||||
|
||||
jb->node_list = sort_nodes(jb->node_list, node_cmp);
|
||||
|
||||
for (np = lowest->next; np; np = np->next) {
|
||||
|
||||
|
||||
if (!np->visible) continue;
|
||||
|
||||
|
||||
if (ntohs(np->packet.header.seq) != ntohs(np->prev->packet.header.seq) + 1) {
|
||||
uint32_t val = (uint32_t)htons(ntohs(np->prev->packet.header.seq) + 1);
|
||||
|
||||
@ -526,12 +528,12 @@ static inline int verify_oldest_frame(switch_jb_t *jb)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (np->packet.header.ts != lowest->packet.header.ts || !np->next) {
|
||||
r = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_unlock(jb->mutex);
|
||||
|
||||
end:
|
||||
@ -560,7 +562,7 @@ static inline void drop_newest_frame(switch_jb_t *jb)
|
||||
static inline void drop_second_newest_frame(switch_jb_t *jb)
|
||||
{
|
||||
switch_jb_node_t *second_newest = jb_find_penultimate_node(jb);
|
||||
|
||||
|
||||
if (second_newest) {
|
||||
drop_ts(jb, second_newest->packet.header.ts);
|
||||
jb_debug(jb, 1, "Dropping second highest frame ts:%u\n", ntohl(second_newest->packet.header.ts));
|
||||
@ -582,7 +584,7 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
||||
switch_core_inthash_insert(jb->node_hash_ts, node->packet.header.ts, node);
|
||||
}
|
||||
|
||||
jb_debug(jb, (packet->header.m ? 1 : 2), "PUT packet last_ts:%u ts:%u seq:%u%s\n",
|
||||
jb_debug(jb, (packet->header.m ? 1 : 2), "PUT packet last_ts:%u ts:%u seq:%u%s\n",
|
||||
ntohl(jb->highest_wrote_ts), ntohl(node->packet.header.ts), ntohs(node->packet.header.seq), packet->header.m ? " <MARK>" : "");
|
||||
|
||||
if (jb->write_init && jb->type == SJB_VIDEO) {
|
||||
@ -593,20 +595,20 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
||||
} else {
|
||||
seq_diff = abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq)));
|
||||
}
|
||||
|
||||
|
||||
if (ntohl(jb->highest_wrote_ts) > (UINT_MAX - 1000) && ntohl(node->packet.header.ts) < 1000) {
|
||||
ts_diff = (UINT_MAX - ntohl(node->packet.header.ts)) + ntohl(node->packet.header.ts);
|
||||
} else {
|
||||
ts_diff = abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts)));
|
||||
}
|
||||
|
||||
if (((seq_diff >= jb->max_frame_len) || (ts_diff > (900000 * 5)))) {
|
||||
|
||||
if (((seq_diff >= 100) || (ts_diff > (900000 * 5)))) {
|
||||
jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))));
|
||||
switch_jb_reset(jb);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jb->write_init || ntohs(packet->header.seq) > ntohs(jb->highest_wrote_seq) ||
|
||||
|
||||
if (!jb->write_init || ntohs(packet->header.seq) > ntohs(jb->highest_wrote_seq) ||
|
||||
(ntohs(jb->highest_wrote_seq) > USHRT_MAX - 100 && ntohs(packet->header.seq) < 100) ) {
|
||||
jb->highest_wrote_seq = packet->header.seq;
|
||||
}
|
||||
@ -622,14 +624,14 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch
|
||||
jb->highest_wrote_ts = packet->header.ts;
|
||||
}
|
||||
} else {
|
||||
if (jb->write_init) {
|
||||
if (jb->write_init || jb->type == SJB_AUDIO) {
|
||||
jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
jb->complete_frames++;
|
||||
} else {
|
||||
jb->highest_wrote_ts = packet->header.ts;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!jb->write_init) jb->write_init = 1;
|
||||
}
|
||||
|
||||
@ -677,7 +679,7 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
jb->dropped = 0;
|
||||
jb_debug(jb, 2, "%s", "DROPPED FRAME DETECTED RESYNCING\n");
|
||||
jb->target_seq = 0;
|
||||
|
||||
|
||||
if (jb->session) {
|
||||
switch_core_session_request_video_refresh(jb->session);
|
||||
}
|
||||
@ -711,7 +713,7 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
//if (jb->session) {
|
||||
// switch_core_session_request_video_refresh(jb->session);
|
||||
//}
|
||||
|
||||
|
||||
for (x = 0; x < 10; x++) {
|
||||
increment_seq(jb);
|
||||
if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) {
|
||||
@ -735,14 +737,14 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
}
|
||||
|
||||
*nodep = node;
|
||||
|
||||
|
||||
if (node) {
|
||||
set_read_seq(jb, node->packet.header.seq);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_NOTFOUND;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -767,7 +769,7 @@ static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_no
|
||||
}
|
||||
|
||||
*nodep = node;
|
||||
|
||||
|
||||
if (node) {
|
||||
set_read_ts(jb, node->packet.header.ts);
|
||||
node->packet.header.seq = htons(jb->psuedo_seq);
|
||||
@ -775,7 +777,7 @@ static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_no
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_NOTFOUND;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static inline switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep)
|
||||
@ -830,7 +832,7 @@ SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag
|
||||
|
||||
SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb)
|
||||
{
|
||||
return (jb->complete_frames >= jb->frame_len);
|
||||
return (jb->complete_frames >= jb->frame_len) || jb->flush;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb)
|
||||
@ -894,7 +896,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t t
|
||||
uint16_t want_seq = seq + peek;
|
||||
node = switch_core_inthash_find(jb->node_hash, htons(want_seq));
|
||||
} else if (ts && jb->samples_per_frame) {
|
||||
uint32_t want_ts = ts + (peek * jb->samples_per_frame);
|
||||
uint32_t want_ts = ts + (peek * jb->samples_per_frame);
|
||||
node = switch_core_inthash_find(jb->node_hash_ts, htonl(want_ts));
|
||||
}
|
||||
|
||||
@ -913,7 +915,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t t
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_jb_get_frames(switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len)
|
||||
SWITCH_DECLARE(switch_status_t) switch_jb_get_frames(switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len)
|
||||
{
|
||||
|
||||
switch_mutex_lock(jb->mutex);
|
||||
@ -953,7 +955,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_set_frames(switch_jb_t *jb, uint32_t m
|
||||
if (jb->frame_len < jb->min_frame_len) {
|
||||
jb->frame_len = jb->min_frame_len;
|
||||
}
|
||||
|
||||
|
||||
if (jb->frame_len > jb->highest_frame_len) {
|
||||
jb->highest_frame_len = jb->frame_len;
|
||||
}
|
||||
@ -1002,7 +1004,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_destroy(switch_jb_t **jbp)
|
||||
{
|
||||
switch_jb_t *jb = *jbp;
|
||||
*jbp = NULL;
|
||||
|
||||
|
||||
if (jb->type == SJB_VIDEO) {
|
||||
switch_core_inthash_destroy(&jb->missing_seq_hash);
|
||||
}
|
||||
@ -1043,7 +1045,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
uint16_t seq;
|
||||
//const char *token;
|
||||
switch_time_t then = 0;
|
||||
|
||||
|
||||
switch_core_hash_this(hi, &var, NULL, &val);
|
||||
//token = (const char *) val;
|
||||
|
||||
@ -1052,7 +1054,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
//printf("WTf\n");
|
||||
// continue;
|
||||
//}
|
||||
|
||||
|
||||
seq = ntohs(*((uint16_t *) var));
|
||||
then = (intptr_t) val;
|
||||
|
||||
@ -1060,7 +1062,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
//jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//if (then != 1) {
|
||||
// jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then);
|
||||
//}
|
||||
@ -1096,7 +1098,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
|
||||
//jb_frame_inc(jb, 1);
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_unlock(jb->mutex);
|
||||
|
||||
|
||||
@ -1144,7 +1146,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
||||
}
|
||||
|
||||
jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1);
|
||||
|
||||
|
||||
for (i = want; i < got; i++) {
|
||||
jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts));
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *)(intptr_t)1);
|
||||
@ -1162,7 +1164,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
||||
if (switch_test_flag(jb, SJB_QUEUE_ONLY) && jb->complete_frames > jb->max_frame_len) {
|
||||
drop_oldest_frame(jb);
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_unlock(jb->mutex);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@ -1203,12 +1205,18 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
switch_mutex_lock(jb->mutex);
|
||||
|
||||
if (jb->complete_frames == 0) {
|
||||
jb->flush = 0;
|
||||
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
||||
}
|
||||
|
||||
if (jb->complete_frames < jb->frame_len) {
|
||||
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
||||
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
||||
|
||||
switch_jb_poll(jb);
|
||||
|
||||
if (!jb->flush) {
|
||||
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
||||
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
||||
}
|
||||
}
|
||||
|
||||
jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
@ -1229,7 +1237,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
if (jb->type == SJB_VIDEO && jb->channel && jb->video_low_bitrate) {
|
||||
//switch_time_t now = switch_time_now();
|
||||
//int ok = (now - jb->last_bitrate_change) > 10000;
|
||||
|
||||
|
||||
if (switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len == jb->min_frame_len) {
|
||||
jb_debug(jb, 2, "%s", "Allow BITRATE changes\n");
|
||||
switch_channel_clear_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE);
|
||||
@ -1241,11 +1249,11 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
switch_core_session_message_t msg = { 0 };
|
||||
|
||||
jb->bitrate_control = jb->video_low_bitrate;
|
||||
|
||||
|
||||
msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
|
||||
msg.numeric_arg = jb->bitrate_control * 1024;
|
||||
msg.from = __FILE__;
|
||||
|
||||
|
||||
jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control);
|
||||
switch_core_session_receive_message(jb->session, &msg);
|
||||
switch_channel_set_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE);
|
||||
@ -1254,9 +1262,9 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
|
||||
|
||||
if (jb->period_miss_pct > 60.0f) {
|
||||
@ -1267,19 +1275,20 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
|
||||
jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
|
||||
|
||||
if (!jb->read_init || ntohs(node->packet.header.seq) > ntohs(jb->highest_read_seq) ||
|
||||
if (!jb->read_init || ntohs(node->packet.header.seq) > ntohs(jb->highest_read_seq) ||
|
||||
(ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) {
|
||||
jb->highest_read_seq = node->packet.header.seq;
|
||||
}
|
||||
|
||||
if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) {
|
||||
|
||||
if (jb->type == SJB_AUDIO ||
|
||||
(jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts)))) {
|
||||
jb->complete_frames--;
|
||||
jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
jb->highest_read_ts = node->packet.header.ts;
|
||||
} else if (!jb->read_init) {
|
||||
jb->highest_read_ts = node->packet.header.ts;
|
||||
}
|
||||
|
||||
|
||||
if (!jb->read_init) jb->read_init = 1;
|
||||
} else {
|
||||
if (jb->type == SJB_VIDEO) {
|
||||
@ -1301,7 +1310,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
switch_jb_reset(jb);
|
||||
switch_goto_status(SWITCH_STATUS_RESTART, end);
|
||||
case SWITCH_STATUS_NOTFOUND:
|
||||
default:
|
||||
default:
|
||||
if (jb->consec_miss_count > jb->frame_len) {
|
||||
switch_jb_reset(jb);
|
||||
jb_frame_inc(jb, 1);
|
||||
@ -1315,10 +1324,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (node) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
|
||||
*packet = node->packet;
|
||||
*len = node->len;
|
||||
jb->last_len = *len;
|
||||
@ -1343,13 +1352,13 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
} else {
|
||||
seq = jb->last_target_seq;
|
||||
}
|
||||
|
||||
|
||||
packet->header.seq = seq;
|
||||
packet->header.ts = ts;
|
||||
}
|
||||
|
||||
switch_mutex_unlock(jb->mutex);
|
||||
|
||||
|
||||
if (jb->complete_frames > jb->max_frame_len) {
|
||||
thin_frames(jb, 8, 25);
|
||||
}
|
||||
|
1265
src/switch_rtp.c
1265
src/switch_rtp.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user