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);
         }