From 48dcab82d746ef0a04817b373fe7b66b0d3ef605 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Apr 2016 10:49:46 -0500 Subject: [PATCH] FS-9000 tweaks --- src/include/switch_core_video.h | 12 +++- .../mod_conference/conference_api.c | 26 ++++--- .../mod_conference/conference_video.c | 25 +++++-- .../mod_conference/mod_conference.h | 3 + src/switch_core_video.c | 68 ++++++++++++++++++- 5 files changed, 115 insertions(+), 19 deletions(-) diff --git a/src/include/switch_core_video.h b/src/include/switch_core_video.h index c836c05a22..068a138107 100644 --- a/src/include/switch_core_video.h +++ b/src/include/switch_core_video.h @@ -97,7 +97,13 @@ typedef struct switch_png_s { int h; } switch_png_t; - +typedef enum { + SRM_NONE = 0, // No rotation. + SRM_90 = 90, // Rotate 90 degrees clockwise. + SRM_180 = 180, // Rotate 180 degrees. + SRM_270 = 270, // Rotate 270 degrees clockwise. +} switch_image_rotation_mode_t; + /*!\brief Open a descriptor, allocating storage for the underlying image * @@ -209,7 +215,7 @@ SWITCH_DECLARE(void) switch_img_patch_rect(switch_image_t *IMG, int X, int Y, sw */ SWITCH_DECLARE(void) switch_img_copy(switch_image_t *img, switch_image_t **new_img); - +SWITCH_DECLARE(void) switch_img_rotate_copy(switch_image_t *img, switch_image_t **new_img, switch_image_rotation_mode_t mode); /*!\brief Flip the image vertically (top for bottom) * @@ -220,7 +226,7 @@ SWITCH_DECLARE(void) switch_img_copy(switch_image_t *img, switch_image_t **new_i * * \return 0 if the requested rectangle is valid, nonzero otherwise. */ -SWITCH_DECLARE(void) switch_img_flip(switch_image_t *img); +SWITCH_DECLARE(void) switch_img_rotate(switch_image_t **img, switch_image_rotation_mode_t mode); /*!\brief Close an image descriptor * diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 4ec801a093..a0089f78e8 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -658,29 +658,37 @@ switch_status_t conference_api_sub_kick(conference_member_t *member, switch_stre switch_status_t conference_api_sub_vid_flip(conference_member_t *member, switch_stream_handle_t *stream, void *data) { - switch_event_t *event; + char *arg = (char *) data; if (member == NULL) { return SWITCH_STATUS_GENERR; } - if (conference_utils_member_test_flag(member, MFLAG_FLIP_VIDEO)) { + if (conference_utils_member_test_flag(member, MFLAG_FLIP_VIDEO) && !arg) { conference_utils_member_clear_flag_locked(member, MFLAG_FLIP_VIDEO); + conference_utils_member_clear_flag_locked(member, MFLAG_ROTATE_VIDEO); } else { conference_utils_member_set_flag_locked(member, MFLAG_FLIP_VIDEO); + + if (arg) { + if (!strcasecmp(arg, "rotate")) { + conference_utils_member_set_flag_locked(member, MFLAG_ROTATE_VIDEO); + } else if (switch_is_number(arg)) { + int num = atoi(arg); + + if (num == 0 || num == 90 || num == 180 || num == 270) { + member->flip = num; + } + } + } else { + member->flip = 180; + } } if (stream != NULL) { stream->write_function(stream, "OK flipped %u\n", member->id); } - if (member->conference && test_eflag(member->conference, EFLAG_KICK_MEMBER)) { - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { - conference_member_add_event_data(member, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "vid-flip-member"); - switch_event_fire(&event); - } - } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index bf6c22a196..998486400e 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -499,6 +499,7 @@ void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_img_fit(&layer->logo_img, ew, eh, layer->logo_fit); switch_img_find_position(layer->logo_pos, ew, eh, layer->logo_img->d_w, layer->logo_img->d_h, &ex, &ey); + switch_img_patch(IMG, layer->logo_img, layer->x_pos + ex + layer->geometry.border, layer->y_pos + ey + layer->geometry.border); if (layer->logo_text_img) { int tx = 0, ty = 0; @@ -3728,12 +3729,26 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session, conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && switch_queue_size(member->video_queue) < member->conference->video_fps.fps * 2 && !member->conference->playing_video_file) { - switch_img_copy(frame->img, &img_copy); - - if (conference_utils_member_test_flag(member, MFLAG_FLIP_VIDEO)) { - switch_img_flip(img_copy); - } + if (conference_utils_member_test_flag(member, MFLAG_FLIP_VIDEO) || conference_utils_member_test_flag(member, MFLAG_ROTATE_VIDEO)) { + if (conference_utils_member_test_flag(member, MFLAG_ROTATE_VIDEO)) { + if (member->flip_count++ > (int)(member->conference->video_fps.fps / 2)) { + member->flip += 90; + if (member->flip > 270) { + member->flip = 0; + } + member->flip_count = 0; + } + + switch_img_rotate_copy(frame->img, &img_copy, member->flip); + } else { + switch_img_rotate_copy(frame->img, &img_copy, member->flip); + } + + } else { + switch_img_copy(frame->img, &img_copy); + } + if (switch_queue_trypush(member->video_queue, img_copy) != SWITCH_STATUS_SUCCESS) { switch_img_free(&img_copy); } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index 863bf39ff8..9feb4e9e31 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -209,6 +209,7 @@ typedef enum { MFLAG_SECOND_SCREEN, MFLAG_SILENT, MFLAG_FLIP_VIDEO, + MFLAG_ROTATE_VIDEO, /////////////////////////// MFLAG_MAX } member_flag_t; @@ -780,6 +781,8 @@ struct conference_member { int force_bw_in; int max_bw_out; int reset_media; + int flip; + int flip_count; }; typedef enum { diff --git a/src/switch_core_video.c b/src/switch_core_video.c index 706b873658..794e37affc 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -228,10 +228,36 @@ SWITCH_DECLARE(int) switch_img_set_rect(switch_image_t *img, #endif } -SWITCH_DECLARE(void) switch_img_flip(switch_image_t *img) +SWITCH_DECLARE(void) switch_img_rotate(switch_image_t **img, switch_image_rotation_mode_t mode) { + switch_image_t *tmp_img; + + switch_assert(img); + #ifdef SWITCH_HAVE_VPX - vpx_img_flip((vpx_image_t *)img); + + if ((*img)->fmt != SWITCH_IMG_FMT_I420) return; + + if (mode == SRM_90 || mode == SRM_270) { + tmp_img = switch_img_alloc(NULL, (*img)->fmt, (*img)->d_h, (*img)->d_w, 1); + } else { + tmp_img = switch_img_alloc(NULL, (*img)->fmt, (*img)->d_w, (*img)->d_h, 1); + } + + switch_assert(tmp_img); + + I420Rotate((*img)->planes[SWITCH_PLANE_Y], (*img)->stride[SWITCH_PLANE_Y], + (*img)->planes[SWITCH_PLANE_U], (*img)->stride[SWITCH_PLANE_U], + (*img)->planes[SWITCH_PLANE_V], (*img)->stride[SWITCH_PLANE_V], + tmp_img->planes[SWITCH_PLANE_Y], tmp_img->stride[SWITCH_PLANE_Y], + tmp_img->planes[SWITCH_PLANE_U], tmp_img->stride[SWITCH_PLANE_U], + tmp_img->planes[SWITCH_PLANE_V], tmp_img->stride[SWITCH_PLANE_V], + (*img)->d_w, (*img)->d_h, mode); + + + switch_img_free(img); + *img = tmp_img; + #endif } @@ -429,6 +455,44 @@ SWITCH_DECLARE(void) switch_img_copy(switch_image_t *img, switch_image_t **new_i #endif } + +SWITCH_DECLARE(void) switch_img_rotate_copy(switch_image_t *img, switch_image_t **new_img, switch_image_rotation_mode_t mode) +{ + switch_assert(img); + switch_assert(new_img); + +#ifdef SWITCH_HAVE_YUV + if (img->fmt != SWITCH_IMG_FMT_I420) abort(); + + if (*new_img != NULL) { + if (img->fmt != (*new_img)->fmt || img->d_w != (*new_img)->d_w || img->d_h != (*new_img)->d_w) { + switch_img_free(new_img); + } + } + + if (*new_img == NULL) { + if (mode == SRM_90 || mode == SRM_270) { + *new_img = switch_img_alloc(NULL, img->fmt, img->d_h, img->d_w, 1); + } else { + *new_img = switch_img_alloc(NULL, img->fmt, img->d_w, img->d_h, 1); + } + } + + switch_assert(*new_img); + + + I420Rotate(img->planes[SWITCH_PLANE_Y], img->stride[SWITCH_PLANE_Y], + img->planes[SWITCH_PLANE_U], img->stride[SWITCH_PLANE_U], + img->planes[SWITCH_PLANE_V], img->stride[SWITCH_PLANE_V], + (*new_img)->planes[SWITCH_PLANE_Y], (*new_img)->stride[SWITCH_PLANE_Y], + (*new_img)->planes[SWITCH_PLANE_U], (*new_img)->stride[SWITCH_PLANE_U], + (*new_img)->planes[SWITCH_PLANE_V], (*new_img)->stride[SWITCH_PLANE_V], + img->d_w, img->d_h, mode); +#else + return; +#endif +} + SWITCH_DECLARE(switch_image_t *) switch_img_copy_rect(switch_image_t *img, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { #ifdef SWITCH_HAVE_VPX