提交 2c368307 authored 作者: Anthony Minessale's avatar Anthony Minessale

FS-10138: [freeswitch-core,mod_conference] Add alpha video to conference #resolve

上级 69f87f0b
......@@ -339,6 +339,7 @@ typedef struct switch_mm_s {
uint8_t try_hardware_encoder;
int scale_w;
int scale_h;
switch_img_fmt_t fmt;
} switch_mm_t;
/*! an abstract representation of a file handle (some parameters based on compat with libsndfile) */
......
......@@ -1330,7 +1330,6 @@ struct av_file_context {
switch_bool_t read_paused;
int errs;
switch_file_handle_t *handle;
switch_bool_t alpha_mode;
};
typedef struct av_file_context av_file_context_t;
......@@ -1389,7 +1388,12 @@ static switch_status_t open_input_file(av_file_context_t *context, switch_file_h
context->has_video = 1;
handle->duration = av_rescale_q(context->video_st.st->duration, context->video_st.st->time_base, AV_TIME_BASE_Q);
}
handle->mm.source_fps = ceil(av_q2d(context->video_st.st->avg_frame_rate));
if (context->video_st.st->avg_frame_rate.num) {
handle->mm.source_fps = ceil(av_q2d(context->video_st.st->avg_frame_rate));
} else {
handle->mm.source_fps = 25;
}
context->read_fps = (int)handle->mm.source_fps;
}
}
......@@ -1585,7 +1589,7 @@ again:
if (got_data && error >= 0) {
switch_img_fmt_t fmt = SWITCH_IMG_FMT_I420;
if (context->alpha_mode && (
if ((
vframe->format == AV_PIX_FMT_YUVA420P ||
vframe->format == AV_PIX_FMT_RGBA ||
vframe->format == AV_PIX_FMT_ARGB ||
......@@ -1632,6 +1636,8 @@ again:
continue;
}
}
context->handle->mm.fmt = fmt;
img = switch_img_alloc(NULL, fmt, vframe->width, vframe->height, 1);
......@@ -1773,8 +1779,6 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa
if (handle->params) {
if ((tmp = switch_event_get_header(handle->params, "av_video_offset"))) {
context->offset = atoi(tmp);
} else if ((tmp = switch_event_get_header(handle->params, "alpha_mode"))) {
context->alpha_mode = switch_true(tmp);
}
}
......
......@@ -270,12 +270,18 @@ switch_status_t conference_file_play(conference_obj_t *conference, char *file, u
goto done;
}
fnode->layer_lock = -1;
if (fnode->fh.params) {
const char *vol = switch_event_get_header(fnode->fh.params, "vol");
const char *position = switch_event_get_header(fnode->fh.params, "position");
const char *canvasstr = switch_event_get_header(fnode->fh.params, "canvas");
const char *loopsstr = switch_event_get_header(fnode->fh.params, "loops");
const char *overlay_layer = switch_event_get_header(fnode->fh.params, "overlay_layer");
const char *overlay_member = switch_event_get_header(fnode->fh.params, "overlay_member");
const char *overlay_role = switch_event_get_header(fnode->fh.params, "overlay_role");
int canvas_id = -1;
int layer_id = -1;
if (loopsstr) {
fnode->loops = atoi(loopsstr);
......@@ -285,6 +291,35 @@ switch_status_t conference_file_play(conference_obj_t *conference, char *file, u
}
}
if (overlay_role) {
conference_member_t *member;
if ((member = conference_member_get_by_role(conference, overlay_role))) {
layer_id = member->video_layer_id;
switch_thread_rwlock_unlock(member->rwlock);
}
} else if (overlay_member) {
int id = atoi(overlay_member);
if (id > 0) {
conference_member_t *member;
if ((member = conference_member_get(conference, id))) {
layer_id = member->video_layer_id;
switch_thread_rwlock_unlock(member->rwlock);
}
}
}
if (layer_id < 0 && overlay_layer) {
layer_id = atoi(overlay_layer);
}
if (layer_id > -1) {
fnode->layer_lock = layer_id;
fnode->layer_id = layer_id;
}
if (canvasstr) {
canvas_id = atoi(canvasstr) - 1;
}
......
......@@ -435,6 +435,51 @@ conference_member_t *conference_member_get_by_var(conference_obj_t *conference,
return member;
}
/* traverse the conference member list for the specified member with role and return it's pointer */
conference_member_t *conference_member_get_by_role(conference_obj_t *conference, const char *role_id)
{
conference_member_t *member = NULL;
switch_assert(conference != NULL);
if (zstr(role_id)) {
return NULL;
}
switch_mutex_lock(conference->member_mutex);
for (member = conference->members; member; member = member->next) {
if (conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) {
continue;
}
if (!zstr(member->video_role_id) && !strcmp(role_id, member->video_role_id)) {
break;
}
}
if (member) {
if (!conference_utils_member_test_flag(member, MFLAG_INTREE) ||
conference_utils_member_test_flag(member, MFLAG_KICKED) ||
(member->session && !switch_channel_up(switch_core_session_get_channel(member->session)))) {
/* member is kicked or hanging up so forget it */
member = NULL;
}
}
if (member) {
if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) {
/* if you cant readlock it's way to late to do anything */
member = NULL;
}
}
switch_mutex_unlock(conference->member_mutex);
return member;
}
void conference_member_check_channels(switch_frame_t *frame, conference_member_t *member, switch_bool_t in)
{
if (member->conference->channels != member->read_impl.number_of_channels || conference_utils_member_test_flag(member, MFLAG_POSITIONAL)) {
......
......@@ -389,6 +389,7 @@ typedef struct conference_file_node {
char *res_id;
int loops;
int new_fnode;
int layer_lock;
} conference_file_node_t;
typedef enum {
......@@ -476,9 +477,9 @@ typedef struct mcu_layer_s {
switch_size_t last_img_addr;
switch_image_t *img;
switch_image_t *cur_img;
switch_image_t *overlay_img;
switch_image_t *banner_img;
switch_image_t *logo_img;
switch_image_t *logo_text_img;
switch_image_t *mute_img;
switch_img_txt_handle_t *txthandle;
conference_file_node_t *fnode;
......@@ -494,6 +495,7 @@ typedef struct mcu_layer_s {
switch_frame_geometry_t pan_geometry;
switch_frame_geometry_t manual_geometry;
mcu_layer_cam_opts_t cam_opts;
switch_mutex_t *overlay_mutex;
} mcu_layer_t;
typedef struct video_layout_s {
......@@ -717,6 +719,7 @@ typedef struct conference_obj {
switch_hash_t *layout_group_hash;
struct conference_fps video_fps;
int playing_video_file;
int overlay_video_file;
int recording_members;
uint32_t video_floor_packets;
video_layout_t *new_personal_vlayout;
......@@ -1073,7 +1076,7 @@ void conference_fnode_check_status(conference_file_node_t *fnode, switch_stream_
conference_relationship_t *conference_member_add_relationship(conference_member_t *member, uint32_t id);
conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id);
conference_member_t *conference_member_get_by_var(conference_obj_t *conference, const char *var, const char *val);
conference_member_t *conference_member_get_by_role(conference_obj_t *conference, const char *role_id);
switch_status_t conference_member_del_relationship(conference_member_t *member, uint32_t id);
switch_status_t conference_member_add(conference_obj_t *conference, conference_member_t *member);
switch_status_t conference_member_del(conference_obj_t *conference, conference_member_t *member);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论