fix(encoder): fixed memory leak in the encoder

Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
k4yt3x 2024-10-21 00:00:00 +00:00
parent bc168d11ab
commit 640d9cd52b
No known key found for this signature in database
2 changed files with 40 additions and 15 deletions

View File

@ -1,9 +1,15 @@
.PHONY: build static debug windows test-realesrgan test-libplacebo leakcheck clean .PHONY: build static debug clean \
test-realesrgan test-libplacebo \
memcheck-realesrgan memcheck-libplacebo \
heaptrack-realesrgan heaptrack-libplacebo
BINDIR=build BINDIR=build
CC=clang CC=clang
CXX=clang++ CXX=clang++
TEST_VIDEO=data/standard-test.mp4
TEST_OUTPUT=data/output.mp4
build: build:
cmake -S . -B $(BINDIR) \ cmake -S . -B $(BINDIR) \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
@ -48,21 +54,24 @@ debian:
libspdlog-dev \ libspdlog-dev \
libopencv-dev libopencv-dev
cmake -B /tmp/build -S . -DUSE_SYSTEM_NCNN=OFF \ cmake -B /tmp/build -S . -DUSE_SYSTEM_NCNN=OFF \
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/install \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/install \
-DINSTALL_BIN_DESTINATION=. -DINSTALL_INCLUDE_DESTINATION=include \ -DINSTALL_BIN_DESTINATION=. -DINSTALL_INCLUDE_DESTINATION=include \
-DINSTALL_LIB_DESTINATION=. -DINSTALL_MODEL_DESTINATION=. -DINSTALL_LIB_DESTINATION=. -DINSTALL_MODEL_DESTINATION=.
cmake --build /tmp/build --config Release --target install --parallel cmake --build /tmp/build --config Release --target install --parallel
clean:
rm -rf $(BINDIR)
test-realesrgan: test-realesrgan:
LD_LIBRARY_PATH=$(BINDIR) $(BINDIR)/video2x -i data/standard-test.mp4 -o data/output.mp4 \ LD_LIBRARY_PATH=$(BINDIR) $(BINDIR)/video2x -i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f realesrgan -r 4 --model realesr-animevideov3 -f realesrgan -r 4 -m realesr-animevideov3
test-libplacebo: test-libplacebo:
LD_LIBRARY_PATH=$(BINDIR) $(BINDIR)/video2x -i data/standard-test.mp4 -o data/output.mp4 \ LD_LIBRARY_PATH=$(BINDIR) $(BINDIR)/video2x -i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f libplacebo -w 1920 -h 1080 -s anime4k-mode-a -f libplacebo -w 1920 -h 1080 -s anime4k-mode-a
leakcheck-realesrgan: memcheck-realesrgan:
LD_LIBRARY_PATH=$(BINDIR) valgrind \ LD_LIBRARY_PATH=$(BINDIR) valgrind \
--tool=memcheck \ --tool=memcheck \
--leak-check=full \ --leak-check=full \
@ -71,11 +80,11 @@ leakcheck-realesrgan:
--show-reachable=yes \ --show-reachable=yes \
--verbose --log-file="valgrind.log" \ --verbose --log-file="valgrind.log" \
$(BINDIR)/video2x \ $(BINDIR)/video2x \
-i data/standard-test.mp4 -o data/output.mp4 \ -i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f realesrgan -r 2 --model realesr-animevideov3 \ -f realesrgan -r 2 -m realesr-animevideov3 \
-p veryfast -b 1000000 -q 30 -p veryfast -b 1000000 -q 30
leakcheck-libplacebo: memcheck-libplacebo:
LD_LIBRARY_PATH=$(BINDIR) valgrind \ LD_LIBRARY_PATH=$(BINDIR) valgrind \
--tool=memcheck \ --tool=memcheck \
--leak-check=full \ --leak-check=full \
@ -84,9 +93,20 @@ leakcheck-libplacebo:
--show-reachable=yes \ --show-reachable=yes \
--verbose --log-file="valgrind.log" \ --verbose --log-file="valgrind.log" \
$(BINDIR)/video2x \ $(BINDIR)/video2x \
-i data/standard-test.mp4 -o data/output.mp4 \ -i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f libplacebo -w 1920 -h 1080 -s anime4k-mode-a \ -f libplacebo -w 1920 -h 1080 -s anime4k-mode-a \
-p veryfast -b 1000000 -q 30 -p veryfast -b 1000000 -q 30
clean: heaptrack-realesrgan:
rm -rf $(BINDIR) LD_LIBRARY_PATH=$(BINDIR) HEAPTRACK_ENABLE_DEBUGINFOD=1 heaptrack \
$(BINDIR)/video2x \
-i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f realesrgan -r 4 -m realesr-animevideov3 \
-p veryfast -b 1000000 -q 30
heaptrack-libplacebo:
LD_LIBRARY_PATH=$(BINDIR) HEAPTRACK_ENABLE_DEBUGINFOD=1 heaptrack \
$(BINDIR)/video2x \
-i $(TEST_VIDEO) -o $(TEST_OUTPUT) \
-f libplacebo -w 1920 -h 1080 -s anime4k-mode-a \
-p veryfast -b 1000000 -q 30

View File

@ -183,18 +183,18 @@ int encode_and_write_frame(
AVFormatContext *ofmt_ctx, AVFormatContext *ofmt_ctx,
int vstream_idx int vstream_idx
) { ) {
AVFrame *converted_frame = nullptr;
int ret; int ret;
// Convert the frame to the encoder's pixel format if needed // Convert the frame to the encoder's pixel format if needed
if (frame->format != enc_ctx->pix_fmt) { if (frame->format != enc_ctx->pix_fmt) {
AVFrame *converted_frame = convert_avframe_pix_fmt(frame, enc_ctx->pix_fmt); converted_frame = convert_avframe_pix_fmt(frame, enc_ctx->pix_fmt);
if (!converted_frame) { if (!converted_frame) {
spdlog::error("Error converting frame to encoder's pixel format"); spdlog::error("Error converting frame to encoder's pixel format");
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
} }
converted_frame->pts = frame->pts; converted_frame->pts = frame->pts;
frame = converted_frame;
} }
AVPacket *enc_pkt = av_packet_alloc(); AVPacket *enc_pkt = av_packet_alloc();
@ -203,7 +203,12 @@ int encode_and_write_frame(
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
if (converted_frame != nullptr) {
ret = avcodec_send_frame(enc_ctx, converted_frame);
av_frame_free(&converted_frame);
} else {
ret = avcodec_send_frame(enc_ctx, frame); ret = avcodec_send_frame(enc_ctx, frame);
}
if (ret < 0) { if (ret < 0) {
spdlog::error("Error sending frame to encoder"); spdlog::error("Error sending frame to encoder");
av_packet_free(&enc_pkt); av_packet_free(&enc_pkt);