FS-9742 #resolve [Refactor canvas zoom code]
This commit is contained in:
parent
1b268de5e2
commit
2ed50a27ca
|
@ -39,6 +39,16 @@
|
|||
#include <switch.h>
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
struct switch_frame_geometry {
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t z;
|
||||
uint32_t m;
|
||||
};
|
||||
|
||||
/*! \brief An abstraction of a data frame */
|
||||
struct switch_frame {
|
||||
/*! a pointer to the codec information */
|
||||
|
@ -75,6 +85,7 @@ SWITCH_BEGIN_EXTERN_C
|
|||
void *user_data;
|
||||
payload_map_t *pmap;
|
||||
switch_image_t *img;
|
||||
struct switch_frame_geometry geometry;
|
||||
};
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
|
|
@ -351,6 +351,8 @@ 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));
|
||||
|
||||
if (layer->geometry.overlap) {
|
||||
layer->canvas->refresh = 1;
|
||||
}
|
||||
|
@ -379,6 +381,18 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
return;
|
||||
}
|
||||
|
||||
if (layer->bugged) {
|
||||
if (layer->member_id > -1 && layer->member && switch_thread_rwlock_tryrdlock(layer->member->rwlock) == SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
layer->bug_frame.img = img;
|
||||
switch_core_media_bug_patch_video(layer->member->session, &layer->bug_frame);
|
||||
layer->bug_frame.img = NULL;
|
||||
switch_thread_rwlock_unlock(layer->member->rwlock);
|
||||
}
|
||||
|
||||
layer->bugged = 0;
|
||||
}
|
||||
|
||||
if (layer->clear) {
|
||||
conference_video_clear_layer(layer);
|
||||
layer->clear = 0;
|
||||
|
@ -406,27 +420,70 @@ 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;
|
||||
unsigned int cropsize = 0;
|
||||
double scale = 1;
|
||||
|
||||
if (screen_aspect < img_aspect) {
|
||||
unsigned int cropsize = 0;
|
||||
double scale = 1;
|
||||
|
||||
if (img->d_h != layer->screen_h) {
|
||||
scale = (double)layer->screen_h / img->d_h;
|
||||
}
|
||||
|
||||
cropsize = (unsigned int)(((img->d_w )-((double)layer->screen_w/scale)) / 2);
|
||||
new_w = (uint32_t)((double)layer->screen_w / scale);
|
||||
new_h = (uint32_t)((double)layer->screen_h / scale);
|
||||
|
||||
if (layer->bug_frame.geometry.x) {
|
||||
if (layer->bug_frame.geometry.x < layer->bug_frame.geometry.w) {
|
||||
cropsize = 1;
|
||||
} else {
|
||||
cropsize = layer->bug_frame.geometry.x - (new_w / 2);
|
||||
}
|
||||
} else {
|
||||
cropsize = (img->d_w - new_w) / 2;
|
||||
}
|
||||
|
||||
if (cropsize > img->d_w - new_w) {
|
||||
cropsize = img->d_w - new_w;
|
||||
}
|
||||
|
||||
if (cropsize < 1) {
|
||||
cropsize = 1;
|
||||
}
|
||||
|
||||
if (cropsize) {
|
||||
switch_img_set_rect(img, cropsize, 0, (unsigned int)(layer->screen_w/scale), (unsigned int)(layer->screen_h/scale));
|
||||
switch_img_set_rect(img, cropsize, 0, new_w, new_h);
|
||||
img_aspect = (double) img->d_w / img->d_h;
|
||||
}
|
||||
|
||||
} else if (screen_aspect > img_aspect) {
|
||||
unsigned int cropsize = 0;
|
||||
double scale = 1;
|
||||
|
||||
if (img->d_w != layer->screen_w) {
|
||||
scale = (double)layer->screen_w / img->d_w;
|
||||
}
|
||||
cropsize = (int)ceil(((img->d_h )-((double)layer->screen_h/scale)) / 2);
|
||||
|
||||
|
||||
new_w = (uint32_t)((double)layer->screen_w / scale);
|
||||
new_h = (uint32_t)((double)layer->screen_h / scale);
|
||||
|
||||
if (layer->bug_frame.geometry.y) {
|
||||
if (layer->bug_frame.geometry.y < layer->bug_frame.geometry.h) {
|
||||
cropsize = 1;
|
||||
} else {
|
||||
cropsize = layer->bug_frame.geometry.y - (new_h / 2);
|
||||
}
|
||||
} else {
|
||||
cropsize = (img->d_h - new_h) / 2;
|
||||
}
|
||||
|
||||
if (cropsize > img->d_h - new_h) {
|
||||
cropsize = img->d_h - new_h;
|
||||
}
|
||||
|
||||
if (cropsize < 1) {
|
||||
cropsize = 1;
|
||||
}
|
||||
|
||||
if (cropsize) {
|
||||
switch_img_set_rect(img, 0, cropsize, (unsigned int)(layer->screen_w/scale), (unsigned int)(layer->screen_h/scale));
|
||||
img_aspect = (double) img->d_w / img->d_h;
|
||||
|
@ -479,19 +536,7 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg,
|
|||
|
||||
switch_img_scale(img, &layer->img, img_w, img_h);
|
||||
|
||||
if (layer->img) {
|
||||
if (layer->bugged) {
|
||||
if (layer->member_id > -1 && layer->member && switch_thread_rwlock_tryrdlock(layer->member->rwlock) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_frame_t write_frame = { 0 };
|
||||
write_frame.img = layer->img;
|
||||
|
||||
switch_core_media_bug_patch_video(layer->member->session, &write_frame);
|
||||
switch_thread_rwlock_unlock(layer->member->rwlock);
|
||||
}
|
||||
|
||||
layer->bugged = 0;
|
||||
}
|
||||
|
||||
if (layer->img) {
|
||||
switch_img_patch(IMG, layer->img, x_pos + layer->geometry.border, y_pos + layer->geometry.border);
|
||||
}
|
||||
|
||||
|
|
|
@ -460,6 +460,7 @@ typedef struct mcu_layer_s {
|
|||
struct mcu_canvas_s *canvas;
|
||||
int need_patch;
|
||||
conference_member_t *member;
|
||||
switch_frame_t bug_frame;
|
||||
} mcu_layer_t;
|
||||
|
||||
typedef struct video_layout_s {
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef struct cv_context_s {
|
|||
switch_mutex_t *mutex;
|
||||
char *png_prefix;
|
||||
int tick_speed;
|
||||
int confidence_level;
|
||||
} cv_context_t;
|
||||
|
||||
|
||||
|
@ -481,6 +482,7 @@ static void init_context(cv_context_t *context)
|
|||
context->png_prefix = switch_core_get_variable_pdup("cv_png_prefix", context->pool);
|
||||
context->cascade_path = switch_core_get_variable_pdup("cv_default_cascade", context->pool);
|
||||
context->nested_cascade_path = switch_core_get_variable_pdup("cv_default_nested_cascade", context->pool);
|
||||
context->confidence_level = 20;
|
||||
|
||||
for (int i = 0; i < MAX_OVERLAY; i++) {
|
||||
context->overlay[i] = (struct overlay *) switch_core_alloc(context->pool, sizeof(struct overlay));
|
||||
|
@ -619,7 +621,7 @@ void detectAndDraw(cv_context_t *context)
|
|||
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 || !context->overlay_count) {
|
||||
if (context->debug) {
|
||||
circle( img, center, radius, color, 3, 8, 0 );
|
||||
}
|
||||
|
||||
|
@ -641,7 +643,7 @@ void detectAndDraw(cv_context_t *context)
|
|||
context->shape[context->shape_idx].cx = context->shape[context->shape_idx].x + (context->shape[context->shape_idx].w / 2);
|
||||
context->shape[context->shape_idx].cy = context->shape[context->shape_idx].y + (context->shape[context->shape_idx].h / 2);
|
||||
|
||||
if (context->debug || !context->overlay_count) {
|
||||
if (context->debug) {
|
||||
rectangle( img, cvPoint(context->shape[context->shape_idx].x, context->shape[context->shape_idx].y),
|
||||
cvPoint(context->shape[context->shape_idx].x2, context->shape[context->shape_idx].y2),
|
||||
color, 3, 8, 0);
|
||||
|
@ -723,7 +725,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep, SWITCH_IMG_FMT_RGB24);
|
||||
detectAndDraw(context);
|
||||
|
||||
if (context->detected.simo_count > 20) {
|
||||
if (context->detected.simo_count > context->confidence_level) {
|
||||
if (!context->detect_event) {
|
||||
context->detect_event = 1;
|
||||
|
||||
|
@ -743,7 +745,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
|
||||
}
|
||||
} else {
|
||||
if (context->detected.simo_miss_count >= 20) {
|
||||
if (context->detected.simo_miss_count >= context->confidence_level) {
|
||||
if (context->detect_event) {
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_VIDEO_DETECT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Type", "primary");
|
||||
|
@ -826,6 +828,16 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
|||
}
|
||||
}
|
||||
|
||||
if (context->detect_event) {
|
||||
frame->geometry.x = context->shape[0].cx;
|
||||
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;
|
||||
} else {
|
||||
frame->geometry.m = 0;
|
||||
}
|
||||
|
||||
if (context->overlay_count && (abs || (context->detect_event && context->shape[0].cx))) {
|
||||
for (i = 0; i < context->overlay_count; i++) {
|
||||
struct overlay *overlay = context->overlay[i];
|
||||
|
@ -989,6 +1001,8 @@ 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, "confidence")) {
|
||||
context->confidence_level = atoi(val);
|
||||
} else if (!strcasecmp(name, "cascade")) {
|
||||
context->cascade_path = switch_core_strdup(context->pool, val);
|
||||
changed++;
|
||||
|
|
Loading…
Reference in New Issue