struct switch_jb_node_s *node_list;
uint32_t last_target_seq;
uint32_t highest_read_ts;
+ uint32_t highest_dropped_ts;
uint32_t highest_read_seq;
uint32_t highest_wrote_ts;
- uint32_t highest_wrote_seq;
+ uint16_t highest_wrote_seq;
uint16_t target_seq;
uint32_t target_ts;
uint32_t last_target_ts;
switch_channel_t *channel;
uint32_t buffer_lag;
uint32_t flush;
+ uint32_t packet_count;
+ uint32_t max_packet_len;
};
}
if (!np) {
+ int mult = 25;
+
+ if (jb->type != SJB_VIDEO) {
+ mult = 2;
+ } else {
+ if (jb->max_packet_len > mult) {
+ mult = jb->max_packet_len;
+ }
+ }
+
+ if (jb->allocated_nodes > jb->max_frame_len * mult) {
+ jb_debug(jb, 2, "ALLOCATED FRAMES TOO HIGH! %d\n", jb->allocated_nodes);
+ switch_jb_reset(jb);
+ switch_mutex_unlock(jb->list_mutex);
+ return NULL;
+ }
np = switch_core_alloc(jb->pool, sizeof(*np));
jb->allocated_nodes++;
}
if (switch_core_inthash_delete(jb->node_hash, node->packet.header.seq)) {
- if (node->packet.header.m && jb->type == SJB_VIDEO) {
+ if (node->packet.header.version == 1 && jb->type == SJB_VIDEO) {
jb->complete_frames--;
}
}
}
#endif
+static inline int check_seq(uint16_t a, uint16_t b)
+{
+ a = ntohs(a);
+ b = ntohs(b);
+
+ if (a >= b || (b > a && b > USHRT_MAX / 2 && a < USHRT_MAX / 2)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int check_ts(uint32_t a, uint32_t b)
+{
+ a = ntohl(a);
+ b = ntohl(b);
+
+ if (a > b || (b > a && b > UINT_MAX / 2 && a < UINT_MAX / 2)) {
+ return 1;
+ }
+
+ return 0;
+}
+
static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
{
switch_jb_node_t *node = new_node(jb);
+ if (!node) {
+ return;
+ }
+
+
node->packet = *packet;
node->len = len;
memcpy(node->packet.body, packet->body, len);
switch_core_inthash_insert(jb->node_hash, node->packet.header.seq, node);
- if (packet->header.m && jb->type == SJB_VIDEO) {
- jb->complete_frames++;
- }
-
if (jb->node_hash_ts) {
switch_core_inthash_insert(jb->node_hash_ts, node->packet.header.ts, node);
}
}
if (jb->type == SJB_VIDEO) {
- if (jb->write_init && ((htons(packet->header.seq) >= htons(jb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_wrote_ts))) ||
- (ntohl(jb->highest_wrote_ts) > (UINT_MAX - 1000) && ntohl(node->packet.header.ts) < 1000))) {
+ if (!switch_test_flag(jb, SJB_QUEUE_ONLY)) {
+ jb->packet_count++;
+ }
+
+ if (jb->write_init && check_seq(packet->header.seq, jb->highest_wrote_seq) && check_ts(node->packet.header.ts, jb->highest_wrote_ts)) {
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->highest_wrote_ts = packet->header.ts;
- //verify_oldest_frame(jb);
+ jb->complete_frames++;
+
+ if (!switch_test_flag(jb, SJB_QUEUE_ONLY)) {
+ if (jb->packet_count > jb->max_packet_len) {
+ jb->max_packet_len = jb->packet_count;
+ }
+
+ jb->packet_count = 0;
+ }
+ node->packet.header.version = 1;
} else if (!jb->write_init) {
jb->highest_wrote_ts = packet->header.ts;
}
jb_frame_inc(jb, 1);
}
- //if (jb->session) {
- // switch_core_session_request_video_refresh(jb->session);
- //}
+ if (jb->session) {
+ switch_core_session_request_video_refresh(jb->session);
+ }
for (x = 0; x < 10; x++) {
increment_seq(jb);
jb_debug(jb, 2, "%s", "SAME FRAME DROPPING\n");
jb->dropped++;
drop_ts(jb, node->packet.header.ts);
+ jb->highest_dropped_ts = ntohl(node->packet.header.ts);
node = NULL;
goto top;
}
jb_debug(jb, 2, "MISSING incremental seq: %u\n", ntohs(jb->target_seq));
}
}
+
} else {
increment_seq(jb);
}
jb->session = session;
jb->channel = switch_core_session_get_channel(session);
- if (jb->type == SJB_VIDEO && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
+ if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) &&
+ (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) {
int tmp = atoi(var);
- if (tmp > 128 && tmp < 10240) {
+ if (tmp >= 128 && tmp <= 10240) {
jb->video_low_bitrate = (uint32_t)tmp;
}
}
switch_mutex_lock(jb->mutex);
+ if (jb->highest_dropped_ts) {
+ if (ntohl(packet->header.ts) < jb->highest_dropped_ts) {
+ jb_debug(jb, 2, "%s", "TS ALREADY DROPPED, DROPPING PACKET\n");
+ switch_mutex_unlock(jb->mutex);
+ return SWITCH_STATUS_SUCCESS;
+ }
+ jb->highest_dropped_ts = 0;
+ }
+
+
if (!want) want = got;
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) {
*packet = node->packet;
*len = node->len;
memcpy(packet->body, node->packet.body, node->len);
+ packet->header.version = 2;
status = SWITCH_STATUS_SUCCESS;
} else {
jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq));
return jb->last_len;
}
-
SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
{
switch_jb_node_t *node = NULL;
if (jb->session) {
switch_core_session_request_video_refresh(jb->session);
}
- } else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->min_frame_len * 2) {
+ } else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->max_frame_len / 2) {
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);
if (jb->session) {
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) ||
- (ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) {
+ if (!jb->read_init || check_seq(node->packet.header.seq, jb->highest_read_seq)) {
jb->highest_read_seq = node->packet.header.seq;
}
- 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)))) {
+ if (jb->type != SJB_VIDEO ||
+ (jb->read_init && check_seq(node->packet.header.seq, jb->highest_read_seq) && check_ts(node->packet.header.ts, jb->highest_read_ts))) {
- if (jb->type == SJB_AUDIO) {
+ if (jb->type != SJB_VIDEO) {
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);
*len = node->len;
jb->last_len = *len;
memcpy(packet->body, node->packet.body, node->len);
+ packet->header.version = 2;
hide_node(node, SWITCH_TRUE);
jb_debug(jb, 1, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
uint32_t last_frame;
uint32_t ts;
uint32_t delta;
- uint32_t delta_ct;
uint32_t delta_ttl;
+ int last_external;
} ts_normalize_t;
struct switch_rtp {
switch_byte_t rtcp_auto_adj_used;
uint8_t pause_jb;
uint16_t last_seq;
+ uint16_t last_write_seq;
switch_time_t last_read_time;
switch_size_t last_flush_packet_count;
uint32_t interdigit_delay;
static void do_2833(switch_rtp_t *rtp_session);
-#define rtp_type(rtp_session) (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio")
+#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio"
static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, const char *host, switch_port_t port)
(rtp_session->stats.inbound.last_processed_seq + 1), lost);
rtp_session->stats.inbound.last_loss++;
+ if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
+ switch_core_session_request_video_refresh(rtp_session->session);
+ }
+
if (rtp_session->stats.inbound.last_loss > 0 && rtp_session->stats.inbound.last_loss < LOST_BURST_CAPTURE) {
rtp_session->stats.inbound.loss[rtp_session->stats.inbound.last_loss] += lost;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
{
+ int new_val;
- if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
- return SWITCH_STATUS_FALSE;
- }
+ if (rtp_session->pause_jb && !pause) {
+ if (rtp_session->jb) {
+ switch_jb_reset(rtp_session->jb);
+ }
- if (!!pause == !!rtp_session->pause_jb) {
- return SWITCH_STATUS_FALSE;
+ if (rtp_session->vb) {
+ switch_jb_reset(rtp_session->vb);
+ }
}
- if (rtp_session->pause_jb && !pause) {
- switch_jb_reset(rtp_session->jb);
- }
+ new_val = pause ? 1 : -1;
- rtp_session->pause_jb = pause ? 1 : 0;
+ if (rtp_session->pause_jb + new_val > -1) {
+ rtp_session->pause_jb += new_val;
+ }
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1,
+ "Jitterbuffer %s is %s\n", rtp_type(rtp_session), rtp_session->pause_jb ? "paused" : "enabled");
+
return SWITCH_STATUS_SUCCESS;
}
for(i = 0; i < SWITCH_RTP_FLAG_INVALID; i++) {
if (flags[i]) {
- rtp_session->flags[i] = flags[i];
-
- if (i == SWITCH_RTP_FLAG_AUTOADJ) {
- rtp_session->autoadj_window = 20;
- rtp_session->autoadj_threshold = 10;
- rtp_session->autoadj_tally = 0;
- if (rtp_session->session) {
- switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
- const char *x = switch_channel_get_variable(channel, "rtp_auto_adjust_threshold");
- if (x && *x) {
- int xn = atoi(x);
- if (xn > 0 && xn <= 65535) {
- rtp_session->autoadj_window = xn*2;
- rtp_session->autoadj_threshold = xn;
- }
- }
- }
-
-
- rtp_session->flags[SWITCH_RTP_FLAG_RTCP_AUTOADJ] = 1;
-
-
- rtp_session->rtcp_autoadj_window = 20;
- rtp_session->rtcp_autoadj_threshold = 1;
- rtp_session->rtcp_autoadj_tally = 0;
-
-
- rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
- } else if (i == SWITCH_RTP_FLAG_NOBLOCK && rtp_session->sock_input) {
- switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE);
- }
+ switch_rtp_set_flag(rtp_session, i);
}
}
}
for(i = 0; i < SWITCH_RTP_FLAG_INVALID; i++) {
if (flags[i]) {
- rtp_session->flags[i] = 0;
+ switch_rtp_clear_flag(rtp_session, i);
}
}
}
SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
{
+ int old_flag = rtp_session->flags[flag];
switch_mutex_lock(rtp_session->flag_mutex);
rtp_session->flags[flag] = 1;
switch_mutex_unlock(rtp_session->flag_mutex);
- if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
+ if (flag == SWITCH_RTP_FLAG_PASSTHRU) {
+ if (!old_flag) {
+ switch_rtp_pause_jitter_buffer(rtp_session, SWITCH_TRUE);
+ }
+ } else if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
rtp_session->stats.inbound.last_processed_seq = 0;
} else if (flag == SWITCH_RTP_FLAG_FLUSH) {
reset_jitter_seq(rtp_session);
SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag)
{
+ int old_flag = rtp_session->flags[flag];
switch_mutex_lock(rtp_session->flag_mutex);
rtp_session->flags[flag] = 0;
switch_mutex_unlock(rtp_session->flag_mutex);
- if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
+ if (flag == SWITCH_RTP_FLAG_PASSTHRU) {
+ if (old_flag) {
+ switch_rtp_pause_jitter_buffer(rtp_session, SWITCH_FALSE);
+ }
+ } else if (flag == SWITCH_RTP_FLAG_DTMF_ON) {
rtp_session->stats.inbound.last_processed_seq = 0;
} else if (flag == SWITCH_RTP_FLAG_PAUSE) {
reset_jitter_seq(rtp_session);
return SWITCH_STATUS_SUCCESS;
}
- if (rtp_session->vb && jb_valid(rtp_session)) {
+ if (rtp_session->vb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
status = switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes);
if (status == SWITCH_STATUS_TOO_LATE) {
}
}
- if (rtp_session->vb && jb_valid(rtp_session)) {
+ if (rtp_session->vb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes);
status = vstatus;
pt = 100000;
}
- if (rtp_session->vb) {
+ if (rtp_session->vb && !rtp_session->pause_jb) {
if (switch_jb_poll(rtp_session->vb)) {
pt = 1000;
}
}
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
- got_jb = (rtp_session->vb && switch_jb_poll(rtp_session->vb));
+ got_jb = (rtp_session->vb && !rtp_session->pause_jb && switch_jb_poll(rtp_session->vb));
} else {
got_jb = SWITCH_TRUE;
}
process_rtcp_packet(rtp_session, &rtcp_bytes);
ret = 1;
- if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) {
+ if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
switch_core_timer_sync(&rtp_session->timer);
reset_jitter_seq(rtp_session);
}
frame->source = __FILE__;
switch_set_flag(frame, SFF_RAW_RTP);
+ switch_set_flag(frame, SFF_EXTERNAL);
if (frame->payload == rtp_session->recv_te) {
switch_set_flag(frame, SFF_RFC2833);
}
}
}
-
- if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA) || switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+ if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) {
+ int external = (*flags & SFF_EXTERNAL);
/* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base
so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough*
*/
if (!rtp_session->ts_norm.ts) {
- if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
- rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1;
- } else {
- switch_core_timer_sync(&rtp_session->timer);
- rtp_session->ts_norm.ts = rtp_session->timer.samplecount;
- }
+ rtp_session->ts_norm.ts = (uint32_t) rand() % 1000000 + 1;
}
- if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc) {
- if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
- if (rtp_session->ts_norm.last_ssrc) {
- rtp_session->ts_norm.delta_ct = 1;
- rtp_session->ts_norm.delta_ttl = 0;
- if (rtp_session->ts_norm.delta) {
- rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
- }
- }
+ if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc || rtp_session->ts_norm.last_external != external) {
+ switch_core_session_t *other_session;
+
+ switch_core_session_request_video_refresh(rtp_session->session);
+ switch_core_media_gen_key_frame(rtp_session->session);
+
+ if (switch_core_session_get_partner(rtp_session->session, &other_session) == SWITCH_STATUS_SUCCESS) {
+ switch_core_session_request_video_refresh(other_session);
+ switch_core_media_gen_key_frame(other_session);
+ switch_core_session_rwunlock(other_session);
+ }
+
+ if (rtp_session->ts_norm.last_ssrc) {
+ rtp_session->ts_norm.delta_ttl = 0;
+ rtp_session->ts_norm.ts++;
}
rtp_session->ts_norm.last_ssrc = send_msg->header.ssrc;
rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts);
}
+ rtp_session->ts_norm.last_external = external;
if (ntohl(send_msg->header.ts) != rtp_session->ts_norm.last_frame) {
- int32_t delta = (int32_t) (ntohl(send_msg->header.ts) - rtp_session->ts_norm.last_frame);
+ int32_t delta;
+ int64_t x, y;
- if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && delta > 0 && delta < 90000) {
- rtp_session->ts_norm.delta = delta;
+ x = rtp_session->ts_norm.last_frame;
+ y = ntohl(send_msg->header.ts);
+
+ if (x > UINT32_MAX / 2 && y < UINT32_MAX / 2) {
+ x -= (int64_t)UINT32_MAX+1;
}
+
+ delta = (int32_t)y-x;
- if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) {
- rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
+ if (delta < 0 || delta > 90000) {
+ switch_core_media_gen_key_frame(rtp_session->session);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1,
+ "Timestamp shift detected last: %d this: %d delta: %d stick with prev delta: %d\n",
+ rtp_session->ts_norm.last_frame, ntohl(send_msg->header.ts), delta, rtp_session->ts_norm.delta);
} else {
- switch_core_timer_sync(&rtp_session->timer);
- if (rtp_session->ts_norm.ts == rtp_session->timer.samplecount) {
- rtp_session->ts_norm.ts = rtp_session->timer.samplecount + 1;
- } else {
- rtp_session->ts_norm.ts = rtp_session->timer.samplecount;
- }
- if (send_msg->header.m) {
- rtp_session->ts_norm.last_frame++;
- }
+ rtp_session->ts_norm.delta = delta;
}
- }
+ rtp_session->ts_norm.ts += rtp_session->ts_norm.delta;
+
+ }
+
rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts);
send_msg->header.ts = htonl(rtp_session->ts_norm.ts);
}
}
if (send) {
- send_msg->header.seq = htons(++rtp_session->seq);
+ int delta = 1;
+
+ if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && (*flags & SFF_EXTERNAL) && rtp_session->stats.outbound.packet_count && rtp_session->flags[SWITCH_RTP_FLAG_PASSTHRU]) {
+ int32_t x;
+ int32_t y;
+
+ x = rtp_session->last_write_seq;
+ y = ntohs(send_msg->header.seq);
+
+ if (x > UINT16_MAX / 2 && y < UINT16_MAX / 2) {
+ x -= (int32_t)UINT16_MAX+1;
+ }
+
+ delta = y-x;
+ }
+ rtp_session->seq += delta;
+
+ send_msg->header.seq = htons(rtp_session->seq);
+ rtp_session->last_write_seq = rtp_session->seq;
+
if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && send_msg->header.pt == rtp_session->payload) {
switch_swap_linear((int16_t *)send_msg->body, (int) datalen);
}
// //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SEND %u\n", ntohs(send_msg->header.seq));
//}
if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
- rtp_session->seq--;
+ rtp_session->seq -= delta;
+
ret = -1;
goto end;
}
fwd = (rtp_session->flags[SWITCH_RTP_FLAG_RAW_WRITE] &&
(switch_test_flag(frame, SFF_RAW_RTP) || switch_test_flag(frame, SFF_RAW_RTP_PARSE_FRAME))) ? 1 : 0;
- if (!fwd && !rtp_session->sending_dtmf && !rtp_session->queue_delay &&
+ if (!fwd && !rtp_session->sending_dtmf && !rtp_session->queue_delay && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] &&
rtp_session->flags[SWITCH_RTP_FLAG_RAW_WRITE] && (rtp_session->rtp_bugs & RTP_BUG_GEN_ONE_GEN_ALL)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Generating RTP locally but timestamp passthru is configured, disabling....\n");
}
- if (switch_test_flag(frame, SFF_RTP_HEADER)) {
- switch_size_t wrote;
-
- wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
- frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
-
- rtp_session->stats.outbound.raw_bytes += wrote;
- rtp_session->stats.outbound.media_bytes += wrote;
- rtp_session->stats.outbound.media_packet_count++;
- rtp_session->stats.outbound.packet_count++;
-
- return wrote;
- }
-
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
payload_map_t *pmap;
if (switch_test_flag(frame, SFF_RAW_RTP_PARSE_FRAME)) {
send_msg->header.version = 2;
send_msg->header.m = frame->m;
+
send_msg->header.ts = htonl(frame->timestamp);
if (frame->ssrc) {
send_msg->header.ssrc = htonl(frame->ssrc);