]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9742 #resolve [Refactor canvas zoom code]
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 15 Nov 2016 22:13:23 +0000 (16:13 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 15 Nov 2016 22:13:23 +0000 (16:13 -0600)
src/include/switch_frame.h
src/mod/applications/mod_conference/conference_video.c
src/mod/applications/mod_conference/mod_conference.h
src/mod/applications/mod_cv/mod_cv.cpp

index 0307db1ce7a0c82baa73e83ed68411664aee49e5..67be1e689f5390896a87e3a14e780023f95370e5 100644 (file)
 #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
index 6db1cbcaf494ab08df54a1a93431db11e1ae448c..8e6baf02475ad46b0c7a5752dfeb15971d37ec5a 100644 (file)
@@ -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);
                }
 
index a042cc551d7402c819ea56a253733b02126794c0..cb5c0442373601334fddc4d3a6ca3ad4d11cbe21 100644 (file)
@@ -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 {
index dd41719f975ddcead6ae2bc733bb6285135064fd..9343030cc26215eeb0f24db587fe3a4c09d9109a 100644 (file)
@@ -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++;