mfplat: Implement ConvertToContiguousBuffer() for multiple buffers.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c567af732b
commit
6601fb3ead
|
@ -1136,9 +1136,78 @@ static HRESULT WINAPI sample_GetBufferByIndex(IMFSample *iface, DWORD index, IMF
|
|||
return hr;
|
||||
}
|
||||
|
||||
static unsigned int 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 sample_copy_to_buffer(struct sample *sample, IMFMediaBuffer *buffer)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_ConvertToContiguousBuffer(IMFSample *iface, IMFMediaBuffer **buffer)
|
||||
{
|
||||
struct sample *sample = impl_from_IMFSample(iface);
|
||||
unsigned int total_length, i;
|
||||
IMFMediaBuffer *dest_buffer;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("%p, %p.\n", iface, buffer);
|
||||
|
@ -1147,16 +1216,30 @@ static HRESULT WINAPI sample_ConvertToContiguousBuffer(IMFSample *iface, IMFMedi
|
|||
|
||||
if (sample->buffer_count == 0)
|
||||
hr = E_UNEXPECTED;
|
||||
else if (sample->buffer_count == 1)
|
||||
else if (sample->buffer_count > 1)
|
||||
{
|
||||
total_length = sample_get_total_length(sample);
|
||||
if (SUCCEEDED(hr = MFCreateMemoryBuffer(total_length, &dest_buffer)))
|
||||
{
|
||||
if (SUCCEEDED(hr = sample_copy_to_buffer(sample, dest_buffer)))
|
||||
{
|
||||
for (i = 0; i < sample->buffer_count; ++i)
|
||||
IMFMediaBuffer_Release(sample->buffers[i]);
|
||||
|
||||
sample->buffers[0] = dest_buffer;
|
||||
IMFMediaBuffer_AddRef(sample->buffers[0]);
|
||||
|
||||
sample->buffer_count = 1;
|
||||
}
|
||||
IMFMediaBuffer_Release(dest_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*buffer = sample->buffers[0];
|
||||
IMFMediaBuffer_AddRef(*buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Samples with multiple buffers are not supported.\n");
|
||||
hr = E_NOTIMPL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&sample->attributes.cs);
|
||||
|
||||
|
@ -1225,21 +1308,6 @@ 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);
|
||||
|
|
|
@ -1778,7 +1778,7 @@ static void test_system_memory_buffer(void)
|
|||
static void test_sample(void)
|
||||
{
|
||||
static const DWORD test_pattern = 0x22222222;
|
||||
IMFMediaBuffer *buffer, *buffer2;
|
||||
IMFMediaBuffer *buffer, *buffer2, *buffer3;
|
||||
DWORD count, flags, length;
|
||||
IMFAttributes *attributes;
|
||||
IMFSample *sample;
|
||||
|
@ -1998,9 +1998,15 @@ static void test_sample(void)
|
|||
ok(buffer2 == buffer, "Unexpected buffer instance.\n");
|
||||
IMFMediaBuffer_Release(buffer2);
|
||||
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = MFCreateMemoryBuffer(16, &buffer2);
|
||||
ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IMFSample_AddBuffer(sample, buffer2);
|
||||
ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
|
||||
IMFMediaBuffer_Release(buffer2);
|
||||
|
@ -2009,15 +2015,22 @@ static void test_sample(void)
|
|||
ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
|
||||
ok(count == 2, "Unexpected buffer count %u.\n", count);
|
||||
|
||||
hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
|
||||
todo_wine
|
||||
hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
|
||||
ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
|
||||
ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
|
||||
ok(length == 7, "Unexpected length %u.\n", length);
|
||||
|
||||
hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
|
||||
ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
|
||||
ok(length == 7, "Unexpected length %u.\n", length);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
IMFMediaBuffer_Release(buffer2);
|
||||
IMFMediaBuffer_Release(buffer3);
|
||||
|
||||
hr = IMFSample_GetBufferCount(sample, &count);
|
||||
ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
|
||||
todo_wine
|
||||
ok(count == 1, "Unexpected buffer count %u.\n", count);
|
||||
|
||||
IMFMediaBuffer_Release(buffer);
|
||||
|
|
Loading…
Reference in New Issue