mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 00:00:44 +00:00
FS-7769 More features
add var=val member lookup usable wherver member_id is valid in api commands add bgimg to layouts with api command or config for global setting fix bug with overlap layouts combined with odd sized layers improve switch_img_fit to take a modifier for fit, streach or both at once
This commit is contained in:
parent
37b6f48ae4
commit
34fd0e9ad8
@ -12,6 +12,43 @@
|
|||||||
<image x="0" y="90" scale="180"/>
|
<image x="0" y="90" scale="180"/>
|
||||||
<image x="180" y="90" scale="180"/>
|
<image x="180" y="90" scale="180"/>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
||||||
|
<layout name="hollywood" auto-3d-position="true" bgimg="/root/fakebg.png">
|
||||||
|
<image x="58" y="0" scale="80" hscale="118" zoom="true" reservation_id="square-1"/>
|
||||||
|
<image x="140" y="0" scale="80" hscale="118" zoom="true" reservation_id="square-2"/>
|
||||||
|
<image x="222" y="0" scale="80" hscale="118" zoom="true" reservation_id="square-3"/>
|
||||||
|
<image x="58" y="121" scale="80" hscale="118" zoom="true" reservation_id="square-4"/>
|
||||||
|
<image x="140" y="121" scale="80" hscale="118" zoom="true" reservation_id="square-5"/>
|
||||||
|
<image x="222" y="121" scale="80" hscale="118" zoom="true" reservation_id="square-6"/>
|
||||||
|
<image x="58" y="242" scale="80" hscale="118" zoom="true" reservation_id="square-7"/>
|
||||||
|
<image x="140" y="242" scale="80" hscale="118" zoom="true" reservation_id="square-8"/>
|
||||||
|
<image x="222" y="242" scale="80" hscale="118" zoom="true" reservation_id="square-9"/>
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
<layout name="3x3-reserved" auto-3d-position="true">
|
||||||
|
<image x="0" y="0" scale="120" reservation_id="square-1"/>
|
||||||
|
<image x="120" y="0" scale="120" reservation_id="square-2"/>
|
||||||
|
<image x="240" y="0" scale="120" reservation_id="square-3"/>
|
||||||
|
<image x="0" y="120" scale="120" reservation_id="square-4"/>
|
||||||
|
<image x="120" y="120" scale="120" reservation_id="square-5"/>
|
||||||
|
<image x="240" y="120" scale="120" reservation_id="square-6"/>
|
||||||
|
<image x="0" y="240" scale="120" reservation_id="square-7"/>
|
||||||
|
<image x="120" y="240" scale="120" reservation_id="square-8"/>
|
||||||
|
<image x="240" y="240" scale="120" reservation_id="square-9"/>
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
<layout name="hollywood-bg" auto-3d-position="true">
|
||||||
|
<image x="0" y="0" scale="360" reservation_id="bg"/>
|
||||||
|
<image x="58" y="0" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-1"/>
|
||||||
|
<image x="140" y="0" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-2"/>
|
||||||
|
<image x="222" y="0" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-3"/>
|
||||||
|
<image x="58" y="121" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-4"/>
|
||||||
|
<image x="140" y="121" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-5"/>
|
||||||
|
<image x="222" y="121" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-6"/>
|
||||||
|
<image x="58" y="242" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-7"/>
|
||||||
|
<image x="140" y="242" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-8"/>
|
||||||
|
<image x="222" y="242" scale="80" hscale="118" zoom="true" overlap="true" reservation_id="square-9"/>
|
||||||
|
</layout>
|
||||||
<layout name="2x1-zoom" auto-3d-position="true">
|
<layout name="2x1-zoom" auto-3d-position="true">
|
||||||
<image x="0" y="0" scale="180" hscale="360" zoom="true"/>
|
<image x="0" y="0" scale="180" hscale="360" zoom="true"/>
|
||||||
<image x="180" y="0" scale="180" hscale="360" zoom="true"/>
|
<image x="180" y="0" scale="180" hscale="360" zoom="true"/>
|
||||||
|
@ -4,6 +4,6 @@ require ESL;
|
|||||||
my $command = shift;
|
my $command = shift;
|
||||||
my $args = join(" ", @ARGV);
|
my $args = join(" ", @ARGV);
|
||||||
|
|
||||||
my $con = new ESL::ESLconnection("localhost", "8021", "ClueCon");
|
my $con = new ESL::ESLconnection("127.0.0.1", "8021", "ClueCon");
|
||||||
my $e = $con->api($command, $args);
|
my $e = $con->api($command, $args);
|
||||||
print $e->getBody();
|
print $e->getBody();
|
||||||
|
@ -57,6 +57,12 @@ typedef enum {
|
|||||||
POS_NONE
|
POS_NONE
|
||||||
} switch_img_position_t;
|
} switch_img_position_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SWITCH_FIT_SIZE,
|
||||||
|
SWITCH_FIT_SCALE,
|
||||||
|
SWITCH_FIT_SIZE_AND_SCALE,
|
||||||
|
SWITCH_FIT_NONE
|
||||||
|
} switch_img_fit_t;
|
||||||
|
|
||||||
typedef struct switch_yuv_color_s {
|
typedef struct switch_yuv_color_s {
|
||||||
uint8_t y;
|
uint8_t y;
|
||||||
@ -356,8 +362,9 @@ SWITCH_DECLARE(void) switch_img_get_rgb_pixel(switch_image_t *img, switch_rgb_co
|
|||||||
SWITCH_DECLARE(void) switch_img_overlay(switch_image_t *IMG, switch_image_t *img, int x, int y, uint8_t alpha);
|
SWITCH_DECLARE(void) switch_img_overlay(switch_image_t *IMG, switch_image_t *img, int x, int y, uint8_t alpha);
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_img_scale(switch_image_t *src, switch_image_t **destP, int width, int height);
|
SWITCH_DECLARE(switch_status_t) switch_img_scale(switch_image_t *src, switch_image_t **destP, int width, int height);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, int height);
|
SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit);
|
||||||
SWITCH_DECLARE(switch_img_position_t) parse_img_position(const char *name);
|
SWITCH_DECLARE(switch_img_position_t) parse_img_position(const char *name);
|
||||||
|
SWITCH_DECLARE(switch_img_fit_t) parse_img_fit(const char *name);
|
||||||
SWITCH_DECLARE(void) switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP);
|
SWITCH_DECLARE(void) switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP);
|
||||||
SWITCH_DECLARE(switch_status_t) switch_img_convert(switch_image_t *src, switch_convert_fmt_t fmt, void *dest, switch_size_t *size);
|
SWITCH_DECLARE(switch_status_t) switch_img_convert(switch_image_t *src, switch_convert_fmt_t fmt, void *dest, switch_size_t *size);
|
||||||
SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_bool_t full, const char *text);
|
SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_bool_t full, const char *text);
|
||||||
|
@ -101,6 +101,7 @@ api_command_t conference_api_sub_commands[] = {
|
|||||||
{"vid-layout", (void_fn_t) & conference_api_sub_vid_layout, CONF_API_SUB_ARGS_SPLIT, "vid-layout", "<layout name>|group <group name> [<canvas id>]"},
|
{"vid-layout", (void_fn_t) & conference_api_sub_vid_layout, CONF_API_SUB_ARGS_SPLIT, "vid-layout", "<layout name>|group <group name> [<canvas id>]"},
|
||||||
{"vid-write-png", (void_fn_t) & conference_api_sub_write_png, CONF_API_SUB_ARGS_SPLIT, "vid-write-png", "<path>"},
|
{"vid-write-png", (void_fn_t) & conference_api_sub_write_png, CONF_API_SUB_ARGS_SPLIT, "vid-write-png", "<path>"},
|
||||||
{"vid-fps", (void_fn_t) & conference_api_sub_vid_fps, CONF_API_SUB_ARGS_SPLIT, "vid-fps", "<fps>"},
|
{"vid-fps", (void_fn_t) & conference_api_sub_vid_fps, CONF_API_SUB_ARGS_SPLIT, "vid-fps", "<fps>"},
|
||||||
|
{"vid-bgimg", (void_fn_t) & conference_api_sub_canvas_bgimg, CONF_API_SUB_ARGS_SPLIT, "vid-bgimg", "<file> | clear [<canvas-id>]"},
|
||||||
{"vid-bandwidth", (void_fn_t) & conference_api_sub_vid_bandwidth, CONF_API_SUB_ARGS_SPLIT, "vid-bandwidth", "<BW>"}
|
{"vid-bandwidth", (void_fn_t) & conference_api_sub_vid_bandwidth, CONF_API_SUB_ARGS_SPLIT, "vid-bandwidth", "<BW>"}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1001,6 +1002,7 @@ switch_status_t conference_api_sub_volume_out(conference_member_t *member, switc
|
|||||||
switch_status_t conference_api_sub_vid_bandwidth(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
switch_status_t conference_api_sub_vid_bandwidth(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int32_t i, video_write_bandwidth;
|
int32_t i, video_write_bandwidth;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
if (!conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) {
|
if (!conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) {
|
||||||
stream->write_function(stream, "Bandwidth control not available.\n");
|
stream->write_function(stream, "Bandwidth control not available.\n");
|
||||||
@ -1013,13 +1015,60 @@ switch_status_t conference_api_sub_vid_bandwidth(conference_obj_t *conference, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
video_write_bandwidth = switch_parse_bandwidth_string(argv[2]);
|
video_write_bandwidth = switch_parse_bandwidth_string(argv[2]);
|
||||||
for (i = 0; i >= conference->canvas_count; i++) {
|
for (i = 0; i <= conference->canvas_count; i++) {
|
||||||
if (conference->canvases[i]) {
|
if (conference->canvases[i]) {
|
||||||
|
stream->write_function(stream, "Set Bandwidth for canvas %d to %d\n", i + 1, video_write_bandwidth);
|
||||||
|
x++;
|
||||||
conference->canvases[i]->video_write_bandwidth = video_write_bandwidth;
|
conference->canvases[i]->video_write_bandwidth = video_write_bandwidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->write_function(stream, "Set Bandwidth %d\n", video_write_bandwidth);
|
if (!x) {
|
||||||
|
stream->write_function(stream, "Bandwidth not set\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_status_t conference_api_sub_canvas_bgimg(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
||||||
|
{
|
||||||
|
mcu_canvas_t *canvas = NULL;
|
||||||
|
int idx = 0;
|
||||||
|
char *file = NULL;
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
|
if (!argv[2]) {
|
||||||
|
stream->write_function(stream, "Invalid input\n");
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = argv[2];
|
||||||
|
|
||||||
|
if (argv[3]) {
|
||||||
|
idx = atoi(argv[3]) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx > SUPER_CANVAS_ID || !conference->canvases[idx]) {
|
||||||
|
stream->write_function(stream, "Invalid canvas\n");
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((canvas = conference->canvases[idx])) {
|
||||||
|
switch_mutex_lock(canvas->mutex);
|
||||||
|
if (!strcasecmp(file, "clear")) {
|
||||||
|
conference_video_reset_image(canvas->img, &canvas->bgcolor);
|
||||||
|
} else {
|
||||||
|
status = conference_video_set_canvas_bgimg(canvas, file);
|
||||||
|
}
|
||||||
|
switch_mutex_unlock(canvas->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
|
stream->write_function(stream, "Set Bgimg %s\n", file);
|
||||||
|
} else {
|
||||||
|
stream->write_function(stream, "Error Setting Bgimg %s\n", file);
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2712,6 +2761,27 @@ switch_status_t conference_api_dispatch(conference_obj_t *conference, switch_str
|
|||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "Non-Existant ID %u\n", id);
|
stream->write_function(stream, "Non-Existant ID %u\n", id);
|
||||||
}
|
}
|
||||||
|
} else if (strchr(argv[argn + 1], '=')) {
|
||||||
|
conference_api_member_cmd_t pfn = (conference_api_member_cmd_t) conference_api_sub_commands[i].pfnapicmd;
|
||||||
|
conference_member_t *member;
|
||||||
|
char *var, *val;
|
||||||
|
|
||||||
|
var = strdup(argv[argn + 1]);
|
||||||
|
|
||||||
|
if ((val = strchr(var, '='))) {
|
||||||
|
*val++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
member = conference_member_get_by_var(conference, var, val);
|
||||||
|
|
||||||
|
if (member != NULL) {
|
||||||
|
pfn(member, stream, argv[argn + 2]);
|
||||||
|
switch_thread_rwlock_unlock(member->rwlock);
|
||||||
|
} else {
|
||||||
|
stream->write_function(stream, "Non-Existant member\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_safe_free(var);
|
||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "%s %s", conference_api_sub_commands[i].pcommand, conference_api_sub_commands[i].psyntax);
|
stream->write_function(stream, "%s %s", conference_api_sub_commands[i].pcommand, conference_api_sub_commands[i].psyntax);
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ uint32_t conference_file_stop(conference_obj_t *conference, file_stop_t stop)
|
|||||||
nptr->done++;
|
nptr->done++;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conference->async_fnode) {
|
if (conference->async_fnode) {
|
||||||
conference->async_fnode->done++;
|
conference->async_fnode->done++;
|
||||||
count++;
|
count++;
|
||||||
|
@ -392,6 +392,52 @@ conference_member_t *conference_member_get(conference_obj_t *conference, uint32_
|
|||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* traverse the conference member list for the specified member with var/val and return it's pointer */
|
||||||
|
conference_member_t *conference_member_get_by_var(conference_obj_t *conference, const char *var, const char *val)
|
||||||
|
{
|
||||||
|
conference_member_t *member = NULL;
|
||||||
|
|
||||||
|
switch_assert(conference != NULL);
|
||||||
|
if (!(var && val)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(conference->member_mutex);
|
||||||
|
for (member = conference->members; member; member = member->next) {
|
||||||
|
const char *check_var;
|
||||||
|
|
||||||
|
if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((check_var = switch_channel_get_variable_dup(member->channel, var , SWITCH_FALSE, -1)) && !strcmp(check_var, val)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (member) {
|
||||||
|
if (!conference_utils_member_test_flag(member, MFLAG_INTREE) ||
|
||||||
|
conference_utils_member_test_flag(member, MFLAG_KICKED) ||
|
||||||
|
(member->session && !switch_channel_up(switch_core_session_get_channel(member->session)))) {
|
||||||
|
|
||||||
|
/* member is kicked or hanging up so forget it */
|
||||||
|
member = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (member) {
|
||||||
|
if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
/* if you cant readlock it's way to late to do anything */
|
||||||
|
member = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_unlock(conference->member_mutex);
|
||||||
|
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
|
||||||
void conference_member_check_agc_levels(conference_member_t *member)
|
void conference_member_check_agc_levels(conference_member_t *member)
|
||||||
{
|
{
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -110,7 +110,7 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
|
|||||||
if ((x_layouts = switch_xml_child(x_layout_settings, "layouts"))) {
|
if ((x_layouts = switch_xml_child(x_layout_settings, "layouts"))) {
|
||||||
for (x_layout = switch_xml_child(x_layouts, "layout"); x_layout; x_layout = x_layout->next) {
|
for (x_layout = switch_xml_child(x_layouts, "layout"); x_layout; x_layout = x_layout->next) {
|
||||||
video_layout_t *vlayout;
|
video_layout_t *vlayout;
|
||||||
const char *val = NULL, *name = NULL;
|
const char *val = NULL, *name = NULL, *bgimg = NULL;
|
||||||
switch_bool_t auto_3d = SWITCH_FALSE;
|
switch_bool_t auto_3d = SWITCH_FALSE;
|
||||||
int border = 0;
|
int border = 0;
|
||||||
|
|
||||||
@ -125,6 +125,8 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
|
|||||||
|
|
||||||
auto_3d = switch_true(switch_xml_attr(x_layout, "auto-3d-position"));
|
auto_3d = switch_true(switch_xml_attr(x_layout, "auto-3d-position"));
|
||||||
|
|
||||||
|
bgimg = switch_xml_attr(x_layout, "bgimg");
|
||||||
|
|
||||||
if ((val = switch_xml_attr(x_layout, "border"))) {
|
if ((val = switch_xml_attr(x_layout, "border"))) {
|
||||||
border = atoi(val);
|
border = atoi(val);
|
||||||
if (border < 0) border = 0;
|
if (border < 0) border = 0;
|
||||||
@ -134,6 +136,10 @@ void conference_video_parse_layouts(conference_obj_t *conference, int WIDTH, int
|
|||||||
vlayout = switch_core_alloc(conference->pool, sizeof(*vlayout));
|
vlayout = switch_core_alloc(conference->pool, sizeof(*vlayout));
|
||||||
vlayout->name = switch_core_strdup(conference->pool, name);
|
vlayout->name = switch_core_strdup(conference->pool, name);
|
||||||
|
|
||||||
|
if (bgimg) {
|
||||||
|
vlayout->bgimg = switch_core_strdup(conference->pool, bgimg);
|
||||||
|
}
|
||||||
|
|
||||||
for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) {
|
for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) {
|
||||||
const char *res_id = NULL, *audio_position = NULL;
|
const char *res_id = NULL, *audio_position = NULL;
|
||||||
int x = -1, y = -1, scale = -1, hscale = -1, floor = 0, flooronly = 0, fileonly = 0, overlap = 0, zoom = 0;
|
int x = -1, y = -1, scale = -1, hscale = -1, floor = 0, flooronly = 0, fileonly = 0, overlap = 0, zoom = 0;
|
||||||
@ -379,34 +385,43 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||||||
double screen_aspect = 0, img_aspect = 0;
|
double screen_aspect = 0, img_aspect = 0;
|
||||||
int x_pos = layer->x_pos;
|
int x_pos = layer->x_pos;
|
||||||
int y_pos = layer->y_pos;
|
int y_pos = layer->y_pos;
|
||||||
|
int64_t img_addr = 0;
|
||||||
|
|
||||||
img_w = layer->screen_w = IMG->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE;
|
img_w = layer->screen_w = IMG->d_w * layer->geometry.scale / VIDEO_LAYOUT_SCALE;
|
||||||
img_h = layer->screen_h = IMG->d_h * layer->geometry.hscale / VIDEO_LAYOUT_SCALE;
|
img_h = layer->screen_h = IMG->d_h * layer->geometry.hscale / VIDEO_LAYOUT_SCALE;
|
||||||
|
|
||||||
|
|
||||||
screen_aspect = (double) layer->screen_w / layer->screen_h;
|
screen_aspect = (double) layer->screen_w / layer->screen_h;
|
||||||
img_aspect = (double) img->d_w / img->d_h;
|
img_aspect = (double) img->d_w / img->d_h;
|
||||||
|
|
||||||
if (layer->geometry.zoom) {
|
img_addr = (int64_t)img;
|
||||||
|
|
||||||
|
if (layer->last_img_addr != img_addr && layer->geometry.zoom) {
|
||||||
if (screen_aspect < img_aspect) {
|
if (screen_aspect < img_aspect) {
|
||||||
int cropsize = 0;
|
int cropsize = 0;
|
||||||
double scale = 1;
|
double scale = 1;
|
||||||
if (img->d_h != layer->screen_h) {
|
if (img->d_h != layer->screen_h) {
|
||||||
scale = (double)layer->screen_h / img->d_h;
|
scale = (double)layer->screen_h / img->d_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
cropsize = ((img->d_w )-((double)layer->screen_w/scale)) / 2;
|
cropsize = ((img->d_w )-((double)layer->screen_w/scale)) / 2;
|
||||||
|
|
||||||
switch_img_set_rect(img, cropsize, 0, layer->screen_w/scale, layer->screen_h/scale);
|
if (cropsize) {
|
||||||
img_aspect = (double) img->d_w / img->d_h;
|
switch_img_set_rect(img, cropsize, 0, layer->screen_w/scale, layer->screen_h/scale);
|
||||||
|
img_aspect = (double) img->d_w / img->d_h;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (screen_aspect > img_aspect) {
|
} else if (screen_aspect > img_aspect) {
|
||||||
int cropsize = 0;
|
int cropsize = 0;
|
||||||
double scale = 1;
|
double scale = 1;
|
||||||
if (img->d_w != layer->screen_w) {
|
if (img->d_w != layer->screen_w) {
|
||||||
scale = (double)layer->screen_w / img->d_w;
|
scale = (double)layer->screen_w / img->d_w;
|
||||||
}
|
}
|
||||||
cropsize = ((img->d_h )-((double)layer->screen_h/scale)) / 2;
|
cropsize = ceil(((img->d_h )-((double)layer->screen_h/scale)) / 2);
|
||||||
|
if (cropsize) {
|
||||||
switch_img_set_rect(img, 0, cropsize, layer->screen_w/scale, layer->screen_h/scale);
|
switch_img_set_rect(img, 0, cropsize, layer->screen_w/scale, layer->screen_h/scale);
|
||||||
img_aspect = (double) img->d_w / img->d_h;
|
img_aspect = (double) img->d_w / img->d_h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,10 +430,10 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (screen_aspect > img_aspect) {
|
if (screen_aspect > img_aspect) {
|
||||||
img_w = img_aspect * layer->screen_h;
|
img_w = ceil((double)img_aspect * layer->screen_h);
|
||||||
x_pos += (layer->screen_w - img_w) / 2;
|
x_pos += (layer->screen_w - img_w) / 2;
|
||||||
} else if (screen_aspect < img_aspect) {
|
} else if (screen_aspect < img_aspect) {
|
||||||
img_h = layer->screen_w / img_aspect;
|
img_h = ceil((double)layer->screen_w / img_aspect);
|
||||||
y_pos += (layer->screen_h - img_h) / 2;
|
y_pos += (layer->screen_h - img_h) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +467,9 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||||||
img_w -= (layer->geometry.border * 2);
|
img_w -= (layer->geometry.border * 2);
|
||||||
img_h -= (layer->geometry.border * 2);
|
img_h -= (layer->geometry.border * 2);
|
||||||
|
|
||||||
if (switch_img_scale(img, &layer->img, img_w, img_h) == SWITCH_STATUS_SUCCESS) {
|
switch_img_scale(img, &layer->img, img_w, img_h);
|
||||||
|
|
||||||
|
if (layer->img) {
|
||||||
if (layer->bugged && layer->member_id > -1) {
|
if (layer->bugged && layer->member_id > -1) {
|
||||||
conference_member_t *member;
|
conference_member_t *member;
|
||||||
if ((member = conference_member_get(layer->canvas->conference, layer->member_id))) {
|
if ((member = conference_member_get(layer->canvas->conference, layer->member_id))) {
|
||||||
@ -470,19 +487,23 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||||||
int ew = layer->screen_w - (layer->geometry.border * 2), eh = layer->screen_h - (layer->banner_img ? layer->banner_img->d_h : 0) - (layer->geometry.border * 2);
|
int ew = layer->screen_w - (layer->geometry.border * 2), eh = layer->screen_h - (layer->banner_img ? layer->banner_img->d_h : 0) - (layer->geometry.border * 2);
|
||||||
int ex = 0, ey = 0;
|
int ex = 0, ey = 0;
|
||||||
|
|
||||||
switch_img_fit(&layer->logo_img, ew, eh);
|
switch_img_fit(&layer->logo_img, ew, eh, layer->logo_fit);
|
||||||
|
|
||||||
switch_img_find_position(layer->logo_pos, ew, eh, layer->logo_img->d_w, layer->logo_img->d_h, &ex, &ey);
|
switch_img_find_position(layer->logo_pos, ew, eh, layer->logo_img->d_w, layer->logo_img->d_h, &ex, &ey);
|
||||||
switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.border);
|
switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.border);
|
||||||
if (layer->logo_text_img) {
|
if (layer->logo_text_img) {
|
||||||
int tx = 0, ty = 0;
|
int tx = 0, ty = 0;
|
||||||
|
|
||||||
switch_img_fit(&layer->logo_text_img, (ew / 2) + 1, (eh / 2) + 1);
|
switch_img_fit(&layer->logo_text_img, (ew / 2) + 1, (eh / 2) + 1, SWITCH_FIT_SIZE);
|
||||||
switch_img_find_position(POS_LEFT_BOT,
|
switch_img_find_position(POS_LEFT_BOT,
|
||||||
layer->logo_img->d_w, layer->logo_img->d_h, layer->logo_text_img->d_w, layer->logo_text_img->d_h, &tx, &ty);
|
layer->logo_img->d_w, layer->logo_img->d_h, layer->logo_text_img->d_w, layer->logo_text_img->d_h, &tx, &ty);
|
||||||
switch_img_patch(IMG, layer->logo_text_img, layer->x_pos + ex + tx + layer->geometry.border, layer->y_pos + ey + ty + layer->geometry.border);
|
switch_img_patch(IMG, layer->logo_text_img, layer->x_pos + ex + tx + layer->geometry.border, layer->y_pos + ey + ty + layer->geometry.border);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layer->last_img_addr = img_addr;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "insert at %d,%d\n", 0, 0);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "insert at %d,%d\n", 0, 0);
|
||||||
switch_img_patch(IMG, img, 0, 0);
|
switch_img_patch(IMG, img, 0, 0);
|
||||||
@ -631,6 +652,7 @@ void conference_video_layer_set_logo(conference_member_t *member, mcu_layer_t *l
|
|||||||
char *parsed = NULL;
|
char *parsed = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
switch_img_position_t pos = POS_LEFT_TOP;
|
switch_img_position_t pos = POS_LEFT_TOP;
|
||||||
|
switch_img_fit_t fit = SWITCH_FIT_SIZE;
|
||||||
|
|
||||||
switch_mutex_lock(layer->canvas->mutex);
|
switch_mutex_lock(layer->canvas->mutex);
|
||||||
|
|
||||||
@ -677,11 +699,14 @@ void conference_video_layer_set_logo(conference_member_t *member, mcu_layer_t *l
|
|||||||
path = tmp + 1;
|
path = tmp + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (params) {
|
if (params) {
|
||||||
if ((var = switch_event_get_header(params, "position"))) {
|
if ((var = switch_event_get_header(params, "position"))) {
|
||||||
pos = parse_img_position(var);
|
pos = parse_img_position(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((var = switch_event_get_header(params, "fit"))) {
|
||||||
|
fit = parse_img_fit(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path && strcasecmp(path, "clear")) {
|
if (path && strcasecmp(path, "clear")) {
|
||||||
@ -690,6 +715,7 @@ void conference_video_layer_set_logo(conference_member_t *member, mcu_layer_t *l
|
|||||||
|
|
||||||
if (layer->logo_img) {
|
if (layer->logo_img) {
|
||||||
layer->logo_pos = pos;
|
layer->logo_pos = pos;
|
||||||
|
layer->logo_fit = fit;
|
||||||
|
|
||||||
if (params) {
|
if (params) {
|
||||||
if ((var = switch_event_get_header(params, "text"))) {
|
if ((var = switch_event_get_header(params, "text"))) {
|
||||||
@ -1012,11 +1038,42 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
|
|||||||
canvas->total_layers = vlayout->layers;
|
canvas->total_layers = vlayout->layers;
|
||||||
canvas->send_keyframe = 1;
|
canvas->send_keyframe = 1;
|
||||||
|
|
||||||
|
if (vlayout->bgimg) {
|
||||||
|
conference_video_set_canvas_bgimg(canvas, vlayout->bgimg);
|
||||||
|
} else if (canvas->bgimg) {
|
||||||
|
switch_img_free(&canvas->bgimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conference->video_canvas_bgimg && !vlayout->bgimg) {
|
||||||
|
conference_video_set_canvas_bgimg(canvas, conference->video_canvas_bgimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch_mutex_unlock(canvas->mutex);
|
switch_mutex_unlock(canvas->mutex);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Canvas position %d applied layout %s\n", canvas->canvas_id, vlayout->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Canvas position %d applied layout %s\n", canvas->canvas_id, vlayout->name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const char *img_path)
|
||||||
|
{
|
||||||
|
|
||||||
|
int x = 0, y = 0;
|
||||||
|
switch_img_free(&canvas->bgimg);
|
||||||
|
canvas->bgimg = switch_img_read_png(img_path, SWITCH_IMG_FMT_I420);
|
||||||
|
|
||||||
|
if (!canvas->bgimg) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open image for bgimg\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_img_fit(&canvas->bgimg, canvas->img->d_w, canvas->img->d_h, SWITCH_FIT_SIZE);
|
||||||
|
switch_img_find_position(POS_CENTER_MID, canvas->img->d_w, canvas->img->d_h, canvas->bgimg->d_w, canvas->bgimg->d_h, &x, &y);
|
||||||
|
switch_img_patch(canvas->img, canvas->bgimg, x, y);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (conference->canvas_count >= MAX_CANVASES + 1) {
|
if (conference->canvas_count >= MAX_CANVASES + 1) {
|
||||||
@ -1098,6 +1155,7 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) {
|
|||||||
mcu_canvas_t *canvas = *canvasP;
|
mcu_canvas_t *canvas = *canvasP;
|
||||||
|
|
||||||
switch_img_free(&canvas->img);
|
switch_img_free(&canvas->img);
|
||||||
|
switch_img_free(&canvas->bgimg);
|
||||||
conference_video_flush_queue(canvas->video_queue);
|
conference_video_flush_queue(canvas->video_queue);
|
||||||
|
|
||||||
for (i = 0; i < MCU_MAX_LAYERS; i++) {
|
for (i = 0; i < MCU_MAX_LAYERS; i++) {
|
||||||
@ -1296,7 +1354,7 @@ void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_fi
|
|||||||
for (i = 0; i < canvas->total_layers; i++) {
|
for (i = 0; i < canvas->total_layers; i++) {
|
||||||
xlayer = &canvas->layers[i];
|
xlayer = &canvas->layers[i];
|
||||||
|
|
||||||
if (xlayer->fnode || xlayer->geometry.res_id || xlayer->member_id) {
|
if (xlayer->fnode || (xlayer->geometry.res_id && (!fnode->res_id || strcmp(xlayer->geometry.res_id, fnode->res_id))) || xlayer->member_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1529,11 +1587,18 @@ void conference_video_fnode_check(conference_file_node_t *fnode) {
|
|||||||
|
|
||||||
if (switch_core_file_has_video(&fnode->fh) && switch_core_file_read_video(&fnode->fh, NULL, SVR_CHECK) == SWITCH_STATUS_BREAK) {
|
if (switch_core_file_has_video(&fnode->fh) && switch_core_file_read_video(&fnode->fh, NULL, SVR_CHECK) == SWITCH_STATUS_BREAK) {
|
||||||
int full_screen = 0;
|
int full_screen = 0;
|
||||||
|
char *res_id = NULL;
|
||||||
|
|
||||||
if (fnode->fh.params && fnode->conference->canvas_count == 1) {
|
if (fnode->fh.params && fnode->conference->canvas_count == 1) {
|
||||||
full_screen = switch_true(switch_event_get_header(fnode->fh.params, "full-screen"));
|
full_screen = switch_true(switch_event_get_header(fnode->fh.params, "full-screen"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fnode->fh.params) {
|
||||||
|
if ((res_id = switch_event_get_header(fnode->fh.params, "reservation_id"))) {
|
||||||
|
fnode->res_id = switch_core_strdup(fnode->pool, res_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (full_screen) {
|
if (full_screen) {
|
||||||
canvas->play_file = 1;
|
canvas->play_file = 1;
|
||||||
canvas->conference->playing_video_file = 1;
|
canvas->conference->playing_video_file = 1;
|
||||||
@ -2971,7 +3036,7 @@ void conference_video_write_frame(conference_obj_t *conference, conference_membe
|
|||||||
int x,y;
|
int x,y;
|
||||||
|
|
||||||
switch_img_copy(vid_frame->img, &tmp_img);
|
switch_img_copy(vid_frame->img, &tmp_img);
|
||||||
switch_img_fit(&tmp_img, conference->canvases[0]->width, conference->canvases[0]->height);
|
switch_img_fit(&tmp_img, conference->canvases[0]->width, conference->canvases[0]->height, SWITCH_FIT_SIZE);
|
||||||
frame_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, conference->canvases[0]->width, conference->canvases[0]->height, 1);
|
frame_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, conference->canvases[0]->width, conference->canvases[0]->height, 1);
|
||||||
conference_video_reset_image(frame_img, &conference->canvases[0]->bgcolor);
|
conference_video_reset_image(frame_img, &conference->canvases[0]->bgcolor);
|
||||||
switch_img_find_position(POS_CENTER_MID, frame_img->d_w, frame_img->d_h, tmp_img->d_w, tmp_img->d_h, &x, &y);
|
switch_img_find_position(POS_CENTER_MID, frame_img->d_w, frame_img->d_h, tmp_img->d_w, tmp_img->d_h, &x, &y);
|
||||||
|
@ -379,6 +379,7 @@ typedef struct conference_file_node {
|
|||||||
int layer_id;
|
int layer_id;
|
||||||
int canvas_id;
|
int canvas_id;
|
||||||
struct conference_obj *conference;
|
struct conference_obj *conference;
|
||||||
|
char *res_id;
|
||||||
} conference_file_node_t;
|
} conference_file_node_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -437,6 +438,7 @@ typedef struct mcu_layer_s {
|
|||||||
int avatar_patched;
|
int avatar_patched;
|
||||||
int refresh;
|
int refresh;
|
||||||
int is_avatar;
|
int is_avatar;
|
||||||
|
int64_t last_img_addr;
|
||||||
switch_img_position_t logo_pos;
|
switch_img_position_t logo_pos;
|
||||||
switch_image_t *img;
|
switch_image_t *img;
|
||||||
switch_image_t *cur_img;
|
switch_image_t *cur_img;
|
||||||
@ -446,12 +448,14 @@ typedef struct mcu_layer_s {
|
|||||||
switch_image_t *mute_img;
|
switch_image_t *mute_img;
|
||||||
switch_img_txt_handle_t *txthandle;
|
switch_img_txt_handle_t *txthandle;
|
||||||
conference_file_node_t *fnode;
|
conference_file_node_t *fnode;
|
||||||
|
switch_img_fit_t logo_fit;
|
||||||
struct mcu_canvas_s *canvas;
|
struct mcu_canvas_s *canvas;
|
||||||
} mcu_layer_t;
|
} mcu_layer_t;
|
||||||
|
|
||||||
typedef struct video_layout_s {
|
typedef struct video_layout_s {
|
||||||
char *name;
|
char *name;
|
||||||
char *audio_position;
|
char *audio_position;
|
||||||
|
char *bgimg;
|
||||||
mcu_layer_geometry_t images[MCU_MAX_LAYERS];
|
mcu_layer_geometry_t images[MCU_MAX_LAYERS];
|
||||||
int layers;
|
int layers;
|
||||||
} video_layout_t;
|
} video_layout_t;
|
||||||
@ -491,6 +495,7 @@ typedef struct mcu_canvas_s {
|
|||||||
switch_queue_t *video_queue;
|
switch_queue_t *video_queue;
|
||||||
int32_t video_write_bandwidth;
|
int32_t video_write_bandwidth;
|
||||||
int recording;
|
int recording;
|
||||||
|
switch_image_t *bgimg;
|
||||||
} mcu_canvas_t;
|
} mcu_canvas_t;
|
||||||
|
|
||||||
/* Record Node */
|
/* Record Node */
|
||||||
@ -545,6 +550,7 @@ typedef struct conference_obj {
|
|||||||
char *video_layout_name;
|
char *video_layout_name;
|
||||||
char *video_layout_group;
|
char *video_layout_group;
|
||||||
char *video_canvas_bgcolor;
|
char *video_canvas_bgcolor;
|
||||||
|
char *video_canvas_bgimg;
|
||||||
char *video_border_color;
|
char *video_border_color;
|
||||||
char *video_super_canvas_bgcolor;
|
char *video_super_canvas_bgcolor;
|
||||||
char *video_letterbox_bgcolor;
|
char *video_letterbox_bgcolor;
|
||||||
@ -919,6 +925,7 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo
|
|||||||
void conference_video_find_floor(conference_member_t *member, switch_bool_t entering);
|
void conference_video_find_floor(conference_member_t *member, switch_bool_t entering);
|
||||||
void conference_video_destroy_canvas(mcu_canvas_t **canvasP);
|
void conference_video_destroy_canvas(mcu_canvas_t **canvasP);
|
||||||
void conference_video_fnode_check(conference_file_node_t *fnode);
|
void conference_video_fnode_check(conference_file_node_t *fnode);
|
||||||
|
switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const char *img_path);
|
||||||
switch_status_t conference_al_parse_position(al_handle_t *al, const char *data);
|
switch_status_t conference_al_parse_position(al_handle_t *al, const char *data);
|
||||||
switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||||
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj);
|
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj);
|
||||||
@ -934,6 +941,7 @@ void conference_fnode_toggle_pause(conference_file_node_t *fnode, switch_stream_
|
|||||||
|
|
||||||
conference_relationship_t *conference_member_add_relationship(conference_member_t *member, uint32_t id);
|
conference_relationship_t *conference_member_add_relationship(conference_member_t *member, uint32_t id);
|
||||||
conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id);
|
conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id);
|
||||||
|
conference_member_t *conference_member_get_by_var(conference_obj_t *conference, const char *var, const char *val);
|
||||||
|
|
||||||
switch_status_t conference_member_del_relationship(conference_member_t *member, uint32_t id);
|
switch_status_t conference_member_del_relationship(conference_member_t *member, uint32_t id);
|
||||||
switch_status_t conference_member_add(conference_obj_t *conference, conference_member_t *member);
|
switch_status_t conference_member_add(conference_obj_t *conference, conference_member_t *member);
|
||||||
@ -1050,6 +1058,7 @@ switch_status_t conference_api_sub_get(conference_obj_t *conference, switch_stre
|
|||||||
switch_status_t conference_api_sub_vid_mute_img(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
switch_status_t conference_api_sub_vid_mute_img(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||||
switch_status_t conference_api_sub_vid_logo_img(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
switch_status_t conference_api_sub_vid_logo_img(conference_member_t *member, switch_stream_handle_t *stream, void *data);
|
||||||
switch_status_t conference_api_sub_vid_fps(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
switch_status_t conference_api_sub_vid_fps(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||||
|
switch_status_t conference_api_sub_canvas_bgimg(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||||
switch_status_t conference_api_sub_write_png(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
switch_status_t conference_api_sub_write_png(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||||
switch_status_t conference_api_sub_file_vol(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
switch_status_t conference_api_sub_file_vol(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||||
switch_status_t conference_api_sub_recording(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
switch_status_t conference_api_sub_recording(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
|
||||||
|
@ -782,7 +782,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
|||||||
switch_img_copy(src_img, &img);
|
switch_img_copy(src_img, &img);
|
||||||
|
|
||||||
if (context->last_w && context->last_h) {
|
if (context->last_w && context->last_h) {
|
||||||
switch_img_fit(&img, context->last_w, context->last_h);
|
switch_img_fit(&img, context->last_w, context->last_h, SWITCH_FIT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->img = img;
|
frame->img = img;
|
||||||
|
@ -471,8 +471,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_patch_spy_frame(switch_med
|
|||||||
switch_img_copy(img, &img_dup);
|
switch_img_copy(img, &img_dup);
|
||||||
img_tmp = switch_img_copy_rect(img_dup, w / 4, 0, w / 2, h);
|
img_tmp = switch_img_copy_rect(img_dup, w / 4, 0, w / 2, h);
|
||||||
|
|
||||||
switch_img_fit(&spy_tmp, w / 2, h);
|
switch_img_fit(&spy_tmp, w / 2, h, SWITCH_FIT_SIZE);
|
||||||
switch_img_fit(&img_tmp, w / 2, h);
|
switch_img_fit(&img_tmp, w / 2, h, SWITCH_FIT_SIZE);
|
||||||
|
|
||||||
switch_color_set_rgb(&bgcolor, "#000000");
|
switch_color_set_rgb(&bgcolor, "#000000");
|
||||||
switch_img_fill(img, 0, 0, img->d_w, img->d_h, &bgcolor);
|
switch_img_fill(img, 0, 0, img->d_w, img->d_h, &bgcolor);
|
||||||
|
@ -86,6 +86,38 @@ SWITCH_DECLARE(switch_img_position_t) parse_img_position(const char *name)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct fit_el {
|
||||||
|
switch_img_fit_t fit;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct fit_el IMG_FIT_TABLE[] = {
|
||||||
|
{SWITCH_FIT_SIZE, "fit-size"},
|
||||||
|
{SWITCH_FIT_SCALE, "fit-scale"},
|
||||||
|
{SWITCH_FIT_SIZE_AND_SCALE, "fit-size-and-scale"},
|
||||||
|
{SWITCH_FIT_NONE, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_img_fit_t) parse_img_fit(const char *name)
|
||||||
|
{
|
||||||
|
switch_img_fit_t r = SWITCH_FIT_SIZE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch_assert(name);
|
||||||
|
|
||||||
|
for(i = 0; IMG_FIT_TABLE[i].name; i++) {
|
||||||
|
if (!strcasecmp(IMG_FIT_TABLE[i].name, name)) {
|
||||||
|
r = IMG_FIT_TABLE[i].fit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_core_has_video(void)
|
SWITCH_DECLARE(switch_bool_t) switch_core_has_video(void)
|
||||||
{
|
{
|
||||||
#ifdef SWITCH_HAVE_VPX
|
#ifdef SWITCH_HAVE_VPX
|
||||||
@ -1797,7 +1829,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_letterbox(switch_image_t *img, switch
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, int height)
|
SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit)
|
||||||
{
|
{
|
||||||
switch_image_t *src, *tmp = NULL;
|
switch_image_t *src, *tmp = NULL;
|
||||||
int new_w = 0, new_h = 0;
|
int new_w = 0, new_h = 0;
|
||||||
@ -1811,6 +1843,13 @@ SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width,
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fit == SWITCH_FIT_SCALE) {
|
||||||
|
switch_img_scale(src, &tmp, width, height);
|
||||||
|
switch_img_free(&src);
|
||||||
|
*srcP = tmp;
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
new_w = src->d_w;
|
new_w = src->d_w;
|
||||||
new_h = src->d_h;
|
new_h = src->d_h;
|
||||||
|
|
||||||
@ -1843,6 +1882,14 @@ SWITCH_DECLARE(switch_status_t) switch_img_fit(switch_image_t **srcP, int width,
|
|||||||
if (switch_img_scale(src, &tmp, new_w, new_h) == SWITCH_STATUS_SUCCESS) {
|
if (switch_img_scale(src, &tmp, new_w, new_h) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_img_free(&src);
|
switch_img_free(&src);
|
||||||
*srcP = tmp;
|
*srcP = tmp;
|
||||||
|
|
||||||
|
if (fit == SWITCH_FIT_SIZE_AND_SCALE) {
|
||||||
|
src = *srcP;
|
||||||
|
switch_img_scale(src, &tmp, width, height);
|
||||||
|
switch_img_free(&src);
|
||||||
|
*srcP = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5086,7 +5086,7 @@ static switch_bool_t video_write_overlay_callback(switch_media_bug_t *bug, void
|
|||||||
|
|
||||||
if (frame->img && oht->img) {
|
if (frame->img && oht->img) {
|
||||||
switch_img_copy(oht->img, &oimg);
|
switch_img_copy(oht->img, &oimg);
|
||||||
switch_img_fit(&oimg, frame->img->d_w, frame->img->d_h);
|
switch_img_fit(&oimg, frame->img->d_w, frame->img->d_h, SWITCH_FIT_SIZE);
|
||||||
switch_img_find_position(oht->pos, frame->img->d_w, frame->img->d_h, oimg->d_w, oimg->d_h, &x, &y);
|
switch_img_find_position(oht->pos, frame->img->d_w, frame->img->d_h, oimg->d_w, oimg->d_h, &x, &y);
|
||||||
switch_img_overlay(frame->img, oimg, x, y, oht->alpha);
|
switch_img_overlay(frame->img, oimg, x, y, oht->alpha);
|
||||||
//switch_img_patch(frame->img, oimg, x, y);
|
//switch_img_patch(frame->img, oimg, x, y);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user