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);
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,
CF_INTERCEPTED,
CF_VIDEO_REFRESH_REQ,
CF_MANUAL_VID_REFRESH,
+ CF_MANUAL_MEDIA_PARAMS,
CF_SERVICE_AUDIO,
CF_SERVICE_VIDEO,
CF_ZRTP_PASSTHRU_REQ,
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)
{
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);
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");
}
}
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, ¶ms);
+ 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;
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);