]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7515: add more features to mod_cv
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 16 Apr 2015 20:38:49 +0000 (15:38 -0500)
committerMichael Jerris <mike@jerris.com>
Thu, 28 May 2015 17:47:22 +0000 (12:47 -0500)
src/mod/applications/mod_cv/mod_cv.cpp
src/switch_core_video.c

index 54feea992a2a3222ef675452f4d25923a4c96fb3..f4b03691a4998eae0aaa78288a6df34f086fd532 100644 (file)
@@ -88,13 +88,14 @@ struct overlay {
     float xo;
     float yo;
     float shape_scale;
+    int scale_w;
+    int scale_h;
     int zidx;
     switch_img_position_t abs;
 };
 
 typedef struct cv_context_s {
     IplImage *rawImage;
-    IplImage *yuvImage;
     CascadeClassifier *cascade;
     CascadeClassifier *nestedCascade;
     int w;
@@ -130,20 +131,93 @@ static int clear_overlay(cv_context_t *context, int idx)
         return 0;
     }
 
+
     context->overlay[idx]->png_path = NULL;
     context->overlay[idx]->nick = NULL;
     switch_img_free(&context->overlay[idx]->png);
     memset(context->overlay[idx], 0, sizeof(struct overlay));
+    context->overlay[idx]->shape_scale = 1;
     context->overlay_count--;
 
+
     for (x = idx + 1; x < i; x++) {
         context->overlay[x-1] = context->overlay[x];
         memset(context->overlay[x], 0, sizeof(struct overlay));
+        context->overlay[x]->shape_scale = 1;
     }
 
     return idx - 1 > 0 ? idx -1 : 0;
 }
 
+static int add_text(cv_context_t *context, const char *nick, const char *fg, const char *bg, const char *font_face, int font_size, const char *text)
+{
+    uint32_t i = context->overlay_count;
+       switch_rgb_color_t fgcolor, bgcolor;
+    int x = 0, width = 0, is_new = 1;
+       switch_img_txt_handle_t *txthandle = NULL;
+    
+    for (x = 0; x < i; x++) {
+        if (context->overlay[x] && context->overlay[x]->png) {
+            if (!zstr(nick)) {
+                if (!zstr(context->overlay[x]->nick) && !strcmp(context->overlay[x]->nick, nick)) {
+                    i = x;
+                    is_new = 0;
+                    break;
+                }
+            } else {
+                if (strstr(context->overlay[x]->png_path, text)) {
+                    if (!zstr(nick) && (zstr(context->overlay[x]->nick) || strcmp(nick, context->overlay[x]->nick))) {
+                        context->overlay[x]->nick = switch_core_strdup(context->pool, nick);
+                    }
+                    i = x;
+                    is_new = 0;
+                    break;
+                }
+            }
+        }
+    }
+
+
+    if (is_new) {
+        context->overlay_count++;
+        if (!zstr(nick)) {
+            context->overlay[i]->nick = switch_core_strdup(context->pool, nick);
+        }
+    }
+
+    if (!font_size) {
+        font_size = 24;
+    }
+
+    if (!font_face) {
+        font_face = "FreeMono.ttf";
+    }
+
+    if (!fg) {
+        fg = "#cccccc";
+    }
+
+    if (!bg) {
+        bg = "#142e55";
+    }
+
+    width = (int) (float)(font_size * 0.75f * strlen(text));
+    
+       switch_color_set_rgb(&fgcolor, fg);
+       switch_color_set_rgb(&bgcolor, bg);
+
+    switch_img_free(&context->overlay[i]->png);
+    context->overlay[i]->png = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, width, font_size * 2, 1);
+    switch_img_fill(context->overlay[i]->png, 0, 0, context->overlay[i]->png->d_w, context->overlay[i]->png->d_h, &bgcolor);
+    switch_img_txt_handle_create(&txthandle, font_face, fg, bg, font_size, 0, NULL);
+    switch_img_txt_handle_render(txthandle, context->overlay[i]->png, font_size / 2, font_size / 2, text, NULL, fg, bg, 0, 0);
+    switch_img_txt_handle_destroy(&txthandle);
+
+    return i;
+
+}
+
+
 static int add_overlay(cv_context_t *context, const char *png_path, const char *nick)
 {
     uint32_t i = context->overlay_count;
@@ -159,6 +233,9 @@ static int add_overlay(cv_context_t *context, const char *png_path, const char *
                 }
             } else {
                 if (strstr(context->overlay[x]->png_path, png_path)) {
+                    if (!zstr(nick) && (zstr(context->overlay[x]->nick) || strcmp(nick, context->overlay[x]->nick))) {
+                        context->overlay[x]->nick = switch_core_strdup(context->pool, nick);
+                    }
                     return x;
                 }
             }
