Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0ad6d688
Commit
0ad6d688
authored
Nov 17, 2022
by
Zebediah Figura
Committed by
Alexandre Julliard
Nov 18, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
quartz: Use a single message thread for all filter graphs.
This matches native, as the test shows, but was motivated by bug 50779, which it may alleviate.
parent
c7a97b5d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
30 deletions
+61
-30
filtergraph.c
dlls/quartz/filtergraph.c
+40
-28
quartz_private.h
dlls/quartz/quartz_private.h
+7
-0
filtergraph.c
dlls/quartz/tests/filtergraph.c
+14
-2
No files found.
dlls/quartz/filtergraph.c
View file @
0ad6d688
...
...
@@ -42,6 +42,19 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
quartz
);
DECLARE_CRITICAL_SECTION
(
message_cs
);
struct
filter_create_params
{
HRESULT
hr
;
IMoniker
*
moniker
;
IBaseFilter
*
filter
;
};
static
HANDLE
message_thread
,
message_thread_ret
;
static
DWORD
message_thread_id
;
static
unsigned
int
message_thread_refcount
;
struct
media_event
{
struct
list
entry
;
...
...
@@ -132,9 +145,6 @@ struct filter_graph
IUnknown
*
pSite
;
LONG
version
;
HANDLE
message_thread
,
message_thread_ret
;
DWORD
message_thread_id
;
/* Respectively: the last timestamp at which we started streaming, and the
* current offset within the stream. */
REFERENCE_TIME
stream_start
,
stream_elapsed
;
...
...
@@ -142,6 +152,7 @@ struct filter_graph
LONGLONG
current_pos
;
unsigned
int
needs_async_run
:
1
;
unsigned
int
threaded
:
1
;
};
struct
enum_filters
...
...
@@ -465,14 +476,17 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
flush_media_events
(
This
);
CloseHandle
(
This
->
media_event_handle
);
This
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
if
(
This
->
message_thread
)
EnterCriticalSection
(
&
message_cs
)
;
if
(
This
->
threaded
&&
!--
message_thread_refcount
)
{
PostThreadMessageW
(
This
->
message_thread_id
,
WM_USER
+
1
,
0
,
0
);
WaitForSingleObject
(
This
->
message_thread
,
INFINITE
);
CloseHandle
(
This
->
message_thread
);
CloseHandle
(
This
->
message_thread_ret
);
PostThreadMessageW
(
message_thread_id
,
WM_USER
+
1
,
0
,
0
);
WaitForSingleObject
(
message_thread
,
INFINITE
);
CloseHandle
(
message_thread
);
CloseHandle
(
message_thread_ret
);
}
LeaveCriticalSection
(
&
message_cs
);
This
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
This
->
event_cs
);
DeleteCriticalSection
(
&
This
->
cs
);
free
(
This
);
...
...
@@ -1012,21 +1026,13 @@ static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface)
return
hr
;
}
struct
filter_create_params
{
HRESULT
hr
;
IMoniker
*
moniker
;
IBaseFilter
*
filter
;
};
static
DWORD
WINAPI
message_thread_run
(
void
*
ctx
)
{
struct
filter_graph
*
graph
=
ctx
;
MSG
msg
;
/* Make sure we have a message queue. */
PeekMessageW
(
&
msg
,
NULL
,
0
,
0
,
PM_NOREMOVE
);
SetEvent
(
graph
->
message_thread_ret
);
SetEvent
(
message_thread_ret
);
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
...
...
@@ -1040,7 +1046,7 @@ static DWORD WINAPI message_thread_run(void *ctx)
params
->
hr
=
IMoniker_BindToObject
(
params
->
moniker
,
NULL
,
NULL
,
&
IID_IBaseFilter
,
(
void
**
)
&
params
->
filter
);
SetEvent
(
graph
->
message_thread_ret
);
SetEvent
(
message_thread_ret
);
}
else
if
(
!
msg
.
hwnd
&&
msg
.
message
==
WM_USER
+
1
)
{
...
...
@@ -1059,13 +1065,17 @@ static DWORD WINAPI message_thread_run(void *ctx)
static
HRESULT
create_filter
(
struct
filter_graph
*
graph
,
IMoniker
*
moniker
,
IBaseFilter
**
filter
)
{
if
(
graph
->
message_threa
d
)
if
(
graph
->
threade
d
)
{
struct
filter_create_params
params
;
params
.
moniker
=
moniker
;
PostThreadMessageW
(
graph
->
message_thread_id
,
WM_USER
,
(
WPARAM
)
&
params
,
0
);
WaitForSingleObject
(
graph
->
message_thread_ret
,
INFINITE
);
EnterCriticalSection
(
&
message_cs
);
PostThreadMessageW
(
message_thread_id
,
WM_USER
,
(
WPARAM
)
&
params
,
0
);
WaitForSingleObject
(
message_thread_ret
,
INFINITE
);
LeaveCriticalSection
(
&
message_cs
);
*
filter
=
params
.
filter
;
return
params
.
hr
;
}
...
...
@@ -5654,14 +5664,16 @@ static HRESULT filter_graph_common_create(IUnknown *outer, IUnknown **out, BOOL
object
->
name_index
=
1
;
object
->
timeformatseek
=
TIME_FORMAT_MEDIA_TIME
;
if
(
threaded
)
object
->
threaded
=
!!
threaded
;
EnterCriticalSection
(
&
message_cs
);
if
(
threaded
&&
!
message_thread_refcount
++
)
{
object
->
message_thread_ret
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
object
->
message_thread
=
CreateThread
(
NULL
,
0
,
message_thread_run
,
object
,
0
,
&
object
->
message_thread_id
);
WaitForSingleObject
(
object
->
message_thread_ret
,
INFINITE
);
message_thread_ret
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
message_thread
=
CreateThread
(
NULL
,
0
,
message_thread_run
,
object
,
0
,
&
message_thread_id
);
WaitForSingleObject
(
message_thread_ret
,
INFINITE
);
}
else
object
->
message_thread
=
NULL
;
LeaveCriticalSection
(
&
message_cs
);
TRACE
(
"Created %sthreaded filter graph %p.
\n
"
,
threaded
?
""
:
"non-"
,
object
);
*
out
=
&
object
->
IUnknown_inner
;
...
...
dlls/quartz/quartz_private.h
View file @
0ad6d688
...
...
@@ -37,6 +37,13 @@
#include "wine/strmbase.h"
#include "wine/list.h"
#define DECLARE_CRITICAL_SECTION(cs) \
static CRITICAL_SECTION cs; \
static CRITICAL_SECTION_DEBUG cs##_debug = \
{ 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \
0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \
static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
static
inline
const
char
*
debugstr_time
(
REFERENCE_TIME
time
)
{
ULONGLONG
abstime
=
time
>=
0
?
time
:
-
time
;
...
...
dlls/quartz/tests/filtergraph.c
View file @
0ad6d688
...
...
@@ -5213,10 +5213,11 @@ static void test_window_threading(void)
};
WCHAR
*
filename
=
load_resource
(
L"test.avi"
);
IFilterGraph2
*
graph
=
create_graph
();
HWND
hwnd
,
hwnd2
,
parent
;
IFilterGraph2
*
graph2
;
IVideoWindow
*
window
;
HWND
hwnd
,
parent
;
DWORD
tid
,
tid2
;
HRESULT
hr
;
DWORD
tid
;
ULONG
ref
;
BOOL
ret
;
...
...
@@ -5253,6 +5254,17 @@ static void test_window_threading(void)
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
IVideoWindow_Release
(
window
);
ok
(
!
(
GetWindowLongW
(
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_NOPARENTNOTIFY
),
"Window has WS_EX_NOPARENTNOTIFY.
\n
"
);
graph2
=
create_graph
();
hr
=
IFilterGraph2_RenderFile
(
graph2
,
filename
,
NULL
);
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
hwnd2
=
get_renderer_hwnd
(
graph
);
ok
(
!!
hwnd2
,
"Failed to get renderer window.
\n
"
);
tid2
=
GetWindowThreadProcessId
(
hwnd
,
NULL
);
ok
(
tid2
==
tid
,
"Expected thread to be shared.
\n
"
);
ref
=
IFilterGraph2_Release
(
graph2
);
ok
(
!
ref
,
"Got outstanding refcount %ld.
\n
"
,
ref
);
}
else
skip
(
"Could not find renderer window.
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment