forked from Mirrors/freeswitch
FS-9742: [mod_conference,mod_cv] Refactor canvas zoom code #resolve
This commit is contained in:
parent
a4eddcafda
commit
da6b9e001c
|
@ -22,6 +22,8 @@ install-maxdemo: all verto-max.js
|
|||
|
||||
install-video_demo: all
|
||||
cp verto-min.js ../video_demo/js
|
||||
cp verto-min.js ../video_demo-live_canvas/js
|
||||
|
||||
install-video_maxdemo: all verto-max.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 @@
|
|||
}
|
||||
});
|
||||
|
||||
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, {
|
||||
handler: function(v, e) {
|
||||
if (typeof(conf.params.chatCallback) === "function") {
|
||||
|
@ -1283,6 +1291,10 @@
|
|||
if (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() {
|
||||
|
@ -1684,6 +1696,14 @@
|
|||
|
||||
//$(".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, {
|
||||
handler: function(v, e) {
|
||||
if (typeof(confMan.params.chatCallback) === "function") {
|
||||
|
|
|
@ -213,8 +213,9 @@ dt.fnClearTable();dt.fnAddData(genArray(obj));dt.fnAdjustColumnSizing();break;ca
|
|||
if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(genArray(obj));}else{dt.fnAddData(genRow(args.data));}
|
||||
dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;}
|
||||
dt.fnUpdate(genRow(args.data),index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(genArray(obj));break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;}
|
||||
if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.conf=function(verto,params){var conf=this;conf.params=$.extend({dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);conf.verto=verto;conf.serno=CONFMAN_SERNO++;createMainModeratorMethods();verto.subscribe(conf.params.laData.modChannel,{handler:function(v,e){if(conf.params.onBroadcast){conf.params.onBroadcast(verto,conf,e.data);}}});verto.subscribe(conf.params.laData.chatChannel,{handler:function(v,e){if(typeof(conf.params.chatCallback)==="function"){conf.params.chatCallback(v,e);}}});};$.verto.conf.prototype.modCommand=function(cmd,id,value){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.conf.prototype.destroy=function(){var conf=this;conf.destroyed=true;conf.params.onBroadcast(conf.verto,conf,'destroy');if(conf.params.laData.modChannel){conf.verto.unsubscribe(conf.params.laData.modChannel);}
|
||||
if(conf.params.laData.chatChannel){conf.verto.unsubscribe(conf.params.laData.chatChannel);}};function createMainModeratorMethods(){$.verto.conf.prototype.listVideoLayouts=function(){this.modCommand("list-videoLayouts",null,null);};$.verto.conf.prototype.play=function(file){this.modCommand("play",null,file);};$.verto.conf.prototype.stop=function(){this.modCommand("stop",null,"all");};$.verto.conf.prototype.deaf=function(memberID){this.modCommand("deaf",parseInt(memberID));};$.verto.conf.prototype.undeaf=function(memberID){this.modCommand("undeaf",parseInt(memberID));};$.verto.conf.prototype.record=function(file){this.modCommand("recording",null,["start",file]);};$.verto.conf.prototype.stopRecord=function(){this.modCommand("recording",null,["stop","all"]);};$.verto.conf.prototype.snapshot=function(file){if(!this.params.hasVid){throw'Conference has no video';}
|
||||
if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.conf=function(verto,params){var conf=this;conf.params=$.extend({dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);conf.verto=verto;conf.serno=CONFMAN_SERNO++;createMainModeratorMethods();verto.subscribe(conf.params.laData.modChannel,{handler:function(v,e){if(conf.params.onBroadcast){conf.params.onBroadcast(verto,conf,e.data);}}});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,{handler:function(v,e){if(typeof(conf.params.chatCallback)==="function"){conf.params.chatCallback(v,e);}}});};$.verto.conf.prototype.modCommand=function(cmd,id,value){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.conf.prototype.destroy=function(){var conf=this;conf.destroyed=true;conf.params.onBroadcast(conf.verto,conf,'destroy');if(conf.params.laData.modChannel){conf.verto.unsubscribe(conf.params.laData.modChannel);}
|
||||
if(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(){$.verto.conf.prototype.listVideoLayouts=function(){this.modCommand("list-videoLayouts",null,null);};$.verto.conf.prototype.play=function(file){this.modCommand("play",null,file);};$.verto.conf.prototype.stop=function(){this.modCommand("stop",null,"all");};$.verto.conf.prototype.deaf=function(memberID){this.modCommand("deaf",parseInt(memberID));};$.verto.conf.prototype.undeaf=function(memberID){this.modCommand("undeaf",parseInt(memberID));};$.verto.conf.prototype.record=function(file){this.modCommand("recording",null,["start",file]);};$.verto.conf.prototype.stopRecord=function(){this.modCommand("recording",null,["stop","all"]);};$.verto.conf.prototype.snapshot=function(file){if(!this.params.hasVid){throw'Conference has no video';}
|
||||
this.modCommand("vid-write-png",null,file);};$.verto.conf.prototype.setVideoLayout=function(layout,canvasID){if(!this.params.hasVid){throw'Conference has no video';}
|
||||
if(canvasID){this.modCommand("vid-layout",null,[layout,canvasID]);}else{this.modCommand("vid-layout",null,layout);}};$.verto.conf.prototype.kick=function(memberID){this.modCommand("kick",parseInt(memberID));};$.verto.conf.prototype.muteMic=function(memberID){this.modCommand("tmute",parseInt(memberID));};$.verto.conf.prototype.muteVideo=function(memberID){if(!this.params.hasVid){throw'Conference has no video';}
|
||||
this.modCommand("tvmute",parseInt(memberID));};$.verto.conf.prototype.presenter=function(memberID){if(!this.params.hasVid){throw'Conference has no video';}
|
||||
|
@ -230,7 +231,7 @@ html+="<br>"+"<button class='ctlbtn' id='"+layer_set_id+"'>Set Layer</button>"+"
|
|||
jq.html(html);if(!jq.data("mouse")){$("#"+box_id).hide();}
|
||||
jq.mouseover(function(e){jq.data({"mouse":true});$("#"+box_id).show();});jq.mouseout(function(e){jq.data({"mouse":false});$("#"+box_id).hide();});$("#"+transfer_id).click(function(){var xten=prompt("Enter Extension");if(xten){confMan.modCommand("transfer",x,xten);}});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+layer_set_id).click(function(){var cid=prompt("Please enter layer ID","");if(cid){confMan.modCommand("vid-layer",x,cid);}});$("#"+layer_next_id).click(function(){confMan.modCommand("vid-layer",x,"next");});$("#"+layer_prev_id).click(function(){confMan.modCommand("vid-layer",x,"prev");});$("#"+canvas_in_set_id).click(function(){var cid=prompt("Please enter canvas ID","");if(cid){confMan.modCommand("vid-canvas",x,cid);}});$("#"+canvas_out_set_id).click(function(){var cid=prompt("Please enter canvas ID","");if(cid){confMan.modCommand("vid-watching-canvas",x,cid);}});$("#"+canvas_in_next_id).click(function(){confMan.modCommand("vid-canvas",x,"next");});$("#"+canvas_in_prev_id).click(function(){confMan.modCommand("vid-canvas",x,"prev");});$("#"+canvas_out_next_id).click(function(){confMan.modCommand("vid-watching-canvas",x,"next");});$("#"+canvas_out_prev_id).click(function(){confMan.modCommand("vid-watching-canvas",x,"prev");});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});if(confMan.params.hasVid){$("#"+tvmute_id).click(function(){confMan.modCommand("tvmute",x);});$("#"+tvpresenter_id).click(function(){confMan.modCommand("vid-res-id",x,"presenter");});$("#"+tvfloor_id).click(function(){confMan.modCommand("vid-floor",x,"force");});$("#"+vbanner_id).click(function(){var text=prompt("Please enter text","");if(text){confMan.modCommand("vid-banner",x,escape(text));}});}
|
||||
$("#"+gainup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+gaindn_id).click(function(){confMan.modCommand("volume_in",x,"down");});$("#"+volup_id).click(function(){confMan.modCommand("volume_out",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_out",x,"down");});return html;}
|
||||
var atitle="";var awidth=0;verto.subscribe(confMan.params.laData.chatChannel,{handler:function(v,e){if(typeof(confMan.params.chatCallback)==="function"){confMan.params.chatCallback(v,e);}}});if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=600;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready<br><br>");}else{$(confMan.params.mainModID).html("");}
|
||||
var atitle="";var awidth=0;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,{handler:function(v,e){if(typeof(confMan.params.chatCallback)==="function"){confMan.params.chatCallback(v,e);}}});if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=600;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready<br><br>");}else{$(confMan.params.mainModID).html("");}
|
||||
verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);}
|
||||
if(e.data["conf-command"]==="list-videoLayouts"){for(var j=0;j<confMan.canvasCount;j++){var vlselect_id="#confman_vl_select_"+j+"_"+confMan.serno;var vlayout_id="#confman_vid_layout_"+j+"_"+confMan.serno;var x=0;var options;$(vlselect_id).selectmenu({});$(vlselect_id).selectmenu("enable");$(vlselect_id).empty();$(vlselect_id).append(new Option("Choose a Layout","none"));if(e.data.responseData){var rdata=[];for(var i in e.data.responseData){rdata.push(e.data.responseData[i].name);}
|
||||
options=rdata.sort(function(a,b){var ga=a.substring(0,6)=="group:"?true:false;var gb=b.substring(0,6)=="group:"?true:false;if((ga||gb)&&ga!=gb){return ga?-1:1;}
|
||||
|
|
|
@ -40,14 +40,15 @@
|
|||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
struct switch_frame_geometry {
|
||||
typedef struct switch_frame_geometry {
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t z;
|
||||
uint32_t m;
|
||||
};
|
||||
uint32_t M;
|
||||
uint32_t X;
|
||||
} switch_frame_geometry_t;
|
||||
|
||||
/*! \brief An abstraction of a data frame */
|
||||
struct switch_frame {
|
||||
|
|
|
@ -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>]"},
|
||||
{"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>"},
|
||||
{"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>]"},
|
||||
{"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>]"},
|
||||
|
@ -2009,6 +2010,262 @@ switch_status_t conference_api_sub_saymember(conference_obj_t *conference, switc
|
|||
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)
|
||||
{
|
||||
uint8_t current = 0, all = 0, async = 0;
|
||||
|
|
|
@ -237,14 +237,22 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
|
|||
const void *vvar;
|
||||
cJSON *array = cJSON_CreateArray();
|
||||
conference_obj_t *conference = NULL;
|
||||
int i;
|
||||
|
||||
if ((conference = conference_find(conference_name, NULL))) {
|
||||
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) {
|
||||
for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||
video_layout_t *vlayout;
|
||||
cJSON *obj = cJSON_CreateObject();
|
||||
cJSON *resarray = cJSON_CreateArray();
|
||||
int i;
|
||||
|
||||
switch_core_hash_this(hi, &vvar, NULL, &val);
|
||||
vlayout = (video_layout_t *)val;
|
||||
|
@ -292,6 +300,83 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
|
|||
switch_thread_rwlock_unlock(conference->rwlock);
|
||||
}
|
||||
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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -501,6 +639,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
|
|||
switch_event_t *variables;
|
||||
switch_event_header_t *hp;
|
||||
char idstr[128] = "";
|
||||
int i;
|
||||
|
||||
snprintf(idstr, sizeof(idstr), "%d", member->id);
|
||||
msg = cJSON_CreateObject();
|
||||
|
@ -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, "infoChannel", cJSON_CreateString(conference->info_event_channel));
|
||||
|
||||
switch_core_get_variables(&variables);
|
||||
for (hp = variables->headers; hp; hp = hp->next) {
|
||||
|
@ -538,12 +678,19 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
|
|||
}
|
||||
switch_event_destroy(&variables);
|
||||
|
||||
switch_event_channel_broadcast(event_channel, &msg, "mod_conference", conference_globals.event_channel_id);
|
||||
|
||||
if (cookie) {
|
||||
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->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,6 +349,45 @@ void conference_video_clear_layer(mcu_layer_t *layer)
|
|||
|
||||
}
|
||||
|
||||
static void set_default_cam_opts(mcu_layer_t *layer)
|
||||
{
|
||||
//layer->cam_opts.autozoom = 1;
|
||||
//layer->cam_opts.autopan = 1;
|
||||
layer->cam_opts.manual_pan = 0;
|
||||
layer->cam_opts.manual_zoom = 0;
|
||||
layer->cam_opts.zoom_factor = 3;
|
||||
layer->cam_opts.snap_factor = 25;
|
||||
layer->cam_opts.zoom_move_factor = 125;
|
||||
layer->cam_opts.pan_speed = 3;
|
||||
layer->cam_opts.pan_accel_speed = 10;
|
||||
layer->cam_opts.pan_accel_min = 50;
|
||||
layer->cam_opts.zoom_speed = 3;
|
||||
layer->cam_opts.zoom_accel_speed = 10;
|
||||
layer->cam_opts.zoom_accel_min = 50;
|
||||
}
|
||||
|
||||
|
||||
void conference_video_reset_layer_cam(mcu_layer_t *layer)
|
||||
{
|
||||
layer->crop_x = 0;
|
||||
layer->crop_y = 0;
|
||||
layer->crop_w = 0;
|
||||
layer->crop_h = 0;
|
||||
layer->last_w = 0;
|
||||
layer->last_h = 0;
|
||||
layer->img_count = 0;
|
||||
|
||||
memset(&layer->bug_frame, 0, sizeof(layer->bug_frame));
|
||||
memset(&layer->auto_geometry, 0, sizeof(layer->auto_geometry));
|
||||
memset(&layer->pan_geometry, 0, sizeof(layer->pan_geometry));
|
||||
memset(&layer->zoom_geometry, 0, sizeof(layer->zoom_geometry));
|
||||
memset(&layer->last_geometry, 0, sizeof(layer->last_geometry));
|
||||
|
||||
set_default_cam_opts(layer);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void conference_video_reset_layer(mcu_layer_t *layer)
|
||||
{
|
||||
switch_img_free(&layer->banner_img);
|
||||
|
@ -361,7 +400,7 @@ void conference_video_reset_layer(mcu_layer_t *layer)
|
|||
layer->is_avatar = 0;
|
||||
layer->need_patch = 0;
|
||||
|
||||
memset(&layer->bug_frame, 0, sizeof(layer->bug_frame));
|
||||
conference_video_reset_layer_cam(layer);
|
||||
|
||||
if (layer->geometry.overlap) {
|
||||
layer->canvas->refresh = 1;
|
||||
|
@ -375,36 +414,73 @@ void conference_video_reset_layer(mcu_layer_t *layer)
|
|||
switch_img_free(&layer->cur_img);
|
||||
}
|
||||
|
||||
static void set_pan(mcu_layer_t *layer, int crop_point, int max_width)
|
||||
static void set_pan(int crop_point, int *target_point, int accel_speed, int accel_min, int speed)
|
||||
{
|
||||
if (layer->crop_point <= 0 || layer->crop_point > max_width) {
|
||||
layer->crop_point = crop_point;
|
||||
} else if (crop_point > layer->crop_point) {
|
||||
if (crop_point - layer->crop_point > 25) {
|
||||
layer->crop_point += 5;
|
||||
|
||||
if (crop_point > *target_point) {
|
||||
if ((crop_point - *target_point) > accel_min) {
|
||||
*target_point += accel_speed;
|
||||
} else {
|
||||
layer->crop_point++;
|
||||
*target_point += speed;
|
||||
}
|
||||
|
||||
if (crop_point < layer->crop_point) {
|
||||
layer->crop_point = crop_point;
|
||||
if (*target_point > crop_point) {
|
||||
*target_point = crop_point;
|
||||
}
|
||||
} else if (crop_point < layer->crop_point) {
|
||||
if (layer->crop_point - crop_point > 25) {
|
||||
layer->crop_point -= 5;
|
||||
} else if (crop_point < *target_point) {
|
||||
|
||||
if ((*target_point - crop_point) > accel_min) {
|
||||
*target_point -= accel_speed;
|
||||
} else {
|
||||
layer->crop_point--;
|
||||
*target_point -= speed;
|
||||
}
|
||||
|
||||
if (crop_point > layer->crop_point) {
|
||||
layer->crop_point = crop_point;
|
||||
if (*target_point < crop_point) {
|
||||
*target_point = crop_point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_bounds(int *x, int *y, int img_w, int img_h, int crop_w, int crop_h)
|
||||
{
|
||||
int crop_x = *x;
|
||||
int crop_y = *y;
|
||||
|
||||
if (crop_x < 0) {
|
||||
crop_x = 0;
|
||||
}
|
||||
|
||||
if (crop_y < 0) {
|
||||
crop_y = 0;
|
||||
}
|
||||
|
||||
if (crop_x + crop_w > img_w) {
|
||||
crop_x = img_w - crop_w;
|
||||
}
|
||||
|
||||
if (crop_y + crop_h > img_h) {
|
||||
crop_y = img_h - crop_h;
|
||||
}
|
||||
|
||||
if (crop_x < 0) {
|
||||
crop_x = 0;
|
||||
}
|
||||
|
||||
if (crop_y < 0) {
|
||||
crop_y = 0;
|
||||
}
|
||||
|
||||
*x = crop_x;
|
||||
*y = crop_y;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze)
|
||||
{
|
||||
switch_image_t *IMG, *img;
|
||||
int img_changed = 0;
|
||||
|
||||
switch_mutex_lock(layer->canvas->mutex);
|
||||
|
||||
|
@ -417,6 +493,47 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
switch_mutex_unlock(layer->canvas->mutex);
|
||||
return;
|
||||
}
|
||||
//printf("RAW %dx%d\n", img->d_w, img->d_h);
|
||||
|
||||
if (layer->img_count++ == 0 || layer->last_w != img->d_w || layer->last_h != img->d_h) {
|
||||
double change_scale;
|
||||
|
||||
if (img->d_w && layer->last_w) {
|
||||
if (img->d_w < layer->last_w) {
|
||||
change_scale = layer->last_w / img->d_w;
|
||||
} else {
|
||||
change_scale = img->d_w / layer->last_w;
|
||||
}
|
||||
|
||||
layer->crop_x = (int)(layer->crop_x * change_scale);
|
||||
layer->crop_y = (int)(layer->crop_y * change_scale);
|
||||
layer->crop_w = (int)(layer->crop_w * change_scale);
|
||||
layer->crop_h = (int)(layer->crop_h * change_scale);
|
||||
|
||||
layer->zoom_geometry.x = (int)(layer->zoom_geometry.x * change_scale);
|
||||
layer->zoom_geometry.y = (int)(layer->zoom_geometry.y * change_scale);
|
||||
layer->zoom_geometry.w = (int)(layer->zoom_geometry.w * change_scale);
|
||||
layer->zoom_geometry.h = (int)(layer->zoom_geometry.h * change_scale);
|
||||
|
||||
|
||||
layer->pan_geometry.x = (int)(layer->pan_geometry.x * change_scale);
|
||||
layer->pan_geometry.y = (int)(layer->pan_geometry.y * change_scale);
|
||||
layer->pan_geometry.w = (int)(layer->pan_geometry.w * change_scale);
|
||||
layer->pan_geometry.h = (int)(layer->pan_geometry.h * change_scale);
|
||||
|
||||
}
|
||||
|
||||
memset(&layer->auto_geometry, 0, sizeof(layer->auto_geometry));
|
||||
//memset(&layer->zoom_geometry, 0, sizeof(layer->zoom_geometry));
|
||||
//memset(&layer->pan_geometry, 0, sizeof(layer->pan_geometry));
|
||||
memset(&layer->last_geometry, 0, sizeof(layer->last_geometry));
|
||||
|
||||
img_changed = 1;
|
||||
}
|
||||
|
||||
layer->last_w = img->d_w;
|
||||
layer->last_h = img->d_h;
|
||||
|
||||
|
||||
if (layer->bugged) {
|
||||
if (layer->member_id > -1 && layer->member && switch_thread_rwlock_tryrdlock(layer->member->rwlock) == SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -427,7 +544,39 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
switch_thread_rwlock_unlock(layer->member->rwlock);
|
||||
}
|
||||
|
||||
if ((!layer->manual_geometry.w ||
|
||||
(layer->last_geometry.x && abs(layer->manual_geometry.x - layer->last_geometry.x) > layer->cam_opts.zoom_move_factor) ||
|
||||
(layer->last_geometry.y && abs(layer->manual_geometry.y - layer->last_geometry.y) > layer->cam_opts.zoom_move_factor) ||
|
||||
(layer->last_geometry.w && abs(layer->manual_geometry.w - layer->last_geometry.w) > layer->cam_opts.zoom_move_factor / 2))) {
|
||||
switch_event_t *event;
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "action", "movement-detection");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "member_id", "%d", layer->member_id);
|
||||
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "last_x", "%d", layer->manual_geometry.x);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "last_y", "%d", layer->manual_geometry.y);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "last_w", "%d", layer->manual_geometry.w);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "last_h", "%d", layer->manual_geometry.h);
|
||||
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "new_x", "%d", layer->bug_frame.geometry.x);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "new_y", "%d", layer->bug_frame.geometry.y);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "new_w", "%d", layer->bug_frame.geometry.w);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "new_h", "%d", layer->bug_frame.geometry.h);
|
||||
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
layer->manual_geometry = layer->bug_frame.geometry;
|
||||
}
|
||||
|
||||
layer->bugged = 0;
|
||||
} else {
|
||||
if (layer->bug_frame.geometry.w) {
|
||||
memset(&layer->bug_frame, 0, sizeof(layer->bug_frame));
|
||||
}
|
||||
layer->cam_opts.autozoom = 0;
|
||||
layer->cam_opts.autopan = 0;
|
||||
}
|
||||
|
||||
if (layer->clear) {
|
||||
|
@ -446,7 +595,7 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
int x_pos = layer->x_pos;
|
||||
int y_pos = layer->y_pos;
|
||||
switch_size_t img_addr = 0;
|
||||
|
||||
switch_frame_geometry_t *use_geometry = &layer->auto_geometry;
|
||||
img_w = layer->screen_w = (uint32_t)(IMG->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE);
|
||||
img_h = layer->screen_h = (uint32_t)(IMG->d_h * layer->geometry.hscale / VIDEO_LAYOUT_SCALE);
|
||||
|
||||
|
@ -456,76 +605,184 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
|
||||
img_addr = (switch_size_t)img;
|
||||
|
||||
if (layer->last_img_addr != img_addr && layer->geometry.zoom) {
|
||||
uint32_t new_w = 0, new_h = 0;
|
||||
int crop_point = 0;
|
||||
|
||||
if (layer->last_img_addr != img_addr && (layer->geometry.zoom || layer->cam_opts.autozoom ||
|
||||
layer->cam_opts.autopan || layer->cam_opts.manual_pan || layer->cam_opts.manual_zoom)) {
|
||||
|
||||
double scale = 1;
|
||||
int crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0, zoom_w = 0, zoom_h = 0;
|
||||
int can_pan = 0;
|
||||
int can_zoom = 0;
|
||||
int did_zoom = 0;
|
||||
|
||||
if (screen_aspect < img_aspect) {
|
||||
|
||||
if (img->d_h != layer->screen_h) {
|
||||
scale = (double)layer->screen_h / img->d_h;
|
||||
}
|
||||
|
||||
new_w = (uint32_t)((double)layer->screen_w / scale);
|
||||
new_h = (uint32_t)((double)layer->screen_h / scale);
|
||||
|
||||
if (layer->bug_frame.geometry.w) {
|
||||
//new_w = layer->bug_frame.geometry.w * 2;
|
||||
//new_h = new_w / screen_aspect;
|
||||
crop_point = switch_round_to_step(layer->bug_frame.geometry.x - (new_w / 2), 25);
|
||||
} else {
|
||||
crop_point = (img->d_w - new_w) / 2;
|
||||
}
|
||||
|
||||
if (crop_point < 1) {
|
||||
crop_point = 1;
|
||||
} else if (crop_point > img->d_w - new_w) {
|
||||
crop_point = img->d_w - new_w;
|
||||
}
|
||||
|
||||
set_pan(layer, crop_point, img->d_w - new_w);
|
||||
|
||||
if (layer->crop_point > 0) {
|
||||
switch_img_set_rect(img, layer->crop_point, 0, new_w, new_h);
|
||||
img_aspect = (double) img->d_w / img->d_h;
|
||||
}
|
||||
|
||||
} else if (screen_aspect > img_aspect) {
|
||||
|
||||
if (img->d_w != layer->screen_w) {
|
||||
scale = (double)layer->screen_w / img->d_w;
|
||||
}
|
||||
}
|
||||
|
||||
if (scale == 1) {
|
||||
crop_w = img->d_w;
|
||||
crop_h = img->d_h;
|
||||
} else {
|
||||
crop_w = (uint32_t)((double)layer->screen_w / scale);
|
||||
crop_h = (uint32_t)((double)layer->screen_h / scale);
|
||||
}
|
||||
|
||||
new_w = (uint32_t)((double)layer->screen_w / scale);
|
||||
new_h = (uint32_t)((double)layer->screen_h / scale);
|
||||
//if (layer->bug_frame.geometry.X > 90) {
|
||||
// memset(&layer->auto_geometry, 0, sizeof(layer->auto_geometry));
|
||||
//}
|
||||
|
||||
if (layer->cam_opts.autopan) {
|
||||
can_pan = layer->bug_frame.geometry.w && (layer->geometry.zoom || layer->cam_opts.manual_zoom);
|
||||
} else {
|
||||
can_pan = layer->cam_opts.manual_pan && (layer->geometry.zoom || layer->cam_opts.manual_zoom);
|
||||
}
|
||||
|
||||
if (layer->bug_frame.geometry.w) {
|
||||
crop_point = layer->bug_frame.geometry.y - (new_h / 2);
|
||||
if (layer->cam_opts.autozoom) {
|
||||
can_zoom = layer->bug_frame.geometry.w;
|
||||
} else {
|
||||
can_zoom = layer->cam_opts.manual_zoom && layer->zoom_geometry.w;
|
||||
}
|
||||
|
||||
//printf("CHECK %d %d,%d %d,%d %d/%d\n", layer->auto_geometry.w,
|
||||
// layer->last_geometry.x, layer->last_geometry.y,
|
||||
// layer->auto_geometry.x, layer->auto_geometry.y,
|
||||
// abs(layer->auto_geometry.x - layer->last_geometry.x),
|
||||
// abs(layer->auto_geometry.y - layer->last_geometry.y));
|
||||
|
||||
if ((layer->cam_opts.autozoom || layer->cam_opts.autopan) &&
|
||||
(!layer->auto_geometry.w ||
|
||||
(layer->last_geometry.x && abs(layer->auto_geometry.x - layer->last_geometry.x) > layer->cam_opts.zoom_move_factor) ||
|
||||
(layer->last_geometry.y && abs(layer->auto_geometry.y - layer->last_geometry.y) > layer->cam_opts.zoom_move_factor) ||
|
||||
(layer->last_geometry.w && abs(layer->auto_geometry.w - layer->last_geometry.w) > layer->cam_opts.zoom_move_factor / 2))) {
|
||||
|
||||
layer->auto_geometry = layer->bug_frame.geometry;
|
||||
}
|
||||
|
||||
if (can_zoom) {
|
||||
|
||||
if (layer->cam_opts.autozoom) {
|
||||
use_geometry = &layer->auto_geometry;
|
||||
} else {
|
||||
crop_point = (img->d_h - new_h) / 2;
|
||||
use_geometry = &layer->zoom_geometry;
|
||||
}
|
||||
|
||||
if (crop_point < 1) {
|
||||
crop_point = 1;
|
||||
} else if (crop_point > img->d_h - new_h) {
|
||||
crop_point = img->d_h - new_h;
|
||||
}
|
||||
zoom_w = use_geometry->w * layer->cam_opts.zoom_factor;
|
||||
zoom_h = zoom_w / screen_aspect;
|
||||
|
||||
if (zoom_w < crop_w && zoom_h < crop_h) {
|
||||
int c_x = use_geometry->x;
|
||||
int c_y = use_geometry->y;
|
||||
|
||||
crop_w = zoom_w;
|
||||
crop_h = zoom_h;
|
||||
|
||||
//crop_w = switch_round_to_step(crop_w, layer->cam_opts.snap_factor);
|
||||
//crop_h = switch_round_to_step(crop_h, layer->cam_opts.snap_factor);
|
||||
|
||||
set_pan(layer, crop_point, img->d_h - new_h);
|
||||
if (layer->cam_opts.autozoom) {
|
||||
did_zoom = 1;
|
||||
}
|
||||
|
||||
|
||||
if (crop_point > 0) {
|
||||
switch_img_set_rect(img, 0, crop_point, (unsigned int)(layer->screen_w/scale), (unsigned int)(layer->screen_h/scale));
|
||||
img_aspect = (double) img->d_w / img->d_h;
|
||||
if (layer->cam_opts.autozoom) {
|
||||
c_x = switch_round_to_step(c_x, layer->cam_opts.snap_factor);
|
||||
c_y = switch_round_to_step(c_y, layer->cam_opts.snap_factor);
|
||||
|
||||
crop_x = c_x - (crop_w / 2);
|
||||
crop_y = c_y - (crop_h / 2);
|
||||
} else {
|
||||
crop_x = c_x;
|
||||
crop_y = c_y;
|
||||
}
|
||||
|
||||
set_bounds(&crop_x, &crop_y, img->d_w, img->d_h, crop_w, crop_h);
|
||||
|
||||
//printf("ZOOM %d,%d %d,%d %dx%d\n", crop_x, crop_y, c_x, c_y, zoom_w, zoom_h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!did_zoom) {
|
||||
|
||||
if (layer->cam_opts.autopan) {
|
||||
use_geometry = &layer->auto_geometry;
|
||||
} else {
|
||||
use_geometry = &layer->pan_geometry;
|
||||
}
|
||||
|
||||
if (can_pan) {
|
||||
if (layer->cam_opts.autopan) {
|
||||
crop_x = use_geometry->x - (crop_w / 2);
|
||||
} else {
|
||||
crop_x = use_geometry->x;
|
||||
}
|
||||
} else if (screen_aspect > img_aspect) {
|
||||
crop_x = img->d_w / 4;
|
||||
}
|
||||
|
||||
if (can_pan) {
|
||||
if (layer->cam_opts.autopan) {
|
||||
crop_y = use_geometry->y - (crop_h / 2);
|
||||
} else {
|
||||
crop_y = use_geometry->y;
|
||||
}
|
||||
} else if (screen_aspect < img_aspect) {
|
||||
crop_y = img->d_h / 4;
|
||||
}
|
||||
|
||||
crop_x = switch_round_to_step(crop_x, layer->cam_opts.snap_factor);
|
||||
crop_y = switch_round_to_step(crop_y, layer->cam_opts.snap_factor);
|
||||
}
|
||||
|
||||
//printf("BOUNDS B4 %d,%d %dx%d %dx%d\n", crop_x, crop_y, img->d_w, img->d_h, crop_w, crop_h);
|
||||
set_bounds(&crop_x, &crop_y, img->d_w, img->d_h, crop_w, crop_h);
|
||||
//printf("BOUNDS AF %d,%d %dx%d %dx%d\n", crop_x, crop_y, img->d_w, img->d_h, crop_w, crop_h);
|
||||
|
||||
if (img_changed) {
|
||||
layer->crop_x = crop_x;
|
||||
layer->crop_y = crop_y;
|
||||
layer->crop_w = crop_w;
|
||||
layer->crop_h = crop_h;
|
||||
}
|
||||
|
||||
//printf("B4 %d,%d %d,%d\n", crop_x, crop_y, layer->crop_x, layer->crop_y);
|
||||
|
||||
|
||||
set_pan(crop_x, &layer->crop_x, layer->cam_opts.pan_accel_speed, layer->cam_opts.pan_accel_min, layer->cam_opts.pan_speed);
|
||||
set_pan(crop_y, &layer->crop_y, layer->cam_opts.pan_accel_speed, layer->cam_opts.pan_accel_min, layer->cam_opts.pan_speed);
|
||||
|
||||
//printf("AF %d,%d\n", layer->crop_x, layer->crop_y);
|
||||
|
||||
|
||||
//printf("B4 %dx%d %dx%d\n", crop_w, crop_h, layer->crop_w, layer->crop_h);
|
||||
set_pan(crop_w, &layer->crop_w, layer->cam_opts.zoom_accel_speed, layer->cam_opts.zoom_accel_min, layer->cam_opts.zoom_speed);
|
||||
layer->crop_h = layer->crop_w / screen_aspect;
|
||||
|
||||
set_bounds(&layer->crop_x, &layer->crop_y, img->d_w, img->d_h, layer->crop_w, layer->crop_h);
|
||||
|
||||
assert(layer->crop_w > 0);
|
||||
|
||||
//printf("RECT %d,%d %dx%d (%dx%d) [%dx%d] [%dx%d]\n", layer->crop_x, layer->crop_y, layer->crop_w, layer->crop_h, layer->crop_w + layer->crop_x, layer->crop_h + layer->crop_y, img->d_w, img->d_h, layer->screen_w, layer->screen_h);
|
||||
|
||||
switch_img_set_rect(img, layer->crop_x, layer->crop_y, layer->crop_w, layer->crop_h);
|
||||
switch_assert(img->d_w == layer->crop_w);
|
||||
|
||||
img_aspect = (double) img->d_w / img->d_h;
|
||||
|
||||
}
|
||||
|
||||
layer->last_geometry = layer->bug_frame.geometry;
|
||||
|
||||
if (freeze) {
|
||||
switch_img_free(&layer->img);
|
||||
}
|
||||
|
||||
|
||||
if (screen_aspect > img_aspect) {
|
||||
img_w = (uint32_t)ceil((double)img_aspect * layer->screen_h);
|
||||
x_pos += (layer->screen_w - img_w) / 2;
|
||||
|
@ -565,9 +822,12 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
img_w -= (layer->geometry.border * 2);
|
||||
img_h -= (layer->geometry.border * 2);
|
||||
|
||||
//printf("SCALE %d,%d %dx%d\n", x_pos, y_pos, img_w, img_h);
|
||||
|
||||
switch_img_scale(img, &layer->img, img_w, img_h);
|
||||
|
||||
if (layer->img) {
|
||||
//switch_img_copy(img, &layer->img);
|
||||
switch_img_patch(IMG, layer->img, x_pos + layer->geometry.border, y_pos + layer->geometry.border);
|
||||
}
|
||||
|
||||
|
@ -734,6 +994,8 @@ void conference_video_detach_video_layer(conference_member_t *member)
|
|||
switch_img_txt_handle_destroy(&layer->txthandle);
|
||||
}
|
||||
|
||||
member->cam_opts = layer->cam_opts;
|
||||
|
||||
conference_video_reset_layer(layer);
|
||||
layer->member_id = 0;
|
||||
layer->member = NULL;
|
||||
|
@ -1121,6 +1383,9 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
|
|||
|
||||
for (i = 0; i < vlayout->layers; i++) {
|
||||
mcu_layer_t *layer = &canvas->layers[i];
|
||||
|
||||
conference_video_reset_layer(layer);
|
||||
|
||||
layer->geometry.x = vlayout->images[i].x;
|
||||
layer->geometry.y = vlayout->images[i].y;
|
||||
layer->geometry.hscale = vlayout->images[i].scale;
|
||||
|
@ -1137,7 +1402,6 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
|
|||
layer->idx = i;
|
||||
layer->refresh = 1;
|
||||
|
||||
|
||||
layer->screen_w = (uint32_t)(canvas->img->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE);
|
||||
layer->screen_h = (uint32_t)(canvas->img->d_h * layer->geometry.hscale / VIDEO_LAYOUT_SCALE);
|
||||
|
||||
|
@ -1147,6 +1411,8 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
|
|||
layer->x_pos = (int)(canvas->img->d_w * layer->geometry.x / VIDEO_LAYOUT_SCALE);
|
||||
layer->y_pos = (int)(canvas->img->d_h * layer->geometry.y / VIDEO_LAYOUT_SCALE);
|
||||
|
||||
set_default_cam_opts(layer);
|
||||
|
||||
|
||||
if (layer->geometry.floor) {
|
||||
canvas->layout_floor_id = i;
|
||||
|
@ -1199,6 +1465,8 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
|
|||
switch_mutex_unlock(canvas->mutex);
|
||||
switch_thread_rwlock_unlock(canvas->video_rwlock);
|
||||
|
||||
conference_event_adv_layout(conference, canvas, vlayout);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Canvas position %d applied layout %s\n", canvas->canvas_id + 1, vlayout->name);
|
||||
|
||||
}
|
||||
|
|
|
@ -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_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 (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
|
|||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create");
|
||||
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:
|
||||
|
||||
switch_mutex_unlock(conference_globals.hash_mutex);
|
||||
|
|
|
@ -429,6 +429,23 @@ typedef struct mcu_layer_def_s {
|
|||
mcu_layer_geometry_t layers[MCU_MAX_LAYERS];
|
||||
} 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;
|
||||
|
||||
typedef struct mcu_layer_s {
|
||||
|
@ -447,7 +464,13 @@ typedef struct mcu_layer_s {
|
|||
int refresh;
|
||||
int clear;
|
||||
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_image_t *img;
|
||||
switch_image_t *cur_img;
|
||||
|
@ -463,6 +486,12 @@ typedef struct mcu_layer_s {
|
|||
int need_patch;
|
||||
conference_member_t *member;
|
||||
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;
|
||||
|
||||
typedef struct video_layout_s {
|
||||
|
@ -540,6 +569,7 @@ typedef struct conference_obj {
|
|||
char *la_event_channel;
|
||||
char *chat_event_channel;
|
||||
char *mod_event_channel;
|
||||
char *info_event_channel;
|
||||
char *desc;
|
||||
char *timer_name;
|
||||
char *tts_engine;
|
||||
|
@ -809,6 +839,7 @@ struct conference_member {
|
|||
char *text_framedata;
|
||||
uint32_t text_framesize;
|
||||
|
||||
mcu_layer_cam_opts_t cam_opts;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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_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_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_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);
|
||||
|
@ -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_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_cam(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_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
|
|||
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_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_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);
|
||||
|
|
|
@ -134,6 +134,10 @@ typedef struct cv_context_s {
|
|||
char *png_prefix;
|
||||
int tick_speed;
|
||||
int confidence_level;
|
||||
int max_search_w;
|
||||
int max_search_h;
|
||||
int neighbors;
|
||||
double search_scale;
|
||||
} cv_context_t;
|
||||
|
||||
|
||||
|
@ -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->nested_cascade_path = switch_core_get_variable_pdup("cv_default_nested_cascade", context->pool);
|
||||
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++) {
|
||||
context->overlay[i] = (struct overlay *) switch_core_alloc(context->pool, sizeof(struct overlay));
|
||||
|
@ -588,12 +598,12 @@ void detectAndDraw(cv_context_t *context)
|
|||
equalizeHist( smallImg, smallImg );
|
||||
|
||||
context->cascade->detectMultiScale( smallImg, detectedObjs,
|
||||
1.1, 2, 0
|
||||
context->search_scale, context->neighbors, 0
|
||||
|CV_HAAR_FIND_BIGGEST_OBJECT
|
||||
|CV_HAAR_DO_ROUGH_SEARCH
|
||||
|CV_HAAR_SCALE_IMAGE
|
||||
,
|
||||
Size(20, 20) );
|
||||
Size(context->max_search_w, context->max_search_h) );
|
||||
|
||||
|
||||
parse_stats(&context->detected, detectedObjs.size(), context->skip);
|
||||
|
@ -616,7 +626,7 @@ void detectAndDraw(cv_context_t *context)
|
|||
|
||||
double aspect_ratio = (double)r->width/r->height;
|
||||
|
||||
if (context->shape_idx >= MAX_SHAPES) {
|
||||
if (context->shape_idx >= 1) {//MAX_SHAPES) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -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.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);
|
||||
|
||||
|
||||
if (context->debug) {
|
||||
circle( img, center, radius, color, 3, 8, 0 );
|
||||
|
@ -679,6 +690,7 @@ void detectAndDraw(cv_context_t *context)
|
|||
|
||||
// Draw rectangle reflecting confidence
|
||||
const int object_neighbors = nestedObjects.size();
|
||||
//printf("WTF %d\n", object_neighbors);
|
||||
//cout << "Detected " << object_neighbors << " object neighbors" << endl;
|
||||
const int rect_height = cvRound((float)img.rows * object_neighbors / max_neighbors);
|
||||
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
|
|||
frame->geometry.y = context->shape[0].cy;
|
||||
frame->geometry.w = context->shape[0].w;
|
||||
frame->geometry.h = context->shape[0].h;
|
||||
frame->geometry.m = 1;
|
||||
frame->geometry.M++;
|
||||
frame->geometry.X = 0;
|
||||
} else {
|
||||
frame->geometry.m = 0;
|
||||
frame->geometry.M = 0;
|
||||
frame->geometry.X++;
|
||||
}
|
||||
|
||||
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
|
|||
*val++ = '\0';
|
||||
}
|
||||
|
||||
if (name && val) {
|
||||
if (name && !zstr(val)) {
|
||||
if (!strcasecmp(name, "xo")) {
|
||||
context->overlay[png_idx]->xo = atof(val);
|
||||
} else if (!strcasecmp(name, "nick")) {
|
||||
|
@ -1029,6 +1043,17 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
|
|||
context->skip = atoi(val);
|
||||
} else if (!strcasecmp(name, "debug")) {
|
||||
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")) {
|
||||
context->confidence_level = atoi(val);
|
||||
} else if (!strcasecmp(name, "cascade")) {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
char *json_text = NULL;
|
||||
switch_bool_t r = SWITCH_FALSE;
|
||||
const char *event_channel = cJSON_GetObjectCstr(params, "eventChannel");
|
||||
cJSON *jevent, *broadcast;
|
||||
const char *display = NULL;
|
||||
|
@ -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) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "multicast socket send error! %s\n", strerror(errno));
|
||||
r = SWITCH_FALSE;
|
||||
cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Send failure!"));
|
||||
//r = SWITCH_FALSE;
|
||||
//cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Send failure!"));
|
||||
} else {
|
||||
r = SWITCH_TRUE;
|
||||
cJSON_AddItemToObject(*response, "message", cJSON_CreateString("MCAST Data Sent"));
|
||||
//r = SWITCH_TRUE;
|
||||
//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);
|
||||
json_text = NULL;
|
||||
|
@ -3956,7 +3956,7 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js
|
|||
|
||||
end:
|
||||
|
||||
return r;
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
static switch_bool_t login_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
|
||||
|
|
Loading…
Reference in New Issue