[PATCH] mfplat: Add Lock()/Unlock() for d3d11 buffers.

Nikolay Sivov nsivov at codeweavers.com
Tue Mar 30 03:28:06 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/buffer.c       | 65 +++++++++++++++++++++++++++++++++++---
 dlls/mfplat/tests/mfplat.c | 12 +------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
index 77767c27d94..f428630ea01 100644
--- a/dlls/mfplat/buffer.c
+++ b/dlls/mfplat/buffer.c
@@ -914,16 +914,73 @@ static void dxgi_surface_buffer_unmap(struct buffer *buffer)
 static HRESULT WINAPI dxgi_surface_buffer_Lock(IMFMediaBuffer *iface, BYTE **data, DWORD *max_length,
         DWORD *current_length)
 {
-    FIXME("%p, %p, %p, %p.\n", iface, data, max_length, current_length);
+    struct buffer *buffer = impl_from_IMFMediaBuffer(iface);
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p, %p, %p.\n", iface, data, max_length, current_length);
+
+    if (!data)
+        return E_POINTER;
+
+    EnterCriticalSection(&buffer->cs);
+
+    if (!buffer->_2d.linear_buffer && buffer->_2d.locks)
+        hr = MF_E_INVALIDREQUEST;
+    else if (!buffer->_2d.linear_buffer)
+    {
+        if (!(buffer->_2d.linear_buffer = heap_alloc(ALIGN_SIZE(buffer->_2d.plane_size, MF_64_BYTE_ALIGNMENT))))
+            hr = E_OUTOFMEMORY;
+
+        if (SUCCEEDED(hr))
+        {
+            hr = dxgi_surface_buffer_map(buffer);
+            if (SUCCEEDED(hr))
+            {
+                MFCopyImage(buffer->_2d.linear_buffer, buffer->_2d.width, buffer->dxgi_surface.map_desc.pData,
+                        buffer->dxgi_surface.map_desc.RowPitch, buffer->_2d.width, buffer->_2d.height);
+            }
+        }
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        ++buffer->_2d.locks;
+        *data = buffer->_2d.linear_buffer;
+        if (max_length)
+            *max_length = buffer->_2d.plane_size;
+        if (current_length)
+            *current_length = buffer->_2d.plane_size;
+    }
+
+    LeaveCriticalSection(&buffer->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI dxgi_surface_buffer_Unlock(IMFMediaBuffer *iface)
 {
-    FIXME("%p.\n", iface);
+    struct buffer *buffer = impl_from_IMFMediaBuffer(iface);
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p.\n", iface);
+
+    EnterCriticalSection(&buffer->cs);
+
+    if (!buffer->_2d.linear_buffer)
+        hr = HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED);
+    else if (!--buffer->_2d.locks)
+    {
+        MFCopyImage(buffer->dxgi_surface.map_desc.pData, buffer->dxgi_surface.map_desc.RowPitch,
+                buffer->_2d.linear_buffer, buffer->_2d.width, buffer->_2d.width, buffer->_2d.height);
+        dxgi_surface_buffer_unmap(buffer);
+
+        heap_free(buffer->_2d.linear_buffer);
+        buffer->_2d.linear_buffer = NULL;
+    }
+
+    LeaveCriticalSection(&buffer->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI dxgi_surface_buffer_SetCurrentLength(IMFMediaBuffer *iface, DWORD current_length)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 1e84acd08fa..c21a57be27f 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -6479,31 +6479,24 @@ static void test_dxgi_surface_buffer(void)
     max_length = cur_length = 0;
     data = NULL;
     hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
-todo_wine {
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
     ok(max_length && max_length == cur_length, "Unexpected length %u.\n", max_length);
-}
     if (data) *(DWORD *)data = ~0u;
 
     color = get_d3d11_texture_color(texture, 0, 0);
     ok(!color, "Unexpected texture color %#x.\n", color);
 
     hr = IMFMediaBuffer_Unlock(buffer);
-todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
     color = get_d3d11_texture_color(texture, 0, 0);
-todo_wine
     ok(color == ~0u, "Unexpected texture color %#x.\n", color);
 
     hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
-todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-    if (SUCCEEDED(hr))
-        ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data);
+    ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data);
 
     hr = IMFMediaBuffer_Unlock(buffer);
-todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
     /* Lock2D()/Unlock2D() */
@@ -6526,7 +6519,6 @@ todo_wine
     ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
 
     hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
-todo_wine
     ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
 
     hr = IMF2DBuffer_Unlock2D(_2d_buffer);
@@ -6906,11 +6898,9 @@ todo_wine
     IMFDXGIBuffer_Release(dxgi_buffer);
 
     hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
-todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
     hr = IMFMediaBuffer_Unlock(buffer);
-todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
     IMFSample_Release(sample);
-- 
2.30.2




More information about the wine-devel mailing list