From: Alfred Agrell floating@muncher.se
--- dlls/wmvcore/tests/wmvcore.c | 214 +++++++++++++++++++++++++++++++++-- 1 file changed, 206 insertions(+), 8 deletions(-)
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index c1114b711f9..78868acad83 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -34,20 +34,32 @@ static const DWORD test_wmv_duration = 20460000;
HRESULT WINAPI WMCreateWriterPriv(IWMWriter **writer);
-static BOOL compare_media_types(const WM_MEDIA_TYPE *a, const WM_MEDIA_TYPE *b) +static BOOL compare_media_types(const WM_MEDIA_TYPE *a, const WM_MEDIA_TYPE *b, BOOL ignore_bitrate) { /* We can't use memcmp(), because WM_MEDIA_TYPE has a hole, which sometimes * contains junk. */ - - return IsEqualGUID(&a->majortype, &b->majortype) + BOOL equal = (IsEqualGUID(&a->majortype, &b->majortype) && IsEqualGUID(&a->subtype, &b->subtype) && a->bFixedSizeSamples == b->bFixedSizeSamples && a->bTemporalCompression == b->bTemporalCompression && a->lSampleSize == b->lSampleSize && IsEqualGUID(&a->formattype, &b->formattype) && a->pUnk == b->pUnk - && a->cbFormat == b->cbFormat - && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); + && a->cbFormat == b->cbFormat); + if (!equal) + return FALSE; + + if (ignore_bitrate) + { + size_t ignore_start = offsetof(VIDEOINFOHEADER, dwBitRate); + size_t ignore_end = ignore_start + sizeof(DWORD); + return !memcmp(a->pbFormat, b->pbFormat, ignore_start) + && !memcmp(a->pbFormat + ignore_end, b->pbFormat + ignore_end, a->cbFormat - ignore_end); + } + else + { + return !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); + } }
static void init_audio_type(WM_MEDIA_TYPE *mt, const GUID *subtype, UINT bits, UINT channels, UINT rate) @@ -1720,7 +1732,7 @@ static void test_sync_reader_types(void) ret_size = sizeof(mt2_buffer); hr = IWMOutputMediaProps_GetMediaType(output_props2, mt2, &ret_size); ok(hr == S_OK, "Got hr %#lx.\n", hr); - ok(compare_media_types(mt, mt2), "Media types didn't match.\n"); + ok(compare_media_types(mt, mt2, FALSE), "Media types didn't match.\n");
ref = IWMOutputMediaProps_Release(output_props2); ok(!ref, "Got outstanding refcount %ld.\n", ref); @@ -1816,6 +1828,191 @@ static void test_sync_reader_file(void) ok(ret, "Failed to delete %s, error %lu.\n", debugstr_w(filename), GetLastError()); }
+static void test_stream_output_type(IWMProfile *profile, WORD stream_num, const WM_MEDIA_TYPE *expected, bool todo_bitrate) +{ + IWMStreamConfig *stream_config; + IWMMediaProps *media_props; + char mt_buffer[2000]; + WM_MEDIA_TYPE *mt; + DWORD ret_size; + HRESULT hr; + + hr = IWMProfile_GetStreamByNumber(profile, stream_num, &stream_config); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IWMStreamConfig_QueryInterface(stream_config, &IID_IWMMediaProps, (void**)&media_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + mt = (WM_MEDIA_TYPE *)mt_buffer; + memset(mt_buffer, 0xcc, sizeof(mt_buffer)); + ret_size = sizeof(mt_buffer); + hr = IWMMediaProps_GetMediaType(media_props, mt, &ret_size); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(compare_media_types(mt, expected, todo_bitrate), "Media types didn't match.\n"); + if (todo_bitrate) + { + VIDEOINFOHEADER *vih1 = (void *)mt->pbFormat; + VIDEOINFOHEADER *vih2 = (void *)expected->pbFormat; + todo_wine ok(vih1->dwBitRate == vih2->dwBitRate, "Bitrates didn't match.\n"); + } + + IWMStreamConfig_Release(stream_config); + IWMMediaProps_Release(media_props); +} + +static const VIDEOINFOHEADER vih_wmv1 = +{ + .rcSource = { 0, 0, 64, 48 }, + .rcTarget = { 0, 0, 64, 48 }, + .dwBitRate = 0x0002e418, + .dwBitErrorRate = 0, + .AvgTimePerFrame = 0, + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 64, + .bmiHeader.biHeight = 48, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 0x18, + .bmiHeader.biCompression = MAKEFOURCC('W','M','V','1'), + .bmiHeader.biSizeImage = 0, + .bmiHeader.biXPelsPerMeter = 0, + .bmiHeader.biYPelsPerMeter = 0, +}; +static const WM_MEDIA_TYPE mt_wmv1 = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_WMV1, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0x31564d57, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .bTemporalCompression = TRUE, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFOHEADER), + .pbFormat = (BYTE *)&vih_wmv1, +}; + +static const MSAUDIO1WAVEFORMAT wfx_msaudio1 = +{ + .wfx.wFormatTag = WAVE_FORMAT_MSAUDIO1, + .wfx.nChannels = 1, + .wfx.nSamplesPerSec = 44100, + .wfx.nAvgBytesPerSec = 16000, + .wfx.nBlockAlign = 0x02e7, + .wfx.wBitsPerSample = 0x0010, + .wfx.cbSize = MSAUDIO1_WFX_EXTRA_BYTES, + .wSamplesPerBlock = 0, + .wEncodeOptions = 1, +}; +static const WM_MEDIA_TYPE mt_msaudio1 = +{ + /* MEDIATYPE_Audio, MEDIASUBTYPE_MSAUDIO1, FORMAT_WaveFormatEx */ + .majortype = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0x00000160, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .bFixedSizeSamples = TRUE, + .lSampleSize = 0x02e7, + .formattype = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(MSAUDIO1WAVEFORMAT), + .pbFormat = (BYTE *)&wfx_msaudio1, +}; + +static void test_sync_reader_compressed_output(void) +{ + static const DWORD audio_sample_times[] = { + 0, 460000, 920000, 1390000, 1850000, 2320000, 2780000, 3250000, 3710000, 4180000, 4640000, 5100000, + 5570000, 6030000, 6500000, 6960000, 7430000, 7890000, 8350000, 8820000, 9280000, 9750000, 10210000, + 10680000, 11140000, 11610000, 12070000, 12530000, 13000000, 13460000, 13930000, 14390000, 14860000, + 15320000, 15790000, 16250000, 16710000, 17180000, 17640000, 18110000, 18570000, 19040000, 19500000, 19960000, + 99999999 + }; + static const DWORD video_sample_sizes[] = { + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8 + }; + + const WCHAR *filename = load_resource(L"test.wmv"); + DWORD flags, bytes_count; + QWORD sample_time, sample_duration; + IWMSyncReader *reader; + DWORD audio_idx = 0; + DWORD video_idx = 0; + IWMProfile *profile; + INSSBuffer *sample; + WORD stream_num; + HRESULT hr; + BYTE *data; + + hr = WMCreateSyncReader(NULL, 0, &reader); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IWMSyncReader_QueryInterface(reader, &IID_IWMProfile, (void **)&profile); + + hr = IWMSyncReader_Open(reader, filename); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + test_stream_output_type(profile, 1, &mt_wmv1, TRUE); + test_stream_output_type(profile, 2, &mt_msaudio1, FALSE); + + hr = IWMSyncReader_SetReadStreamSamples(reader, 1, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetReadStreamSamples(reader, 2, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + test_stream_output_type(profile, 1, &mt_wmv1, TRUE); + test_stream_output_type(profile, 2, &mt_msaudio1, FALSE); + + while (video_idx < 50 || audio_idx < 44) + { + DWORD next_video_time = 460000 + video_idx * 400000; + DWORD next_audio_time = audio_sample_times[audio_idx]; + + winetest_push_context("%lu/%lu", video_idx, audio_idx); + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &sample_time, &sample_duration, &flags, NULL, &stream_num); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + /* we don't care about the buffer, but GetLength is unimplemented in Wine */ + hr = INSSBuffer_GetBufferAndLength(sample, &data, &bytes_count); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + if (next_video_time <= next_audio_time) + { + ok(stream_num == 1, "Got %lu\n", (DWORD)stream_num); + ok(sample_time == next_video_time, "Expected %lu, got %lu\n", next_video_time, (DWORD)sample_time); + todo_wine ok(sample_duration == 10000, "Got %lu\n", (DWORD)sample_duration); + + if (video_idx == 0) + ok(flags == (WM_SF_CLEANPOINT|WM_SF_DISCONTINUITY), "Got %lu\n", flags); + else if (video_sample_sizes[video_idx] == 1117) + ok(flags == WM_SF_CLEANPOINT, "Got %lu\n", flags); + else + ok(flags == 0, "Got %lu\n", flags); + ok(bytes_count == video_sample_sizes[video_idx], + "Expected %lu, got %lu\n", video_sample_sizes[video_idx], bytes_count); + video_idx++; + } + else + { + ok(stream_num == 2, "Got %lu\n", (DWORD)stream_num); + ok(sample_time == next_audio_time, "Expected %lu, got %lu\n", next_audio_time, (DWORD)sample_time); + todo_wine ok(sample_duration == 460000, "Got %lu\n", (DWORD)sample_duration); + + if (audio_idx == 0) + todo_wine ok(flags == (WM_SF_CLEANPOINT|WM_SF_DISCONTINUITY), "Got %lu\n", flags); + else + todo_wine ok(flags == WM_SF_CLEANPOINT, "Got %lu\n", flags); + ok(bytes_count == 743, "Got %lu\n", bytes_count); + + audio_idx++; + } + + INSSBuffer_Release(sample); + winetest_pop_context(); + } + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &sample_time, &sample_duration, &flags, NULL, &stream_num); + ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#lx.\n", hr); + + IWMSyncReader_Release(reader); + IWMProfile_Release(profile); +} + struct callback { IWMReaderCallback IWMReaderCallback_iface; @@ -3555,7 +3752,7 @@ static void test_async_reader_types(void)
/* The sample size might differ. */ mt2->lSampleSize = mt->lSampleSize; - ok(compare_media_types(mt, mt2), "Media types didn't match.\n"); + ok(compare_media_types(mt, mt2, FALSE), "Media types didn't match.\n"); } else { @@ -3638,7 +3835,7 @@ static void test_async_reader_types(void) ret_size = sizeof(mt2_buffer); hr = IWMOutputMediaProps_GetMediaType(output_props2, mt2, &ret_size); ok(hr == S_OK, "Got hr %#lx.\n", hr); - ok(compare_media_types(mt, mt2), "Media types didn't match.\n"); + ok(compare_media_types(mt, mt2, FALSE), "Media types didn't match.\n");
ref = IWMOutputMediaProps_Release(output_props2); ok(!ref, "Got outstanding refcount %ld.\n", ref); @@ -3971,6 +4168,7 @@ START_TEST(wmvcore) test_sync_reader_streaming(); test_sync_reader_types(); test_sync_reader_file(); + test_sync_reader_compressed_output(); test_async_reader_settings(); test_async_reader_streaming(); test_async_reader_types();