From 0a00a3a3fac836a222c34622f086dabca17d16e1 Mon Sep 17 00:00:00 2001 From: Keukhan Date: Tue, 4 Mar 2025 18:30:22 +0900 Subject: [PATCH] Fixed the video corruption issue that occurs during input source transitions when using the NVIDIA encoder --- src/projects/transcoder/transcoder_stream.cpp | 39 +++++++++++++++++++ src/projects/transcoder/transcoder_stream.h | 1 + 2 files changed, 40 insertions(+) diff --git a/src/projects/transcoder/transcoder_stream.cpp b/src/projects/transcoder/transcoder_stream.cpp index 10523a961..b120eaecc 100644 --- a/src/projects/transcoder/transcoder_stream.cpp +++ b/src/projects/transcoder/transcoder_stream.cpp @@ -251,6 +251,7 @@ bool TranscoderStream::UpdateInternal(const std::shared_ptr &strea RemoveDecoders(); RemoveFilters(); + RemoveSpecificEncoders(); CreateDecoders(); } @@ -333,6 +334,44 @@ void TranscoderStream::RemoveFilters() } } +// In a scheduled stream, when the video input changes and the decoder is reinitialized, +// the NVIDIA encoder must also be reinitialized. If not, video corruption may occur. +void TranscoderStream::RemoveSpecificEncoders() +{ + std::unique_lock encoder_lock(_encoder_map_mutex); + auto encoders = _encoders; + encoder_lock.unlock(); + + for (auto &[id, object] : encoders) + { + auto filter = object.first; + auto encoder = object.second; + + if (encoder->GetRefTrack()->GetMediaType() != cmn::MediaType::Video) + { + continue; + } + if (encoder->GetRefTrack()->GetCodecModuleId() != cmn::MediaCodecModuleId::NVENC) + { + continue; + } + + _encoders.erase(id); + + if (filter != nullptr) + { + filter->Stop(); + filter.reset(); + } + + if (encoder != nullptr) + { + encoder->Stop(); + encoder.reset(); + } + } +} + void TranscoderStream::RemoveEncoders() { std::unique_lock encoder_lock(_encoder_map_mutex); diff --git a/src/projects/transcoder/transcoder_stream.h b/src/projects/transcoder/transcoder_stream.h index 4ffb2613a..d0fbb2c26 100644 --- a/src/projects/transcoder/transcoder_stream.h +++ b/src/projects/transcoder/transcoder_stream.h @@ -239,6 +239,7 @@ class TranscoderStream : public ov::EnableSharedFromThis, std::optional, std::shared_ptr>> GetEncoder(MediaTrackId encoder_id); void SetEncoder(MediaTrackId encoder_id, std::shared_ptr filter, std::shared_ptr encoder); void RemoveEncoders(); + void RemoveSpecificEncoders(); void ProcessPacket(const std::shared_ptr &packet);