Commit 47f35c191c for ffmpeg
commit 47f35c191c77bc2a51b72bc6d8941c319551ed9a
Author: Jake Fineman <jake@wave.online>
Date: Tue Oct 27 17:48:23 2026 -0400
avfilter/dnn_backend_tf: free the last level task after inference
fill_model_input_tf() pops a LastLevelTaskItem from lltask_queue and
stores it in request->lltask, but nothing frees it once the inference
has completed. The next fill_model_input_tf() on the same request just
overwrites the pointer, so only the last lltask of each request is
released, by destroy_request_item() when the model is freed. Every
inference therefore leaks one lltask, apart from the last one of each
of the nireq requests, with both async=0 and async=1.
Free it in infer_completion_callback() before the request is pushed
back to request_queue, as the OpenVINO backend does in its completion
callback. Also free it on the failure paths of execute_model_tf() and
dnn_flush_tf(), where the popped lltask is dropped in the same way. No
inference thread is running on any of these paths. av_freep() resets
the pointer, so the av_freep() in destroy_request_item() is still safe.
Signed-off-by: Jake Fineman <jake@wave.online>
diff --git a/libavfilter/dnn/dnn_backend_tf.c b/libavfilter/dnn/dnn_backend_tf.c
index 6882e0bb31..f722e8bf8d 100644
--- a/libavfilter/dnn/dnn_backend_tf.c
+++ b/libavfilter/dnn/dnn_backend_tf.c
@@ -748,6 +748,7 @@ static void infer_completion_callback(void *args) {
err:
tf_free_request(infer_request);
av_freep(&outputs);
+ av_freep(&request->lltask);
if (ff_safe_queue_push_back(tf_model->request_queue, request) < 0) {
destroy_request_item(&request);
@@ -794,6 +795,7 @@ static int execute_model_tf(TFRequestItem *request, Queue *lltask_queue)
}
err:
tf_free_request(request->infer_request);
+ av_freep(&request->lltask);
if (ff_safe_queue_push_back(tf_model->request_queue, request) < 0) {
destroy_request_item(&request);
}
@@ -874,6 +876,7 @@ static int dnn_flush_tf(const DNNModel *model)
ret = fill_model_input_tf(tf_model, request);
if (ret != 0) {
av_log(ctx, AV_LOG_ERROR, "Failed to fill model input.\n");
+ av_freep(&request->lltask);
if (ff_safe_queue_push_back(tf_model->request_queue, request) < 0) {
destroy_request_item(&request);
}