winegstreamer: Implement IWMHeaderInfo::GetAttributeByName(L"Duration").

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-11-02 00:13:02 -05:00 committed by Alexandre Julliard
parent 399ccc0327
commit 799c7704e8
2 changed files with 172 additions and 3 deletions

View File

@ -874,9 +874,47 @@ static HRESULT WINAPI header_info_GetAttributeByIndex(IWMHeaderInfo3 *iface, WOR
static HRESULT WINAPI header_info_GetAttributeByName(IWMHeaderInfo3 *iface, WORD *stream_number,
const WCHAR *name, WMT_ATTR_DATATYPE *type, BYTE *value, WORD *size)
{
FIXME("iface %p, stream_number %p, name %s, type %p, value %p, size %p, stub!\n",
iface, stream_number, debugstr_w(name), type, value, size);
return E_NOTIMPL;
struct wm_reader *reader = impl_from_IWMHeaderInfo3(iface);
const WORD req_size = *size;
TRACE("reader %p, stream_number %p, name %s, type %p, value %p, size %u.\n",
reader, stream_number, debugstr_w(name), type, value, *size);
if (!stream_number)
return E_INVALIDARG;
if (!wcscmp(name, L"Duration"))
{
QWORD duration;
if (*stream_number)
{
WARN("Requesting duration for stream %u, returning ASF_E_NOTFOUND.\n", *stream_number);
return ASF_E_NOTFOUND;
}
*size = sizeof(QWORD);
if (!value)
{
*type = WMT_TYPE_QWORD;
return S_OK;
}
if (req_size < *size)
return ASF_E_BUFFERTOOSMALL;
*type = WMT_TYPE_QWORD;
EnterCriticalSection(&reader->cs);
duration = wg_parser_stream_get_duration(wg_parser_get_stream(reader->wg_parser, 0));
LeaveCriticalSection(&reader->cs);
TRACE("Returning duration %s.\n", debugstr_time(duration));
memcpy(value, &duration, sizeof(QWORD));
return S_OK;
}
else
{
FIXME("Unknown attribute %s.\n", debugstr_w(name));
return ASF_E_NOTFOUND;
}
}
static HRESULT WINAPI header_info_SetAttribute(IWMHeaderInfo3 *iface, WORD stream_number,

View File

@ -420,6 +420,135 @@ static const IStreamVtbl stream_vtbl =
stream_Clone,
};
static void test_reader_attributes(IWMProfile *profile)
{
WORD size, stream_number, ret_stream_number;
IWMHeaderInfo *header_info;
IWMStreamConfig *config;
WMT_ATTR_DATATYPE type;
ULONG count, i;
QWORD duration;
DWORD dword;
HRESULT hr;
IWMProfile_QueryInterface(profile, &IID_IWMHeaderInfo, (void **)&header_info);
hr = IWMProfile_GetStreamCount(profile, &count);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(count == 2, "Got count %u.\n", count);
for (i = 0; i < count; ++i)
{
hr = IWMProfile_GetStream(profile, i, &config);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IWMStreamConfig_GetStreamNumber(config, &stream_number);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ret_stream_number = stream_number;
size = sizeof(DWORD);
type = 0xdeadbeef;
dword = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &ret_stream_number,
L"WM/VideoFrameRate", &type, (BYTE *)&dword, &size);
ok(hr == ASF_E_NOTFOUND, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(DWORD), "Got size %u.\n", size);
ok(dword == 0xdeadbeef, "Got frame rate %u.\n", dword);
ok(ret_stream_number == stream_number, "Expected stream number %u, got %u.\n",
stream_number, ret_stream_number);
size = sizeof(QWORD);
type = 0xdeadbeef;
duration = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &ret_stream_number,
L"Duration", &type, (BYTE *)&duration, &size);
ok(hr == ASF_E_NOTFOUND, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(QWORD), "Got size %u.\n", size);
ok(ret_stream_number == stream_number, "Expected stream number %u, got %u.\n",
stream_number, ret_stream_number);
IWMStreamConfig_Release(config);
}
/* WM/VideoFrameRate with a NULL stream number. */
size = sizeof(DWORD);
type = 0xdeadbeef;
dword = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, NULL,
L"WM/VideoFrameRate", &type, (BYTE *)&dword, &size);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(DWORD), "Got size %u.\n", size);
ok(dword == 0xdeadbeef, "Got frame rate %u.\n", dword);
/* And with a zero stream number. */
stream_number = 0;
size = sizeof(DWORD);
type = 0xdeadbeef;
dword = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &stream_number,
L"WM/VideoFrameRate", &type, (BYTE *)&dword, &size);
ok(hr == ASF_E_NOTFOUND, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(DWORD), "Got size %u.\n", size);
ok(dword == 0xdeadbeef, "Got frame rate %u.\n", dword);
ok(stream_number == 0, "Got stream number %u.\n", stream_number);
/* Duration with a NULL stream number. */
size = sizeof(QWORD);
type = 0xdeadbeef;
duration = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, NULL,
L"Duration", &type, (BYTE *)&duration, &size);
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(QWORD), "Got size %u.\n", size);
ok(duration == 0xdeadbeef, "Got duration %I64u.\n", duration);
/* And with a zero stream number. */
size = sizeof(QWORD);
type = 0xdeadbeef;
duration = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &stream_number,
L"Duration", &type, (BYTE *)&duration, &size);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(type == WMT_TYPE_QWORD, "Got type %#x.\n", type);
ok(size == sizeof(QWORD), "Got size %u.\n", size);
ok(duration == 20460000, "Got duration %I64u.\n", duration);
ok(stream_number == 0, "Got stream number %u.\n", stream_number);
/* Pass a too-small size. */
size = sizeof(QWORD) - 1;
type = 0xdeadbeef;
duration = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &stream_number,
L"Duration", &type, (BYTE *)&duration, &size);
ok(hr == ASF_E_BUFFERTOOSMALL, "Got hr %#x.\n", hr);
ok(type == 0xdeadbeef, "Got type %#x.\n", type);
ok(size == sizeof(QWORD), "Got size %u.\n", size);
ok(duration == 0xdeadbeef, "Got duration %I64u.\n", duration);
ok(stream_number == 0, "Got stream number %u.\n", stream_number);
/* Pass a NULL buffer. */
size = 0xdead;
type = 0xdeadbeef;
hr = IWMHeaderInfo_GetAttributeByName(header_info, &stream_number,
L"Duration", &type, NULL, &size);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(type == WMT_TYPE_QWORD, "Got type %#x.\n", type);
ok(size == sizeof(QWORD), "Got size %u.\n", size);
ok(stream_number == 0, "Got stream number %u.\n", stream_number);
IWMHeaderInfo_Release(header_info);
}
static void test_sync_reader_streaming(void)
{
DWORD size, flags, output_number, expect_output_number;
@ -596,6 +725,8 @@ static void test_sync_reader_streaming(void)
&pts, &duration, &flags, NULL, NULL);
ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr);
test_reader_attributes(profile);
hr = IWMSyncReader_Close(reader);
ok(hr == S_OK, "Got hr %#x.\n", hr);