提交 5c51617d authored 作者: Anthony Minessale II's avatar Anthony Minessale II

Merge pull request #1219 in FS/freeswitch from feature/FS-9742-refactor-canvas-zoom-code to master

* commit 'da6b9e00':
  FS-9742: [mod_conference,mod_cv] Refactor canvas zoom code #resolve
...@@ -22,6 +22,8 @@ install-maxdemo: all verto-max.js ...@@ -22,6 +22,8 @@ install-maxdemo: all verto-max.js
install-video_demo: all install-video_demo: all
cp verto-min.js ../video_demo/js cp verto-min.js ../video_demo/js
cp verto-min.js ../video_demo-live_canvas/js
install-video_maxdemo: all verto-max.js install-video_maxdemo: all verto-max.js
cp verto-max.js ../video_demo/js/verto-min.js cp verto-max.js ../video_demo/js/verto-min.js
cp verto-max.js ../video_demo-live_canvas/js/verto-min.js
...@@ -1247,6 +1247,14 @@ ...@@ -1247,6 +1247,14 @@
} }
}); });
verto.subscribe(conf.params.laData.infoChannel, {
handler: function(v, e) {
if (typeof(conf.params.infoCallback) === "function") {
conf.params.infoCallback(v,e);
}
}
});
verto.subscribe(conf.params.laData.chatChannel, { verto.subscribe(conf.params.laData.chatChannel, {
handler: function(v, e) { handler: function(v, e) {
if (typeof(conf.params.chatCallback) === "function") { if (typeof(conf.params.chatCallback) === "function") {
...@@ -1283,6 +1291,10 @@ ...@@ -1283,6 +1291,10 @@
if (conf.params.laData.chatChannel) { if (conf.params.laData.chatChannel) {
conf.verto.unsubscribe(conf.params.laData.chatChannel); conf.verto.unsubscribe(conf.params.laData.chatChannel);
} }
if (conf.params.laData.infoChannel) {
conf.verto.unsubscribe(conf.params.laData.infoChannel);
}
}; };
function createMainModeratorMethods() { function createMainModeratorMethods() {
...@@ -1684,6 +1696,14 @@ ...@@ -1684,6 +1696,14 @@
//$(".jsDataTable").width(confMan.params.hasVid ? "900px" : "800px"); //$(".jsDataTable").width(confMan.params.hasVid ? "900px" : "800px");
verto.subscribe(confMan.params.laData.infoChannel, {
handler: function(v, e) {
if (typeof(confMan.params.infoCallback) === "function") {
confMan.params.infoCallback(v,e);
}
}
});
verto.subscribe(confMan.params.laData.chatChannel, { verto.subscribe(confMan.params.laData.chatChannel, {
handler: function(v, e) { handler: function(v, e) {
if (typeof(confMan.params.chatCallback) === "function") { if (typeof(confMan.params.chatCallback) === "function") {
......
This diff was suppressed by a .gitattributes entry.
...@@ -40,14 +40,15 @@ ...@@ -40,14 +40,15 @@
SWITCH_BEGIN_EXTERN_C SWITCH_BEGIN_EXTERN_C
struct switch_frame_geometry { typedef struct switch_frame_geometry {
uint32_t w; uint32_t w;
uint32_t h; uint32_t h;
uint32_t x; uint32_t x;
uint32_t y; uint32_t y;
uint32_t z; uint32_t z;
uint32_t m; uint32_t M;
}; uint32_t X;
} switch_frame_geometry_t;
/*! \brief An abstraction of a data frame */ /*! \brief An abstraction of a data frame */
struct switch_frame { struct switch_frame {
......
...@@ -60,6 +60,7 @@ api_command_t conference_api_sub_commands[] = { ...@@ -60,6 +60,7 @@ api_command_t conference_api_sub_commands[] = {
{"file_seek", (void_fn_t) & conference_api_sub_file_seek, CONF_API_SUB_ARGS_SPLIT, "file_seek", "[+-]<val> [<member_id>]"}, {"file_seek", (void_fn_t) & conference_api_sub_file_seek, CONF_API_SUB_ARGS_SPLIT, "file_seek", "[+-]<val> [<member_id>]"},
{"say", (void_fn_t) & conference_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "say", "<text>"}, {"say", (void_fn_t) & conference_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "say", "<text>"},
{"saymember", (void_fn_t) & conference_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "saymember", "<member_id> <text>"}, {"saymember", (void_fn_t) & conference_api_sub_saymember, CONF_API_SUB_ARGS_AS_ONE, "saymember", "<member_id> <text>"},
{"cam", (void_fn_t) & conference_api_sub_cam, CONF_API_SUB_ARGS_SPLIT, "cam", ""},
{"stop", (void_fn_t) & conference_api_sub_stop, CONF_API_SUB_ARGS_SPLIT, "stop", "<[current|all|async|last]> [<member_id>]"}, {"stop", (void_fn_t) & conference_api_sub_stop, CONF_API_SUB_ARGS_SPLIT, "stop", "<[current|all|async|last]> [<member_id>]"},
{"dtmf", (void_fn_t) & conference_api_sub_dtmf, CONF_API_SUB_MEMBER_TARGET, "dtmf", "<[member_id|all|last|non_moderator]> <digits>"}, {"dtmf", (void_fn_t) & conference_api_sub_dtmf, CONF_API_SUB_MEMBER_TARGET, "dtmf", "<[member_id|all|last|non_moderator]> <digits>"},
{"kick", (void_fn_t) & conference_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "kick", "<[member_id|all|last|non_moderator]> [<optional sound file>]"}, {"kick", (void_fn_t) & conference_api_sub_kick, CONF_API_SUB_MEMBER_TARGET, "kick", "<[member_id|all|last|non_moderator]> [<optional sound file>]"},
...@@ -2009,6 +2010,262 @@ switch_status_t conference_api_sub_saymember(conference_obj_t *conference, switc ...@@ -2009,6 +2010,262 @@ switch_status_t conference_api_sub_saymember(conference_obj_t *conference, switc
return ret_status; return ret_status;
} }
switch_status_t conference_api_sub_cam(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
int x;
int canvas_id = -1;
int layer_id = -1;
int ok = 0;
mcu_canvas_t *canvas = NULL;
mcu_layer_t *layer = NULL;
if (!conference->canvases[0]) {
stream->write_function(stream, "Conference is not in mixing mode\n");
return SWITCH_STATUS_SUCCESS;
}
if (argc > 4) {
canvas_id = atoi(argv[2]);
layer_id = atoi(argv[3]);
if (canvas_id > -1 && layer_id > -1 && canvas_id < conference->canvas_count) {
switch_mutex_lock(conference->canvas_mutex);
canvas = conference->canvases[canvas_id];
switch_mutex_lock(canvas->mutex);
if (layer_id < canvas->total_layers) {
layer = &canvas->layers[layer_id];
ok = 1;
for (x = 4; x < argc; x++) {
char *p = strchr(argv[x], '=');
int val = -1, isfalse = 0;
char *str_arg = NULL;
if (p) {
*p++ = '\0';
if (!p) p = "";
if (!strcasecmp(argv[x], "zoom") || !strcasecmp(argv[x], "pan")) {
str_arg = p;
if (switch_false(p)) {
isfalse = 1;
}
} else {
if (switch_is_number(p)) {
val = atoi(p);
} else if (switch_true(p)) {
val = 1;
} else {
val = 0;
isfalse = 1;
}
}
} else if (!strcasecmp(argv[x], "reset")) {
str_arg = "true";
}
if (val < 0 && !str_arg) {
stream->write_function(stream, "-ERR invalid val for option [%s]\n", argv[x]);
continue;
}
if (!strcasecmp(argv[x], "autozoom")) {
if ((layer->cam_opts.autozoom = val)) {
layer->cam_opts.manual_zoom = 0;
}
} else if (!strcasecmp(argv[x], "autopan")) {
if ((layer->cam_opts.autopan = val)) {
layer->cam_opts.manual_pan = 0;
}
} else if (!strcasecmp(argv[x], "zoom_factor")) {
if (val > 0 && val < 5) {
layer->cam_opts.zoom_factor = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-4\n", argv[x]);
}
} else if (!strcasecmp(argv[x], "snap_factor")) {
if (val > 0 && val < layer->screen_w / 2) {
layer->cam_opts.snap_factor = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-%d\n", argv[x], layer->screen_w / 2);
}
} else if (!strcasecmp(argv[x], "zoom_move_factor")) {
if (val > 0 && val < layer->screen_w / 2) {
layer->cam_opts.zoom_move_factor = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-4\n", argv[x], layer->screen_w / 2);
}
} else if (!strcasecmp(argv[x], "pan_speed")) {
if (val > 0 && val < 100) {
layer->cam_opts.pan_speed = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "pan_accel_speed")) {
if (val > 0 && val < 100) {
layer->cam_opts.pan_accel_speed = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "pan_accel_min")) {
if (val > 0 && val < 100) {
layer->cam_opts.pan_accel_min = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "zoom_speed")) {
if (val > 0 && val < 100) {
layer->cam_opts.zoom_speed = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "zoom_accel_speed")) {
if (val > 0 && val < 100) {
layer->cam_opts.zoom_accel_speed = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "zoom_accel_min")) {
if (val > 0 && val < 100) {
layer->cam_opts.zoom_accel_min = val;
} else {
stream->write_function(stream, "-ERR invalid val for option [%s] must be 1-100\n");
}
} else if (!strcasecmp(argv[x], "reset")) {
conference_video_reset_layer_cam(layer);
} else if (!strcasecmp(argv[x], "pan")) {
char *x_val = NULL, *y_val = NULL;
int x = -1, y = -1;
int on = 0;
if (isfalse) {
layer->pan_geometry.x = 0;
layer->pan_geometry.y = 0;
layer->cam_opts.manual_pan = 0;
} else {
if (str_arg) {
char *p = strchr(str_arg, ':');
if (p) {
*p++ = '\0';
if (*str_arg == 'x') {
x_val = p;
} else if (*str_arg == 'y') {
y_val = p;
}
}
}
if (!x_val && !y_val) {
stream->write_function(stream, "-ERR invalid val for pan\n");
}
if (x_val) x = atoi(x_val);
if (y_val) y = atoi(y_val);
if (x_val && strrchr(x_val, 'i')) {
int nx = (int)layer->pan_geometry.x + x;
if (nx < 0) nx = 0;
if (nx + layer->pan_geometry.w > layer->img->d_w) nx = layer->img->d_w - layer->pan_geometry.w;
layer->pan_geometry.x = nx;
on++;
} else if (x > -1) {
layer->pan_geometry.x = x;
on++;
}
if (y_val && strrchr(y_val, 'i')) {
int ny = (int)layer->pan_geometry.y + y;
if (ny < 0) ny = 0;
if (ny + layer->pan_geometry.h > layer->img->d_h) ny = layer->img->d_h - layer->pan_geometry.h;
layer->pan_geometry.y = ny;
on++;
} else if (y > -1) {
layer->pan_geometry.y = y;
on++;
}
if (on) {
layer->cam_opts.manual_pan = 1;
layer->cam_opts.autopan = 0;
stream->write_function(stream, "+OK PAN %d,%d\n", layer->pan_geometry.x, layer->pan_geometry.y);
}
}
} else if (!strcasecmp(argv[x], "zoom")) {
if (str_arg && !isfalse) {
char *array[4] = {0};
int iray[4] = {0};
int ac;
if ((ac = switch_split(str_arg, ':', array)) >= 3) {
int i;
for (i = 0; i < ac; i++) {
int tmp = atoi(array[i]);
if (tmp < 0) break;
iray[i] = tmp;
}
if (i == ac) {
layer->cam_opts.manual_zoom = 1;
layer->cam_opts.autozoom = 0;
layer->zoom_geometry.x = iray[0];
layer->zoom_geometry.y = iray[1];
layer->zoom_geometry.w = iray[2];
if (iray[3]) {
layer->zoom_geometry.h = iray[3];
} else {
layer->zoom_geometry.h = iray[2];
}
layer->crop_x = iray[0];
layer->crop_y = iray[1];
layer->crop_w = iray[2];
layer->crop_h = iray[2];
layer->pan_geometry = layer->zoom_geometry;
} else {
ok = 0;
}
}
} else {
layer->zoom_geometry.x = 0;
layer->zoom_geometry.y = 0;
layer->zoom_geometry.w = 0;
layer->zoom_geometry.h = 0;
layer->cam_opts.manual_zoom = 0;
}
} else {
stream->write_function(stream, "-ERR invalid option [%s]\n", argv[x]);
}
}
}
switch_mutex_unlock(canvas->mutex);
switch_mutex_unlock(conference->canvas_mutex);
}
}
if (ok) {
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "-ERR invalid args\n");
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t conference_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) switch_status_t conference_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{ {
uint8_t current = 0, all = 0, async = 0; uint8_t current = 0, all = 0, async = 0;
......
...@@ -237,14 +237,22 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json ...@@ -237,14 +237,22 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
const void *vvar; const void *vvar;
cJSON *array = cJSON_CreateArray(); cJSON *array = cJSON_CreateArray();
conference_obj_t *conference = NULL; conference_obj_t *conference = NULL;
int i;
if ((conference = conference_find(conference_name, NULL))) { if ((conference = conference_find(conference_name, NULL))) {
switch_mutex_lock(conference_globals.setup_mutex); switch_mutex_lock(conference_globals.setup_mutex);
for (i = 0; i <= conference->canvas_count; i++) {
if (conference->canvases[i]) {
conference_event_adv_layout(conference, conference->canvases[i], conference->canvases[i]->vlayout);
}
}
if (conference->layout_hash) { if (conference->layout_hash) {
for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) { for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) {
video_layout_t *vlayout; video_layout_t *vlayout;
cJSON *obj = cJSON_CreateObject(); cJSON *obj = cJSON_CreateObject();
cJSON *resarray = cJSON_CreateArray(); cJSON *resarray = cJSON_CreateArray();
int i;
switch_core_hash_this(hi, &vvar, NULL, &val); switch_core_hash_this(hi, &vvar, NULL, &val);
vlayout = (video_layout_t *)val; vlayout = (video_layout_t *)val;
...@@ -292,6 +300,83 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json ...@@ -292,6 +300,83 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
switch_thread_rwlock_unlock(conference->rwlock); switch_thread_rwlock_unlock(conference->rwlock);
} }
addobj = array; addobj = array;
} else if (!strcasecmp(action, "click-layer")) {
} else if (!strcasecmp(action, "shift-click-layer")) {
} else if (!strcasecmp(action, "reset-layer") || !strcasecmp(action, "layer-pan-x") || !strcasecmp(action, "layer-pan-y")) {
cJSON *v;
int layer_id = 0, canvas_id = 0, metric = 0, absolute = 0;
const char *i = "i", *xy = "";
if ((v = cJSON_GetObjectItem(data, "layerID"))) {
layer_id = v->valueint;
}
if ((v = cJSON_GetObjectItem(data, "canvasID"))) {
canvas_id = v->valueint;
}
if ((v = cJSON_GetObjectItem(data, "metric"))) {
metric = v->valueint;
}
if ((v = cJSON_GetObjectItem(data, "absolute"))) {
if ((absolute = v->valueint)) {
i = "";
}
}
if (canvas_id > -1 && layer_id > -1) {
if (!strcasecmp(action, "layer-pan-x")) {
xy = "x";
} else if (!strcasecmp(action, "layer-pan-y")) {
xy = "y";
}
if (!strcasecmp(action, "reset-layer")) {
exec = switch_mprintf("%s cam %d %d reset", conference_name, canvas_id, layer_id);
} else {
exec = switch_mprintf("%s cam %d %d pan=%s:%d%s", conference_name, canvas_id, layer_id, xy, metric, i);
}
}
} else if (!strcasecmp(action, "zoom-layer")) {
cJSON *v;
int layer_id = -1, canvas_id = -1, x = -1, y = -1, w = -1, h = -1;
if ((v = cJSON_GetObjectItem(data, "layerID"))) {
layer_id = v->valueint;
}
if ((v = cJSON_GetObjectItem(data, "canvasID"))) {
canvas_id = v->valueint;
}
if ((v = cJSON_GetObjectItem(data, "dimensions"))) {
cJSON *d;
if ((d = cJSON_GetObjectItem(v, "w"))) {
w = d->valueint;
}
if ((d = cJSON_GetObjectItem(v, "h"))) {
h = d->valueint;
}
if ((d = cJSON_GetObjectItem(v, "x"))) {
x = d->valueint;
}
if ((d = cJSON_GetObjectItem(v, "y"))) {
y = d->valueint;
}
}
if (canvas_id > -1 && layer_id > -1 && x > -1 && y > -1 && w > -1 && h > -1) {
exec = switch_mprintf("%s cam %d %d zoom=%d:%d:%d:%d snap_factor=1 zoom_factor=1", conference_name, canvas_id, layer_id, x, y, w, h);
}
} }
if (exec) { if (exec) {
...@@ -486,6 +571,59 @@ void conference_event_la_command_handler(switch_live_array_t *la, const char *cm ...@@ -486,6 +571,59 @@ void conference_event_la_command_handler(switch_live_array_t *la, const char *cm
{ {
} }
void conference_event_adv_layout(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout)
{
cJSON *msg, *data, *obj;
int i = 0;
msg = cJSON_CreateObject();
data = json_add_child_obj(msg, "eventData", NULL);
cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(conference->info_event_channel));
cJSON_AddItemToObject(data, "contentType", cJSON_CreateString("layout-info"));
switch_thread_rwlock_rdlock(canvas->video_rwlock);
switch_mutex_lock(canvas->mutex);
if ((obj = get_canvas_info(canvas))) {
cJSON *array = cJSON_CreateArray();
for (i = 0; i < vlayout->layers; i++) {
cJSON *layout = cJSON_CreateObject();
int scale = vlayout->images[i].scale;
int hscale = vlayout->images[i].hscale ? vlayout->images[i].hscale : scale;
cJSON_AddItemToObject(layout, "x", cJSON_CreateNumber(vlayout->images[i].x));
cJSON_AddItemToObject(layout, "y", cJSON_CreateNumber(vlayout->images[i].y));
cJSON_AddItemToObject(layout, "scale", cJSON_CreateNumber(vlayout->images[i].scale));
cJSON_AddItemToObject(layout, "hscale", cJSON_CreateNumber(hscale));
cJSON_AddItemToObject(layout, "scale", cJSON_CreateNumber(scale));
cJSON_AddItemToObject(layout, "zoom", cJSON_CreateNumber(vlayout->images[i].zoom));
cJSON_AddItemToObject(layout, "border", cJSON_CreateNumber(vlayout->images[i].border));
cJSON_AddItemToObject(layout, "floor", cJSON_CreateNumber(vlayout->images[i].floor));
cJSON_AddItemToObject(layout, "overlap", cJSON_CreateNumber(vlayout->images[i].overlap));
cJSON_AddItemToObject(layout, "screenWidth", cJSON_CreateNumber((uint32_t)(canvas->img->d_w * scale / VIDEO_LAYOUT_SCALE)));
cJSON_AddItemToObject(layout, "screenHeight", cJSON_CreateNumber((uint32_t)(canvas->img->d_h * hscale / VIDEO_LAYOUT_SCALE)));
cJSON_AddItemToObject(layout, "xPOS", cJSON_CreateNumber((int)(canvas->img->d_w * vlayout->images[i].x / VIDEO_LAYOUT_SCALE)));
cJSON_AddItemToObject(layout, "yPOS", cJSON_CreateNumber((int)(canvas->img->d_h * vlayout->images[i].y / VIDEO_LAYOUT_SCALE)));
cJSON_AddItemToObject(layout, "resID", cJSON_CreateString(vlayout->images[i].res_id));
cJSON_AddItemToObject(layout, "audioPOS", cJSON_CreateString(vlayout->images[i].audio_position));
cJSON_AddItemToArray(array, layout);
}
cJSON_AddItemToObject(obj, "canvasLayouts", array);
cJSON_AddItemToObject(obj, "scale", cJSON_CreateNumber(VIDEO_LAYOUT_SCALE));
cJSON_AddItemToObject(data, "canvasInfo", obj);
}
switch_mutex_unlock(canvas->mutex);
switch_thread_rwlock_unlock(canvas->video_rwlock);
switch_event_channel_broadcast(conference->info_event_channel, &msg, "mod_conference", conference_globals.event_channel_id);
}
void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join) void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join)
{ {
...@@ -501,6 +639,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t * ...@@ -501,6 +639,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
switch_event_t *variables; switch_event_t *variables;
switch_event_header_t *hp; switch_event_header_t *hp;
char idstr[128] = ""; char idstr[128] = "";
int i;
snprintf(idstr, sizeof(idstr), "%d", member->id); snprintf(idstr, sizeof(idstr), "%d", member->id);
msg = cJSON_CreateObject(); msg = cJSON_CreateObject();
...@@ -526,6 +665,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t * ...@@ -526,6 +665,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
} }
cJSON_AddItemToObject(data, "chatChannel", cJSON_CreateString(conference->chat_event_channel)); cJSON_AddItemToObject(data, "chatChannel", cJSON_CreateString(conference->chat_event_channel));
cJSON_AddItemToObject(data, "infoChannel", cJSON_CreateString(conference->info_event_channel));
switch_core_get_variables(&variables); switch_core_get_variables(&variables);
for (hp = variables->headers; hp; hp = hp->next) { for (hp = variables->headers; hp; hp = hp->next) {
...@@ -538,12 +678,19 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t * ...@@ -538,12 +678,19 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
} }
switch_event_destroy(&variables); switch_event_destroy(&variables);
switch_event_channel_broadcast(event_channel, &msg, "mod_conference", conference_globals.event_channel_id);
if (cookie) { if (cookie) {
switch_event_channel_permission_modify(cookie, conference->la_event_channel, join); switch_event_channel_permission_modify(cookie, conference->la_event_channel, join);
switch_event_channel_permission_modify(cookie, conference->mod_event_channel, join); switch_event_channel_permission_modify(cookie, conference->mod_event_channel, join);
switch_event_channel_permission_modify(cookie, conference->chat_event_channel, join); switch_event_channel_permission_modify(cookie, conference->chat_event_channel, join);
switch_event_channel_permission_modify(cookie, conference->info_event_channel, join);
}
switch_event_channel_broadcast(event_channel, &msg, "mod_conference", conference_globals.event_channel_id);
for (i = 0; i <= conference->canvas_count; i++) {
if (conference->canvases[i]) {
conference_event_adv_layout(conference, conference->canvases[i], conference->canvases[i]->vlayout);
}
} }
} }
} }
......
...@@ -3447,6 +3447,34 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co ...@@ -3447,6 +3447,34 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
conference->super_canvas_label_layers = video_super_canvas_label_layers; conference->super_canvas_label_layers = video_super_canvas_label_layers;
conference->super_canvas_show_all_layers = video_super_canvas_show_all_layers; conference->super_canvas_show_all_layers = video_super_canvas_show_all_layers;
if (conference_utils_test_flag(conference, CFLAG_LIVEARRAY_SYNC)) {
char *p;
if (strchr(conference->name, '@')) {
conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name);
conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s", conference->name);
conference->info_event_channel = switch_core_sprintf(conference->pool, "conference-info.%s", conference->name);
conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name);
} else {
conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain);
conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s@%s", conference->name, conference->domain);
conference->info_event_channel = switch_core_sprintf(conference->pool, "conference-info.%s@%s", conference->name, conference->domain);
conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain);
}
conference->la_name = switch_core_strdup(conference->pool, conference->name);
if ((p = strchr(conference->la_name, '@'))) {
*p = '\0';
}
switch_live_array_create(conference->la_event_channel, conference->la_name, conference_globals.event_channel_id, &conference->la);
switch_live_array_set_user_data(conference->la, conference);
switch_live_array_set_command_handler(conference->la, conference_event_la_command_handler);
}
if (video_canvas_count < 1) video_canvas_count = 1; if (video_canvas_count < 1) video_canvas_count = 1;
if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) && video_canvas_count > 1) { if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) && video_canvas_count > 1) {
...@@ -3499,30 +3527,6 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co ...@@ -3499,30 +3527,6 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create");
switch_event_fire(&event); switch_event_fire(&event);
if (conference_utils_test_flag(conference, CFLAG_LIVEARRAY_SYNC)) {
char *p;
if (strchr(conference->name, '@')) {
conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name);
conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s", conference->name);
conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name);
} else {
conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain);
conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s@%s", conference->name, conference->domain);
conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain);
}
conference->la_name = switch_core_strdup(conference->pool, conference->name);
if ((p = strchr(conference->la_name, '@'))) {
*p = '\0';
}
switch_live_array_create(conference->la_event_channel, conference->la_name, conference_globals.event_channel_id, &conference->la);
switch_live_array_set_user_data(conference->la, conference);
switch_live_array_set_command_handler(conference->la, conference_event_la_command_handler);
}
end: end:
switch_mutex_unlock(conference_globals.hash_mutex); switch_mutex_unlock(conference_globals.hash_mutex);
......
...@@ -429,6 +429,23 @@ typedef struct mcu_layer_def_s { ...@@ -429,6 +429,23 @@ typedef struct mcu_layer_def_s {
mcu_layer_geometry_t layers[MCU_MAX_LAYERS]; mcu_layer_geometry_t layers[MCU_MAX_LAYERS];
} mcu_layer_def_t; } mcu_layer_def_t;
typedef struct mcu_layer_cam_opts_s {
int manual_pan;
int manual_zoom;
int autozoom;
int autopan;
int zoom_factor;
int snap_factor;
int zoom_move_factor;
int pan_speed;
int pan_accel_speed;
int pan_accel_min;
int zoom_speed;
int zoom_accel_speed;
int zoom_accel_min;
} mcu_layer_cam_opts_t;
struct mcu_canvas_s; struct mcu_canvas_s;
typedef struct mcu_layer_s { typedef struct mcu_layer_s {
...@@ -447,7 +464,13 @@ typedef struct mcu_layer_s { ...@@ -447,7 +464,13 @@ typedef struct mcu_layer_s {
int refresh; int refresh;
int clear; int clear;
int is_avatar; int is_avatar;
int crop_point; int crop_x;
int crop_y;
int crop_w;
int crop_h;
int last_w;
int last_h;
uint32_t img_count;
switch_size_t last_img_addr; switch_size_t last_img_addr;
switch_image_t *img; switch_image_t *img;
switch_image_t *cur_img; switch_image_t *cur_img;
...@@ -463,6 +486,12 @@ typedef struct mcu_layer_s { ...@@ -463,6 +486,12 @@ typedef struct mcu_layer_s {
int need_patch; int need_patch;
conference_member_t *member; conference_member_t *member;
switch_frame_t bug_frame; switch_frame_t bug_frame;
switch_frame_geometry_t last_geometry;
switch_frame_geometry_t auto_geometry;
switch_frame_geometry_t zoom_geometry;
switch_frame_geometry_t pan_geometry;
switch_frame_geometry_t manual_geometry;
mcu_layer_cam_opts_t cam_opts;
} mcu_layer_t; } mcu_layer_t;
typedef struct video_layout_s { typedef struct video_layout_s {
...@@ -540,6 +569,7 @@ typedef struct conference_obj { ...@@ -540,6 +569,7 @@ typedef struct conference_obj {
char *la_event_channel; char *la_event_channel;
char *chat_event_channel; char *chat_event_channel;
char *mod_event_channel; char *mod_event_channel;
char *info_event_channel;
char *desc; char *desc;
char *timer_name; char *timer_name;
char *tts_engine; char *tts_engine;
...@@ -809,6 +839,7 @@ struct conference_member { ...@@ -809,6 +839,7 @@ struct conference_member {
char *text_framedata; char *text_framedata;
uint32_t text_framesize; uint32_t text_framesize;
mcu_layer_cam_opts_t cam_opts;
}; };
...@@ -967,6 +998,7 @@ void conference_event_send_rfc(conference_obj_t *conference); ...@@ -967,6 +998,7 @@ void conference_event_send_rfc(conference_obj_t *conference);
void conference_member_update_status_field(conference_member_t *member); void conference_member_update_status_field(conference_member_t *member);
void conference_event_la_command_handler(switch_live_array_t *la, const char *cmd, const char *sessid, cJSON *jla, void *user_data); void conference_event_la_command_handler(switch_live_array_t *la, const char *cmd, const char *sessid, cJSON *jla, void *user_data);
void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join); void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join);
void conference_event_adv_layout(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout);
switch_status_t conference_video_init_canvas(conference_obj_t *conference, video_layout_t *vlayout, mcu_canvas_t **canvasP); switch_status_t conference_video_init_canvas(conference_obj_t *conference, video_layout_t *vlayout, mcu_canvas_t **canvasP);
switch_status_t conference_video_attach_canvas(conference_obj_t *conference, mcu_canvas_t *canvas, int super); switch_status_t conference_video_attach_canvas(conference_obj_t *conference, mcu_canvas_t *canvas, int super);
void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout); void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canvas_t *canvas, video_layout_t *vlayout);
...@@ -980,6 +1012,7 @@ void conference_video_set_canvas_letterbox_bgcolor(mcu_canvas_t *canvas, char *c ...@@ -980,6 +1012,7 @@ void conference_video_set_canvas_letterbox_bgcolor(mcu_canvas_t *canvas, char *c
void conference_video_set_canvas_bgcolor(mcu_canvas_t *canvas, char *color); void conference_video_set_canvas_bgcolor(mcu_canvas_t *canvas, char *color);
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze); void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze);
void conference_video_reset_layer(mcu_layer_t *layer); void conference_video_reset_layer(mcu_layer_t *layer);
void conference_video_reset_layer_cam(mcu_layer_t *layer);
void conference_video_clear_layer(mcu_layer_t *layer); void conference_video_clear_layer(mcu_layer_t *layer);
void conference_video_reset_image(switch_image_t *img, switch_rgb_color_t *color); void conference_video_reset_image(switch_image_t *img, switch_rgb_color_t *color);
void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int HEIGHT); void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int HEIGHT);
...@@ -1111,6 +1144,7 @@ switch_status_t conference_api_sub_check_record(conference_obj_t *conference, sw ...@@ -1111,6 +1144,7 @@ switch_status_t conference_api_sub_check_record(conference_obj_t *conference, sw
switch_status_t conference_api_sub_check_record(conference_obj_t *conference, switch_stream_handle_t *stream, int arc, char **argv); switch_status_t conference_api_sub_check_record(conference_obj_t *conference, switch_stream_handle_t *stream, int arc, char **argv);
switch_status_t conference_api_sub_volume_in(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_volume_in(conference_member_t *member, switch_stream_handle_t *stream, void *data);
switch_status_t conference_api_sub_file_seek(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); switch_status_t conference_api_sub_file_seek(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_cam(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); switch_status_t conference_api_sub_stop(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_hup(conference_member_t *member, switch_stream_handle_t *stream, void *data); switch_status_t conference_api_sub_hup(conference_member_t *member, switch_stream_handle_t *stream, void *data);
switch_status_t conference_api_sub_pauserec(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv); switch_status_t conference_api_sub_pauserec(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
......
...@@ -134,6 +134,10 @@ typedef struct cv_context_s { ...@@ -134,6 +134,10 @@ typedef struct cv_context_s {
char *png_prefix; char *png_prefix;
int tick_speed; int tick_speed;
int confidence_level; int confidence_level;
int max_search_w;
int max_search_h;
int neighbors;
double search_scale;
} cv_context_t; } cv_context_t;
...@@ -484,6 +488,12 @@ static void init_context(cv_context_t *context) ...@@ -484,6 +488,12 @@ static void init_context(cv_context_t *context)
context->cascade_path = switch_core_get_variable_pdup("cv_default_cascade", context->pool); context->cascade_path = switch_core_get_variable_pdup("cv_default_cascade", context->pool);
context->nested_cascade_path = switch_core_get_variable_pdup("cv_default_nested_cascade", context->pool); context->nested_cascade_path = switch_core_get_variable_pdup("cv_default_nested_cascade", context->pool);
context->confidence_level = 20; context->confidence_level = 20;
context->max_search_w = 20;
context->max_search_h = 20;
context->neighbors = 2;
context->search_scale = 1.1;
for (int i = 0; i < MAX_OVERLAY; i++) { for (int i = 0; i < MAX_OVERLAY; i++) {
context->overlay[i] = (struct overlay *) switch_core_alloc(context->pool, sizeof(struct overlay)); context->overlay[i] = (struct overlay *) switch_core_alloc(context->pool, sizeof(struct overlay));
...@@ -588,12 +598,12 @@ void detectAndDraw(cv_context_t *context) ...@@ -588,12 +598,12 @@ void detectAndDraw(cv_context_t *context)
equalizeHist( smallImg, smallImg ); equalizeHist( smallImg, smallImg );
context->cascade->detectMultiScale( smallImg, detectedObjs, context->cascade->detectMultiScale( smallImg, detectedObjs,
1.1, 2, 0 context->search_scale, context->neighbors, 0
|CV_HAAR_FIND_BIGGEST_OBJECT |CV_HAAR_FIND_BIGGEST_OBJECT
|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_DO_ROUGH_SEARCH
|CV_HAAR_SCALE_IMAGE |CV_HAAR_SCALE_IMAGE
, ,
Size(20, 20) ); Size(context->max_search_w, context->max_search_h) );
parse_stats(&context->detected, detectedObjs.size(), context->skip); parse_stats(&context->detected, detectedObjs.size(), context->skip);
...@@ -616,7 +626,7 @@ void detectAndDraw(cv_context_t *context) ...@@ -616,7 +626,7 @@ void detectAndDraw(cv_context_t *context)
double aspect_ratio = (double)r->width/r->height; double aspect_ratio = (double)r->width/r->height;
if (context->shape_idx >= MAX_SHAPES) { if (context->shape_idx >= 1) {//MAX_SHAPES) {
break; break;
} }
...@@ -625,6 +635,7 @@ void detectAndDraw(cv_context_t *context) ...@@ -625,6 +635,7 @@ void detectAndDraw(cv_context_t *context)
center.x = switch_round_to_step(cvRound((r->x + r->width*0.5)*scale), 20); center.x = switch_round_to_step(cvRound((r->x + r->width*0.5)*scale), 20);
center.y = switch_round_to_step(cvRound((r->y + r->height*0.5)*scale), 20); center.y = switch_round_to_step(cvRound((r->y + r->height*0.5)*scale), 20);
radius = switch_round_to_step(cvRound((r->width + r->height)*0.25*scale), 20); radius = switch_round_to_step(cvRound((r->width + r->height)*0.25*scale), 20);
if (context->debug) { if (context->debug) {
circle( img, center, radius, color, 3, 8, 0 ); circle( img, center, radius, color, 3, 8, 0 );
...@@ -679,6 +690,7 @@ void detectAndDraw(cv_context_t *context) ...@@ -679,6 +690,7 @@ void detectAndDraw(cv_context_t *context)
// Draw rectangle reflecting confidence // Draw rectangle reflecting confidence
const int object_neighbors = nestedObjects.size(); const int object_neighbors = nestedObjects.size();
//printf("WTF %d\n", object_neighbors);
//cout << "Detected " << object_neighbors << " object neighbors" << endl; //cout << "Detected " << object_neighbors << " object neighbors" << endl;
const int rect_height = cvRound((float)img.rows * object_neighbors / max_neighbors); const int rect_height = cvRound((float)img.rows * object_neighbors / max_neighbors);
CvScalar col = CV_RGB((float)255 * object_neighbors / max_neighbors, 0, 0); CvScalar col = CV_RGB((float)255 * object_neighbors / max_neighbors, 0, 0);
...@@ -861,9 +873,11 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi ...@@ -861,9 +873,11 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
frame->geometry.y = context->shape[0].cy; frame->geometry.y = context->shape[0].cy;
frame->geometry.w = context->shape[0].w; frame->geometry.w = context->shape[0].w;
frame->geometry.h = context->shape[0].h; frame->geometry.h = context->shape[0].h;
frame->geometry.m = 1; frame->geometry.M++;
frame->geometry.X = 0;
} else { } else {
frame->geometry.m = 0; frame->geometry.M = 0;
frame->geometry.X++;
} }
if (context->overlay_count && (abs || (context->detect_event && context->shape[0].cx))) { if (context->overlay_count && (abs || (context->detect_event && context->shape[0].cx))) {
...@@ -991,7 +1005,7 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv ...@@ -991,7 +1005,7 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
*val++ = '\0'; *val++ = '\0';
} }
if (name && val) { if (name && !zstr(val)) {
if (!strcasecmp(name, "xo")) { if (!strcasecmp(name, "xo")) {
context->overlay[png_idx]->xo = atof(val); context->overlay[png_idx]->xo = atof(val);
} else if (!strcasecmp(name, "nick")) { } else if (!strcasecmp(name, "nick")) {
...@@ -1029,6 +1043,17 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv ...@@ -1029,6 +1043,17 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
context->skip = atoi(val); context->skip = atoi(val);
} else if (!strcasecmp(name, "debug")) { } else if (!strcasecmp(name, "debug")) {
context->debug = atoi(val); context->debug = atoi(val);
} else if (!strcasecmp(name, "neighbors")) {
context->neighbors = atoi(val);
} else if (!strcasecmp(name, "max_search_w")) {
context->max_search_w = atoi(val);
} else if (!strcasecmp(name, "max_search_h")) {
context->max_search_h = atoi(val);
} else if (!strcasecmp(name, "search_scale")) {
double tmp = atof(val);
if (tmp > 1) {
context->search_scale = tmp;
}
} else if (!strcasecmp(name, "confidence")) { } else if (!strcasecmp(name, "confidence")) {
context->confidence_level = atoi(val); context->confidence_level = atoi(val);
} else if (!strcasecmp(name, "cascade")) { } else if (!strcasecmp(name, "cascade")) {
......
...@@ -3898,7 +3898,6 @@ static switch_bool_t verto__unsubscribe_func(const char *method, cJSON *params, ...@@ -3898,7 +3898,6 @@ static switch_bool_t verto__unsubscribe_func(const char *method, cJSON *params,
static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response) static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
{ {
char *json_text = NULL; char *json_text = NULL;
switch_bool_t r = SWITCH_FALSE;
const char *event_channel = cJSON_GetObjectCstr(params, "eventChannel"); const char *event_channel = cJSON_GetObjectCstr(params, "eventChannel");
cJSON *jevent, *broadcast; cJSON *jevent, *broadcast;
const char *display = NULL; const char *display = NULL;
...@@ -3941,11 +3940,12 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js ...@@ -3941,11 +3940,12 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js
if (mcast_socket_send(&jsock->profile->mcast_pub, json_text, strlen(json_text) + 1) <= 0) { if (mcast_socket_send(&jsock->profile->mcast_pub, json_text, strlen(json_text) + 1) <= 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "multicast socket send error! %s\n", strerror(errno)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "multicast socket send error! %s\n", strerror(errno));
r = SWITCH_FALSE; //r = SWITCH_FALSE;
cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Send failure!")); //cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Send failure!"));
} else { } else {
r = SWITCH_TRUE; //r = SWITCH_TRUE;
cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Sent")); //cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Sent"));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MCAST Data Sent\n");
} }
free(json_text); free(json_text);
json_text = NULL; json_text = NULL;
...@@ -3956,7 +3956,7 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js ...@@ -3956,7 +3956,7 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js
end: end:
return r; return SWITCH_TRUE;
} }
static switch_bool_t login_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response) static switch_bool_t login_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论