diff --git a/src/conference.cpp b/src/conference.cpp index c41f252243b8e314299cd83f65fb0485a1c33ce7..4c527b684d42d195ddf3c81fc1df04052a9d4196 100644 --- a/src/conference.cpp +++ b/src/conference.cpp @@ -1012,11 +1012,10 @@ Conference::resizeRemoteParticipants(ConfInfo& confInfo, std::string_view peerUR } } + const float zoomX = (float) remoteFrameWidth / localCell.w; + const float zoomY = (float) remoteFrameHeight / localCell.h; // Do the resize for each remote participant for (auto& remoteCell : confInfo) { - const float zoomX = (float) remoteFrameWidth / localCell.w; - const float zoomY = (float) remoteFrameHeight / localCell.h; - remoteCell.x = remoteCell.x / zoomX + localCell.x; remoteCell.y = remoteCell.y / zoomY + localCell.y; remoteCell.w = remoteCell.w / zoomX; @@ -1052,8 +1051,10 @@ Conference::mergeConfInfo(ConfInfo& newInfo, const std::string& peerURI) } // Send confInfo only if needed to avoid loops if (updateNeeded) { - std::lock_guard<std::mutex> lk(confInfoMutex_); - sendConferenceInfos(); + // Trigger the layout update in the mixer because the frame resolution may + // change from participant to conference and cause a mismatch between + // confInfo layout and rendering layout. + getVideoMixer()->updateLayout(); } } diff --git a/src/media/video/video_mixer.cpp b/src/media/video/video_mixer.cpp index 216142118ad69ef2ed63f94b991b2472b44cd94f..3bcf40ad8f1c1b9b0a9350a795168202fd1ef038 100644 --- a/src/media/video/video_mixer.cpp +++ b/src/media/video/video_mixer.cpp @@ -178,13 +178,19 @@ void VideoMixer::setActiveHost() { activeSource_ = videoLocalSecondary_ ? videoLocalSecondary_.get() : videoLocal_.get(); - layoutUpdated_ += 1; + updateLayout(); } void VideoMixer::setActiveParticipant(Observable<std::shared_ptr<MediaFrame>>* ob) { activeSource_ = ob; + updateLayout(); +} + +void +VideoMixer::updateLayout() +{ layoutUpdated_ += 1; } @@ -197,7 +203,7 @@ VideoMixer::attached(Observable<std::shared_ptr<MediaFrame>>* ob) src->render_frame = std::make_shared<VideoFrame>(); src->source = ob; sources_.emplace_back(std::move(src)); - layoutUpdated_ += 1; + updateLayout(); } void @@ -213,7 +219,7 @@ VideoMixer::detached(Observable<std::shared_ptr<MediaFrame>>* ob) activeSource_ = videoLocalSecondary_ ? videoLocalSecondary_.get() : videoLocal_.get(); } sources_.remove(x); - layoutUpdated_ += 1; + updateLayout(); break; } } @@ -285,7 +291,7 @@ VideoMixer::process() // If orientation changed or if the first valid frame for source // is received -> trigger layout calculation and confInfo update if (x->rotation != input->getOrientation() or !x->w or !x->h) { - layoutUpdated_ += 1; + updateLayout(); needsUpdate = true; } @@ -313,7 +319,7 @@ VideoMixer::process() auto hasVideo = x->hasVideo; x->hasVideo = input && successfullyRendered; if (hasVideo != x->hasVideo) { - layoutUpdated_ += 1; + updateLayout(); needsUpdate = true; } } else if (needsUpdate) { @@ -471,7 +477,7 @@ VideoMixer::setParameters(int width, int height, AVPixelFormat format) libav_utils::fillWithBlack(previous_p->pointer()); start_sink(); - layoutUpdated_ += 1; + updateLayout(); startTime_ = av_gettime(); } diff --git a/src/media/video/video_mixer.h b/src/media/video/video_mixer.h index 00f0d4ae404d741cc56fceab25aae0784674fd9a..872674670b6dfddee03585b0c62a0b5832ba7238 100644 --- a/src/media/video/video_mixer.h +++ b/src/media/video/video_mixer.h @@ -89,6 +89,8 @@ public: std::shared_ptr<VideoFrameActiveWriter>& getVideoLocal() { return videoLocal_; } + void updateLayout(); + private: NON_COPYABLE(VideoMixer); struct VideoMixerSource;