[QUARTZ_WINETEST] Sync with Wine 3.0. CORE-14225
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 21 Jan 2018 21:34:54 +0000 (22:34 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 21 Jan 2018 21:34:54 +0000 (22:34 +0100)
modules/rostests/winetests/quartz/CMakeLists.txt
modules/rostests/winetests/quartz/avisplitter.c
modules/rostests/winetests/quartz/filtergraph.c
modules/rostests/winetests/quartz/rsrc.rc [new file with mode: 0644]
modules/rostests/winetests/quartz/test.avi [new file with mode: 0644]
modules/rostests/winetests/quartz/test.mpg [new file with mode: 0644]

index e73e531..d74b8c5 100644 (file)
@@ -16,11 +16,11 @@ list(APPEND SOURCE
     testlist.c)
 
 add_idl_headers(quartz_test_idlheader fil_data.idl)
-add_executable(quartz_winetest ${SOURCE})
+add_executable(quartz_winetest ${SOURCE} rsrc.rc)
 target_link_libraries(quartz_winetest uuid)
 add_dependencies(quartz_winetest dxsdk quartz_test_idlheader)
 set_module_type(quartz_winetest win32cui)
-add_importlibs(quartz_winetest ole32 oleaut32 advapi32 msvcrt kernel32)
+add_importlibs(quartz_winetest ole32 oleaut32 advapi32 user32 msvcrt kernel32)
 
 if(MSVC)
     add_importlibs(quartz_winetest ntdll)
index 78ca8b8..8bafb14 100644 (file)
 #include "dshow.h"
 #include "tlhelp32.h"
 
-static HANDLE (WINAPI *pCreateToolhelp32Snapshot)(DWORD, DWORD);
-static BOOL (WINAPI *pThread32First)(HANDLE, LPTHREADENTRY32);
-static BOOL (WINAPI *pThread32Next)(HANDLE, LPTHREADENTRY32);
-
 static IUnknown *pAviSplitter = NULL;
 
-static int count_threads(void)
-{
-    THREADENTRY32 te;
-    int threads;
-    HANDLE h;
-
-    h = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
-    te.dwSize = sizeof(te);
-
-    if (h == INVALID_HANDLE_VALUE)
-        return -1;
-
-    pThread32First(h, &te);
-    if (te.th32OwnerProcessID == GetCurrentProcessId())
-        threads = 1;
-    else
-        threads = 0;
-
-    while (pThread32Next(h, &te))
-        if (te.th32OwnerProcessID == GetCurrentProcessId())
-            ++threads;
-
-    CloseHandle(h);
-    return threads;
-}
-
 static BOOL create_avisplitter(void)
 {
     HRESULT hr;
@@ -300,45 +270,54 @@ static void test_filesourcefilter(void)
     }
 }
 
-static const WCHAR wfile[] = {'t','e','s','t','.','a','v','i',0};
-static const char afile[] = "test.avi";
+static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0};
 
