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
*
*/
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)
*
*
* \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
*
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;
}
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;
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);
}
MFLAG_SECOND_SCREEN,
MFLAG_SILENT,
MFLAG_FLIP_VIDEO,
+ MFLAG_ROTATE_VIDEO,
///////////////////////////
MFLAG_MAX
} member_flag_t;
int force_bw_in;
int max_bw_out;
int reset_media;
+ int flip;
+ int flip_count;
};
typedef enum {
#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
}
#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