Initialize async resources in dnn_load_model_th and ensure proper cleanup and 
thread joining in dnn_free_model_th.

Signed-off-by: Raja Rathour <[email protected]>
---
 libavfilter/dnn/dnn_backend_torch.cpp | 85 ++++++++++++++++++++++-----
 1 file changed, 69 insertions(+), 16 deletions(-)

diff --git a/libavfilter/dnn/dnn_backend_torch.cpp 
b/libavfilter/dnn/dnn_backend_torch.cpp
index b5ff5b44d1..f384999152 100644
--- a/libavfilter/dnn/dnn_backend_torch.cpp
+++ b/libavfilter/dnn/dnn_backend_torch.cpp
@@ -127,27 +127,70 @@ static void dnn_free_model_th(DNNModel **model)
     if (!model || !*model)
         return;
 
-    th_model = (THModel *) (*model);
-    while (ff_safe_queue_size(th_model->request_queue) != 0) {
-        THRequestItem *item = (THRequestItem 
*)ff_safe_queue_pop_front(th_model->request_queue);
-        destroy_request_item(&item);
+    th_model = (THModel *)(*model);
+
+    /* 1. Stop and join the worker thread if it exists */
+    if (th_model->worker_thread) {
+        {
+            std::lock_guard<std::mutex> lock(*th_model->mutex);
+            th_model->worker_stop = true;
+        }
+        th_model->cond->notify_all();
+        th_model->worker_thread->join();
+        delete th_model->worker_thread;
+        th_model->worker_thread = NULL;
     }
-    ff_safe_queue_destroy(th_model->request_queue);
 
-    while (ff_queue_size(th_model->lltask_queue) != 0) {
-        LastLevelTaskItem *item = (LastLevelTaskItem 
*)ff_queue_pop_front(th_model->lltask_queue);
-        av_freep(&item);
+    /* 2. Safely delete C++ synchronization objects */
+    if (th_model->mutex) {
+        delete th_model->mutex;
+        th_model->mutex = NULL;
+    }
+    if (th_model->cond) {
+        delete th_model->cond;
+        th_model->cond = NULL;
     }
-    ff_queue_destroy(th_model->lltask_queue);
 
-    while (ff_queue_size(th_model->task_queue) != 0) {
-        TaskItem *item = (TaskItem *)ff_queue_pop_front(th_model->task_queue);
-        av_frame_free(&item->in_frame);
-        av_frame_free(&item->out_frame);
-        av_freep(&item);
+    /* 3. Clean up the pending queue */
+    if (th_model->pending_queue) {
+        while (ff_safe_queue_size(th_model->pending_queue) > 0) {
+            THRequestItem *item = (THRequestItem 
*)ff_safe_queue_pop_front(th_model->pending_queue);
+            destroy_request_item(&item);
+        }
+        ff_safe_queue_destroy(th_model->pending_queue);
+    }
+
+    /* 4. Clean up standard backend queues */
+    if (th_model->request_queue) {
+        while (ff_safe_queue_size(th_model->request_queue) != 0) {
+            THRequestItem *item = (THRequestItem 
*)ff_safe_queue_pop_front(th_model->request_queue);
+            destroy_request_item(&item);
+        }
+        ff_safe_queue_destroy(th_model->request_queue);
     }
-    ff_queue_destroy(th_model->task_queue);
-    delete th_model->jit_model;
+
+    if (th_model->lltask_queue) {
+        while (ff_queue_size(th_model->lltask_queue) != 0) {
+            LastLevelTaskItem *item = (LastLevelTaskItem 
*)ff_queue_pop_front(th_model->lltask_queue);
+            av_freep(&item);
+        }
+        ff_queue_destroy(th_model->lltask_queue);
+    }
+
+    if (th_model->task_queue) {
+        while (ff_queue_size(th_model->task_queue) != 0) {
+            TaskItem *item = (TaskItem 
*)ff_queue_pop_front(th_model->task_queue);
+            av_frame_free(&item->in_frame);
+            av_frame_free(&item->out_frame);
+            av_freep(&item);
+        }
+        ff_queue_destroy(th_model->task_queue);
+    }
+
+    /* 5. Final model cleanup */
+    if (th_model->jit_model)
+        delete th_model->jit_model;
+    
     av_freep(&th_model);
     *model = NULL;
 }
@@ -513,6 +556,16 @@ static DNNModel *dnn_load_model_th(DnnContext *ctx, 
DNNFunctionType func_type, A
         goto fail;
     }
 
+    th_model->pending_queue = ff_safe_queue_create();
+    if (!th_model->pending_queue) {
+        goto fail;
+    }
+
+    th_model->mutex = new std::mutex();
+    th_model->cond = new std::condition_variable();
+    th_model->worker_stop = false;
+    th_model->worker_thread = new std::thread(th_worker_thread, th_model);
+
     model->get_input = &get_input_th;
     model->get_output = &get_output_th;
     model->filter_ctx = filter_ctx;
-- 
2.48.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to