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
c815f908
Commit
c815f908
authored
Mar 07, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 07, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mf: Control time source state from presentation clock.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7e955923
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
182 additions
and
9 deletions
+182
-9
session.c
dlls/mf/session.c
+113
-8
mf.c
dlls/mf/tests/mf.c
+67
-0
mferror.h
include/mferror.h
+2
-1
No files found.
dlls/mf/session.c
View file @
c815f908
...
@@ -47,6 +47,7 @@ struct presentation_clock
...
@@ -47,6 +47,7 @@ struct presentation_clock
IMFShutdown
IMFShutdown_iface
;
IMFShutdown
IMFShutdown_iface
;
LONG
refcount
;
LONG
refcount
;
IMFPresentationTimeSource
*
time_source
;
IMFPresentationTimeSource
*
time_source
;
IMFClockStateSink
*
time_source_sink
;
MFCLOCK_STATE
state
;
MFCLOCK_STATE
state
;
CRITICAL_SECTION
cs
;
CRITICAL_SECTION
cs
;
};
};
...
@@ -341,6 +342,8 @@ static ULONG WINAPI present_clock_Release(IMFPresentationClock *iface)
...
@@ -341,6 +342,8 @@ static ULONG WINAPI present_clock_Release(IMFPresentationClock *iface)
{
{
if
(
clock
->
time_source
)
if
(
clock
->
time_source
)
IMFPresentationTimeSource_Release
(
clock
->
time_source
);
IMFPresentationTimeSource_Release
(
clock
->
time_source
);
if
(
clock
->
time_source_sink
)
IMFClockStateSink_Release
(
clock
->
time_source_sink
);
DeleteCriticalSection
(
&
clock
->
cs
);
DeleteCriticalSection
(
&
clock
->
cs
);
heap_free
(
clock
);
heap_free
(
clock
);
}
}
...
@@ -395,9 +398,29 @@ static HRESULT WINAPI present_clock_GetProperties(IMFPresentationClock *iface, M
...
@@ -395,9 +398,29 @@ static HRESULT WINAPI present_clock_GetProperties(IMFPresentationClock *iface, M
static
HRESULT
WINAPI
present_clock_SetTimeSource
(
IMFPresentationClock
*
iface
,
static
HRESULT
WINAPI
present_clock_SetTimeSource
(
IMFPresentationClock
*
iface
,
IMFPresentationTimeSource
*
time_source
)
IMFPresentationTimeSource
*
time_source
)
{
{
FIXME
(
"%p, %p.
\n
"
,
iface
,
time_source
);
struct
presentation_clock
*
clock
=
impl_from_IMFPresentationClock
(
iface
);
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p, %p.
\n
"
,
iface
,
time_source
);
EnterCriticalSection
(
&
clock
->
cs
);
if
(
clock
->
time_source
)
IMFPresentationTimeSource_Release
(
clock
->
time_source
);
if
(
clock
->
time_source_sink
)
IMFClockStateSink_Release
(
clock
->
time_source_sink
);
clock
->
time_source
=
NULL
;
clock
->
time_source_sink
=
NULL
;
hr
=
IMFPresentationTimeSource_QueryInterface
(
time_source
,
&
IID_IMFClockStateSink
,
(
void
**
)
&
clock
->
time_source_sink
);
if
(
SUCCEEDED
(
hr
))
{
clock
->
time_source
=
time_source
;
IMFPresentationTimeSource_AddRef
(
clock
->
time_source
);
}
LeaveCriticalSection
(
&
clock
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
present_clock_GetTimeSource
(
IMFPresentationClock
*
iface
,
static
HRESULT
WINAPI
present_clock_GetTimeSource
(
IMFPresentationClock
*
iface
,
...
@@ -443,25 +466,107 @@ static HRESULT WINAPI present_clock_RemoveClockStateSink(IMFPresentationClock *i
...
@@ -443,25 +466,107 @@ static HRESULT WINAPI present_clock_RemoveClockStateSink(IMFPresentationClock *i
return
E_NOTIMPL
;
return
E_NOTIMPL
;
}
}
enum
clock_command
{
CLOCK_CMD_START
=
0
,
CLOCK_CMD_STOP
,
CLOCK_CMD_PAUSE
,
CLOCK_CMD_MAX
,
};
static
HRESULT
clock_change_state
(
struct
presentation_clock
*
clock
,
enum
clock_command
command
)
{
static
const
BYTE
state_change_is_allowed
[
MFCLOCK_STATE_PAUSED
+
1
][
CLOCK_CMD_MAX
]
=
{
/* S S* P */
/* INVALID */
{
1
,
1
,
1
},
/* RUNNING */
{
1
,
1
,
1
},
/* STOPPED */
{
1
,
1
,
0
},
/* PAUSED */
{
1
,
1
,
0
},
};
static
const
MFCLOCK_STATE
states
[
CLOCK_CMD_MAX
]
=
{
/* CLOCK_CMD_START */
MFCLOCK_STATE_RUNNING
,
/* CLOCK_CMD_STOP */
MFCLOCK_STATE_STOPPED
,
/* CLOCK_CMD_PAUSE */
MFCLOCK_STATE_PAUSED
,
};
HRESULT
hr
;
/* FIXME: use correct timestamps. */
if
(
clock
->
state
==
states
[
command
]
&&
clock
->
state
!=
MFCLOCK_STATE_RUNNING
)
return
MF_E_CLOCK_STATE_ALREADY_SET
;
if
(
!
state_change_is_allowed
[
clock
->
state
][
command
])
return
MF_E_INVALIDREQUEST
;
switch
(
command
)
{
case
CLOCK_CMD_START
:
if
(
clock
->
state
==
MFCLOCK_STATE_PAUSED
)
hr
=
IMFClockStateSink_OnClockRestart
(
clock
->
time_source_sink
,
0
);
else
hr
=
IMFClockStateSink_OnClockStart
(
clock
->
time_source_sink
,
0
,
0
);
break
;
case
CLOCK_CMD_STOP
:
hr
=
IMFClockStateSink_OnClockStop
(
clock
->
time_source_sink
,
0
);
break
;
case
CLOCK_CMD_PAUSE
:
hr
=
IMFClockStateSink_OnClockPause
(
clock
->
time_source_sink
,
0
);
break
;
default:
;
}
if
(
FAILED
(
hr
))
return
hr
;
clock
->
state
=
states
[
command
];
/* FIXME: notify registered sinks. */
return
S_OK
;
}
static
HRESULT
WINAPI
present_clock_Start
(
IMFPresentationClock
*
iface
,
LONGLONG
start_offset
)
static
HRESULT
WINAPI
present_clock_Start
(
IMFPresentationClock
*
iface
,
LONGLONG
start_offset
)
{
{
FIXME
(
"%p, %s.
\n
"
,
iface
,
wine_dbgstr_longlong
(
start_offset
));
struct
presentation_clock
*
clock
=
impl_from_IMFPresentationClock
(
iface
);
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p, %s.
\n
"
,
iface
,
wine_dbgstr_longlong
(
start_offset
));
EnterCriticalSection
(
&
clock
->
cs
);
hr
=
clock_change_state
(
clock
,
CLOCK_CMD_START
);
LeaveCriticalSection
(
&
clock
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
present_clock_Stop
(
IMFPresentationClock
*
iface
)
static
HRESULT
WINAPI
present_clock_Stop
(
IMFPresentationClock
*
iface
)
{
{
FIXME
(
"%p.
\n
"
,
iface
);
struct
presentation_clock
*
clock
=
impl_from_IMFPresentationClock
(
iface
);
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p.
\n
"
,
iface
);
EnterCriticalSection
(
&
clock
->
cs
);
hr
=
clock_change_state
(
clock
,
CLOCK_CMD_STOP
);
LeaveCriticalSection
(
&
clock
->
cs
);
return
hr
;
}
}
static
HRESULT
WINAPI
present_clock_Pause
(
IMFPresentationClock
*
iface
)
static
HRESULT
WINAPI
present_clock_Pause
(
IMFPresentationClock
*
iface
)
{
{
FIXME
(
"%p.
\n
"
,
iface
);
struct
presentation_clock
*
clock
=
impl_from_IMFPresentationClock
(
iface
);
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p.
\n
"
,
iface
);
EnterCriticalSection
(
&
clock
->
cs
);
hr
=
clock_change_state
(
clock
,
CLOCK_CMD_PAUSE
);
LeaveCriticalSection
(
&
clock
->
cs
);
return
hr
;
}
}
static
const
IMFPresentationClockVtbl
presentationclockvtbl
=
static
const
IMFPresentationClockVtbl
presentationclockvtbl
=
...
...
dlls/mf/tests/mf.c
View file @
c815f908
...
@@ -735,8 +735,37 @@ static void test_MFShutdownObject(void)
...
@@ -735,8 +735,37 @@ static void test_MFShutdownObject(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
);
}
}
enum
clock_action
{
CLOCK_START
,
CLOCK_STOP
,
CLOCK_PAUSE
,
};
static
void
test_presentation_clock
(
void
)
static
void
test_presentation_clock
(
void
)
{
{
static
const
struct
clock_state_test
{
enum
clock_action
action
;
MFCLOCK_STATE
clock_state
;
MFCLOCK_STATE
source_state
;
HRESULT
hr
;
}
clock_state_change
[]
=
{
{
CLOCK_STOP
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_INVALID
},
{
CLOCK_PAUSE
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_INVALID
,
MF_E_INVALIDREQUEST
},
{
CLOCK_STOP
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_INVALID
,
MF_E_CLOCK_STATE_ALREADY_SET
},
{
CLOCK_START
,
MFCLOCK_STATE_RUNNING
,
MFCLOCK_STATE_RUNNING
},
{
CLOCK_START
,
MFCLOCK_STATE_RUNNING
,
MFCLOCK_STATE_RUNNING
},
{
CLOCK_PAUSE
,
MFCLOCK_STATE_PAUSED
,
MFCLOCK_STATE_PAUSED
},
{
CLOCK_PAUSE
,
MFCLOCK_STATE_PAUSED
,
MFCLOCK_STATE_PAUSED
,
MF_E_CLOCK_STATE_ALREADY_SET
},
{
CLOCK_STOP
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_STOPPED
},
{
CLOCK_START
,
MFCLOCK_STATE_RUNNING
,
MFCLOCK_STATE_RUNNING
},
{
CLOCK_STOP
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_STOPPED
},
{
CLOCK_STOP
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_STOPPED
,
MF_E_CLOCK_STATE_ALREADY_SET
},
{
CLOCK_PAUSE
,
MFCLOCK_STATE_STOPPED
,
MFCLOCK_STATE_STOPPED
,
MF_E_INVALIDREQUEST
},
};
IMFPresentationTimeSource
*
time_source
;
IMFPresentationTimeSource
*
time_source
;
IMFRateControl
*
rate_control
;
IMFRateControl
*
rate_control
;
IMFPresentationClock
*
clock
;
IMFPresentationClock
*
clock
;
...
@@ -746,6 +775,7 @@ static void test_presentation_clock(void)
...
@@ -746,6 +775,7 @@ static void test_presentation_clock(void)
MFCLOCK_STATE
state
;
MFCLOCK_STATE
state
;
IMFTimer
*
timer
;
IMFTimer
*
timer
;
MFTIME
systime
;
MFTIME
systime
;
unsigned
int
i
;
DWORD
value
;
DWORD
value
;
HRESULT
hr
;
HRESULT
hr
;
...
@@ -779,6 +809,43 @@ todo_wine
...
@@ -779,6 +809,43 @@ todo_wine
todo_wine
todo_wine
ok
(
hr
==
MF_E_CLOCK_NO_TIME_SOURCE
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
hr
==
MF_E_CLOCK_NO_TIME_SOURCE
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Set default time source. */
hr
=
MFCreateSystemTimeSource
(
&
time_source
);
ok
(
hr
==
S_OK
,
"Failed to create time source, hr %#x.
\n
"
,
hr
);
hr
=
IMFPresentationClock_SetTimeSource
(
clock
,
time_source
);
ok
(
hr
==
S_OK
,
"Failed to set time source, hr %#x.
\n
"
,
hr
);
/* State changes. */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
clock_state_change
);
++
i
)
{
switch
(
clock_state_change
[
i
].
action
)
{
case
CLOCK_STOP
:
hr
=
IMFPresentationClock_Stop
(
clock
);
break
;
case
CLOCK_PAUSE
:
hr
=
IMFPresentationClock_Pause
(
clock
);
break
;
case
CLOCK_START
:
hr
=
IMFPresentationClock_Start
(
clock
,
0
);
break
;
default:
;
}
ok
(
hr
==
clock_state_change
[
i
].
hr
,
"%u: unexpected hr %#x.
\n
"
,
i
,
hr
);
hr
=
IMFPresentationTimeSource_GetState
(
time_source
,
0
,
&
state
);
ok
(
hr
==
S_OK
,
"%u: failed to get state, hr %#x.
\n
"
,
i
,
hr
);
ok
(
state
==
clock_state_change
[
i
].
source_state
,
"%u: unexpected state %d.
\n
"
,
i
,
state
);
hr
=
IMFPresentationClock_GetState
(
clock
,
0
,
&
state
);
ok
(
hr
==
S_OK
,
"%u: failed to get state, hr %#x.
\n
"
,
i
,
hr
);
ok
(
state
==
clock_state_change
[
i
].
clock_state
,
"%u: unexpected state %d.
\n
"
,
i
,
state
);
}
IMFPresentationTimeSource_Release
(
time_source
);
hr
=
IMFPresentationClock_QueryInterface
(
clock
,
&
IID_IMFRateControl
,
(
void
**
)
&
rate_control
);
hr
=
IMFPresentationClock_QueryInterface
(
clock
,
&
IID_IMFRateControl
,
(
void
**
)
&
rate_control
);
ok
(
hr
==
S_OK
,
"Failed to get rate control interface, hr %#x.
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"Failed to get rate control interface, hr %#x.
\n
"
,
hr
);
IMFRateControl_Release
(
rate_control
);
IMFRateControl_Release
(
rate_control
);
...
...
include/mferror.h
View file @
c815f908
...
@@ -82,6 +82,7 @@
...
@@ -82,6 +82,7 @@
#define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a)
#define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a)
#define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
#define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
#define MF_E_CLOCK_NO_TIME_SOURCE _HRESULT_TYPEDEF_(0xc00d9c41)
#define MF_E_CLOCK_NO_TIME_SOURCE _HRESULT_TYPEDEF_(0xc00d9c41)
#define MF_E_CLOCK_STATE_ALREADY_SET _HRESULT_TYPEDEF_(0xc00d9c42)
#endif
/* __WINE_MFERROR_H */
#endif
/* __WINE_MFERROR_H */
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