-/* This test doesn't use the quartz filtergraph because it makes it impossible
- * to be certain that a thread is really one owned by the avi splitter.
- * A lot of the decoder filters will also have their own thread, and Windows'
- * filtergraph has a separate thread for start/stop/seeking requests.
- * By avoiding the filtergraph altogether and connecting streams directly to
- * the null renderer I am sure that this is not the case here.
- */
-static void test_threads(void)
+static WCHAR *load_resource(const WCHAR *name)
+{
+    static WCHAR pathW[MAX_PATH];
+    DWORD written;
+    HANDLE file;
+    HRSRC res;
+    void *ptr;
+
+    GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
+    lstrcatW(pathW, name);
+
+    file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW),
+        GetLastError());
+
+    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
+    ok( res != 0, "couldn't find resource\n" );
+    ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
+    WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
+    ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
+    CloseHandle( file );
+
+    return pathW;
+}
+
+static void test_filter_graph(void)
 {
     IFileSourceFilter *pfile = NULL;
     IBaseFilter *preader = NULL, *pavi = NULL;
     IEnumPins *enumpins = NULL;
     IPin *filepin = NULL, *avipin = NULL;
     HRESULT hr;
-    int baselevel, curlevel, expected;
     HANDLE file = NULL;
     PIN_DIRECTION dir = PINDIR_OUTPUT;
     char buffer[13];
     DWORD readbytes;
     FILTER_STATE state;
 
-    /* We need another way of counting threads on NT4. Skip these tests (for now) */
-    if (!pCreateToolhelp32Snapshot || !pThread32First || !pThread32Next)
-    {
-        win_skip("Needed thread functions are not available (NT4)\n");
-        return;
-    }
-
-    /* Before doing anything (the thread count at the start differs per OS) */
-    baselevel = count_threads();
+    WCHAR *filename = load_resource(avifile);
 
-    file = CreateFileW(wfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
+    file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
         NULL, OPEN_EXISTING, 0, NULL);
     if (file == INVALID_HANDLE_VALUE)
     {
-        skip("Could not read test file \"%s\", skipping test\n", afile);
+        skip("Could not read test file \"%s\", skipping test\n", wine_dbgstr_w(filename));
+        DeleteFileW(filename);
         return;
     }
 
@@ -349,7 +328,8 @@ static void test_threads(void)
     if (strncmp(buffer, "RIFF", 4) || strcmp(buffer + 8, "AVI "))
     {
         skip("%s is not an avi riff file, not doing the avi splitter test\n",
-            afile);
+            wine_dbgstr_w(filename));
+        DeleteFileW(filename);
         return;
     }
 
@@ -379,10 +359,10 @@ static void test_threads(void)
     if (hr != S_OK)
         goto fail;
 
-    hr = IFileSourceFilter_Load(pfile, wfile, NULL);
+    hr = IFileSourceFilter_Load(pfile, filename, NULL);
     if (hr != S_OK)
     {
-        trace("Could not load file\n");
+        trace("Could not load file: %08x\n", hr);
         goto fail;
     }
 
@@ -409,20 +389,11 @@ static void test_threads(void)
     if (hr != S_OK)
         goto fail;
 
-    curlevel = count_threads();
-    ok(curlevel == baselevel,
-        "The thread count should be %d not %d\n", baselevel, curlevel);
-
     hr = IPin_Connect(filepin, avipin, NULL);
     ok(hr == S_OK, "Could not connect: %08x\n", hr);
     if (hr != S_OK)
         goto fail;
 
-    expected = 1 + baselevel;
-    curlevel = count_threads();
-    ok(curlevel == expected,
-        "The thread count should be %d not %d\n", expected, curlevel);
-
     IPin_Release(avipin);
     avipin = NULL;
 
@@ -444,12 +415,17 @@ static void test_threads(void)
 
             hr = CoCreateInstance(&CLSID_NullRenderer, NULL,
                 CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pnull);
-            ok(hr == S_OK, "Could not create null renderer: %08x\n", hr);
-            if (hr != S_OK)
+            if (hr == REGDB_E_CLASSNOTREG)
+            {
+                win_skip("Null renderer not registered, skipping\n");
                 break;
+            }
+            ok(hr == S_OK, "Could not create null renderer: %08x\n", hr);
 
-            IBaseFilter_EnumPins(pnull, &nullenum);
-            IEnumPins_Next(nullenum, 1, &nullpin, NULL);
+            hr = IBaseFilter_EnumPins(pnull, &nullenum);
+            ok(hr == S_OK, "Failed to enum pins, hr %#x.\n", hr);
+            hr = IEnumPins_Next(nullenum, 1, &nullpin, NULL);
+            ok(hr == S_OK, "Failed to get next pin, hr %#x.\n", hr);
             IEnumPins_Release(nullenum);
             IPin_QueryDirection(nullpin, &dir);
 
@@ -462,7 +438,6 @@ static void test_threads(void)
                 break;
             }
             IBaseFilter_Run(pnull, 0);
-            ++expected;
         }
 
         IPin_Release(avipin);
@@ -494,10 +469,6 @@ static void test_threads(void)
     IBaseFilter_Run(pavi, 0);
     IBaseFilter_GetState(pavi, INFINITE, &state);
 
-    curlevel = count_threads();
-    ok(curlevel == expected,
-        "The thread count should be %d not %d\n", expected, curlevel);
-
     IBaseFilter_Pause(pavi);
     IBaseFilter_Pause(preader);
     IBaseFilter_Stop(pavi);
