mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-05-18 09:17:31 +08:00
fix(*): address nullptr deref and resource leaks
Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
@@ -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.
|
- 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
|
## [6.4.0] - 2025-01-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -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) {
|
if (target_pix_fmt != AV_PIX_FMT_NONE && best_pix_fmt != target_pix_fmt) {
|
||||||
logger()->warn(
|
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),
|
av_get_pix_fmt_name(target_pix_fmt),
|
||||||
encoder->name,
|
encoder->name,
|
||||||
av_get_pix_fmt_name(best_pix_fmt)
|
av_get_pix_fmt_name(best_pix_fmt)
|
||||||
|
|||||||
@@ -184,6 +184,10 @@ int FilterRealcugan::filter(AVFrame* in_frame, AVFrame** out_frame) {
|
|||||||
|
|
||||||
// Convert ncnn::Mat to AVFrame
|
// Convert ncnn::Mat to AVFrame
|
||||||
*out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
*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
|
// Rescale PTS to encoder's time base
|
||||||
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ int FilterRealesrgan::filter(AVFrame* in_frame, AVFrame** out_frame) {
|
|||||||
|
|
||||||
// Convert ncnn::Mat to AVFrame
|
// Convert ncnn::Mat to AVFrame
|
||||||
*out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
*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
|
// Rescale PTS to encoder's time base
|
||||||
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ int InterpolatorRIFE::interpolate(
|
|||||||
|
|
||||||
// Convert ncnn::Mat to AVFrame
|
// Convert ncnn::Mat to AVFrame
|
||||||
*out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
*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
|
// Rescale PTS to encoder's time base
|
||||||
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ int init_libplacebo(
|
|||||||
AVFilterGraph* graph = avfilter_graph_alloc();
|
AVFilterGraph* graph = avfilter_graph_alloc();
|
||||||
if (!graph) {
|
if (!graph) {
|
||||||
logger()->error("Unable to create filter graph.");
|
logger()->error("Unable to create filter graph.");
|
||||||
|
av_buffer_unref(&vk_hw_device_ctx);
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ int init_libplacebo(
|
|||||||
if (!buffersrc) {
|
if (!buffersrc) {
|
||||||
logger()->error("Filter 'buffer' not found.");
|
logger()->error("Filter 'buffer' not found.");
|
||||||
avfilter_graph_free(&graph);
|
avfilter_graph_free(&graph);
|
||||||
|
av_buffer_unref(&vk_hw_device_ctx);
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
return AVERROR_FILTER_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +92,7 @@ int init_libplacebo(
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
logger()->error("Cannot create buffer source.");
|
logger()->error("Cannot create buffer source.");
|
||||||
avfilter_graph_free(&graph);
|
avfilter_graph_free(&graph);
|
||||||
|
av_buffer_unref(&vk_hw_device_ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +103,7 @@ int init_libplacebo(
|
|||||||
if (!libplacebo_filter) {
|
if (!libplacebo_filter) {
|
||||||
logger()->error("Filter 'libplacebo' not found.");
|
logger()->error("Filter 'libplacebo' not found.");
|
||||||
avfilter_graph_free(&graph);
|
avfilter_graph_free(&graph);
|
||||||
|
av_buffer_unref(&vk_hw_device_ctx);
|
||||||
return AVERROR_FILTER_NOT_FOUND;
|
return AVERROR_FILTER_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +127,7 @@ int init_libplacebo(
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
logger()->error("Cannot create libplacebo filter.");
|
logger()->error("Cannot create libplacebo filter.");
|
||||||
avfilter_graph_free(&graph);
|
avfilter_graph_free(&graph);
|
||||||
|
av_buffer_unref(&vk_hw_device_ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ void LoggerManager::hook_ffmpeg_logging() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LoggerManager::unhook_ffmpeg_logging() {
|
void LoggerManager::unhook_ffmpeg_logging() {
|
||||||
av_log_set_callback(nullptr);
|
av_log_set_callback(av_log_default_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace logger_manager
|
} // namespace logger_manager
|
||||||
|
|||||||
@@ -170,7 +170,9 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
// Calculate estimated time remaining
|
// Calculate estimated time remaining
|
||||||
int64_t frames_remaining = total_frames - processed_frames;
|
int64_t frames_remaining = total_frames - processed_frames;
|
||||||
double processing_rate = static_cast<double>(processed_frames) / time_elapsed;
|
double processing_rate = time_elapsed > 0
|
||||||
|
? static_cast<double>(processed_frames) / time_elapsed
|
||||||
|
: 0.0;
|
||||||
int time_remaining =
|
int time_remaining =
|
||||||
static_cast<int>(static_cast<double>(frames_remaining) / processing_rate);
|
static_cast<int>(static_cast<double>(frames_remaining) / processing_rate);
|
||||||
time_remaining = std::max<int>(time_remaining, 0);
|
time_remaining = std::max<int>(time_remaining, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user