When the pitch and width are the same, the original 2D buffer can be used. This saves a potentially expensive allocation and memory copy.
From: Brendan McGrath bmcgrath@codeweavers.com
When the pitch and width are the same, the original 2D buffer can be used. This saves a potentially expensive allocation and memory copy. --- dlls/mfplat/buffer.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index 6d59245b40c..0ad40e72cec 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -290,6 +290,9 @@ static HRESULT WINAPI memory_1d_2d_buffer_QueryInterface(IMFMediaBuffer *iface, return S_OK; }
+static HRESULT memory_2d_buffer_lock(struct buffer *buffer, BYTE **scanline0, LONG *pitch, + BYTE **buffer_start, DWORD *buffer_length); + static HRESULT WINAPI memory_1d_2d_buffer_Lock(IMFMediaBuffer *iface, BYTE **data, DWORD *max_length, DWORD *current_length) { struct buffer *buffer = impl_from_IMFMediaBuffer(iface); @@ -307,6 +310,14 @@ static HRESULT WINAPI memory_1d_2d_buffer_Lock(IMFMediaBuffer *iface, BYTE **dat
if (!buffer->_2d.linear_buffer && buffer->_2d.locks) hr = MF_E_INVALIDREQUEST; + else if (!buffer->_2d.linear_buffer && buffer->_2d.width == buffer->_2d.pitch) + { + BYTE *scanline; + LONG pitch; + + /* width and pitch are the same, so this avoids a potentially expensive copy */ + hr = memory_2d_buffer_lock(buffer, &scanline, &pitch, data, NULL); + } else if (!buffer->_2d.linear_buffer) { if (!(buffer->_2d.linear_buffer = malloc(buffer->_2d.plane_size))) @@ -323,10 +334,14 @@ static HRESULT WINAPI memory_1d_2d_buffer_Lock(IMFMediaBuffer *iface, BYTE **dat } }
- if (SUCCEEDED(hr)) + if (SUCCEEDED(hr) && buffer->_2d.linear_buffer) { ++buffer->_2d.locks; *data = buffer->_2d.linear_buffer; + } + + if (SUCCEEDED(hr)) + { if (max_length) *max_length = buffer->_2d.plane_size; if (current_length) @@ -341,12 +356,20 @@ static HRESULT WINAPI memory_1d_2d_buffer_Lock(IMFMediaBuffer *iface, BYTE **dat static HRESULT WINAPI memory_1d_2d_buffer_Unlock(IMFMediaBuffer *iface) { struct buffer *buffer = impl_from_IMFMediaBuffer(iface); + HRESULT hr = S_OK;
TRACE("%p.\n", iface);
EnterCriticalSection(&buffer->cs);
- if (buffer->_2d.linear_buffer && !--buffer->_2d.locks) + if (!buffer->_2d.linear_buffer && buffer->_2d.width == buffer->_2d.pitch) + { + if (buffer->_2d.locks) + --buffer->_2d.locks; + else + hr = HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED); + } + else if (buffer->_2d.linear_buffer && !--buffer->_2d.locks) { int pitch = buffer->_2d.pitch;
@@ -361,7 +384,7 @@ static HRESULT WINAPI memory_1d_2d_buffer_Unlock(IMFMediaBuffer *iface)
LeaveCriticalSection(&buffer->cs);
- return S_OK; + return hr; }
static const IMFMediaBufferVtbl memory_1d_2d_buffer_vtbl =
Looks like this change causes some tests to fail, so I will mark as draft whilst I investigate.