diff --git a/CHANGELOG.md b/CHANGELOG.md index 01b48b3..f482f3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Separate audio and subtitle stream copying options. +### Fixed + +- Null pointer dereference in Real-ESRGAN, Real-CUGAN, and RIFE processors when frame conversion fails. +- Vulkan hardware device context leak on error paths in libplacebo filter initialization. +- Incorrect spdlog format string using printf-style specifiers instead of fmt-style placeholders. +- Division by zero in CLI progress display within the first second of processing. +- `unhook_ffmpeg_logging` disabling all FFmpeg logging instead of restoring the default callback. + ## [6.4.0] - 2025-01-24 ### Added diff --git a/src/avutils.cpp b/src/avutils.cpp index 06daada..9c50790 100644 --- a/src/avutils.cpp +++ b/src/avutils.cpp @@ -126,7 +126,7 @@ AVPixelFormat get_encoder_default_pix_fmt(const AVCodec* encoder, AVPixelFormat if (target_pix_fmt != AV_PIX_FMT_NONE && best_pix_fmt != target_pix_fmt) { logger()->warn( - "Incompatible pixel format '%s' for encoder '%s'; auto-selecting format '%s'", + "Incompatible pixel format '{}' for encoder '{}'; auto-selecting format '{}'", av_get_pix_fmt_name(target_pix_fmt), encoder->name, av_get_pix_fmt_name(best_pix_fmt) diff --git a/src/filter_realcugan.cpp b/src/filter_realcugan.cpp index 57c16f4..6598e10 100644 --- a/src/filter_realcugan.cpp +++ b/src/filter_realcugan.cpp @@ -184,6 +184,10 @@ int FilterRealcugan::filter(AVFrame* in_frame, AVFrame** out_frame) { // Convert ncnn::Mat to AVFrame *out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_); + if (*out_frame == nullptr) { + logger()->error("Failed to convert ncnn::Mat to AVFrame"); + return AVERROR(ENOMEM); + } // Rescale PTS to encoder's time base (*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_); diff --git a/src/filter_realesrgan.cpp b/src/filter_realesrgan.cpp index 0e85c34..abfd100 100644 --- a/src/filter_realesrgan.cpp +++ b/src/filter_realesrgan.cpp @@ -124,6 +124,10 @@ int FilterRealesrgan::filter(AVFrame* in_frame, AVFrame** out_frame) { // Convert ncnn::Mat to AVFrame *out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_); + if (*out_frame == nullptr) { + logger()->error("Failed to convert ncnn::Mat to AVFrame"); + return AVERROR(ENOMEM); + } // Rescale PTS to encoder's time base (*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_); diff --git a/src/interpolator_rife.cpp b/src/interpolator_rife.cpp index 29ca7c2..918256e 100644 --- a/src/interpolator_rife.cpp +++ b/src/interpolator_rife.cpp @@ -128,6 +128,10 @@ int InterpolatorRIFE::interpolate( // Convert ncnn::Mat to AVFrame *out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_); + if (*out_frame == nullptr) { + logger()->error("Failed to convert ncnn::Mat to AVFrame"); + return AVERROR(ENOMEM); + } // Rescale PTS to encoder's time base (*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_); diff --git a/src/libplacebo.cpp b/src/libplacebo.cpp index f889350..e5e1c47 100644 --- a/src/libplacebo.cpp +++ b/src/libplacebo.cpp @@ -44,6 +44,7 @@ int init_libplacebo( AVFilterGraph* graph = avfilter_graph_alloc(); if (!graph) { logger()->error("Unable to create filter graph."); + av_buffer_unref(&vk_hw_device_ctx); return AVERROR(ENOMEM); } @@ -52,6 +53,7 @@ int init_libplacebo( if (!buffersrc) { logger()->error("Filter 'buffer' not found."); avfilter_graph_free(&graph); + av_buffer_unref(&vk_hw_device_ctx); return AVERROR_FILTER_NOT_FOUND; } @@ -90,6 +92,7 @@ int init_libplacebo( if (ret < 0) { logger()->error("Cannot create buffer source."); avfilter_graph_free(&graph); + av_buffer_unref(&vk_hw_device_ctx); return ret; } @@ -100,6 +103,7 @@ int init_libplacebo( if (!libplacebo_filter) { logger()->error("Filter 'libplacebo' not found."); avfilter_graph_free(&graph); + av_buffer_unref(&vk_hw_device_ctx); return AVERROR_FILTER_NOT_FOUND; } @@ -123,6 +127,7 @@ int init_libplacebo( if (ret < 0) { logger()->error("Cannot create libplacebo filter."); avfilter_graph_free(&graph); + av_buffer_unref(&vk_hw_device_ctx); return ret; } diff --git a/src/logger_manager.cpp b/src/logger_manager.cpp index 0f0e0dd..cc482f5 100644 --- a/src/logger_manager.cpp +++ b/src/logger_manager.cpp @@ -109,7 +109,7 @@ void LoggerManager::hook_ffmpeg_logging() { } void LoggerManager::unhook_ffmpeg_logging() { - av_log_set_callback(nullptr); + av_log_set_callback(av_log_default_callback); } } // namespace logger_manager diff --git a/tools/video2x/src/video2x.cpp b/tools/video2x/src/video2x.cpp index 6a669f9..c70f37c 100644 --- a/tools/video2x/src/video2x.cpp +++ b/tools/video2x/src/video2x.cpp @@ -170,7 +170,9 @@ int main(int argc, char** argv) { // Calculate estimated time remaining int64_t frames_remaining = total_frames - processed_frames; - double processing_rate = static_cast(processed_frames) / time_elapsed; + double processing_rate = time_elapsed > 0 + ? static_cast(processed_frames) / time_elapsed + : 0.0; int time_remaining = static_cast(static_cast(frames_remaining) / processing_rate); time_remaining = std::max(time_remaining, 0);