From 039677890f40729804d10d1911521fc5b434f23f Mon Sep 17 00:00:00 2001 From: Joaquin Anton Guirao Date: Tue, 27 Oct 2026 16:04:02 +0100 Subject: [PATCH 1/3] Make the video decoders' FFmpeg helpers safe from several threads av_error_string formatted into a function-static buffer, and every decoder constructor set FFmpeg's process-wide log level. Use a local buffer, and set the log level only once. Signed-off-by: Joaquin Anton Guirao --- dali/operators/video/frames_decoder_base.cc | 17 ++++++++++++++--- dali/operators/video/video_utils.cc | 6 +++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/dali/operators/video/frames_decoder_base.cc b/dali/operators/video/frames_decoder_base.cc index b7c27f3989a..a2c5bebe4e4 100644 --- a/dali/operators/video/frames_decoder_base.cc +++ b/dali/operators/video/frames_decoder_base.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ #include "dali/operators/video/frames_decoder_base.h" #include #include +#include #include "dali/core/error_handling.h" #include "dali/core/small_vector.h" #include "dali/operators/video/video_utils.h" @@ -212,8 +213,18 @@ bool FramesDecoderBase::CheckDimensions() { return true; } +namespace { + +// FFmpeg's log level is process-wide; set it once, not from every decoder (several threads) +void SetAvLogLevel() { + static std::once_flag once; + std::call_once(once, [] { av_log_set_level(AV_LOG_ERROR); }); +} + +} // namespace + FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType image_type) { - av_log_set_level(AV_LOG_ERROR); + SetAvLogLevel(); filename_ = filename; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type)); @@ -234,7 +245,7 @@ FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType } FramesDecoderBase::FramesDecoderBase(const char *memory_file, size_t memory_file_size, std::string_view source_info, DALIImageType image_type) { - av_log_set_level(AV_LOG_ERROR); + SetAvLogLevel(); filename_ = source_info; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type)); diff --git a/dali/operators/video/video_utils.cc b/dali/operators/video/video_utils.cc index d0c4b5392b0..d0fb16cbb48 100644 --- a/dali/operators/video/video_utils.cc +++ b/dali/operators/video/video_utils.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ #include #include #include +#include namespace dali { @@ -148,8 +149,7 @@ std::vector GetVideoFiles(const std::string& file_root, } std::string av_error_string(int ret) { - static char msg[AV_ERROR_MAX_STRING_SIZE]; - memset(msg, 0, sizeof(msg)); + char msg[AV_ERROR_MAX_STRING_SIZE] = {}; // not static: decoders run on several threads return std::string(av_make_error_string(msg, AV_ERROR_MAX_STRING_SIZE, ret)); } From 0d7be216c191e97d2da795a44c437b2f50cd77eb Mon Sep 17 00:00:00 2001 From: Joaquin Anton Guirao Date: Tue, 27 Oct 2026 16:58:51 +0100 Subject: [PATCH 2/3] Set FFmpeg's log level from every video decoder again, as before av_log_set_level only stores the level, so calling it every time costs less than call_once, and it keeps the level adjustable while running. Signed-off-by: Joaquin Anton Guirao --- dali/operators/video/frames_decoder_base.cc | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/dali/operators/video/frames_decoder_base.cc b/dali/operators/video/frames_decoder_base.cc index a2c5bebe4e4..b7c27f3989a 100644 --- a/dali/operators/video/frames_decoder_base.cc +++ b/dali/operators/video/frames_decoder_base.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ #include "dali/operators/video/frames_decoder_base.h" #include #include -#include #include "dali/core/error_handling.h" #include "dali/core/small_vector.h" #include "dali/operators/video/video_utils.h" @@ -213,18 +212,8 @@ bool FramesDecoderBase::CheckDimensions() { return true; } -namespace { - -// FFmpeg's log level is process-wide; set it once, not from every decoder (several threads) -void SetAvLogLevel() { - static std::once_flag once; - std::call_once(once, [] { av_log_set_level(AV_LOG_ERROR); }); -} - -} // namespace - FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType image_type) { - SetAvLogLevel(); + av_log_set_level(AV_LOG_ERROR); filename_ = filename; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type)); @@ -245,7 +234,7 @@ FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType } FramesDecoderBase::FramesDecoderBase(const char *memory_file, size_t memory_file_size, std::string_view source_info, DALIImageType image_type) { - SetAvLogLevel(); + av_log_set_level(AV_LOG_ERROR); filename_ = source_info; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type)); From 5b4cb1fefb6f1731257ec3b5e5e6c3b606b1f26f Mon Sep 17 00:00:00 2001 From: Joaquin Anton Guirao Date: Tue, 27 Oct 2026 17:03:01 +0100 Subject: [PATCH 3/3] Set FFmpeg's log level once, when the library is loaded av_log_set_level stores the level in a plain global, so calling it from every decoder made decoders created on several threads write it concurrently. It is now set by a static initializer, before any decoder exists, and a level set later is kept. Signed-off-by: Joaquin Anton Guirao --- dali/operators/video/frames_decoder_base.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dali/operators/video/frames_decoder_base.cc b/dali/operators/video/frames_decoder_base.cc index b7c27f3989a..0dcde3fe7f1 100644 --- a/dali/operators/video/frames_decoder_base.cc +++ b/dali/operators/video/frames_decoder_base.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,6 +21,18 @@ namespace dali { +namespace { + +// FFmpeg's log level is a plain global (av_log_set_level only stores it). It is set once, while the +// library is loaded and before any decoder exists, rather than by every decoder: decoders are +// created on several threads +const bool av_log_level_set = [] { + av_log_set_level(AV_LOG_ERROR); + return true; +}(); + +} // namespace + int MemoryVideoFile::Read(unsigned char *buffer, int buffer_size) { int left_in_file = size_ - position_; if (left_in_file <= 0) { @@ -213,7 +225,6 @@ bool FramesDecoderBase::CheckDimensions() { } FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType image_type) { - av_log_set_level(AV_LOG_ERROR); filename_ = filename; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type)); @@ -234,7 +245,6 @@ FramesDecoderBase::FramesDecoderBase(const std::string &filename, DALIImageType } FramesDecoderBase::FramesDecoderBase(const char *memory_file, size_t memory_file_size, std::string_view source_info, DALIImageType image_type) { - av_log_set_level(AV_LOG_ERROR); filename_ = source_info; DALI_ENFORCE(image_type == DALI_YCbCr || image_type == DALI_RGB, make_string("Invalid image type: ", image_type));