]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[mod_verto] indicate video fps and size of current layer to client
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 30 Mar 2020 01:01:03 +0000 (20:01 -0500)
committerAndrey Volk <andywolk@gmail.com>
Sat, 23 Oct 2021 19:00:20 +0000 (22:00 +0300)
src/include/switch_core_media.h
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/endpoints/mod_verto/mod_verto.c
src/switch_core_media.c

index 105cd50f971cd155d3976d1ef71d782243df89cc..c84416c86e59f9917562d281b1dc2109d2f6c666 100644 (file)
@@ -249,6 +249,8 @@ SWITCH_DECLARE(switch_core_media_params_t *) switch_core_media_get_mparams(switc
 SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *session, switch_bool_t force);
 SWITCH_DECLARE(void) switch_core_media_start_udptl(switch_core_session_t *session, switch_t38_options_t *t38_options);
 SWITCH_DECLARE(void) switch_core_media_hard_mute(switch_core_session_t *session, switch_bool_t on);
+SWITCH_DECLARE(cJSON *) switch_core_media_gen_json_constraint(float min, float ideal, float max);
+SWITCH_DECLARE(switch_status_t) switch_core_media_media_params(switch_core_session_t *session, const char *json);
 SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
 
 
index bfbdb9c3cea085217dd0446d5f41b7ea326dbd51..2baddf0101a8e750323a4a538ed83776245e76a2 100644 (file)
@@ -1137,6 +1137,7 @@ typedef enum {
        SWITCH_MESSAGE_INDICATE_DEFLECT,
        SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ,
        SWITCH_MESSAGE_INDICATE_DISPLAY,
+       SWITCH_MESSAGE_INDICATE_MEDIA_PARAMS,
        SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY,
        SWITCH_MESSAGE_INDICATE_AUDIO_SYNC,
        SWITCH_MESSAGE_INDICATE_VIDEO_SYNC,
@@ -1532,6 +1533,7 @@ typedef enum {
        CF_INTERCEPTED,
        CF_VIDEO_REFRESH_REQ,
        CF_MANUAL_VID_REFRESH,
+       CF_MANUAL_MEDIA_PARAMS,
        CF_SERVICE_AUDIO,
        CF_SERVICE_VIDEO,
        CF_ZRTP_PASSTHRU_REQ,
index 5d8313e5c5bce1c2a9e081206fc432b6f884846f..960268cd4f63c9480885ddbb061ee67ab06f0812 100644 (file)
@@ -4041,6 +4041,46 @@ SWITCH_STANDARD_API(uuid_display_function)
        return SWITCH_STATUS_SUCCESS;
 }
 
+#define MEDIA_PARAMS_SYNTAX "<uuid> <json>"
+SWITCH_STANDARD_API(uuid_media_params_function)
+{
+       char *mycmd = NULL, *argv[2] = { 0 };
+       int argc = 0;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_core_session_t *tsession = NULL;
+       
+       if (!zstr(cmd) && (mycmd = strdup(cmd))) {
+               argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+       }
+
+       if (zstr(cmd) || argc < 2 || zstr(argv[0]) || zstr(argv[1])) {
+               stream->write_function(stream, "-USAGE: %s\n", MEDIA_PARAMS_SYNTAX);
+               goto end;
+       } else {
+               if ((tsession = switch_core_session_locate(argv[0]))) {
+                       switch_channel_t *channel = switch_core_session_get_channel(session);
+
+                       if (switch_false(argv[1])) {
+                               switch_channel_clear_flag(channel, CF_MANUAL_MEDIA_PARAMS);
+                       } else if ((status = switch_core_media_media_params(tsession, argv[1])) == SWITCH_STATUS_SUCCESS) {
+                               switch_channel_set_flag(channel, CF_MANUAL_MEDIA_PARAMS);
+                       }
+                       switch_core_session_rwunlock(tsession);
+               }
+       }
+
+       if (status == SWITCH_STATUS_SUCCESS) {
+               stream->write_function(stream, "+OK Success\n");
+       } else {
+               stream->write_function(stream, "-ERR Operation failed\n");
+       }
+
+  end:
+
+       switch_safe_free(mycmd);
+       return SWITCH_STATUS_SUCCESS;
+}
+
 #define BUGLIST_SYNTAX "<uuid>"
 SWITCH_STANDARD_API(uuid_buglist_function)
 {
@@ -7636,6 +7676,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        SWITCH_ADD_API(commands_api_interface, "uuid_deflect", "Send a deflect", uuid_deflect, UUID_DEFLECT_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_displace", "Displace audio", session_displace_function, "<uuid> [start|stop] <path> [<limit>] [mux]");
        SWITCH_ADD_API(commands_api_interface, "uuid_display", "Update phone display", uuid_display_function, DISPLAY_SYNTAX);
+       SWITCH_ADD_API(commands_api_interface, "uuid_media_params", "Update remote vid params", uuid_media_params_function, MEDIA_PARAMS_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_drop_dtmf", "Drop all DTMF or replace it with a mask", uuid_drop_dtmf, UUID_DROP_DTMF_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_dump", "Dump session vars", uuid_dump_function, DUMP_SYNTAX);
        SWITCH_ADD_API(commands_api_interface, "uuid_exists", "Check if a uuid exists", uuid_exists_function, EXISTS_SYNTAX);
@@ -7827,6 +7868,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
        switch_console_set_complete("add uuid_deflect ::console::list_uuid");
        switch_console_set_complete("add uuid_displace ::console::list_uuid");
        switch_console_set_complete("add uuid_display ::console::list_uuid");
+       switch_console_set_complete("add uuid_media_params ::console::list_uuid");
        switch_console_set_complete("add uuid_drop_dtmf ::console::list_uuid");
        switch_console_set_complete("add uuid_dump ::console::list_uuid");
        switch_console_set_complete("add uuid_answer ::console::list_uuid");
index c5f2a1afb5854eedac5e28fce883cbd2eb3797db..4420f86a21e6d52348ebdc773752df0824d3def1 100644 (file)
@@ -2636,6 +2636,33 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_
                        }
                }
                break;
+       case SWITCH_MESSAGE_INDICATE_MEDIA_PARAMS:
+               {
+                       const char *json_text;
+                       cJSON *jmsg = NULL, *params = NULL, *vparams = NULL;
+                       jsock_t *jsock = NULL;
+                       
+                       if ((jsock = get_jsock(tech_pvt->jsock_uuid))) {
+                               
+                               json_text = msg->string_arg;
+
+                               if (json_text) {
+                                       jmsg = jrpc_new_req("verto.mediaParams", tech_pvt->call_id, &params);
+                                       if ((vparams = cJSON_Parse((char *)json_text))) {
+                                               cJSON_AddItemToObject(params, "mediaParams", vparams);
+                                               jsock_queue_event(jsock, &jmsg, SWITCH_TRUE);
+                                       } else {
+                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Parsing Media Params\n");
+                                               r = SWITCH_STATUS_FALSE;
+                                               cJSON_Delete(jmsg);
+                                       }
+                               }
+
+                               switch_thread_rwlock_unlock(jsock->rwlock);
+                       }
+
+               }
+               break;
        case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG:
                {
                        jsock_t *jsock = NULL;
index 71c02aa6a991e6c705b5f67f0aec227ee81354eb..b6cb4b6670878fb3d2c86d0201a7876f075076ed 100644 (file)
@@ -12429,6 +12429,149 @@ SWITCH_DECLARE(void) switch_core_media_hard_mute(switch_core_session_t *session,
        switch_core_session_receive_message(session, &msg);
 }
 
+SWITCH_DECLARE(cJSON *) switch_core_media_gen_json_constraint(float min, float ideal, float max)
+{
+       cJSON *ret = NULL, *n = NULL;
+
+       if ((!ideal && !max)) {
+               ret = cJSON_CreateNumber(min);
+       } else {
+               ret = cJSON_CreateObject();
+               n = cJSON_CreateNumber(min);
+               cJSON_AddItemToObject(ret, "min", n);
+               
+               if (ideal) {
+                       n = cJSON_CreateNumber(ideal);
+                       cJSON_AddItemToObject(ret, "ideal", n);
+               }
+
+               if (max) {
+                       n = cJSON_CreateNumber(max);
+                       cJSON_AddItemToObject(ret, "max", n);
+               }
+       }
+
+       return ret;
+}
+
+static cJSON *parse_val(char *str) {
+       char *argv[3];
+       int argc = 0;
+       float min = 0, ideal = 0, max = 0;
+       
+       argc = switch_separate_string(str, ':', argv, (sizeof(argv) / sizeof(argv[0])));
+
+       if (argc > 0) {
+               min = atof(argv[0]);
+       }
+
+       if (argc > 1) {
+               ideal = atof(argv[1]);
+       }
+
+       if (argc > 2) {
+               max = atof(argv[2]);
+       }
+       
+       return switch_core_media_gen_json_constraint(min, ideal, max);
+
+}
+
+SWITCH_DECLARE(switch_status_t) switch_core_media_media_params(switch_core_session_t *session, const char *json)
+{
+       switch_core_session_message_t msg = { 0 };
+       char *parse = NULL;
+       char *argv[25];
+    int argc = 0, i;
+       switch_status_t r = SWITCH_STATUS_SUCCESS;
+       cJSON *obj = NULL;
+       char *aspect = NULL, *fps = NULL, *width = NULL, *height = NULL, *jtmp = NULL;
+
+       
+       if (switch_channel_test_flag(session->channel, CF_MANUAL_MEDIA_PARAMS)) {
+               return SWITCH_STATUS_INUSE;
+       }
+       
+       if (switch_stristr("=", json)) {
+               char *name, *val;
+               cJSON *video, *p;
+               int vid = 0;
+               
+               parse = strdup(json);
+               argc = switch_separate_string(parse, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+               for(i = 0; i < argc; i++) {
+                       name = argv[i];
+                       if ((val = strchr(name, '='))) {
+                               *val++ = '\0';
+                       }
+
+                       if (name && val) {
+                               if (!strcmp(name, "aspect")) {
+                                       aspect = val;
+                                       vid++;
+                               } else if (!strcmp(name, "fps")) {
+                                       fps = val;              
+                                       vid++;
+                               } else if (!strcmp(name, "width")) {
+                                       width = val;
+                                       vid++;
+                               } else if (!strcmp(name, "height")) {
+                                       height = val;
+                                       vid++;
+                               }
+                       }
+               }
+
+               obj = cJSON_CreateObject();
+
+               if (vid) {
+                       video = cJSON_CreateObject();
+
+                       if (fps) {
+                               p = parse_val(fps);
+                               cJSON_AddItemToObject(video, "frameRate", p);
+                       }
+
+                       if (width) {
+                               p = parse_val(width);
+                               cJSON_AddItemToObject(video, "width", p);
+                       }
+
+                       if (height) {
+                               p = parse_val(height);
+                               cJSON_AddItemToObject(video, "height", p);
+                       }
+
+                       if (aspect) {
+                               p = cJSON_CreateNumber(atof(aspect));
+                               cJSON_AddItemToObject(video, "aspectRatio", p);
+                       }
+                       
+                       cJSON_AddItemToObject(obj, "video", video);
+               }
+
+               jtmp = cJSON_PrintUnformatted(obj);
+               json = jtmp;
+       }
+
+
+       
+       msg.from = __FILE__;
+
+       msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA_PARAMS;
+       msg.string_arg = json;
+       r = switch_core_session_receive_message(session, &msg);
+
+       switch_safe_free(parse);
+       switch_safe_free(jtmp);
+       if (obj) {
+               cJSON_Delete(obj);
+       }
+       
+       return r;
+}
+
 static int check_engine(switch_rtp_engine_t *engine)
 {
        dtls_state_t dtls_state = switch_rtp_dtls_state(engine->rtp_session, DTLS_TYPE_RTP);