diff --git a/src/mod/formats/mod_png/mod_png.c b/src/mod/formats/mod_png/mod_png.c index 01bd93bea5..63936d1aef 100644 --- a/src/mod/formats/mod_png/mod_png.c +++ b/src/mod/formats/mod_png/mod_png.c @@ -36,8 +36,11 @@ #pragma warning(disable : 4996) #endif +switch_loadable_module_interface_t *MODULE_INTERFACE; + SWITCH_MODULE_LOAD_FUNCTION(mod_png_load); -SWITCH_MODULE_DEFINITION(mod_png, mod_png_load, NULL, NULL); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_png_shutdown); +SWITCH_MODULE_DEFINITION(mod_png, mod_png_load, mod_png_shutdown, NULL); struct png_file_context { switch_memory_pool_t *pool; @@ -201,17 +204,106 @@ static switch_status_t png_file_read_video(switch_file_handle_t *handle, switch_ return SWITCH_STATUS_SUCCESS; } +static switch_bool_t write_png_bug_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + switch_core_session_t *session = switch_core_media_bug_get_session(bug); + switch_channel_t *channel = switch_core_session_get_channel(session); + char *path = (char *) user_data; + + switch (type) { + case SWITCH_ABC_TYPE_INIT: + { + switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ); + } + break; + case SWITCH_ABC_TYPE_CLOSE: + { + switch_thread_rwlock_unlock(MODULE_INTERFACE->rwlock); + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); + } + break; + case SWITCH_ABC_TYPE_READ_VIDEO_PING: + { + switch_frame_t *frame = switch_core_media_bug_get_video_ping_frame(bug); + if (!frame || !frame->img) break; + switch_img_write_png(frame->img, path); + return SWITCH_FALSE; + } + break; + default: + break; + } + + return SWITCH_TRUE; +} + +SWITCH_STANDARD_API(uuid_write_png_function) +{ + int argc = 0; + char *argv[2] = { 0 }; + char *mydata = NULL; + char *uuid; + char *path; + switch_media_bug_t *bug; + switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING; + switch_core_session_t *session_; + + if (!zstr(cmd) && (mydata = strdup(cmd))) { + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 2) { + stream->write_function(stream, "-USAGE: \n"); + goto end; + } + + uuid = argv[0]; + if (!(session_ = switch_core_session_locate(uuid))) { + stream->write_function(stream, "-ERR Could not locate session.\n"); + goto end; + } + + if (!switch_channel_test_flag(switch_core_session_get_channel(session_), CF_VIDEO)) { + stream->write_function(stream, "-ERR Session does not have video.\n"); + switch_core_session_rwunlock(session_); + goto end; + } + + if (!switch_is_file_path(argv[1])) { + const char *prefix = SWITCH_GLOBAL_dirs.images_dir; + path = switch_core_session_sprintf(session_, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, argv[1]); + } else { + path = switch_core_session_strdup(session_, argv[1]); + } + + switch_thread_rwlock_rdlock(MODULE_INTERFACE->rwlock); + + if (switch_core_media_bug_add(session_, NULL, NULL, write_png_bug_callback, path, 0, flags, &bug) != SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "-ERR Could not attach bug.\n"); + switch_thread_rwlock_unlock(MODULE_INTERFACE->rwlock); + } else { + stream->write_function(stream, "+OK\n"); + } + + switch_core_session_rwunlock(session_); + + end: + switch_safe_free(mydata); + return SWITCH_STATUS_SUCCESS; +} static char *supported_formats[2] = { 0 }; SWITCH_MODULE_LOAD_FUNCTION(mod_png_load) { + switch_api_interface_t *api_interface; switch_file_interface_t *file_interface; supported_formats[0] = (char *)"png"; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); + MODULE_INTERFACE = *module_interface; file_interface = (switch_file_interface_t *)switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE); file_interface->interface_name = modname; @@ -221,10 +313,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_png_load) file_interface->file_read = png_file_read; file_interface->file_read_video = png_file_read_video; + SWITCH_ADD_API(api_interface, "uuid_write_png", "grab an image from a call",uuid_write_png_function, ""); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_png_shutdown) +{ + return SWITCH_STATUS_UNLOAD; +} + /* For Emacs: * Local Variables: * mode:c