@@ -181,9 +258,7 @@ static int add_overlay(cv_context_t *context, const char *png_path, const char *
         context->overlay[i]->png_path = new_png_path;
         if (!zstr(nick)) {
             context->overlay[i]->nick = switch_core_strdup(context->pool, nick);
-        }
-        if (!context->overlay[i]->shape_scale) context->overlay[i]->shape_scale = 1;
-            
+        }            
         r = (int) i;
     } else {
         context->overlay[i]->png_path = NULL;
@@ -236,6 +311,7 @@ static void uninit_context(cv_context_t *context)
         context->overlay[i]->png_path = NULL;
         context->overlay_count = 0;
         memset(context->overlay[i], 0, sizeof(struct overlay));
+        context->overlay[i]->shape_scale = 1;
     }
 
     switch_core_destroy_memory_pool(&context->pool);
@@ -256,6 +332,7 @@ static void init_context(cv_context_t *context)
         for (int i = 0; i < MAX_OVERLAY; i++) {
             context->overlay[i] = (struct overlay *) switch_core_alloc(context->pool, sizeof(struct overlay));
             context->overlay[i]->abs = POS_NONE;
+            context->overlay[i]->shape_scale = 1;
         }
 
         create = 1;
@@ -461,45 +538,63 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
 {
     cv_context_t *context = (cv_context_t *) user_data;
     switch_channel_t *channel = switch_core_session_get_channel(session);
+    int i;
 
     if (!switch_channel_ready(channel)) {
         return SWITCH_STATUS_FALSE;
     }
 
-    if (frame->img) {
+    if (!frame->img) {
+        return SWITCH_STATUS_SUCCESS;
+    }
+
+
+    if (context->cascade) {
+        switch_event_t *event;
+
         if ((frame->img->d_w != context->w || frame->img->d_h != context->h) && context->rawImage) {
             cvReleaseImage(&context->rawImage);
-            cvReleaseImage(&context->yuvImage);
         }
-
+            
         if (!context->rawImage) {
             context->rawImage = cvCreateImage(cvSize(frame->img->d_w, frame->img->d_h), IPL_DEPTH_8U, 3);
-            context->yuvImage = cvCreateImage(cvSize(frame->img->d_w, frame->img->d_h), IPL_DEPTH_8U, 3);
             switch_assert(context->rawImage);
             switch_assert(context->rawImage->width * 3 == context->rawImage->widthStep);
         }
 
-        //printf("context->rawImage: %dx%d stride: %d size: %d color:%s\n", context->rawImage->width, context->rawImage->height, context->rawImage->widthStep, context->rawImage->imageSize, context->rawImage->colorModel);
-
         libyuv::I420ToRGB24(frame->img->planes[0], frame->img->stride[0],
                             frame->img->planes[1], frame->img->stride[1],
                             frame->img->planes[2], frame->img->stride[2],
                             (uint8_t *)context->rawImage->imageData, context->rawImage->widthStep,
                             context->rawImage->width, context->rawImage->height);
 
-
-        if (context->cascade) {
-            switch_event_t *event;
-
-            detectAndDraw(context);
+        detectAndDraw(context);
             
-            if (context->detected.simo_count > 20) {
-                if (!context->detect_event) {
-                    context->detect_event = 1;
+        if (context->detected.simo_count > 20) {
+            if (!context->detect_event) {
+                context->detect_event = 1;
+                    
+                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");
+                    switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "start");
+                    switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%u", context->detected.simo_count);
+                    switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->detected.avg);
+                    switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->detected.last_score);
+                    switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
+                    //switch_channel_event_set_data(channel, event);
+                    DUMP_EVENT(event);
+                    switch_event_fire(&event);
+                }
+                    
+                switch_channel_execute_on(channel, "execute_on_cv_detect_primary");
                     
+            }
+        } else {
+            if (context->detected.simo_miss_count >= 20) {
+                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");
-                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "start");
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "stop");
                         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%u", context->detected.simo_count);
                         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->detected.avg);
                         switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->detected.last_score);
@@ -508,154 +603,157 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
                         DUMP_EVENT(event);
                         switch_event_fire(&event);
                     }