@@ -520,7 +491,9 @@ fail2:
             if (dir == PINDIR_OUTPUT)
             {
                 PIN_INFO info;
-                IPin_QueryPinInfo(to, &info);
+
+                hr = IPin_QueryPinInfo(to, &info);
+                ok(hr == S_OK, "Failed to query pin info, hr %#x.\n", hr);
 
                 /* Release twice: Once normal, second from the
                  * previous while loop
@@ -569,20 +542,11 @@ fail:
     if (pfile)
         IFileSourceFilter_Release(pfile);
 
-    curlevel = count_threads();
-    todo_wine
-    ok(curlevel == baselevel,
-        "The thread count should be %d not %d\n", baselevel, curlevel);
+    DeleteFileW(filename);
 }
 
 START_TEST(avisplitter)
 {
-    HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
-
-    pCreateToolhelp32Snapshot = (void*)GetProcAddress(kernel32, "CreateToolhelp32Snapshot");
-    pThread32First = (void*)GetProcAddress(kernel32, "Thread32First");
-    pThread32Next = (void*)GetProcAddress(kernel32, "Thread32Next");
-
     CoInitialize(NULL);
 
     if (!create_avisplitter())
@@ -594,7 +558,7 @@ START_TEST(avisplitter)
     test_query_interface();
     test_basefilter();
     test_filesourcefilter();
-    test_threads();
+    test_filter_graph();
 
     release_avisplitter();
 
index a895071..5fd3107 100644 (file)
@@ -42,6 +42,31 @@ typedef struct TestFilterImpl
 static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0};
 static const WCHAR mpegfile[] = {'t','e','s','t','.','m','p','g',0};
 
+static WCHAR *load_resource(const WCHAR *name)
+{
+    static WCHAR pathW[MAX_PATH];
+    DWORD written;
+    HANDLE file;
+    HRSRC res;
+    void *ptr;
+
+    GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
+    lstrcatW(pathW, name);
+
+    file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW),
+        GetLastError());
+
+    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
+    ok( res != 0, "couldn't find resource\n" );
+    ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
+    WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
+    ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
+    CloseHandle( file );
+
+    return pathW;
+}
+
 static IGraphBuilder *pgraph;
 
 static int createfiltergraph(void)
@@ -53,7 +78,7 @@ static int createfiltergraph(void)
 static void test_basic_video(void)
 {
     IBasicVideo* pbv;
-    LONG video_width, video_height;
+    LONG video_width, video_height, window_width;
     LONG left, top, width, height;
     HRESULT hr;
 
@@ -158,6 +183,8 @@ static void test_basic_video(void)
     ok(height == video_height/4+1, "expected %d, got %d\n", video_height/4+1, height);
 
     /* test destination rectangle */
+    window_width = max(video_width, GetSystemMetrics(SM_CXMIN) - 2 * GetSystemMetrics(SM_CXFRAME));
+
     hr = IBasicVideo_GetDestinationPosition(pbv, NULL, NULL, NULL, NULL);
     ok(hr == E_POINTER, "IBasicVideo_GetDestinationPosition returned: %x\n", hr);
     hr = IBasicVideo_GetDestinationPosition(pbv, &left, &top, NULL, NULL);
@@ -168,7 +195,7 @@ static void test_basic_video(void)
     ok(hr == S_OK, "Cannot get destination position returned: %x\n", hr);
     ok(left == 0, "expected 0, got %d\n", left);
     ok(top == 0, "expected 0, got %d\n", top);
-    todo_wine ok(width == video_width, "expected %d, got %d\n", video_width, width);
+    todo_wine ok(width == window_width, "expected %d, got %d\n", window_width, width);
     todo_wine ok(height == video_height, "expected %d, got %d\n", video_height, height);
 
     hr = IBasicVideo_SetDestinationPosition(pbv, 0, 0, 0, 0);
@@ -328,8 +355,7 @@ static void rungraph(void)
     hr = IMediaEvent_GetEventHandle(pme, (OAEVENT*)&hEvent);
     ok(hr==S_OK, "Cannot get event handle returned: %x\n", hr);
 
-    /* WaitForSingleObject(hEvent, INFINITE); */
-    Sleep(20000);
+    ok(WaitForSingleObject(hEvent, 2000) == WAIT_OBJECT_0, "Wait failed\n");
 
     hr = IMediaEvent_Release(pme);
     ok(hr==2, "Releasing mediaevent returned: %x\n", hr);
@@ -354,26 +380,39 @@ static void test_render_run(const WCHAR *file)
     HANDLE h;
     HRESULT hr;
 
-    h = CreateFileW(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+    WCHAR *filename = load_resource(file);
+
+    h = CreateFileW(filename, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
     if (h == INVALID_HANDLE_VALUE) {
         skip("Could not read test file %s, skipping test\n", wine_dbgstr_w(file));
+        DeleteFileW(filename);
         return;
     }
     CloseHandle(h);
 
     if (!createfiltergraph())
+    {
+        DeleteFileW(filename);
         return;
+    }
 
-    hr = IGraphBuilder_RenderFile(pgraph, file, NULL);
-    ok(hr == S_OK, "RenderFile returned: %x\n", hr);
-    rungraph();
+    hr = IGraphBuilder_RenderFile(pgraph, filename, NULL);
+    if (hr == VFW_E_CANNOT_RENDER)
+        skip("%s: codec not supported; skipping test\n", wine_dbgstr_w(file));
+    else
+    {
+        ok(hr == S_OK || hr == VFW_S_AUDIO_NOT_RENDERED, "RenderFile failed: %x\n", hr);
+        rungraph();
+    }
 
     releasefiltergraph();
 
     /* check reference leaks */
-    h = CreateFileW(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+    h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     ok(h != INVALID_HANDLE_VALUE, "CreateFile failed: err=%d\n", GetLastError());
     CloseHandle(h);
+
+    DeleteFileW(filename);
 }
 
 static DWORD WINAPI call_RenderFile_multithread(LPVOID lParam)
@@ -392,8 +431,9 @@ static DWORD WINAPI call_RenderFile_multithread(LPVOID lParam)
     CloseHandle(handle);
 
     hr = IFilterGraph2_RenderFile(filter_graph, mp3file, NULL);
-    todo_wine ok(hr == VFW_E_CANNOT_RENDER || /* xp or older */
-                 hr == VFW_E_NO_TRANSPORT, /* win7 or newer */
+    todo_wine ok(hr == VFW_E_CANNOT_RENDER || /* xp or older + DirectX 9 */
+                 hr == VFW_E_NO_TRANSPORT || /* win7 or newer */
+                 broken(hr == CLASS_E_CLASSNOTAVAILABLE), /* xp or older + DirectX 8 or older */
                  "Expected 0x%08x or 0x%08x, returned 0x%08x\n", VFW_E_CANNOT_RENDER, VFW_E_NO_TRANSPORT, hr);
 
     DeleteFileW(mp3file);
@@ -446,6 +486,7 @@ static void test_render_with_multithread(void)
     IFilterGraph2_Release(filter_graph);
     IGraphBuilder_Release(graph_builder);
     IClassFactory_Release(classfactory);
+    CloseHandle(thread);
     CoUninitialize();
     return;
 }
diff --git a/modules/rostests/winetests/quartz/rsrc.rc b/modules/rostests/winetests/quartz/rsrc.rc
new file mode 100644 (file)
index 0000000..9bea5be
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Resource file for quartz tests.
+ *
+ * Copyright 2017 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "windef.h"
+
+/* @makedep: test.avi */
+test.avi RCDATA "test.avi"
+
+/* @makedep: test.mpg */
+test.mpg RCDATA "test.mpg"
diff --git a/modules/rostests/winetests/quartz/test.avi b/modules/rostests/winetests/quartz/test.avi
new file mode 100644 (file)
index 0000000..bec304d
Binary files /dev/null and b/modules/rostests/winetests/quartz/test.avi differ
diff --git a/modules/rostests/winetests/quartz/test.mpg b/modules/rostests/winetests/quartz/test.mpg
new file mode 100644 (file)
index 0000000..7fe379a
Binary files /dev/null and b/modules/rostests/winetests/quartz/test.mpg differ