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
eff5a7ae
Commit
eff5a7ae
authored
Mar 04, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 04, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mfplat: Implement media event queue.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2f166690
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
455 additions
and
86 deletions
+455
-86
main.c
dlls/mfplat/main.c
+259
-77
mfplat.c
dlls/mfplat/tests/mfplat.c
+193
-9
mferror.h
include/mferror.h
+1
-0
mfobjects.idl
include/mfobjects.idl
+2
-0
No files found.
dlls/mfplat/main.c
View file @
eff5a7ae
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include "wine/heap.h"
#include "wine/heap.h"
#include "wine/debug.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/unicode.h"
#include "wine/list.h"
#include "mfplat_private.h"
#include "mfplat_private.h"
...
@@ -2797,6 +2798,9 @@ static const IMFMediaEventVtbl mfmediaevent_vtbl =
...
@@ -2797,6 +2798,9 @@ static const IMFMediaEventVtbl mfmediaevent_vtbl =
mfmediaevent_GetValue
,
mfmediaevent_GetValue
,
};
};
/***********************************************************************
* MFCreateMediaEvent (mfplat.@)
*/
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
)
{
{
...
@@ -2824,141 +2828,316 @@ HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HR
...
@@ -2824,141 +2828,316 @@ HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HR
return
S_OK
;
return
S_OK
;
}
}
typedef
struct
_mfevent
queue
struct
event_
queue
{
{
IMFMediaEventQueue
IMFMediaEventQueue_iface
;
IMFMediaEventQueue
IMFMediaEventQueue_iface
;
LONG
ref
;
LONG
refcount
;
}
mfeventqueue
;
CRITICAL_SECTION
cs
;
CONDITION_VARIABLE
update_event
;
struct
list
events
;
BOOL
is_shut_down
;
IMFAsyncResult
*
subscriber
;
};
struct
queued_event
{
struct
list
entry
;
IMFMediaEvent
*
event
;
};
static
inline
mfevent
queue
*
impl_from_IMFMediaEventQueue
(
IMFMediaEventQueue
*
iface
)
static
inline
struct
event_
queue
*
impl_from_IMFMediaEventQueue
(
IMFMediaEventQueue
*
iface
)
{
{
return
CONTAINING_RECORD
(
iface
,
mfevent
queue
,
IMFMediaEventQueue_iface
);
return
CONTAINING_RECORD
(
iface
,
struct
event_
queue
,
IMFMediaEventQueue_iface
);
}
}
static
HRESULT
WINAPI
mfeventqueue_QueryInterface
(
IMFMediaEventQueue
*
iface
,
REFIID
riid
,
void
**
out
)
static
IMFMediaEvent
*
queue_pop_event
(
struct
event_queue
*
queue
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
list
*
head
=
list_head
(
&
queue
->
events
);
struct
queued_event
*
queued_event
;
IMFMediaEvent
*
event
;
TRACE
(
"(%p)->(%s %p)
\n
"
,
This
,
debugstr_guid
(
riid
),
out
);
if
(
!
head
)
return
NULL
;
if
(
IsEqualGUID
(
riid
,
&
IID_IUnknown
)
||
queued_event
=
LIST_ENTRY
(
head
,
struct
queued_event
,
entry
);
IsEqualGUID
(
riid
,
&
IID_IMFMediaEventQueue
))
event
=
queued_event
->
event
;
{
list_remove
(
&
queued_event
->
entry
);
*
out
=
&
This
->
IMFMediaEventQueue_iface
;
heap_free
(
queued_event
);
}
return
event
;
else
}
static
void
event_queue_cleanup
(
struct
event_queue
*
queue
)
{
IMFMediaEvent
*
event
;
while
((
event
=
queue_pop_event
(
queue
)))
IMFMediaEvent_Release
(
event
);
}
static
HRESULT
WINAPI
eventqueue_QueryInterface
(
IMFMediaEventQueue
*
iface
,
REFIID
riid
,
void
**
out
)
{
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
TRACE
(
"%p, %s, %p.
\n
"
,
iface
,
debugstr_guid
(
riid
),
out
);
if
(
IsEqualIID
(
riid
,
&
IID_IMFMediaEventQueue
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
{
FIXME
(
"(%s, %p)
\n
"
,
debugstr_guid
(
riid
),
out
)
;
*
out
=
&
queue
->
IMFMediaEventQueue_iface
;
*
out
=
NULL
;
IMFMediaEventQueue_AddRef
(
iface
)
;
return
E_NOINTERFACE
;
return
S_OK
;
}
}
IUnknown_AddRef
((
IUnknown
*
)
*
out
);
WARN
(
"Unsupported %s.
\n
"
,
debugstr_guid
(
riid
));
return
S_OK
;
*
out
=
NULL
;
return
E_NOINTERFACE
;
}
}
static
ULONG
WINAPI
mf
eventqueue_AddRef
(
IMFMediaEventQueue
*
iface
)
static
ULONG
WINAPI
eventqueue_AddRef
(
IMFMediaEventQueue
*
iface
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
ULONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
ULONG
ref
count
=
InterlockedIncrement
(
&
queue
->
refcount
);
TRACE
(
"
(%p) ref=%u
\n
"
,
This
,
ref
);
TRACE
(
"
%p, refcount %u.
\n
"
,
iface
,
refcount
);
return
ref
;
return
ref
count
;
}
}
static
ULONG
WINAPI
mf
eventqueue_Release
(
IMFMediaEventQueue
*
iface
)
static
ULONG
WINAPI
eventqueue_Release
(
IMFMediaEventQueue
*
iface
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
ULONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
ULONG
ref
count
=
InterlockedDecrement
(
&
queue
->
refcount
);
TRACE
(
"
(%p) ref=%u
\n
"
,
This
,
ref
);
TRACE
(
"
%p, refcount %u.
\n
"
,
queue
,
refcount
);
if
(
!
ref
)
if
(
!
ref
count
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
This
);
event_queue_cleanup
(
queue
);
DeleteCriticalSection
(
&
queue
->
cs
);
heap_free
(
queue
);
}
}
return
ref
;
return
ref
count
;
}
}
static
HRESULT
WINAPI
mf
eventqueue_GetEvent
(
IMFMediaEventQueue
*
iface
,
DWORD
flags
,
IMFMediaEvent
**
event
)
static
HRESULT
WINAPI
eventqueue_GetEvent
(
IMFMediaEventQueue
*
iface
,
DWORD
flags
,
IMFMediaEvent
**
event
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
HRESULT
hr
=
S_OK
;
FIXME
(
"%p, %p
\n
"
,
This
,
event
);
TRACE
(
"%p, %p.
\n
"
,
iface
,
event
);
return
E_NOTIMPL
;
EnterCriticalSection
(
&
queue
->
cs
);
if
(
queue
->
is_shut_down
)
hr
=
MF_E_SHUTDOWN
;
else
if
(
queue
->
subscriber
)
hr
=
MF_E_MULTIPLE_SUBSCRIBERS
;
else
{
if
(
flags
&
MF_EVENT_FLAG_NO_WAIT
)
{
if
(
!
(
*
event
=
queue_pop_event
(
queue
)))
hr
=
MF_E_NO_EVENTS_AVAILABLE
;
}
else
{
while
(
list_empty
(
&
queue
->
events
)
&&
!
queue
->
is_shut_down
)
{
SleepConditionVariableCS
(
&
queue
->
update_event
,
&
queue
->
cs
,
INFINITE
);
}
*
event
=
queue_pop_event
(
queue
);
if
(
queue
->
is_shut_down
)
hr
=
MF_E_SHUTDOWN
;
}
}
LeaveCriticalSection
(
&
queue
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
mfeventqueue_BeginGetEvent
(
IMFMediaEventQueue
*
iface
,
IMFAsyncCallback
*
callback
,
IUnknown
*
stat
e
)
static
void
queue_notify_subscriber
(
struct
event_queue
*
queu
e
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
if
(
list_empty
(
&
queue
->
events
)
||
!
queue
->
subscriber
)
return
;
FIXME
(
"%p, %p, %p
\n
"
,
This
,
callback
,
state
);
MFPutWorkItemEx
(
MFASYNC_CALLBACK_QUEUE_STANDARD
,
queue
->
subscriber
);
}
return
E_NOTIMPL
;
static
HRESULT
WINAPI
eventqueue_BeginGetEvent
(
IMFMediaEventQueue
*
iface
,
IMFAsyncCallback
*
callback
,
IUnknown
*
state
)
{
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
MFASYNCRESULT
*
result_data
=
(
MFASYNCRESULT
*
)
queue
->
subscriber
;
HRESULT
hr
;
TRACE
(
"%p, %p, %p.
\n
"
,
iface
,
callback
,
state
);
if
(
!
callback
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
queue
->
cs
);
if
(
queue
->
is_shut_down
)
hr
=
MF_E_SHUTDOWN
;
else
if
(
result_data
)
{
if
(
result_data
->
pCallback
==
callback
)
hr
=
IMFAsyncResult_GetStateNoAddRef
(
queue
->
subscriber
)
==
state
?
MF_S_MULTIPLE_BEGIN
:
MF_E_MULTIPLE_BEGIN
;
else
hr
=
MF_E_MULTIPLE_SUBSCRIBERS
;
}
else
{
hr
=
MFCreateAsyncResult
(
NULL
,
callback
,
state
,
&
queue
->
subscriber
);
if
(
SUCCEEDED
(
hr
))
queue_notify_subscriber
(
queue
);
}
LeaveCriticalSection
(
&
queue
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
mf
eventqueue_EndGetEvent
(
IMFMediaEventQueue
*
iface
,
IMFAsyncResult
*
result
,
IMFMediaEvent
**
event
)
static
HRESULT
WINAPI
eventqueue_EndGetEvent
(
IMFMediaEventQueue
*
iface
,
IMFAsyncResult
*
result
,
IMFMediaEvent
**
event
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
HRESULT
hr
=
E_FAIL
;
FIXME
(
"%p, %p, %p
\n
"
,
This
,
result
,
event
);
TRACE
(
"%p, %p, %p.
\n
"
,
iface
,
result
,
event
);
return
E_NOTIMPL
;
EnterCriticalSection
(
&
queue
->
cs
);
if
(
queue
->
is_shut_down
)
hr
=
MF_E_SHUTDOWN
;
else
if
(
queue
->
subscriber
==
result
)
{
*
event
=
queue_pop_event
(
queue
);
if
(
queue
->
subscriber
)
IMFAsyncResult_Release
(
queue
->
subscriber
);
queue
->
subscriber
=
NULL
;
hr
=
*
event
?
S_OK
:
E_FAIL
;
}
LeaveCriticalSection
(
&
queue
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
mfeventqueue_QueueEvent
(
IMFMediaEventQueue
*
ifac
e
,
IMFMediaEvent
*
event
)
static
HRESULT
eventqueue_queue_event
(
struct
event_queue
*
queu
e
,
IMFMediaEvent
*
event
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
queued_event
*
queued_event
;
HRESULT
hr
=
S_OK
;
queued_event
=
heap_alloc
(
sizeof
(
*
queued_event
));
if
(
!
queued_event
)
return
E_OUTOFMEMORY
;
FIXME
(
"%p, %p
\n
"
,
This
,
event
)
;
queued_event
->
event
=
event
;
return
E_NOTIMPL
;
EnterCriticalSection
(
&
queue
->
cs
);
if
(
queue
->
is_shut_down
)
hr
=
MF_E_SHUTDOWN
;
else
{
IMFMediaEvent_AddRef
(
queued_event
->
event
);
list_add_tail
(
&
queue
->
events
,
&
queued_event
->
entry
);
queue_notify_subscriber
(
queue
);
}
LeaveCriticalSection
(
&
queue
->
cs
);
if
(
FAILED
(
hr
))
heap_free
(
queued_event
);
WakeAllConditionVariable
(
&
queue
->
update_event
);
return
hr
;
}
}
static
HRESULT
WINAPI
mfeventqueue_QueueEventParamVar
(
IMFMediaEventQueue
*
iface
,
MediaEventType
met
,
static
HRESULT
WINAPI
eventqueue_QueueEvent
(
IMFMediaEventQueue
*
iface
,
IMFMediaEvent
*
event
)
REFGUID
type
,
HRESULT
status
,
const
PROPVARIANT
*
value
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
FIXME
(
"%p, %d, %s, 0x%08x, %p
\n
"
,
This
,
met
,
debugstr_guid
(
type
),
status
,
value
);
TRACE
(
"%p, %p.
\n
"
,
iface
,
event
);
return
E_NOTIMPL
;
return
eventqueue_queue_event
(
queue
,
event
)
;
}
}
static
HRESULT
WINAPI
mfeventqueue_QueueEventParamUnk
(
IMFMediaEventQueue
*
iface
,
MediaEventType
met
,
REFGUID
type
,
static
HRESULT
WINAPI
eventqueue_QueueEventParamVar
(
IMFMediaEventQueue
*
iface
,
MediaEventType
event_
type
,
HRESULT
status
,
IUnknown
*
unk
)
REFGUID
extended_type
,
HRESULT
status
,
const
PROPVARIANT
*
value
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
IMFMediaEvent
*
event
;
HRESULT
hr
;
FIXME
(
"%p, %d, %s, 0x%08x, %p
\n
"
,
This
,
met
,
debugstr_guid
(
type
),
status
,
unk
);
TRACE
(
"%p, %d, %s, %#x, %p
\n
"
,
iface
,
event_type
,
debugstr_guid
(
extended_type
),
status
,
value
);
return
E_NOTIMPL
;
if
(
FAILED
(
hr
=
MFCreateMediaEvent
(
event_type
,
extended_type
,
status
,
value
,
&
event
)))
return
hr
;
hr
=
eventqueue_queue_event
(
queue
,
event
);
IMFMediaEvent_Release
(
event
);
return
hr
;
}
}
static
HRESULT
WINAPI
mfeventqueue_Shutdown
(
IMFMediaEventQueue
*
iface
)
static
HRESULT
WINAPI
eventqueue_QueueEventParamUnk
(
IMFMediaEventQueue
*
iface
,
MediaEventType
event_type
,
REFGUID
extended_type
,
HRESULT
status
,
IUnknown
*
unk
)
{
{
mfeventqueue
*
This
=
impl_from_IMFMediaEventQueue
(
iface
);
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
IMFMediaEvent
*
event
;
PROPVARIANT
value
;
HRESULT
hr
;
FIXME
(
"%p
\n
"
,
This
);
TRACE
(
"%p, %d, %s, %#x, %p.
\n
"
,
iface
,
event_type
,
debugstr_guid
(
extended_type
),
status
,
unk
);
return
E_NOTIMPL
;
value
.
vt
=
VT_UNKNOWN
;
value
.
punkVal
=
unk
;
if
(
FAILED
(
hr
=
MFCreateMediaEvent
(
event_type
,
extended_type
,
status
,
&
value
,
&
event
)))
return
hr
;
hr
=
eventqueue_queue_event
(
queue
,
event
);
IMFMediaEvent_Release
(
event
);
return
hr
;
}
}
static
const
IMFMediaEventQueueVtbl
mfeventqueue_vtbl
=
static
HRESULT
WINAPI
eventqueue_Shutdown
(
IMFMediaEventQueue
*
iface
)
{
{
mfeventqueue_QueryInterface
,
struct
event_queue
*
queue
=
impl_from_IMFMediaEventQueue
(
iface
);
mfeventqueue_AddRef
,
mfeventqueue_Release
,
TRACE
(
"%p
\n
"
,
queue
);
mfeventqueue_GetEvent
,
mfeventqueue_BeginGetEvent
,
EnterCriticalSection
(
&
queue
->
cs
);
mfeventqueue_EndGetEvent
,
mfeventqueue_QueueEvent
,
if
(
!
queue
->
is_shut_down
)
mfeventqueue_QueueEventParamVar
,
{
mfeventqueue_QueueEventParamUnk
,
event_queue_cleanup
(
queue
);
mfeventqueue_Shutdown
queue
->
is_shut_down
=
TRUE
;
}
LeaveCriticalSection
(
&
queue
->
cs
);
WakeAllConditionVariable
(
&
queue
->
update_event
);
return
S_OK
;
}
static
const
IMFMediaEventQueueVtbl
eventqueuevtbl
=
{
eventqueue_QueryInterface
,
eventqueue_AddRef
,
eventqueue_Release
,
eventqueue_GetEvent
,
eventqueue_BeginGetEvent
,
eventqueue_EndGetEvent
,
eventqueue_QueueEvent
,
eventqueue_QueueEventParamVar
,
eventqueue_QueueEventParamUnk
,
eventqueue_Shutdown
};
};
/***********************************************************************
/***********************************************************************
...
@@ -2966,16 +3145,19 @@ static const IMFMediaEventQueueVtbl mfeventqueue_vtbl =
...
@@ -2966,16 +3145,19 @@ static const IMFMediaEventQueueVtbl mfeventqueue_vtbl =
*/
*/
HRESULT
WINAPI
MFCreateEventQueue
(
IMFMediaEventQueue
**
queue
)
HRESULT
WINAPI
MFCreateEventQueue
(
IMFMediaEventQueue
**
queue
)
{
{
mfevent
queue
*
object
;
struct
event_
queue
*
object
;
TRACE
(
"%p
\n
"
,
queue
);
TRACE
(
"%p
\n
"
,
queue
);
object
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
object
)
);
object
=
heap_alloc_zero
(
sizeof
(
*
object
)
);
if
(
!
object
)
if
(
!
object
)
return
E_OUTOFMEMORY
;
return
E_OUTOFMEMORY
;
object
->
ref
=
1
;
object
->
IMFMediaEventQueue_iface
.
lpVtbl
=
&
eventqueuevtbl
;
object
->
IMFMediaEventQueue_iface
.
lpVtbl
=
&
mfeventqueue_vtbl
;
object
->
refcount
=
1
;
list_init
(
&
object
->
events
);
InitializeCriticalSection
(
&
object
->
cs
);
InitializeConditionVariable
(
&
object
->
update_event
);
*
queue
=
&
object
->
IMFMediaEventQueue_iface
;
*
queue
=
&
object
->
IMFMediaEventQueue_iface
;
...
...
dlls/mfplat/tests/mfplat.c
View file @
eff5a7ae
...
@@ -36,6 +36,8 @@
...
@@ -36,6 +36,8 @@
#include "wine/test.h"
#include "wine/test.h"
static
BOOL
is_win8_plus
;
static
HRESULT
(
WINAPI
*
pMFCopyImage
)(
BYTE
*
dest
,
LONG
deststride
,
const
BYTE
*
src
,
LONG
srcstride
,
static
HRESULT
(
WINAPI
*
pMFCopyImage
)(
BYTE
*
dest
,
LONG
deststride
,
const
BYTE
*
src
,
LONG
srcstride
,
DWORD
width
,
DWORD
lines
);
DWORD
width
,
DWORD
lines
);
static
HRESULT
(
WINAPI
*
pMFCreateSourceResolver
)(
IMFSourceResolver
**
resolver
);
static
HRESULT
(
WINAPI
*
pMFCreateSourceResolver
)(
IMFSourceResolver
**
resolver
);
...
@@ -327,6 +329,8 @@ static void init_functions(void)
...
@@ -327,6 +329,8 @@ static void init_functions(void)
X
(
MFPutWaitingWorkItem
);
X
(
MFPutWaitingWorkItem
);
X
(
MFRemovePeriodicCallback
);
X
(
MFRemovePeriodicCallback
);
#undef X
#undef X
is_win8_plus
=
pMFPutWaitingWorkItem
!=
NULL
;
}
}
static
void
test_MFCreateMediaType
(
void
)
static
void
test_MFCreateMediaType
(
void
)
...
@@ -700,6 +704,17 @@ static void test_MFSample(void)
...
@@ -700,6 +704,17 @@ static void test_MFSample(void)
IMFSample_Release
(
sample
);
IMFSample_Release
(
sample
);
}
}
struct
test_callback
{
IMFAsyncCallback
IMFAsyncCallback_iface
;
HANDLE
event
;
};
static
struct
test_callback
*
impl_from_IMFAsyncCallback
(
IMFAsyncCallback
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
test_callback
,
IMFAsyncCallback_iface
);
}
static
HRESULT
WINAPI
testcallback_QueryInterface
(
IMFAsyncCallback
*
iface
,
REFIID
riid
,
void
**
obj
)
static
HRESULT
WINAPI
testcallback_QueryInterface
(
IMFAsyncCallback
*
iface
,
REFIID
riid
,
void
**
obj
)
{
{
if
(
IsEqualIID
(
riid
,
&
IID_IMFAsyncCallback
)
||
if
(
IsEqualIID
(
riid
,
&
IID_IMFAsyncCallback
)
||
...
@@ -732,7 +747,43 @@ static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD
...
@@ -732,7 +747,43 @@ static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD
static
HRESULT
WINAPI
testcallback_Invoke
(
IMFAsyncCallback
*
iface
,
IMFAsyncResult
*
result
)
static
HRESULT
WINAPI
testcallback_Invoke
(
IMFAsyncCallback
*
iface
,
IMFAsyncResult
*
result
)
{
{
struct
test_callback
*
callback
=
impl_from_IMFAsyncCallback
(
iface
);
IMFMediaEventQueue
*
queue
;
IUnknown
*
state
,
*
obj
;
HRESULT
hr
;
ok
(
result
!=
NULL
,
"Unexpected result object.
\n
"
);
ok
(
result
!=
NULL
,
"Unexpected result object.
\n
"
);
state
=
IMFAsyncResult_GetStateNoAddRef
(
result
);
if
(
state
&&
SUCCEEDED
(
IUnknown_QueryInterface
(
state
,
&
IID_IMFMediaEventQueue
,
(
void
**
)
&
queue
)))
{
IMFMediaEvent
*
event
;
if
(
is_win8_plus
)
{
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
MF_EVENT_FLAG_NO_WAIT
,
&
event
);
ok
(
hr
==
MF_E_MULTIPLE_SUBSCRIBERS
,
"Failed to get event, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
0
,
&
event
);
ok
(
hr
==
MF_E_MULTIPLE_SUBSCRIBERS
,
"Failed to get event, hr %#x.
\n
"
,
hr
);
}
hr
=
IMFMediaEventQueue_EndGetEvent
(
queue
,
result
,
&
event
);
ok
(
hr
==
S_OK
,
"Failed to finalize GetEvent, hr %#x.
\n
"
,
hr
);
hr
=
IMFAsyncResult_GetObject
(
result
,
&
obj
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
IMFMediaEvent_Release
(
event
);
hr
=
IMFMediaEventQueue_EndGetEvent
(
queue
,
result
,
&
event
);
ok
(
hr
==
E_FAIL
,
"Unexpected result, hr %#x.
\n
"
,
hr
);
IMFMediaEventQueue_Release
(
queue
);
SetEvent
(
callback
->
event
);
}
return
E_NOTIMPL
;
return
E_NOTIMPL
;
}
}
...
@@ -745,15 +796,23 @@ static const IMFAsyncCallbackVtbl testcallbackvtbl =
...
@@ -745,15 +796,23 @@ static const IMFAsyncCallbackVtbl testcallbackvtbl =
testcallback_Invoke
,
testcallback_Invoke
,
};
};
static
void
init_test_callback
(
struct
test_callback
*
callback
)
{
callback
->
IMFAsyncCallback_iface
.
lpVtbl
=
&
testcallbackvtbl
;
callback
->
event
=
NULL
;
}
static
void
test_MFCreateAsyncResult
(
void
)
static
void
test_MFCreateAsyncResult
(
void
)
{
{
IMFAsyncCallback
callback
=
{
&
testcallbackvtbl
};
IMFAsyncResult
*
result
,
*
result2
;
IMFAsyncResult
*
result
,
*
result2
;
struct
test_callback
callback
;
IUnknown
*
state
,
*
object
;
IUnknown
*
state
,
*
object
;
MFASYNCRESULT
*
data
;
MFASYNCRESULT
*
data
;
ULONG
refcount
;
ULONG
refcount
;
HRESULT
hr
;
HRESULT
hr
;
init_test_callback
(
&
callback
);
hr
=
MFCreateAsyncResult
(
NULL
,
NULL
,
NULL
,
NULL
);
hr
=
MFCreateAsyncResult
(
NULL
,
NULL
,
NULL
,
NULL
);
ok
(
FAILED
(
hr
),
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
FAILED
(
hr
),
"Unexpected hr %#x.
\n
"
,
hr
);
...
@@ -797,11 +856,11 @@ static void test_MFCreateAsyncResult(void)
...
@@ -797,11 +856,11 @@ static void test_MFCreateAsyncResult(void)
ok
(
state
==
NULL
,
"Unexpected state.
\n
"
);
ok
(
state
==
NULL
,
"Unexpected state.
\n
"
);
/* Object. */
/* Object. */
hr
=
MFCreateAsyncResult
((
IUnknown
*
)
result
,
&
callback
,
NULL
,
&
result2
);
hr
=
MFCreateAsyncResult
((
IUnknown
*
)
result
,
&
callback
.
IMFAsyncCallback_iface
,
NULL
,
&
result2
);
ok
(
hr
==
S_OK
,
"Failed to create object, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to create object, hr %#x.
\n
"
,
hr
);
data
=
(
MFASYNCRESULT
*
)
result2
;
data
=
(
MFASYNCRESULT
*
)
result2
;
ok
(
data
->
pCallback
==
&
callback
,
"Unexpected callback value.
\n
"
);
ok
(
data
->
pCallback
==
&
callback
.
IMFAsyncCallback_iface
,
"Unexpected callback value.
\n
"
);
ok
(
data
->
hrStatusResult
==
S_OK
,
"Unexpected status %#x.
\n
"
,
data
->
hrStatusResult
);
ok
(
data
->
hrStatusResult
==
S_OK
,
"Unexpected status %#x.
\n
"
,
data
->
hrStatusResult
);
ok
(
data
->
dwBytesTransferred
==
0
,
"Unexpected byte length %u.
\n
"
,
data
->
dwBytesTransferred
);
ok
(
data
->
dwBytesTransferred
==
0
,
"Unexpected byte length %u.
\n
"
,
data
->
dwBytesTransferred
);
ok
(
data
->
hEvent
==
NULL
,
"Unexpected event.
\n
"
);
ok
(
data
->
hEvent
==
NULL
,
"Unexpected event.
\n
"
);
...
@@ -815,11 +874,11 @@ static void test_MFCreateAsyncResult(void)
...
@@ -815,11 +874,11 @@ static void test_MFCreateAsyncResult(void)
IMFAsyncResult_Release
(
result2
);
IMFAsyncResult_Release
(
result2
);
/* State object. */
/* State object. */
hr
=
MFCreateAsyncResult
(
NULL
,
&
callback
,
(
IUnknown
*
)
result
,
&
result2
);
hr
=
MFCreateAsyncResult
(
NULL
,
&
callback
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
result
,
&
result2
);
ok
(
hr
==
S_OK
,
"Failed to create object, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to create object, hr %#x.
\n
"
,
hr
);
data
=
(
MFASYNCRESULT
*
)
result2
;
data
=
(
MFASYNCRESULT
*
)
result2
;
ok
(
data
->
pCallback
==
&
callback
,
"Unexpected callback value.
\n
"
);
ok
(
data
->
pCallback
==
&
callback
.
IMFAsyncCallback_iface
,
"Unexpected callback value.
\n
"
);
ok
(
data
->
hrStatusResult
==
S_OK
,
"Unexpected status %#x.
\n
"
,
data
->
hrStatusResult
);
ok
(
data
->
hrStatusResult
==
S_OK
,
"Unexpected status %#x.
\n
"
,
data
->
hrStatusResult
);
ok
(
data
->
dwBytesTransferred
==
0
,
"Unexpected byte length %u.
\n
"
,
data
->
dwBytesTransferred
);
ok
(
data
->
dwBytesTransferred
==
0
,
"Unexpected byte length %u.
\n
"
,
data
->
dwBytesTransferred
);
ok
(
data
->
hEvent
==
NULL
,
"Unexpected event.
\n
"
);
ok
(
data
->
hEvent
==
NULL
,
"Unexpected event.
\n
"
);
...
@@ -1096,15 +1155,17 @@ static void test_MFHeapAlloc(void)
...
@@ -1096,15 +1155,17 @@ static void test_MFHeapAlloc(void)
static
void
test_scheduled_items
(
void
)
static
void
test_scheduled_items
(
void
)
{
{
IMFAsyncCallback
callback
=
{
&
testcallbackvtbl
}
;
struct
test_callback
callback
;
IMFAsyncResult
*
result
;
IMFAsyncResult
*
result
;
MFWORKITEM_KEY
key
,
key2
;
MFWORKITEM_KEY
key
,
key2
;
HRESULT
hr
;
HRESULT
hr
;
init_test_callback
(
&
callback
);
hr
=
MFStartup
(
MF_VERSION
,
MFSTARTUP_FULL
);
hr
=
MFStartup
(
MF_VERSION
,
MFSTARTUP_FULL
);
ok
(
hr
==
S_OK
,
"Failed to start up, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to start up, hr %#x.
\n
"
,
hr
);
hr
=
MFScheduleWorkItem
(
&
callback
,
NULL
,
-
5000
,
&
key
);
hr
=
MFScheduleWorkItem
(
&
callback
.
IMFAsyncCallback_iface
,
NULL
,
-
5000
,
&
key
);
ok
(
hr
==
S_OK
,
"Failed to schedule item, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to schedule item, hr %#x.
\n
"
,
hr
);
hr
=
MFCancelWorkItem
(
key
);
hr
=
MFCancelWorkItem
(
key
);
...
@@ -1119,7 +1180,7 @@ static void test_scheduled_items(void)
...
@@ -1119,7 +1180,7 @@ static void test_scheduled_items(void)
return
;
return
;
}
}
hr
=
MFCreateAsyncResult
(
NULL
,
&
callback
,
NULL
,
&
result
);
hr
=
MFCreateAsyncResult
(
NULL
,
&
callback
.
IMFAsyncCallback_iface
,
NULL
,
&
result
);
ok
(
hr
==
S_OK
,
"Failed to create result, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to create result, hr %#x.
\n
"
,
hr
);
hr
=
pMFPutWaitingWorkItem
(
NULL
,
0
,
result
,
&
key
);
hr
=
pMFPutWaitingWorkItem
(
NULL
,
0
,
result
,
&
key
);
...
@@ -1136,7 +1197,7 @@ static void test_scheduled_items(void)
...
@@ -1136,7 +1197,7 @@ static void test_scheduled_items(void)
IMFAsyncResult_Release
(
result
);
IMFAsyncResult_Release
(
result
);
hr
=
MFScheduleWorkItem
(
&
callback
,
NULL
,
-
5000
,
&
key
);
hr
=
MFScheduleWorkItem
(
&
callback
.
IMFAsyncCallback_iface
,
NULL
,
-
5000
,
&
key
);
ok
(
hr
==
S_OK
,
"Failed to schedule item, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to schedule item, hr %#x.
\n
"
,
hr
);
hr
=
MFCancelWorkItem
(
key
);
hr
=
MFCancelWorkItem
(
key
);
...
@@ -1246,6 +1307,128 @@ static void test_periodic_callback(void)
...
@@ -1246,6 +1307,128 @@ static void test_periodic_callback(void)
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
}
}
static
void
test_event_queue
(
void
)
{
struct
test_callback
callback
,
callback2
;
IMFMediaEvent
*
event
,
*
event2
;
IMFMediaEventQueue
*
queue
;
IMFAsyncResult
*
result
;
HRESULT
hr
;
DWORD
ret
;
init_test_callback
(
&
callback
);
init_test_callback
(
&
callback2
);
hr
=
MFStartup
(
MF_VERSION
,
MFSTARTUP_FULL
);
ok
(
hr
==
S_OK
,
"Failed to start up, hr %#x.
\n
"
,
hr
);
hr
=
MFCreateEventQueue
(
&
queue
);
ok
(
hr
==
S_OK
,
"Failed to create event queue, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
MF_EVENT_FLAG_NO_WAIT
,
&
event
);
ok
(
hr
==
MF_E_NO_EVENTS_AVAILABLE
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
MFCreateMediaEvent
(
MEError
,
&
GUID_NULL
,
E_FAIL
,
NULL
,
&
event
);
ok
(
hr
==
S_OK
,
"Failed to create event object, hr %#x.
\n
"
,
hr
);
if
(
is_win8_plus
)
{
hr
=
IMFMediaEventQueue_QueueEvent
(
queue
,
event
);
ok
(
hr
==
S_OK
,
"Failed to queue event, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
MF_EVENT_FLAG_NO_WAIT
,
&
event2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
event2
==
event
,
"Unexpected event object.
\n
"
);
IMFMediaEvent_Release
(
event2
);
hr
=
IMFMediaEventQueue_QueueEvent
(
queue
,
event
);
ok
(
hr
==
S_OK
,
"Failed to queue event, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
0
,
&
event2
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
IMFMediaEvent_Release
(
event2
);
}
/* Async case. */
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
queue
);
ok
(
hr
==
S_OK
,
"Failed to Begin*, hr %#x.
\n
"
,
hr
);
/* Same callback, same state. */
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
queue
);
ok
(
hr
==
MF_S_MULTIPLE_BEGIN
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Same callback, different state. */
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
&
callback
);
ok
(
hr
==
MF_E_MULTIPLE_BEGIN
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Different callback, same state. */
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback2
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
queue
);
ok
(
hr
==
MF_E_MULTIPLE_SUBSCRIBERS
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Different callback, different state. */
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback2
.
IMFAsyncCallback_iface
,
(
IUnknown
*
)
&
callback
.
IMFAsyncCallback_iface
);
ok
(
hr
==
MF_E_MULTIPLE_SUBSCRIBERS
,
"Unexpected hr %#x.
\n
"
,
hr
);
callback
.
event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
hr
=
IMFMediaEventQueue_QueueEvent
(
queue
,
event
);
ok
(
hr
==
S_OK
,
"Failed to queue event, hr %#x.
\n
"
,
hr
);
ret
=
WaitForSingleObject
(
callback
.
event
,
100
);
ok
(
ret
==
WAIT_OBJECT_0
,
"Unexpected return value %#x.
\n
"
,
ret
);
CloseHandle
(
callback
.
event
);
IMFMediaEvent_Release
(
event
);
hr
=
MFCreateAsyncResult
(
NULL
,
&
callback
.
IMFAsyncCallback_iface
,
NULL
,
&
result
);
ok
(
hr
==
S_OK
,
"Failed to create result, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_EndGetEvent
(
queue
,
result
,
&
event
);
ok
(
hr
==
E_FAIL
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Shutdown behavior. */
hr
=
IMFMediaEventQueue_Shutdown
(
queue
);
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_GetEvent
(
queue
,
MF_EVENT_FLAG_NO_WAIT
,
&
event
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
MFCreateMediaEvent
(
MEError
,
&
GUID_NULL
,
E_FAIL
,
NULL
,
&
event
);
ok
(
hr
==
S_OK
,
"Failed to create event object, hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_QueueEvent
(
queue
,
event
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
IMFMediaEvent_Release
(
event
);
hr
=
IMFMediaEventQueue_QueueEventParamUnk
(
queue
,
MEError
,
&
GUID_NULL
,
E_FAIL
,
NULL
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_QueueEventParamVar
(
queue
,
MEError
,
&
GUID_NULL
,
E_FAIL
,
NULL
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
&
callback
.
IMFAsyncCallback_iface
,
NULL
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_BeginGetEvent
(
queue
,
NULL
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFMediaEventQueue_EndGetEvent
(
queue
,
result
,
&
event
);
ok
(
hr
==
MF_E_SHUTDOWN
,
"Unexpected hr %#x.
\n
"
,
hr
);
IMFAsyncResult_Release
(
result
);
/* Already shut down. */
hr
=
IMFMediaEventQueue_Shutdown
(
queue
);
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
IMFMediaEventQueue_Release
(
queue
);
hr
=
MFShutdown
();
ok
(
hr
==
S_OK
,
"Failed to shut down, hr %#x.
\n
"
,
hr
);
}
START_TEST
(
mfplat
)
START_TEST
(
mfplat
)
{
{
CoInitialize
(
NULL
);
CoInitialize
(
NULL
);
...
@@ -1270,6 +1453,7 @@ START_TEST(mfplat)
...
@@ -1270,6 +1453,7 @@ START_TEST(mfplat)
test_scheduled_items
();
test_scheduled_items
();
test_serial_queue
();
test_serial_queue
();
test_periodic_callback
();
test_periodic_callback
();
test_event_queue
();
CoUninitialize
();
CoUninitialize
();
}
}
include/mferror.h
View file @
eff5a7ae
...
@@ -66,6 +66,7 @@
...
@@ -66,6 +66,7 @@
#define MF_E_ATTRIBUTENOTFOUND _HRESULT_TYPEDEF_(0xc00d36e6)
#define MF_E_ATTRIBUTENOTFOUND _HRESULT_TYPEDEF_(0xc00d36e6)
#define MF_E_PROPERTY_TYPE_NOT_ALLOWED _HRESULT_TYPEDEF_(0xc00d36e7)
#define MF_E_PROPERTY_TYPE_NOT_ALLOWED _HRESULT_TYPEDEF_(0xc00d36e7)
#define MF_E_INVALID_WORKQUEUE _HRESULT_TYPEDEF_(0xc00d36ff)
#define MF_E_INVALID_WORKQUEUE _HRESULT_TYPEDEF_(0xc00d36ff)
#define MF_E_NO_EVENTS_AVAILABLE _HRESULT_TYPEDEF_(0xc00d3e80)
#define MF_E_SHUTDOWN _HRESULT_TYPEDEF_(0xc00d3e85)
#define MF_E_SHUTDOWN _HRESULT_TYPEDEF_(0xc00d3e85)
#define MF_E_TOPO_INVALID_OPTIONAL_NODE _HRESULT_TYPEDEF_(0xc00d520e)
#define MF_E_TOPO_INVALID_OPTIONAL_NODE _HRESULT_TYPEDEF_(0xc00d520e)
...
...
include/mfobjects.idl
View file @
eff5a7ae
...
@@ -553,6 +553,8 @@ interface IMFMediaEvent : IMFAttributes
...
@@ -553,6 +553,8 @@ interface IMFMediaEvent : IMFAttributes
HRESULT
GetValue
(
[
out
]
PROPVARIANT
*
pvValue
)
;
HRESULT
GetValue
(
[
out
]
PROPVARIANT
*
pvValue
)
;
}
}
cpp_quote
(
"#define MF_EVENT_FLAG_NO_WAIT 0x00000001"
)
[
[
object
,
object
,
uuid
(
2
cd0bd52
-
bcd5
-
4b89
-
b62c
-
eadc0c031e7d
)
uuid
(
2
cd0bd52
-
bcd5
-
4b89
-
b62c
-
eadc0c031e7d
)
...
...
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