-                    
-                    switch_channel_execute_on(channel, "execute_on_cv_detect_primary");
-                    
-                }
-            } else {
-                if (context->detected.simo_miss_count >= 20) {
-                    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");
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "stop");
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%u", context->detected.simo_count);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->detected.avg);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->detected.last_score);
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
-                            //switch_channel_event_set_data(channel, event);
-                            DUMP_EVENT(event);
-                            switch_event_fire(&event);
-                        }
 
                     
-                        memset(context->shape, 0, sizeof(context->shape[0]) * MAX_SHAPES);
-
-                        switch_channel_execute_on(channel, "execute_on_cv_detect_off_primary");
-                        reset_stats(&context->nestDetected);
-                        reset_stats(&context->detected);
-                    }
+                    memset(context->shape, 0, sizeof(context->shape[0]) * MAX_SHAPES);
 
-                    context->detect_event = 0;
+                    switch_channel_execute_on(channel, "execute_on_cv_detect_off_primary");
+                    reset_stats(&context->nestDetected);
+                    reset_stats(&context->detected);
                 }
 
+                context->detect_event = 0;
             }
 
-            if (context->nestedCascade && context->detected.simo_count > 20) {
-                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHECKING: %d %d %f %d\n", context->nestDetected.itr, context->nestDetected.last_score, context->nestDetected.avg, context->nestDetected.above_avg_simo_count);
-
-                if (context->nestDetected.simo_count > 20 && context->nestDetected.last_score > context->nestDetected.avg && 
-                    context->nestDetected.above_avg_simo_count > 5) {
-                    if (!context->nest_detect_event) {
-                        context->nest_detect_event = 1;
-
-                        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", "nested");
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "start");
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%d", context->nestDetected.simo_count);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->nestDetected.avg);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->nestDetected.last_score);
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
-                            //switch_channel_event_set_data(channel, event);
-                            DUMP_EVENT(event);
-                            switch_event_fire(&event);
-                        }
-
-                        switch_channel_execute_on(channel, "execute_on_cv_detect_nested");
+        }
+
+        if (context->nestedCascade && context->detected.simo_count > 20) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHECKING: %d %d %f %d\n", context->nestDetected.itr, context->nestDetected.last_score, context->nestDetected.avg, context->nestDetected.above_avg_simo_count);
+
+            if (context->nestDetected.simo_count > 20 && context->nestDetected.last_score > context->nestDetected.avg && 
+                context->nestDetected.above_avg_simo_count > 5) {
+                if (!context->nest_detect_event) {
+                    context->nest_detect_event = 1;
+
+                    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", "nested");
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "start");
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%d", context->nestDetected.simo_count);
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->nestDetected.avg);
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->nestDetected.last_score);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
+                        //switch_channel_event_set_data(channel, event);
+                        DUMP_EVENT(event);
+                        switch_event_fire(&event);
                     }
-                } else if (context->nestDetected.above_avg_simo_count == 0) {
-                    if (context->nest_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", "nested");
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "stop");
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%d", context->nestDetected.simo_count);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->nestDetected.avg);
-                            switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->nestDetected.last_score);
-                            switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
-                            //switch_channel_event_set_data(channel, event);
-                            DUMP_EVENT(event);
-                            switch_event_fire(&event);
-                        }
-                        switch_channel_execute_on(channel, "execute_on_cv_detect_off_nested");
-                        reset_stats(&context->nestDetected);
+
+                    switch_channel_execute_on(channel, "execute_on_cv_detect_nested");
+                }
+            } else if (context->nestDetected.above_avg_simo_count == 0) {
+                if (context->nest_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", "nested");
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detect-Disposition", "stop");
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Simo-Count", "%d", context->nestDetected.simo_count);
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Average", "%f", context->nestDetected.avg);
+                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Detect-Last-Score", "%u", context->nestDetected.last_score);
+                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
+                        //switch_channel_event_set_data(channel, event);
+                        DUMP_EVENT(event);
+                        switch_event_fire(&event);
                     }
-                    
-                    context->nest_detect_event = 0;
+                    switch_channel_execute_on(channel, "execute_on_cv_detect_off_nested");
+                    reset_stats(&context->nestDetected);
                 }
+                    
+                context->nest_detect_event = 0;
             }
         }
+    }
+
+    int w = context->rawImage->width;
+    int h = context->rawImage->height;
+
+    if (context->debug || !context->overlay_count) {
+        libyuv::RGB24ToI420((uint8_t *)context->rawImage->imageData, w * 3,
+                            frame->img->planes[0], frame->img->stride[0],
+                            frame->img->planes[1], frame->img->stride[1],
+                            frame->img->planes[2], frame->img->stride[2],
+                            context->rawImage->width, context->rawImage->height);
+    }
 
-        int w = context->rawImage->width;
-        int h = context->rawImage->height;
+    int abs = 0;
 
