Skip to content

Commit

Permalink
Fixed the video corruption issue that occurs during input source tran…
Browse files Browse the repository at this point in the history
…sitions when using the NVIDIA encoder
  • Loading branch information
Keukhan committed Mar 4, 2025
1 parent fce93fb commit 0a00a3a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/projects/transcoder/transcoder_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ bool TranscoderStream::UpdateInternal(const std::shared_ptr<info::Stream> &strea

RemoveDecoders();
RemoveFilters();
RemoveSpecificEncoders();

CreateDecoders();
}
Expand Down Expand Up @@ -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<std::shared_mutex> 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<std::shared_mutex> encoder_lock(_encoder_map_mutex);
Expand Down
1 change: 1 addition & 0 deletions src/projects/transcoder/transcoder_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class TranscoderStream : public ov::EnableSharedFromThis<TranscoderStream>,
std::optional<std::pair<std::shared_ptr<TranscodeFilter>, std::shared_ptr<TranscodeEncoder>>> GetEncoder(MediaTrackId encoder_id);
void SetEncoder(MediaTrackId encoder_id, std::shared_ptr<TranscodeFilter> filter, std::shared_ptr<TranscodeEncoder> encoder);
void RemoveEncoders();
void RemoveSpecificEncoders();

void ProcessPacket(const std::shared_ptr<MediaPacket> &packet);

Expand Down

0 comments on commit 0a00a3a

Please sign in to comment.