mfplat: Implement CopyToBuffer().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
68da7ea97d
commit
b50c7c7999
|
@ -771,22 +771,29 @@ static HRESULT WINAPI sample_RemoveAllBuffers(IMFSample *iface)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD sample_get_total_length(struct sample *sample)
|
||||
{
|
||||
DWORD total_length = 0, length;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sample->buffer_count; ++i)
|
||||
{
|
||||
length = 0;
|
||||
if (SUCCEEDED(IMFMediaBuffer_GetCurrentLength(sample->buffers[i], &length)))
|
||||
total_length += length;
|
||||
}
|
||||
|
||||
return total_length;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *total_length)
|
||||
{
|
||||
struct sample *sample = impl_from_IMFSample(iface);
|
||||
DWORD length;
|
||||
size_t i;
|
||||
|
||||
TRACE("%p, %p.\n", iface, total_length);
|
||||
|
||||
*total_length = 0;
|
||||
|
||||
EnterCriticalSection(&sample->attributes.cs);
|
||||
for (i = 0; i < sample->buffer_count; ++i)
|
||||
{
|
||||
if (SUCCEEDED(IMFMediaBuffer_GetCurrentLength(sample->buffers[i], &length)))
|
||||
*total_length += length;
|
||||
}
|
||||
*total_length = sample_get_total_length(sample);
|
||||
LeaveCriticalSection(&sample->attributes.cs);
|
||||
|
||||
return S_OK;
|
||||
|
@ -794,9 +801,61 @@ static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *total_lengt
|
|||
|
||||
static HRESULT WINAPI sample_CopyToBuffer(IMFSample *iface, IMFMediaBuffer *buffer)
|
||||
{
|
||||
FIXME("%p, %p.\n", iface, buffer);
|
||||
struct sample *sample = impl_from_IMFSample(iface);
|
||||
DWORD total_length, dst_length, dst_current_length, src_max_length, current_length;
|
||||
BYTE *src_ptr, *dst_ptr;
|
||||
BOOL locked;
|
||||
HRESULT hr;
|
||||
size_t i;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("%p, %p.\n", iface, buffer);
|
||||
|
||||
EnterCriticalSection(&sample->attributes.cs);
|
||||
|
||||
total_length = sample_get_total_length(sample);
|
||||
dst_current_length = 0;
|
||||
|
||||
dst_ptr = NULL;
|
||||
dst_length = current_length = 0;
|
||||
locked = SUCCEEDED(hr = IMFMediaBuffer_Lock(buffer, &dst_ptr, &dst_length, ¤t_length));
|
||||
if (locked)
|
||||
{
|
||||
if (dst_length < total_length)
|
||||
hr = MF_E_BUFFERTOOSMALL;
|
||||
else if (dst_ptr)
|
||||
{
|
||||
for (i = 0; i < sample->buffer_count && SUCCEEDED(hr); ++i)
|
||||
{
|
||||
src_ptr = NULL;
|
||||
src_max_length = current_length = 0;
|
||||
if (SUCCEEDED(hr = IMFMediaBuffer_Lock(sample->buffers[i], &src_ptr, &src_max_length, ¤t_length)))
|
||||
{
|
||||
if (src_ptr)
|
||||
{
|
||||
if (current_length > dst_length)
|
||||
hr = MF_E_BUFFERTOOSMALL;
|
||||
else if (current_length)
|
||||
{
|
||||
memcpy(dst_ptr, src_ptr, current_length);
|
||||
dst_length -= current_length;
|
||||
dst_current_length += current_length;
|
||||
dst_ptr += current_length;
|
||||
}
|
||||
}
|
||||
IMFMediaBuffer_Unlock(sample->buffers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMFMediaBuffer_SetCurrentLength(buffer, dst_current_length);
|
||||
|
||||
if (locked)
|
||||
IMFMediaBuffer_Unlock(buffer);
|
||||
|
||||
LeaveCriticalSection(&sample->attributes.cs);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IMFSampleVtbl samplevtbl =
|
||||
|
|
|
@ -1760,12 +1760,14 @@ static void test_system_memory_buffer(void)
|
|||
|
||||
static void test_sample(void)
|
||||
{
|
||||
static const DWORD test_pattern = 0x22222222;
|
||||
IMFMediaBuffer *buffer, *buffer2;
|
||||
DWORD count, flags, length;
|
||||
IMFAttributes *attributes;
|
||||
IMFSample *sample;
|
||||
LONGLONG time;
|
||||
HRESULT hr;
|
||||
BYTE *data;
|
||||
|
||||
hr = MFCreateSample( &sample );
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
@ -1868,6 +1870,94 @@ static void test_sample(void)
|
|||
IMFAttributes_Release(attributes);
|
||||
IMFSample_Release(sample);
|
||||
|
||||
/* CopyToBuffer() */
|
||||
hr = MFCreateSample(&sample);
|
||||
ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
|
||||
|
||||
hr = MFCreateMemoryBuffer(16, &buffer2);
|
||||
ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
|
||||
|
||||
/* Sample with no buffers. */
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
|
||||
ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
|
||||
hr = IMFSample_CopyToBuffer(sample, buffer2);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
|
||||
ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
|
||||
ok(!length, "Unexpected length %u.\n", length);
|
||||
|
||||
/* Single buffer, larger destination. */
|
||||
hr = MFCreateMemoryBuffer(8, &buffer);
|
||||
ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
|
||||
ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
|
||||
*(DWORD *)data = 0x11111111;
|
||||
hr = IMFMediaBuffer_Unlock(buffer);
|
||||
ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
|
||||
ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_AddBuffer(sample, buffer);
|
||||
ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
|
||||
|
||||
/* Existing content is overwritten. */
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
|
||||
ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_CopyToBuffer(sample, buffer2);
|
||||
ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
|
||||
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
|
||||
ok(length == 4, "Unexpected buffer length %u.\n", length);
|
||||
|
||||
/* Multiple buffers, matching total size. */
|
||||
hr = IMFSample_AddBuffer(sample, buffer);
|
||||
ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_GetBufferCount(sample, &count);
|
||||
ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
|
||||
ok(count == 2, "Unexpected buffer count %u.\n", count);
|
||||
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
|
||||
ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_CopyToBuffer(sample, buffer2);
|
||||
ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
|
||||
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
|
||||
ok(length == 16, "Unexpected buffer length %u.\n", length);
|
||||
|
||||
hr = IMFSample_AddBuffer(sample, buffer);
|
||||
ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
|
||||
ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
|
||||
ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
|
||||
*(DWORD *)data = test_pattern;
|
||||
hr = IMFMediaBuffer_Unlock(buffer2);
|
||||
ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_CopyToBuffer(sample, buffer2);
|
||||
ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
|
||||
ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
|
||||
ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
|
||||
hr = IMFMediaBuffer_Unlock(buffer2);
|
||||
ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
|
||||
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
|
||||
ok(!length, "Unexpected buffer length %u.\n", length);
|
||||
|
||||
IMFMediaBuffer_Release(buffer2);
|
||||
IMFSample_Release(sample);
|
||||
|
||||
/* ConvertToContiguousBuffer() */
|
||||
hr = MFCreateSample(&sample);
|
||||
ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
|
||||
|
|
Loading…
Reference in New Issue