From 0176c99ce717b0245770efde8b1a9576ac4aff89 Mon Sep 17 00:00:00 2001 From: agsantos <aline.gondimsantos@savoirfairelinux.com> Date: Fri, 16 Apr 2021 18:31:11 -0400 Subject: [PATCH] conference: keep frame sizes if frame is empty This is needed to have a proper overlay for conference participant with muted video. GitLab: #484 Change-Id: Ie037728f4651d937741b24a656b7c49cf7670856 --- src/media/video/video_mixer.cpp | 67 ++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/media/video/video_mixer.cpp b/src/media/video/video_mixer.cpp index 3bcf40ad8f..f7f6950f8c 100644 --- a/src/media/video/video_mixer.cpp +++ b/src/media/video/video_mixer.cpp @@ -58,7 +58,8 @@ struct VideoMixer::VideoMixerSource render_frame = newFrame; } - std::shared_ptr<VideoFrame> getRenderFrame() { + std::shared_ptr<VideoFrame> getRenderFrame() + { std::lock_guard<std::mutex> lock(mutex_); return render_frame; } @@ -68,7 +69,7 @@ struct VideoMixer::VideoMixerSource int y {}; int w {}; int h {}; - bool hasVideo {false}; + bool hasVideo {true}; private: std::mutex mutex_; @@ -140,7 +141,8 @@ VideoMixer::switchInput(const std::string& input) } void -VideoMixer::switchSecondaryInput(const std::string& input) { +VideoMixer::switchSecondaryInput(const std::string& input) +{ if (auto local = videoLocalSecondary_) { // Detach videoInput from mixer local->detach(this); @@ -216,7 +218,8 @@ VideoMixer::detached(Observable<std::shared_ptr<MediaFrame>>* ob) // Handle the case where the current shown source leave the conference if (activeSource_ == ob) { currentLayout_ = Layout::GRID; - activeSource_ = videoLocalSecondary_ ? videoLocalSecondary_.get() : videoLocal_.get(); + activeSource_ = videoLocalSecondary_ ? videoLocalSecondary_.get() + : videoLocal_.get(); } sources_.remove(x); updateLayout(); @@ -236,7 +239,9 @@ VideoMixer::update(Observable<std::shared_ptr<MediaFrame>>* ob, #ifdef RING_ACCEL std::shared_ptr<VideoFrame> frame; try { - frame = HardwareAccel::transferToMainMemory(*std::static_pointer_cast<VideoFrame>(frame_p), AV_PIX_FMT_NV12); + frame = HardwareAccel::transferToMainMemory(*std::static_pointer_cast<VideoFrame>( + frame_p), + AV_PIX_FMT_NV12); x->atomic_copy(*std::static_pointer_cast<VideoFrame>(frame)); } catch (const std::runtime_error& e) { JAMI_ERR("Accel failure: %s", e.what()); @@ -284,16 +289,7 @@ VideoMixer::process() // make rendered frame temporarily unavailable for update() // to avoid concurrent access. std::shared_ptr<VideoFrame> input = x->getRenderFrame(); - - if (!input->height() or !input->width()) - continue; - - // 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) { - updateLayout(); - needsUpdate = true; - } + std::shared_ptr<VideoFrame> fooInput = std::make_shared<VideoFrame>(); auto wantedIndex = i; if (currentLayout_ == Layout::ONE_BIG) { @@ -308,16 +304,35 @@ VideoMixer::process() } } + auto hasVideo = x->hasVideo; + bool blackFrame = false; + + if (!input->height() or !input->width()) { + successfullyRendered = true; + fooInput->reserve(format_, width_, height_); + blackFrame = true; + } else { + fooInput.swap(input); + } + + // If orientation changed or if the first valid frame for source + // is received -> trigger layout calculation and confInfo update + if (x->rotation != fooInput->getOrientation() or !x->w or !x->h) { + updateLayout(); + needsUpdate = true; + } + if (needsUpdate) - calc_position(x, input, wantedIndex); + calc_position(x, fooInput, wantedIndex); - if (input) - successfullyRendered |= render_frame(output, input, x); - else - JAMI_WARN("Nothing to render for %p", x->source); + if (!blackFrame) { + if (fooInput) + successfullyRendered |= render_frame(output, fooInput, x); + else + JAMI_WARN("Nothing to render for %p", x->source); + } - auto hasVideo = x->hasVideo; - x->hasVideo = input && successfullyRendered; + x->hasVideo = !blackFrame && successfullyRendered; if (hasVideo != x->hasVideo) { updateLayout(); needsUpdate = true; @@ -348,10 +363,10 @@ VideoMixer::process() } output.pointer()->pts = av_rescale_q_rnd(av_gettime() - startTime_, - {1, AV_TIME_BASE}, - {1, MIXER_FRAMERATE}, - static_cast<AVRounding>(AV_ROUND_NEAR_INF - | AV_ROUND_PASS_MINMAX)); + {1, AV_TIME_BASE}, + {1, MIXER_FRAMERATE}, + static_cast<AVRounding>(AV_ROUND_NEAR_INF + | AV_ROUND_PASS_MINMAX)); lastTimestamp_ = output.pointer()->pts; publishFrame(); } -- GitLab