The branch, master has been updated
       via  61835e1d8be9ace611e82b64f136a50f191a6e25 (commit)
       via  c4e537793b5939262cabb708ff798a732b8aba33 (commit)
       via  1849068c657c23e979e804cf90e63ae2f7381ec5 (commit)
       via  4879c9f4e2f2afc269d305d941cf70d18f3883a8 (commit)
       via  23d9412ff9598b8989072e53d5474a41d2f14042 (commit)
       via  983fed34f8172228c2e5490882531668d9d35105 (commit)
      from  8accbbdf9a99a1999e7e0c19f6cc91085b3b1905 (commit)


- Log -----------------------------------------------------------------
commit 61835e1d8be9ace611e82b64f136a50f191a6e25
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 22:03:28 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: keep cbdata object alive
    
    Depending on the threading backend the stdlib uses, creating a
    mutex/condvar can be quite expensive.
    So keep this object alive in the ctx, on which we synchronize via the
    uninit mutex anyway.

diff --git a/libavfilter/vsrc_gfxcapture_winrt.cpp 
b/libavfilter/vsrc_gfxcapture_winrt.cpp
index 62b1a94802..1738fa23af 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.cpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.cpp
@@ -149,6 +149,7 @@ struct GfxCaptureContextCpp {
     volatile int wgc_thread_init_res { INT_MAX };
     std::recursive_mutex wgc_thread_uninit_mutex;
     volatile int wgc_thread_res { 0 };
+    std::shared_ptr<void> wgc_thread_cb_data;
 
     HWND capture_hwnd { nullptr };
     HMONITOR capture_hmonitor { nullptr };
@@ -716,11 +717,17 @@ static int run_on_wgc_thread(AVFilterContext *avctx, F 
&&cb)
     struct CBData {
         std::mutex mutex;
         std::condition_variable cond;
-        bool done { false };
-        bool cancel { false };
-        int ret { AVERROR_BUG };
+        bool done;
+        bool cancel;
+        int ret;
     };
-    auto cbdata = std::make_shared<CBData>();
+    auto cbdata = ctx->wgc_thread_cb_data ?
+                  std::static_pointer_cast<CBData>(ctx->wgc_thread_cb_data) :
+                  std::make_shared<CBData>();
+    ctx->wgc_thread_cb_data = cbdata;
+
+    cbdata->done = cbdata->cancel = false;
+    cbdata->ret = AVERROR_BUG;
 
     boolean res = 0;
     CHECK_HR_RET(wgctx->dispatcher_queue->TryEnqueue(

commit c4e537793b5939262cabb708ff798a732b8aba33
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 21:31:56 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: fix leaking all callback handlers
    
    Fixes #20537

diff --git a/libavfilter/vsrc_gfxcapture_winrt.hpp 
b/libavfilter/vsrc_gfxcapture_winrt.hpp
index a02e768c8f..ba1979b1c1 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.hpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.hpp
@@ -159,9 +159,9 @@ private:
 template<class Iface, typename... Args, typename F>
 static Microsoft::WRL::ComPtr<Iface> create_cb_handler(F&& cb_func)
 {
-    return Microsoft::WRL::ComPtr<Iface>(
-        new FFTypedCBHandler<Iface, F, Args...>(std::forward<F>(cb_func))
-    );
+    Microsoft::WRL::ComPtr<Iface> res;
+    res.Attach(new FFTypedCBHandler<Iface, F, 
Args...>(std::forward<F>(cb_func)));
+    return res;
 }
 
 /******************************************

commit 1849068c657c23e979e804cf90e63ae2f7381ec5
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 20:23:37 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: use free threaded capture frame pool
    
    Apparently, using a normal frame pool in a multithreaded environment
    leads to strange resource leaks on shutdown, which vanish when using a
    free threaded pool.

diff --git a/libavfilter/vsrc_gfxcapture_winrt.cpp 
b/libavfilter/vsrc_gfxcapture_winrt.cpp
index 47c3b2db88..62b1a94802 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.cpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.cpp
@@ -327,7 +327,7 @@ static int wgc_setup_gfxcapture_session(AVFilterContext 
*avctx)
     std::unique_ptr<GfxCaptureContextWgc> &wgctx = ctx->wgc;
     int ret;
 
-    ComPtr<IDirect3D11CaptureFramePoolStatics> frame_pool_statics;
+    ComPtr<IDirect3D11CaptureFramePoolStatics2> frame_pool_statics;
     ComPtr<ID3D11Device> d3d11_device = ctx->device_hwctx->device;
     ComPtr<ID3D10Multithread> d3d10_multithread;
     ComPtr<IDXGIDevice> dxgi_device;
@@ -350,8 +350,8 @@ static int wgc_setup_gfxcapture_session(AVFilterContext 
*avctx)
     CHECK_HR_RET(d3d11_device.As(&dxgi_device));
     
CHECK_HR_RET(ctx->fn.CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.Get(), 
&wgctx->d3d_device));
 
-    
CHECK_HR_RET(get_activation_factory<IDirect3D11CaptureFramePoolStatics>(ctx, 
RuntimeClass_Windows_Graphics_Capture_Direct3D11CaptureFramePool, 
&frame_pool_statics));
-    CHECK_HR_RET(frame_pool_statics->Create(wgctx->d3d_device.Get(), fmt, 
CAPTURE_POOL_SIZE, wgctx->cap_size, &wgctx->frame_pool));
+    
CHECK_HR_RET(get_activation_factory<IDirect3D11CaptureFramePoolStatics2>(ctx, 
RuntimeClass_Windows_Graphics_Capture_Direct3D11CaptureFramePool, 
&frame_pool_statics));
+    
CHECK_HR_RET(frame_pool_statics->CreateFreeThreaded(wgctx->d3d_device.Get(), 
fmt, CAPTURE_POOL_SIZE, wgctx->cap_size, &wgctx->frame_pool));
     
CHECK_HR_RET(wgctx->frame_pool->CreateCaptureSession(wgctx->capture_item.Get(), 
&wgctx->capture_session));
 
     if (SUCCEEDED(wgctx->capture_session.As(&session2))) {

commit 4879c9f4e2f2afc269d305d941cf70d18f3883a8
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 19:13:29 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: stop capture session before initializing capture 
thread shutdown
    
    It might have things going on in the background that still need cleaned
    up, and this gives it a chance to enqueue them on the dispatch queue.

diff --git a/libavfilter/vsrc_gfxcapture_winrt.cpp 
b/libavfilter/vsrc_gfxcapture_winrt.cpp
index ade14d297f..47c3b2db88 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.cpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.cpp
@@ -229,7 +229,7 @@ static void wgc_stop_capture_session(AVFilterContext 
*avctx) noexcept
     if (wgctx->capture_session) {
         ComPtr<IClosable> closable;
         if (SUCCEEDED(wgctx->capture_session.As(&closable))) {
-            closable->Close();
+            CHECK_HR_LOG(closable->Close());
         } else {
             av_log(avctx, AV_LOG_ERROR, "Failed to get capture session 
IClosable interface\n");
         }
@@ -243,6 +243,11 @@ static void wgc_stop_capture_session(AVFilterContext 
*avctx) noexcept
             av_log(avctx, AV_LOG_ERROR, "Failed to get frame pool IClosable 
interface\n");
         }
     }
+
+    wgctx->capture_session.Reset();
+    wgctx->frame_pool.Reset();
+    wgctx->capture_item.Reset();
+    wgctx->d3d_device.Reset();
 }
 
 static int wgc_calculate_client_area(AVFilterContext *avctx)
@@ -557,6 +562,9 @@ static int wgc_thread_worker(AVFilterContext *avctx)
 
         if (!msg.hwnd && msg.message == WM_WGC_THREAD_SHUTDOWN) {
             av_log(avctx, AV_LOG_DEBUG, "Initializing WGC thread shutdown\n");
+
+            wgc_stop_capture_session(avctx);
+
             if 
(FAILED(wgctx->dispatcher_queue_controller->ShutdownQueueAsync(&async))) {
                 av_log(avctx, AV_LOG_ERROR, "Failed to shutdown dispatcher 
queue\n");
                 return AVERROR_EXTERNAL;

commit 23d9412ff9598b8989072e53d5474a41d2f14042
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 19:12:53 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: fix re-using ret variable from outside of lambda 
scope

diff --git a/libavfilter/vsrc_gfxcapture_winrt.cpp 
b/libavfilter/vsrc_gfxcapture_winrt.cpp
index b037dc89aa..ade14d297f 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.cpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.cpp
@@ -1394,9 +1394,9 @@ static int process_frame_if_exists(AVFilterLink *outlink)
         ComPtr<ID3D11Texture2D> frame_texture;
         TimeSpan frame_time = { 0 };
 
-        ret = wgc_try_get_next_frame(avctx, capture_frame);
-        if (ret < 0)
-            return ret;
+        int res = wgc_try_get_next_frame(avctx, capture_frame);
+        if (res < 0)
+            return res;
 
         CHECK_HR_RET(capture_frame->get_SystemRelativeTime(&frame_time));
 

commit 983fed34f8172228c2e5490882531668d9d35105
Author:     Timo Rothenpieler <[email protected]>
AuthorDate: Wed Sep 17 18:31:11 2025 +0200
Commit:     Timo Rothenpieler <[email protected]>
CommitDate: Thu Sep 18 01:04:59 2025 +0000

    avfilter/vsrc_gfxcapture: don't pass pointer to ComPtr
    
    While it does appear to work fine, with all the operator overloads, it
    at least has potential for surprises, so pass it by reference instead.

diff --git a/libavfilter/vsrc_gfxcapture_winrt.cpp 
b/libavfilter/vsrc_gfxcapture_winrt.cpp
index 9562863d7f..b037dc89aa 100644
--- a/libavfilter/vsrc_gfxcapture_winrt.cpp
+++ b/libavfilter/vsrc_gfxcapture_winrt.cpp
@@ -436,7 +436,7 @@ static int wgc_setup_gfxcapture_capture(AVFilterContext 
*avctx)
     return 0;
 }
 
-static int wgc_try_get_next_frame(AVFilterContext *avctx, 
ComPtr<IDirect3D11CaptureFrame> *capture_frame)
+static int wgc_try_get_next_frame(AVFilterContext *avctx, 
ComPtr<IDirect3D11CaptureFrame> &capture_frame)
 {
     GfxCaptureContext *cctx = CCTX(avctx->priv);
     GfxCaptureContextCpp *ctx = cctx->ctx;
@@ -447,11 +447,11 @@ static int wgc_try_get_next_frame(AVFilterContext *avctx, 
ComPtr<IDirect3D11Capt
     ComPtr<ID3D11Texture2D> frame_texture;
     SizeInt32 frame_size = { 0, 0 };
 
-    
CHECK_HR_RET(wgctx->frame_pool->TryGetNextFrame(capture_frame->ReleaseAndGetAddressOf()));
-    if (!capture_frame->Get())
+    CHECK_HR_RET(wgctx->frame_pool->TryGetNextFrame(&capture_frame));
+    if (!capture_frame)
         return AVERROR(EAGAIN);
 
-    CHECK_HR_RET(capture_frame->Get()->get_ContentSize(&frame_size));
+    CHECK_HR_RET(capture_frame->get_ContentSize(&frame_size));
     if (frame_size.Width != wgctx->cap_size.Width || frame_size.Height != 
wgctx->cap_size.Height) {
         av_log(avctx, AV_LOG_VERBOSE, "Capture size changed to %dx%d\n", 
frame_size.Width, frame_size.Height);
 
@@ -1394,7 +1394,7 @@ static int process_frame_if_exists(AVFilterLink *outlink)
         ComPtr<ID3D11Texture2D> frame_texture;
         TimeSpan frame_time = { 0 };
 
-        ret = wgc_try_get_next_frame(avctx, &capture_frame);
+        ret = wgc_try_get_next_frame(avctx, capture_frame);
         if (ret < 0)
             return ret;
 

-----------------------------------------------------------------------

Summary of changes:
 libavfilter/vsrc_gfxcapture_winrt.cpp | 45 +++++++++++++++++++++++------------
 libavfilter/vsrc_gfxcapture_winrt.hpp |  6 ++---
 2 files changed, 33 insertions(+), 18 deletions(-)


hooks/post-receive
-- 

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

Reply via email to