From c95873bbd56f8bb87506c26e936394a15d05bd8c Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 2 Aug 2024 05:21:34 +0900 Subject: [PATCH] d3d12screencapturesrc: Always release acquired frame AcquireNextFrame() call should be paired with ReleaseFrame(). Part-of: --- .../sys/d3d12/gstd3d12dxgicapture.cpp | 142 ++++++++++-------- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12dxgicapture.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12dxgicapture.cpp index b0e881c671..f5199c431d 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12dxgicapture.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12dxgicapture.cpp @@ -671,6 +671,78 @@ public: return GST_FLOW_OK; } + GstFlowReturn + ExecuteInternal (IDXGIResource * resource) + { + ComPtr cur_texture; + HRESULT hr; + resource->QueryInterface (IID_PPV_ARGS (&cur_texture)); + if (!cur_texture) { + GST_ERROR ("Couldn't get texture interface"); + return GST_FLOW_ERROR; + } + + metadata_buffer_.resize (frame_info_.TotalMetadataBufferSize); + if (frame_info_.TotalMetadataBufferSize > 0) { + UINT buf_size = frame_info_.TotalMetadataBufferSize; + hr = dupl_->GetFrameMoveRects (buf_size, + (DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), &buf_size); + if (FAILED (hr)) { + GST_ERROR ("Couldn't get move rect, hr: 0x%x", (guint) hr); + return flow_return_from_hr (device_.Get (), + hr, FrameInfoExpectedErrors); + } + + auto move_count = buf_size / sizeof (DXGI_OUTDUPL_MOVE_RECT); + if (move_count > 0) { + auto ret = copyMoveRects (cur_texture.Get (), + (DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), move_count); + if (ret != GST_FLOW_OK) + return ret; + } + + auto dirty_rects = metadata_buffer_.data () + buf_size; + buf_size = frame_info_.TotalMetadataBufferSize - buf_size; + + hr = dupl_->GetFrameDirtyRects (buf_size, (RECT *) dirty_rects, + &buf_size); + if (FAILED (hr)) { + GST_ERROR ("Couldn't get dirty rect, hr: 0x%x", (guint) hr); + return flow_return_from_hr (device_.Get (), + hr, FrameInfoExpectedErrors); + } + + auto dirty_count = buf_size / sizeof (RECT); + if (dirty_count > 0) { + auto ret = copyDirtyRects (cur_texture.Get (), (RECT *) dirty_rects, + dirty_count); + if (ret != GST_FLOW_OK) + return ret; + } + } + + if (frame_info_.LastMouseUpdateTime.QuadPart != 0) { + ptr_info_.position_info = frame_info_.PointerPosition; + ptr_info_.LastTimeStamp = frame_info_.LastMouseUpdateTime; + + if (frame_info_.PointerShapeBufferSize > 0) { + UINT buf_size; + ptr_info_.shape_buffer.resize (frame_info_.PointerShapeBufferSize); + hr = dupl_->GetFramePointerShape (frame_info_.PointerShapeBufferSize, + (void *) ptr_info_.shape_buffer.data (), &buf_size, + &ptr_info_.shape_info); + if (FAILED (hr)) { + return flow_return_from_hr(device_.Get (), + hr, FrameInfoExpectedErrors); + } + + ptr_info_.BuildTexture (); + } + } + + return GST_FLOW_OK; + } + GstFlowReturn Execute (ID3D11Texture2D * dest, D3D11_BOX * src_box, UINT64 fence_val) { @@ -679,74 +751,16 @@ public: if (hr != DXGI_ERROR_WAIT_TIMEOUT) { if (FAILED (hr)) { GST_WARNING ("AcquireNextFrame failed with 0x%x", (guint) hr); + dupl_->ReleaseFrame (); return flow_return_from_hr (device_.Get (), hr, FrameInfoExpectedErrors); } - ComPtr cur_texture; - resource.As (&cur_texture); - if (!cur_texture) { - GST_ERROR ("Couldn't get texture interface"); - return GST_FLOW_ERROR; - } - - metadata_buffer_.resize (frame_info_.TotalMetadataBufferSize); - if (frame_info_.TotalMetadataBufferSize > 0) { - UINT buf_size = frame_info_.TotalMetadataBufferSize; - hr = dupl_->GetFrameMoveRects (buf_size, - (DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), &buf_size); - if (FAILED (hr)) { - GST_ERROR ("Couldn't get move rect, hr: 0x%x", (guint) hr); - return flow_return_from_hr (device_.Get (), - hr, FrameInfoExpectedErrors); - } - - auto move_count = buf_size / sizeof (DXGI_OUTDUPL_MOVE_RECT); - if (move_count > 0) { - auto ret = copyMoveRects (cur_texture.Get (), - (DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), move_count); - if (ret != GST_FLOW_OK) - return ret; - } - - auto dirty_rects = metadata_buffer_.data () + buf_size; - buf_size = frame_info_.TotalMetadataBufferSize - buf_size; - - hr = dupl_->GetFrameDirtyRects (buf_size, (RECT *) dirty_rects, - &buf_size); - if (FAILED (hr)) { - GST_ERROR ("Couldn't get dirty rect, hr: 0x%x", (guint) hr); - return flow_return_from_hr (device_.Get (), - hr, FrameInfoExpectedErrors); - } - - auto dirty_count = buf_size / sizeof (RECT); - if (dirty_count > 0) { - auto ret = copyDirtyRects (cur_texture.Get (), (RECT *) dirty_rects, - dirty_count); - if (ret != GST_FLOW_OK) - return ret; - } - } - - if (frame_info_.LastMouseUpdateTime.QuadPart != 0) { - ptr_info_.position_info = frame_info_.PointerPosition; - ptr_info_.LastTimeStamp = frame_info_.LastMouseUpdateTime; - - if (frame_info_.PointerShapeBufferSize > 0) { - UINT buf_size; - ptr_info_.shape_buffer.resize (frame_info_.PointerShapeBufferSize); - hr = dupl_->GetFramePointerShape (frame_info_.PointerShapeBufferSize, - (void *) ptr_info_.shape_buffer.data (), &buf_size, - &ptr_info_.shape_info); - if (FAILED (hr)) { - return flow_return_from_hr(device_.Get (), - hr, FrameInfoExpectedErrors); - } - - ptr_info_.BuildTexture (); - } - } + auto ret = ExecuteInternal(resource.Get ()); + dupl_->ReleaseFrame (); + if (ret != GST_FLOW_OK) + return ret; + } else { dupl_->ReleaseFrame (); }