mfplat: Implement MFCreateMediaBufferFromMediaType() for audio types.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
63a06295c6
commit
ba014235ec
|
@ -448,6 +448,68 @@ HRESULT WINAPI MFCreate2DMediaBuffer(DWORD width, DWORD height, DWORD fourcc, BO
|
||||||
return create_2d_buffer(width, height, fourcc, buffer);
|
return create_2d_buffer(width, height, fourcc, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int buffer_get_aligned_length(unsigned int length, unsigned int alignment)
|
||||||
|
{
|
||||||
|
length = (length + alignment) / alignment;
|
||||||
|
length *= alignment;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
|
||||||
|
DWORD alignment, IMFMediaBuffer **buffer)
|
||||||
|
{
|
||||||
|
UINT32 length = 0, block_alignment;
|
||||||
|
LONGLONG avg_length;
|
||||||
|
HRESULT hr;
|
||||||
|
GUID major;
|
||||||
|
|
||||||
|
TRACE("%p, %s, %u, %u, %p.\n", media_type, wine_dbgstr_longlong(duration), min_length, alignment, buffer);
|
||||||
|
|
||||||
|
if (!media_type)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (FAILED(hr = IMFMediaType_GetMajorType(media_type, &major)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (IsEqualGUID(&major, &MFMediaType_Audio))
|
||||||
|
{
|
||||||
|
block_alignment = 0;
|
||||||
|
if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment)))
|
||||||
|
WARN("Block alignment was not specified.\n");
|
||||||
|
|
||||||
|
if (block_alignment)
|
||||||
|
{
|
||||||
|
avg_length = 0;
|
||||||
|
|
||||||
|
if (duration)
|
||||||
|
{
|
||||||
|
length = 0;
|
||||||
|
if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &length)))
|
||||||
|
{
|
||||||
|
/* 100 ns -> 1 s */
|
||||||
|
avg_length = length * duration / (10 * 1000 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alignment = max(16, alignment);
|
||||||
|
|
||||||
|
length = buffer_get_aligned_length(avg_length + 1, alignment);
|
||||||
|
length = buffer_get_aligned_length(length, block_alignment);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
length = 0;
|
||||||
|
|
||||||
|
length = max(length, min_length);
|
||||||
|
|
||||||
|
return create_1d_buffer(length, MF_1_BYTE_ALIGNMENT, buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FIXME("Major type %s is not supported.\n", debugstr_guid(&major));
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI sample_QueryInterface(IMFSample *iface, REFIID riid, void **out)
|
static HRESULT WINAPI sample_QueryInterface(IMFSample *iface, REFIID riid, void **out)
|
||||||
{
|
{
|
||||||
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
|
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
@ stdcall MFCreateMFByteStreamOnStreamEx(ptr ptr)
|
@ stdcall MFCreateMFByteStreamOnStreamEx(ptr ptr)
|
||||||
@ stdcall MFCreateMFByteStreamWrapper(ptr ptr)
|
@ stdcall MFCreateMFByteStreamWrapper(ptr ptr)
|
||||||
@ stub MFCreateMFVideoFormatFromMFMediaType
|
@ stub MFCreateMFVideoFormatFromMFMediaType
|
||||||
|
@ stdcall MFCreateMediaBufferFromMediaType(ptr int64 long long ptr)
|
||||||
@ stub MFCreateMediaBufferWrapper
|
@ stub MFCreateMediaBufferWrapper
|
||||||
@ stdcall MFCreateMediaEvent(long ptr long ptr ptr)
|
@ stdcall MFCreateMediaEvent(long ptr long ptr ptr)
|
||||||
@ stdcall MFCreateMediaType(ptr)
|
@ stdcall MFCreateMediaType(ptr)
|
||||||
|
|
|
@ -95,6 +95,8 @@ static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height
|
||||||
static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
|
static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
|
||||||
static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
|
static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
|
||||||
IMFMediaBuffer **buffer);
|
IMFMediaBuffer **buffer);
|
||||||
|
static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
|
||||||
|
DWORD min_alignment, IMFMediaBuffer **buffer);
|
||||||
|
|
||||||
static const WCHAR fileschemeW[] = L"file://";
|
static const WCHAR fileschemeW[] = L"file://";
|
||||||
|
|
||||||
|
@ -665,6 +667,7 @@ static void init_functions(void)
|
||||||
X(MFCreate2DMediaBuffer);
|
X(MFCreate2DMediaBuffer);
|
||||||
X(MFCreateDXGIDeviceManager);
|
X(MFCreateDXGIDeviceManager);
|
||||||
X(MFCreateSourceResolver);
|
X(MFCreateSourceResolver);
|
||||||
|
X(MFCreateMediaBufferFromMediaType);
|
||||||
X(MFCreateMFByteStreamOnStream);
|
X(MFCreateMFByteStreamOnStream);
|
||||||
X(MFCreateTransformActivate);
|
X(MFCreateTransformActivate);
|
||||||
X(MFGetPlaneSize);
|
X(MFGetPlaneSize);
|
||||||
|
@ -4587,6 +4590,72 @@ static void test_MFCreate2DMediaBuffer(void)
|
||||||
IMFMediaBuffer_Release(buffer);
|
IMFMediaBuffer_Release(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_MFCreateMediaBufferFromMediaType(void)
|
||||||
|
{
|
||||||
|
static struct audio_buffer_test
|
||||||
|
{
|
||||||
|
unsigned int duration;
|
||||||
|
unsigned int min_length;
|
||||||
|
unsigned int min_alignment;
|
||||||
|
unsigned int block_alignment;
|
||||||
|
unsigned int bytes_per_second;
|
||||||
|
unsigned int buffer_length;
|
||||||
|
} audio_tests[] =
|
||||||
|
{
|
||||||
|
{ 0, 0, 0, 4, 0, 20 },
|
||||||
|
{ 0, 16, 0, 4, 0, 20 },
|
||||||
|
{ 0, 0, 32, 4, 0, 36 },
|
||||||
|
{ 0, 64, 32, 4, 0, 64 },
|
||||||
|
{ 1, 0, 0, 4, 16, 36 },
|
||||||
|
{ 2, 0, 0, 4, 16, 52 },
|
||||||
|
};
|
||||||
|
IMFMediaBuffer *buffer;
|
||||||
|
UINT32 length;
|
||||||
|
HRESULT hr;
|
||||||
|
IMFMediaType *media_type;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!pMFCreateMediaBufferFromMediaType)
|
||||||
|
{
|
||||||
|
win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
|
||||||
|
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = MFCreateMediaType(&media_type);
|
||||||
|
ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
|
||||||
|
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
|
||||||
|
{
|
||||||
|
const struct audio_buffer_test *ptr = &audio_tests[i];
|
||||||
|
|
||||||
|
hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
|
||||||
|
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
|
||||||
|
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
|
||||||
|
ptr->min_alignment, &buffer);
|
||||||
|
ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr);
|
||||||
|
if (FAILED(hr))
|
||||||
|
break;
|
||||||
|
|
||||||
|
hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
|
||||||
|
ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
|
||||||
|
ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
|
||||||
|
|
||||||
|
IMFMediaBuffer_Release(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMFMediaType_Release(media_type);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(mfplat)
|
START_TEST(mfplat)
|
||||||
{
|
{
|
||||||
char **argv;
|
char **argv;
|
||||||
|
@ -4640,6 +4709,7 @@ START_TEST(mfplat)
|
||||||
test_queue_com();
|
test_queue_com();
|
||||||
test_MFGetStrideForBitmapInfoHeader();
|
test_MFGetStrideForBitmapInfoHeader();
|
||||||
test_MFCreate2DMediaBuffer();
|
test_MFCreate2DMediaBuffer();
|
||||||
|
test_MFCreateMediaBufferFromMediaType();
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,6 +411,8 @@ HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **man
|
||||||
HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue);
|
HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue);
|
||||||
HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags,
|
HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags,
|
||||||
LPCWSTR url, IMFByteStream **bytestream);
|
LPCWSTR url, IMFByteStream **bytestream);
|
||||||
|
HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
|
||||||
|
DWORD min_alignment, IMFMediaBuffer **buffer);
|
||||||
HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status,
|
HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status,
|
||||||
const PROPVARIANT *value, IMFMediaEvent **event);
|
const PROPVARIANT *value, IMFMediaEvent **event);
|
||||||
HRESULT WINAPI MFCreateMediaType(IMFMediaType **type);
|
HRESULT WINAPI MFCreateMediaType(IMFMediaType **type);
|
||||||
|
|
Loading…
Reference in New Issue