]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7499 second pass at adding TMMBR (WIP)
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 13 May 2015 00:55:28 +0000 (19:55 -0500)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:47:31 +0000 (12:47 -0500)
src/include/switch_rtp.h
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/switch_core_media.c
src/switch_rtp.c

index 71f7100b0ce31ff82ffe889262f4c262226907d1..6dfa1e253171e9771bc2c950ece215baa4402b66 100644 (file)
@@ -579,7 +579,8 @@ SWITCH_DECLARE(dtls_state_t) switch_rtp_dtls_state(switch_rtp_t *rtp_session, dt
 
 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);
 
index cec2f605bcf7386cb22964bb6edbbab25f4aea1d..108b03e33c8ddf7dc91ca8e1d8a6f798ba25d679 100644 (file)
@@ -1069,6 +1069,8 @@ typedef enum {
        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,
index cae64d20a7f3f9ed686504bb7ca294e591839b2f..60bcda10d007085b5e1304a9bc8958db72434cd1 100644 (file)
@@ -3952,6 +3952,49 @@ SWITCH_STANDARD_API(uuid_video_refresh_function)
        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)
@@ -6799,6 +6842,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        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);
@@ -7004,6 +7048,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        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 ...");
index 1d810706ada2d86e0a6f255155f4ca6dc83be479..e437a2347d3af92fba01c5fa89ef4177add2352f 100644 (file)
@@ -48,7 +48,7 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
 #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),
@@ -8614,6 +8614,22 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
 
                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;
@@ -10270,6 +10286,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
                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) && 
index f35b48c70fff2e2d0d1c542d19b8880ee6a4e5f4..d8392ae9803c6dc1ccb9870df83cefaebd227580 100644 (file)
@@ -127,26 +127,13 @@ typedef struct {
 #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 {
@@ -322,6 +309,7 @@ struct switch_rtp {
        uint16_t fir_count;
        uint16_t pli_count;
        uint32_t cur_nack;
+       uint32_t cur_tmmbr;
        uint32_t tmmbr;
        uint32_t tmmbn;
 
@@ -1854,6 +1842,31 @@ static int rtcp_stats(switch_rtp_t *rtp_session)
        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;
@@ -2018,10 +2031,14 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
                                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;
 
@@ -2030,25 +2047,27 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
 
                                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);                     
                        }
 
                }
@@ -4162,38 +4181,24 @@ SWITCH_DECLARE(void) switch_rtp_flush(switch_rtp_t *rtp_session)
        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;
 }