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;
|
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)
|
static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *total_length)
|
||||||
{
|
{
|
||||||
struct sample *sample = impl_from_IMFSample(iface);
|
struct sample *sample = impl_from_IMFSample(iface);
|
||||||
DWORD length;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
TRACE("%p, %p.\n", iface, total_length);
|
TRACE("%p, %p.\n", iface, total_length);
|
||||||
|
|
||||||
*total_length = 0;
|
|
||||||
|
|
||||||
EnterCriticalSection(&sample->attributes.cs);
|
EnterCriticalSection(&sample->attributes.cs);
|
||||||
for (i = 0; i < sample->buffer_count; ++i)
|
*total_length = sample_get_total_length(sample);
|
||||||
{
|
|
||||||
if (SUCCEEDED(IMFMediaBuffer_GetCurrentLength(sample->buffers[i], &length)))
|
|
||||||
*total_length += length;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&sample->attributes.cs);
|
LeaveCriticalSection(&sample->attributes.cs);
|
||||||
|
|
||||||
return S_OK;
|
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)
|
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 =
|
static const IMFSampleVtbl samplevtbl =
|
||||||
|
|
|
@ -1760,12 +1760,14 @@ static void test_system_memory_buffer(void)
|
||||||
|
|
||||||
static void test_sample(void)
|
static void test_sample(void)
|
||||||
{
|
{
|
||||||
|
static const DWORD test_pattern = 0x22222222;
|
||||||
IMFMediaBuffer *buffer, *buffer2;
|
IMFMediaBuffer *buffer, *buffer2;
|
||||||
DWORD count, flags, length;
|
DWORD count, flags, length;
|
||||||
IMFAttributes *attributes;
|
IMFAttributes *attributes;
|
||||||
IMFSample *sample;
|
IMFSample *sample;
|
||||||
LONGLONG time;
|
LONGLONG time;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
BYTE *data;
|
||||||
|
|
||||||
hr = MFCreateSample( &sample );
|
hr = MFCreateSample( &sample );
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
@ -1868,6 +1870,94 @@ static void test_sample(void)
|
||||||
IMFAttributes_Release(attributes);
|
IMFAttributes_Release(attributes);
|
||||||
IMFSample_Release(sample);
|
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() */
|
/* ConvertToContiguousBuffer() */
|
||||||
hr = MFCreateSample(&sample);
|
hr = MFCreateSample(&sample);
|
||||||
ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
|
||||||
|
|
Loading…
Reference in New Issue