SWITCH_DECLARE(int) switch_rtp_has_dtls(void);
-SWITCH_DECLARE(switch_status_t) switch_rtp_req_bandwidth(switch_rtp_t *rtp_session, uint32_t bps);
+SWITCH_DECLARE(switch_status_t) switch_rtp_req_bitrate(switch_rtp_t *rtp_session, uint32_t bps);
+SWITCH_DECLARE(switch_status_t) switch_rtp_ack_bitrate(switch_rtp_t *rtp_session, uint32_t bps);
SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_video_loss(switch_rtp_t *rtp_session);
SWITCH_MESSAGE_INDICATE_MEDIA_RENEG,
SWITCH_MESSAGE_INDICATE_KEEPALIVE,
SWITCH_MESSAGE_INDICATE_HARD_MUTE,
+ SWITCH_MESSAGE_INDICATE_BITRATE_REQ,
+ SWITCH_MESSAGE_INDICATE_BITRATE_ACK,
SWITCH_MESSAGE_REFER_EVENT,
SWITCH_MESSAGE_ANSWER_EVENT,
SWITCH_MESSAGE_PROGRESS_EVENT,
return SWITCH_STATUS_SUCCESS;
}
+#define VIDEO_BITRATE_SYNTAX "<uuid> <bitrate>"
+SWITCH_STANDARD_API(uuid_video_bitrate_function)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ char *mycmd = NULL, *argv[2] = { 0 };
+ int argc = 0;
+
+ if (!zstr(cmd) && (mycmd = strdup(cmd))) {
+ argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ }
+
+ if (argc < 2) {
+ stream->write_function(stream, "-USAGE: %s\n", VIDEO_REFRESH_SYNTAX);
+ } else {
+ switch_core_session_t *lsession = NULL;
+
+ if ((lsession = switch_core_session_locate(argv[0]))) {
+ int kps = switch_parse_bandwidth_string(argv[1]);
+ switch_core_session_message_t msg = { 0 };
+
+ msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
+ msg.numeric_arg = kps * 1024;
+ msg.from = __FILE__;
+
+ switch_core_session_receive_message(lsession, &msg);
+ switch_core_session_video_reinit(lsession);
+ switch_channel_video_sync(switch_core_session_get_channel(lsession));
+ status = SWITCH_STATUS_SUCCESS;
+ switch_core_session_rwunlock(lsession);
+ }
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ stream->write_function(stream, "+OK Success\n");
+ } else {
+ stream->write_function(stream, "-ERR Operation Failed\n");
+ }
+
+ switch_safe_free(mycmd);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
#define DEBUG_MEDIA_SYNTAX "<uuid> <read|write|both|vread|vwrite|vboth|all> <on|off>"
SWITCH_STANDARD_API(uuid_debug_media_function)
SWITCH_ADD_API(commands_api_interface, "uuid_send_message", "Send MESSAGE to the endpoint", uuid_send_message_function, SEND_MESSAGE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_send_info", "Send info to the endpoint", uuid_send_info_function, INFO_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_set_media_stats", "Set media stats", uuid_set_media_stats, UUID_MEDIA_STATS_SYNTAX);
+ SWITCH_ADD_API(commands_api_interface, "uuid_video_bitrate", "Send video bitrate req.", uuid_video_bitrate_function, VIDEO_BITRATE_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_video_refresh", "Send video refresh.", uuid_video_refresh_function, VIDEO_REFRESH_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_outgoing_answer", "Answer outgoing channel", outgoing_answer_function, OUTGOING_ANSWER_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_limit", "Increase limit resource", uuid_limit_function, LIMIT_SYNTAX);
switch_console_set_complete("add uuid_transfer ::console::list_uuid");
switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid");
switch_console_set_complete("add uuid_video_refresh ::console::list_uuid");
+ switch_console_set_complete("add uuid_video_bitrate ::console::list_uuid");
switch_console_set_complete("add version");
switch_console_set_complete("add uuid_warning ::console::list_uuid");
switch_console_set_complete("add ...");
#define MAX_CODEC_CHECK_FRAMES 50//x:mod_sofia.h
#define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h
#define type2str(type) type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio"
-#define VIDEO_REFRESH_FREQ 1000000
+#define VIDEO_REFRESH_FREQ 100000
typedef enum {
SMF_INIT = (1 << 0),
break;
+ case SWITCH_MESSAGE_INDICATE_BITRATE_REQ:
+ {
+ if (v_engine->rtp_session) {
+ switch_rtp_req_bitrate(v_engine->rtp_session, msg->numeric_arg);
+ }
+ }
+ break;
+
+ case SWITCH_MESSAGE_INDICATE_BITRATE_ACK:
+ {
+ if (v_engine->rtp_session) {
+ switch_rtp_ack_bitrate(v_engine->rtp_session, msg->numeric_arg);
+ }
+ }
+ break;
+
case SWITCH_MESSAGE_INDICATE_DEBUG_MEDIA:
{
switch_rtp_t *rtp = a_engine->rtp_session;
switch_goto_status(vstatus, done);
}
+
/* When desired, scale video to match the input signal (if output is bigger) */
if (switch_channel_test_flag(session->channel, CF_VIDEO_READY) && smh->vid_params.width &&
switch_channel_test_flag(session->channel, CF_VIDEO_MIRROR_INPUT) &&
#pragma pack(push, r1, 1)
#endif
-#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
-
-typedef struct {
- uint32_t ssrc;
- unsigned exp:6;
- unsigned mantissa:17;
- unsigned overhead:9;
-} rtcp_tmmbx_t;
-#else
typedef struct {
uint32_t ssrc;
- unsigned overhead:9;
- unsigned mantissa:17;
- unsigned exp:6;
+ uint8_t parts[4];
} rtcp_tmmbx_t;
-#endif
-
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
typedef struct {
uint16_t fir_count;
uint16_t pli_count;
uint32_t cur_nack;
+ uint32_t cur_tmmbr;
uint32_t tmmbr;
uint32_t tmmbn;
return 1;
}
+static void calc_bw_exp(uint32_t bps, uint8_t bits, rtcp_tmmbx_t *tmmbx)
+{
+ uint32_t mantissa_max, i = 0;
+ uint8_t exp = 0;
+ uint32_t mantissa = 0;
+ uint16_t overhead = 0;
+
+ mantissa_max = (1 << bits) - 1;
+
+ for (i = 0; i < 64; ++i) {
+ if (bps <= (mantissa_max << i)) {
+ exp = i;
+ break;
+ }
+ }
+
+ mantissa = (bps >> exp);
+
+ tmmbx->parts[0] = (uint8_t) ((exp << 2) + ((mantissa >> 15) & 0x03));
+ tmmbx->parts[1] = (uint8_t) (mantissa >> 7);
+ tmmbx->parts[2] = (uint8_t) ((mantissa >> 1) + ((overhead >> 8) & 0x01));
+ tmmbx->parts[3] = (uint8_t) (overhead);
+}
+
+
static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
{
int ret = 0;
rtp_session->fir_count--;
}
+ //if (!rtp_session->tmmbr && rtp_session->cur_tmmbr) {
+ // rtp_session->tmmbr = rtp_session->cur_tmmbr;
+ //}
+
while (rtp_session->tmmbr || rtp_session->tmmbn) {
switch_rtcp_ext_hdr_t *ext_hdr;
rtcp_tmmbx_t *tmmbx;
- uint32_t body = 0;
+ uint32_t bps = 0;
p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes;
ext_hdr = (switch_rtcp_ext_hdr_t *) p;
ext_hdr->version = 2;
ext_hdr->p = 0;
- ext_hdr->pt = RTCP_PT_PSFB;
+ ext_hdr->pt = RTCP_PT_RTPFB;
ext_hdr->send_ssrc = htonl(rtp_session->ssrc);
ext_hdr->recv_ssrc = 0;
if (rtp_session->tmmbr) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP TMMBR %u\n", rtp_session->tmmbr);
ext_hdr->fmt = RTCP_RTPFB_TMMBR;
- body = rtp_session->tmmbr;
+ bps = rtp_session->tmmbr;
rtp_session->tmmbr = 0;
} else {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP TMMBN %u\n", rtp_session->tmmbr);
ext_hdr->fmt = RTCP_RTPFB_TMMBN;
- body = rtp_session->tmmbn;
+ bps = rtp_session->tmmbn;
rtp_session->tmmbn = 0;
}
tmmbx->ssrc = htonl(rtp_session->remote_ssrc);
- memcpy(p+4, &body, sizeof(body));
+ calc_bw_exp(bps, 17, tmmbx);
- ext_hdr->length = htons((uint8_t)((sizeof(switch_rtcp_ext_hdr_t) + sizeof(rtcp_fir_t)) / 4) - 1);
- rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t) + sizeof(rtcp_tmmbx_t);
+ ext_hdr->length = htons((uint8_t)((sizeof(switch_rtcp_ext_hdr_t) + sizeof(rtcp_tmmbx_t)) / 4) - 1);
+ rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t) + sizeof(rtcp_tmmbx_t);
}
}
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
}
-static uint32_t calc_bw_exp(uint32_t bps, uint8_t bits)
+SWITCH_DECLARE(switch_status_t) switch_rtp_req_bitrate(switch_rtp_t *rtp_session, uint32_t bps)
{
- uint32_t r = 0;
- rtcp_tmmbx_t *tmmbx;
- uint32_t mantissa_max, i = 0;
-
- tmmbx = (rtcp_tmmbx_t *) &r;
-
- mantissa_max = (1 << bits) - 1;
-
- for (i = 0; i < 64; ++i) {
- if (bps <= (mantissa_max << i)) {
- tmmbx->exp = i;
- break;
- }
+ if (!rtp_write_ready(rtp_session, 0, __LINE__) || rtp_session->tmmbr) {
+ return SWITCH_STATUS_FALSE;
}
- tmmbx->mantissa = (bps >> tmmbx->exp);
-
+ rtp_session->tmmbr = bps;
-
- return r;
+ return SWITCH_STATUS_SUCCESS;
}
-
-SWITCH_DECLARE(switch_status_t) switch_rtp_req_bandwidth(switch_rtp_t *rtp_session, uint32_t bps)
+SWITCH_DECLARE(switch_status_t) switch_rtp_ack_bitrate(switch_rtp_t *rtp_session, uint32_t bps)
{
- if (!rtp_write_ready(rtp_session, 0, __LINE__) || rtp_session->tmmbr) {
+ if (!rtp_write_ready(rtp_session, 0, __LINE__) || rtp_session->tmmbn) {
return SWITCH_STATUS_FALSE;
}
- rtp_session->tmmbr = calc_bw_exp(bps, 17);
+ rtp_session->tmmbn = bps;
return SWITCH_STATUS_SUCCESS;
}