diff --git a/src/mod/applications/mod_cv/mod_cv.cpp b/src/mod/applications/mod_cv/mod_cv.cpp index 54feea992a..f4b03691a4 100644 --- a/src/mod/applications/mod_cv/mod_cv.cpp +++ b/src/mod/applications/mod_cv/mod_cv.cpp @@ -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); + 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); - } - - 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 (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 (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); - } + 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; - switch_channel_execute_on(channel, "execute_on_cv_detect_nested"); + 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); - } - - context->nest_detect_event = 0; + + 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); + } + 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; + 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); + 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 abs = 0; + + 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; + 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; - shape_w = context->shape[0].w; - shape_h = context->shape[0].h; + 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); - - 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); + } else { + scale_w = overlay->png->d_w; + scale_h = overlay->png->d_h; } - - switch_img_scale(overlay->png, &img, scale_w, scale_h); - if (img) { - switch_img_patch(frame->img, img, x, y); - switch_img_free(&img); + 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); + + 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; diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 477d6e8606..03341b5642 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -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;