diff --git a/pjmedia/src/pjmedia/vid_port.c b/pjmedia/src/pjmedia/vid_port.c index 4cb3739f0..777207914 100644 --- a/pjmedia/src/pjmedia/vid_port.c +++ b/pjmedia/src/pjmedia/vid_port.c @@ -887,9 +887,46 @@ static pj_status_t client_port_event_cb(pjmedia_event *event, if (event->type == PJMEDIA_EVENT_FMT_CHANGED) { const pjmedia_video_format_detail *vfd; + const pjmedia_video_format_detail *vfd_cur; pjmedia_vid_dev_param vid_param; pj_status_t status; + /* Retrieve the current video format detail */ + pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param); + vfd_cur = pjmedia_format_get_video_format_detail( + &vid_param.fmt, PJ_TRUE); + if (!vfd_cur) + return PJMEDIA_EVID_BADFORMAT; + + /* Retrieve the new video format detail */ + vfd = pjmedia_format_get_video_format_detail( + &event->data.fmt_changed.new_fmt, PJ_TRUE); + if (!vfd || !vfd->fps.num || !vfd->fps.denum) + return PJMEDIA_EVID_BADFORMAT; + + /* Ticket #1876: if this is a passive renderer and only frame rate is + * changing, simply modify the clock. + */ + if (vp->dir == PJMEDIA_DIR_RENDER && + vp->stream_role == ROLE_PASSIVE && vp->role == ROLE_ACTIVE) + { + pj_bool_t fps_only; + pjmedia_video_format_detail tmp_vfd; + + tmp_vfd = *vfd_cur; + tmp_vfd.fps = vfd->fps; + fps_only = pj_memcmp(vfd, &tmp_vfd, sizeof(*vfd)) == 0; + if (fps_only) { + pjmedia_clock_param clock_param; + clock_param.usec_interval = PJMEDIA_PTIME(&vfd->fps); + clock_param.clock_rate = vid_param.clock_rate; + pjmedia_clock_modify(vp->clock, &clock_param); + + return pjmedia_event_publish(NULL, vp, event, + PJMEDIA_EVENT_PUBLISH_POST_EVENT); + } + } + /* Ticket #1827: * Stopping video port should not be necessary here because * it will also try to stop the clock, from inside the clock's @@ -899,12 +936,6 @@ static pj_status_t client_port_event_cb(pjmedia_event *event, */ pjmedia_vid_dev_stream_stop(vp->strm); - /* Retrieve the video format detail */ - vfd = pjmedia_format_get_video_format_detail( - &event->data.fmt_changed.new_fmt, PJ_TRUE); - if (!vfd || !vfd->fps.num || !vfd->fps.denum) - return PJMEDIA_EVID_BADFORMAT; - /* Change the destination format to the new format */ pjmedia_format_copy(&vp->conv.conv_param.src, &event->data.fmt_changed.new_fmt); @@ -918,7 +949,6 @@ static pj_status_t client_port_event_cb(pjmedia_event *event, return status; } - pjmedia_vid_dev_stream_get_param(vp->strm, &vid_param); if (vid_param.fmt.id != vp->conv.conv_param.dst.id || (vid_param.fmt.det.vid.size.h != vp->conv.conv_param.dst.det.vid.size.h) || diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index fae0cb13d..912d986fc 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -977,21 +977,27 @@ static void on_call_media_event(pjsua_call_id call_id, if (event->type == PJMEDIA_EVENT_FMT_CHANGED) { /* Adjust renderer window size to original video size */ pjsua_call_info ci; - pjsua_vid_win_id wid; - pjmedia_rect_size size; pjsua_call_get_info(call_id, &ci); if ((ci.media[med_idx].type == PJMEDIA_TYPE_VIDEO) && (ci.media[med_idx].dir & PJMEDIA_DIR_DECODING)) { - wid = ci.media[med_idx].stream.vid.win_in; - size = event->data.fmt_changed.new_fmt.det.vid.size; - pjsua_vid_win_set_size(wid, &size); - } + pjsua_vid_win_id wid; + pjmedia_rect_size size; + pjsua_vid_win_info win_info; - /* Re-arrange video windows */ - arrange_window(PJSUA_INVALID_ID); + wid = ci.media[med_idx].stream.vid.win_in; + pjsua_vid_win_get_info(wid, &win_info); + + size = event->data.fmt_changed.new_fmt.det.vid.size; + if (size.w != win_info.size.w || size.h != win_info.size.h) { + pjsua_vid_win_set_size(wid, &size); + + /* Re-arrange video windows */ + arrange_window(PJSUA_INVALID_ID); + } + } } #else PJ_UNUSED_ARG(call_id);