-        if (context->debug || !context->overlay_count) {
-            libyuv::RGB24ToI420((uint8_t *)context->rawImage->imageData, w * 3,
-                                frame->img->planes[0], frame->img->stride[0],
-                                frame->img->planes[1], frame->img->stride[1],
-                                frame->img->planes[2], frame->img->stride[2],
-                                context->rawImage->width, context->rawImage->height);
+    for (i = 0; i < context->overlay_count; i++) {
+        if (context->overlay[i]->abs != POS_NONE) {
+            abs++;
         }
+    }
 
-        if (context->overlay_count && context->detect_event && context->shape[0].cx) {
-            int i;
-            
-            for (i = 0; i < context->overlay_count; i++) {
-                struct overlay *overlay = context->overlay[i];
-                int x = 0, y = 0;
-                switch_image_t *img = NULL;
-                int scale_w = 0, scale_h = 0;
-                int xo = 0, yo = 0;
-                int shape_w, shape_h;
-                int cx, cy;
-
-                shape_w = context->shape[0].w;
-                shape_h = context->shape[0].h;
+    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];
+            int x = 0, y = 0;
+            switch_image_t *img = NULL;
+            int scale_w = 0, scale_h = 0;
+            int xo = 0, yo = 0;
+            int shape_w, shape_h;
+            int cx, cy;
+
+            if (context->overlay[i]->abs == POS_NONE && !context->detect_event && !context->shape[0].cx) {
+                continue;
+            }
+
+            shape_w = context->shape[0].w;
+            shape_h = context->shape[0].h;
             
-                cx = context->shape[0].cx;
-                cy = context->shape[0].cy;
+            cx = context->shape[0].cx;
+            cy = context->shape[0].cy;
             
 
-                if (overlay->abs != POS_NONE) {
-                    if (overlay->shape_scale != 1) {
-                        scale_w = overlay->png->d_w * overlay->shape_scale;
-                        if (scale_w > frame->img->d_w) {
-                            scale_w = frame->img->d_w;
-                        }
+            if (overlay->abs != POS_NONE) {
+                if (overlay->scale_w || overlay->scale_h) {
+                    if (overlay->scale_w && !overlay->scale_h) {
+                        scale_w = frame->img->d_w;
                         scale_h = ((overlay->png->d_h * scale_w) / overlay->png->d_w);
+                    } else if (overlay->scale_h && !overlay->scale_w) {
+                        scale_h = frame->img->d_h;
+                        scale_w = ((overlay->png->d_w * scale_h) / overlay->png->d_h);
                     } else {
-                        scale_w = overlay->png->d_w;
-                        scale_h = overlay->png->d_h;
+                        scale_w = frame->img->d_w;
+                        scale_h = frame->img->d_h;
                     }
+                } else if (overlay->shape_scale != 1) {
+                    scale_w = overlay->png->d_w * overlay->shape_scale;
 
-                    switch_img_find_position(overlay->abs, frame->img->d_w, frame->img->d_h, scale_w, scale_h, &x, &y);
-                } else {
-
-                    scale_w = shape_w * overlay->shape_scale;
                     if (scale_w > frame->img->d_w) {
                         scale_w = frame->img->d_w;
                     }
+
                     scale_h = ((overlay->png->d_h * scale_w) / overlay->png->d_w);
+                } else {
+                    scale_w = overlay->png->d_w;
+                    scale_h = overlay->png->d_h;
+                }
 
-                    if (overlay->xo) {
-                        xo = overlay->xo * shape_w;
-                    }
-                    
-                    if (overlay->yo) {
-                        yo = overlay->yo * context->shape[0].h;
-                    }
-                    
-                    x = cx - ((scale_w / 2) + xo);
-                    y = cy - ((scale_h / 2) + yo);
+                switch_img_find_position(overlay->abs, frame->img->d_w, frame->img->d_h, scale_w, scale_h, &x, &y);
+            } else {
+
+                scale_w = shape_w * overlay->shape_scale;
+                if (scale_w > frame->img->d_w) {
+                    scale_w = frame->img->d_w;
                 }
-                
-                switch_img_scale(overlay->png, &img, scale_w, scale_h);
+                scale_h = ((overlay->png->d_h * scale_w) / overlay->png->d_w);
 
-                if (img) {
-                    switch_img_patch(frame->img, img, x, y);
-                    switch_img_free(&img);
+                if (overlay->xo) {
+                    xo = overlay->xo * shape_w;
+                }
+                    
+                if (overlay->yo) {
+                    yo = overlay->yo * context->shape[0].h;
                 }
+                    
+                x = cx - ((scale_w / 2) + xo);
+                y = cy - ((scale_h / 2) + yo);
+            }
+
+            switch_img_scale(overlay->png, &img, scale_w, scale_h);
+
+            if (img) {
+                switch_img_patch(frame->img, img, x, y);
+                switch_img_free(&img);
             }
         }
-        
     }
 
     return SWITCH_STATUS_SUCCESS;
@@ -701,7 +799,6 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
         }
 
         if (name && val) {
-
             if (!strcasecmp(name, "xo")) {
                 context->overlay[png_idx]->xo = atof(val);
             } else if (!strcasecmp(name, "nick")) {
@@ -714,8 +811,27 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
                 sort++;
             } else if (!strcasecmp(name, "abs")) {
                 context->overlay[png_idx]->abs = parse_img_position(val);
+                if (context->overlay[png_idx]->abs == POS_NONE) {
+                    context->overlay[png_idx]->scale_w = context->overlay[png_idx]->scale_h = 0;
+                }
+            } else if (!strcasecmp(name, "scaleto") && context->overlay[png_idx]->abs != POS_NONE) {
+                if (strchr(val, 'W')) {
+                    context->overlay[png_idx]->scale_w = 1;
+                }
+
+                if (strchr(val, 'H')) {
+                    context->overlay[png_idx]->scale_h = 1;
+                }
+
+                if (strchr(val, 'w')) {
+                    context->overlay[png_idx]->scale_w = 0;
+                }
+
+                if (strchr(val, 'h')) {
+                    context->overlay[png_idx]->scale_h = 0;
+                }
             } else if (!strcasecmp(name, "scale")) {
-                context->overlay[png_idx]->shape_scale = atof(val);
+                context->overlay[png_idx]->shape_scale = atof(val);                
             } else if (!strcasecmp(name, "skip")) {
                 context->skip = atoi(val);
             } else if (!strcasecmp(name, "debug")) {
@@ -728,10 +844,26 @@ static void parse_params(cv_context_t *context, int start, int argc, char **argv
                 changed++;
             } else if (!strcasecmp(name, "png")) {
                 png_idx = add_overlay(context, val, nick);
+            } else if (!strcasecmp(name, "txt")) {
+                int iargc = 0;
+                char *iargv[10] = { 0 };
+
+                iargc = switch_split(val, ':', iargv);
+                if (iargc >= 5) {
+                    png_idx = add_text(context, nick, iargv[0], iargv[1], iargv[2], atoi(iargv[3]), iargv[4]);
+                }
             }
         } else if (name) {
             if (!strcasecmp(name, "clear")) {
                 png_idx = clear_overlay(context, png_idx);
+            } else if (!strcasecmp(name, "allclear")) {
+                for (int x = context->overlay_count - 1; x >= 0; x--) {
+                    png_idx = clear_overlay(context, x);
+                    context->overlay[x]->xo = context->overlay[x]->yo = context->overlay[x]->shape_scale = 0.0f;
+                    context->overlay[x]->zidx = 0;
+                    context->overlay[x]->scale_w = context->overlay[x]->scale_h = 0;
+                    context->overlay[x]->shape_scale = 1;
+                }
             } else if (!strcasecmp(name, "home")) {
                 context->overlay[png_idx]->xo = context->overlay[png_idx]->yo = context->overlay[png_idx]->shape_scale = 0.0f;
                 context->overlay[png_idx]->zidx = 0;
index 477d6e8606f5f18915fdb32f9d56d9ffeedcec2f..03341b5642b286f666b32c333838fb28e8d4f162 100644 (file)
@@ -507,7 +507,22 @@ SWITCH_DECLARE(switch_status_t) switch_img_txt_handle_create(switch_img_txt_hand
 
        new_handle->pool = pool;
        new_handle->free_pool = free_pool;
-       new_handle->font_family = switch_core_strdup(new_handle->pool, font_family);
+
+       if (!switch_is_file_path(font_family)) {
+               new_handle->font_family = switch_core_sprintf(new_handle->pool, "%s%s%s",SWITCH_GLOBAL_dirs.fonts_dir, SWITCH_PATH_SEPARATOR, font_family);
+       } else {
+               new_handle->font_family = switch_core_strdup(new_handle->pool, font_family);
+       }
+
+       if (switch_file_exists(new_handle->font_family, new_handle->pool) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Font %s does not exist\n", new_handle->font_family);
+               if (free_pool) {
+                       switch_core_destroy_memory_pool(&pool);
+               }
+               *handleP = NULL;
+               return SWITCH_STATUS_FALSE;
+       }
+
        new_handle->font_size = font_size;
        new_handle->angle = angle;