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
0b8b0021
Commit
0b8b0021
authored
Oct 06, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
Oct 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
evr/mixer: Keep per-stream output rectangles.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
adc4dd67
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
190 additions
and
43 deletions
+190
-43
mixer.c
dlls/evr/mixer.c
+59
-24
evr.c
dlls/evr/tests/evr.c
+131
-19
No files found.
dlls/evr/mixer.c
View file @
0b8b0021
...
...
@@ -41,6 +41,7 @@ struct input_stream
unsigned
int
id
;
IMFAttributes
*
attributes
;
IMFVideoMediaType
*
media_type
;
MFVideoNormalizedRect
rect
;
};
struct
output_stream
...
...
@@ -145,15 +146,18 @@ static int video_mixer_compare_input_id(const void *a, const void *b)
return
0
;
}
static
struct
input_stream
*
video_mixer_get_input
(
const
struct
video_mixer
*
mixer
,
unsigned
int
id
)
static
HRESULT
video_mixer_get_input
(
const
struct
video_mixer
*
mixer
,
unsigned
int
id
,
struct
input_stream
**
stream
)
{
return
bsearch
(
&
id
,
mixer
->
inputs
,
mixer
->
input_count
,
sizeof
(
*
mixer
->
inputs
),
video_mixer_compare_input_id
);
*
stream
=
bsearch
(
&
id
,
mixer
->
inputs
,
mixer
->
input_count
,
sizeof
(
*
mixer
->
inputs
),
video_mixer_compare_input_id
);
return
*
stream
?
S_OK
:
MF_E_INVALIDSTREAMNUMBER
;
}
static
void
video_mixer_init_input
(
struct
input_stream
*
stream
)
{
if
(
SUCCEEDED
(
MFCreateAttributes
(
&
stream
->
attributes
,
1
)))
IMFAttributes_SetUINT32
(
stream
->
attributes
,
&
MF_SA_REQUIRED_SAMPLE_COUNT
,
1
);
stream
->
rect
.
left
=
stream
->
rect
.
top
=
0
.
0
f
;
stream
->
rect
.
right
=
stream
->
rect
.
bottom
=
1
.
0
f
;
}
static
void
video_mixer_clear_types
(
struct
video_mixer
*
mixer
)
...
...
@@ -352,19 +356,19 @@ static HRESULT WINAPI video_mixer_transform_GetInputStreamInfo(IMFTransform *ifa
{
struct
video_mixer
*
mixer
=
impl_from_IMFTransform
(
iface
);
struct
input_stream
*
input
;
HRESULT
hr
=
S_OK
;
HRESULT
hr
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
id
,
info
);
EnterCriticalSection
(
&
mixer
->
cs
);
if
(
!
(
input
=
video_mixer_get_input
(
mixer
,
id
)))
hr
=
MF_E_INVALIDSTREAMNUMBER
;
else
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
input
)))
{
memset
(
info
,
0
,
sizeof
(
*
info
));
if
(
id
)
info
->
dwFlags
|=
MFT_INPUT_STREAM_REMOVABLE
|
MFT_INPUT_STREAM_OPTIONAL
;
}
LeaveCriticalSection
(
&
mixer
->
cs
);
return
hr
;
...
...
@@ -402,15 +406,13 @@ static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransfor
{
struct
video_mixer
*
mixer
=
impl_from_IMFTransform
(
iface
);
struct
input_stream
*
input
;
HRESULT
hr
=
S_OK
;
HRESULT
hr
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
id
,
attributes
);
EnterCriticalSection
(
&
mixer
->
cs
);
if
(
!
(
input
=
video_mixer_get_input
(
mixer
,
id
)))
hr
=
MF_E_INVALIDSTREAMNUMBER
;
else
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
input
)))
{
*
attributes
=
input
->
attributes
;
if
(
*
attributes
)
...
...
@@ -434,17 +436,18 @@ static HRESULT WINAPI video_mixer_transform_DeleteInputStream(IMFTransform *ifac
{
struct
video_mixer
*
mixer
=
impl_from_IMFTransform
(
iface
);
struct
input_stream
*
input
;
HRESULT
hr
=
S_OK
;
unsigned
int
idx
;
HRESULT
hr
;
TRACE
(
"%p, %u.
\n
"
,
iface
,
id
);
if
(
!
id
)
return
MF_E_INVALIDSTREAMNUMBER
;
EnterCriticalSection
(
&
mixer
->
cs
);
/* Can't delete reference stream. */
if
(
!
id
||
!
(
input
=
video_mixer_get_input
(
mixer
,
id
)))
hr
=
MF_E_INVALIDSTREAMNUMBER
;
else
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
input
)))
{
mixer
->
input_count
--
;
idx
=
input
-
mixer
->
inputs
;
...
...
@@ -736,13 +739,13 @@ static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *if
{
struct
video_mixer
*
mixer
=
impl_from_IMFTransform
(
iface
);
struct
input_stream
*
stream
;
HRESULT
hr
=
S_OK
;
HRESULT
hr
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
id
,
type
);
EnterCriticalSection
(
&
mixer
->
cs
);
if
(
(
stream
=
video_mixer_get_input
(
mixer
,
id
)))
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
stream
)))
{
if
(
!
stream
->
media_type
)
hr
=
MF_E_TRANSFORM_TYPE_NOT_SET
;
...
...
@@ -752,8 +755,6 @@ static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *if
IMFMediaType_AddRef
(
*
type
);
}
}
else
hr
=
MF_E_INVALIDSTREAMNUMBER
;
LeaveCriticalSection
(
&
mixer
->
cs
);
...
...
@@ -1029,20 +1030,54 @@ static HRESULT WINAPI video_mixer_control_GetStreamZOrder(IMFVideoMixerControl2
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
video_mixer_control_SetStreamOutputRect
(
IMFVideoMixerControl2
*
iface
,
DWORD
stream_
id
,
static
HRESULT
WINAPI
video_mixer_control_SetStreamOutputRect
(
IMFVideoMixerControl2
*
iface
,
DWORD
id
,
const
MFVideoNormalizedRect
*
rect
)
{
FIXME
(
"%p, %u, %p.
\n
"
,
iface
,
stream_id
,
rect
);
struct
video_mixer
*
mixer
=
impl_from_IMFVideoMixerControl2
(
iface
);
struct
input_stream
*
stream
;
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
id
,
rect
);
if
(
!
rect
)
return
E_POINTER
;
if
(
rect
->
left
>
rect
->
right
||
rect
->
top
>
rect
->
bottom
||
rect
->
left
<
0
.
0
f
||
rect
->
top
<
0
.
0
f
||
rect
->
right
>
1
.
0
f
||
rect
->
bottom
>
1
.
0
f
)
{
return
E_INVALIDARG
;
}
EnterCriticalSection
(
&
mixer
->
cs
);
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
stream
)))
stream
->
rect
=
*
rect
;
LeaveCriticalSection
(
&
mixer
->
cs
);
return
hr
;
}
static
HRESULT
WINAPI
video_mixer_control_GetStreamOutputRect
(
IMFVideoMixerControl2
*
iface
,
DWORD
stream_
id
,
static
HRESULT
WINAPI
video_mixer_control_GetStreamOutputRect
(
IMFVideoMixerControl2
*
iface
,
DWORD
id
,
MFVideoNormalizedRect
*
rect
)
{
FIXME
(
"%p, %u, %p.
\n
"
,
iface
,
stream_id
,
rect
);
struct
video_mixer
*
mixer
=
impl_from_IMFVideoMixerControl2
(
iface
);
struct
input_stream
*
stream
;
HRESULT
hr
;
return
E_NOTIMPL
;
TRACE
(
"%p, %u, %p.
\n
"
,
iface
,
id
,
rect
);
if
(
!
rect
)
return
E_POINTER
;
EnterCriticalSection
(
&
mixer
->
cs
);
if
(
SUCCEEDED
(
hr
=
video_mixer_get_input
(
mixer
,
id
,
&
stream
)))
*
rect
=
stream
->
rect
;
LeaveCriticalSection
(
&
mixer
->
cs
);
return
hr
;
}
static
HRESULT
WINAPI
video_mixer_control_SetMixingPrefs
(
IMFVideoMixerControl2
*
iface
,
DWORD
flags
)
...
...
dlls/evr/tests/evr.c
View file @
0b8b0021
...
...
@@ -33,6 +33,14 @@ static const WCHAR sink_id[] = {'E','V','R',' ','I','n','p','u','t','0',0};
static
HRESULT
(
WINAPI
*
pMFCreateVideoMediaTypeFromSubtype
)(
const
GUID
*
subtype
,
IMFVideoMediaType
**
video_type
);
static
void
set_rect
(
MFVideoNormalizedRect
*
rect
,
float
left
,
float
top
,
float
right
,
float
bottom
)
{
rect
->
left
=
left
;
rect
->
top
=
top
;
rect
->
right
=
right
;
rect
->
bottom
=
bottom
;
}
static
HWND
create_window
(
void
)
{
RECT
r
=
{
0
,
0
,
640
,
480
};
...
...
@@ -1483,38 +1491,24 @@ static void test_presenter_video_position(void)
ok
(
dst_rect
.
left
==
0
&&
dst_rect
.
right
==
10
&&
dst_rect
.
top
==
0
&&
dst_rect
.
bottom
==
10
,
"Unexpected destination rectangle %s.
\n
"
,
wine_dbgstr_rect
(
&
dst_rect
));
src_rect
.
left
=
src_rect
.
top
=
0
.
0
f
;
src_rect
.
right
=
2
.
0
f
;
src_rect
.
bottom
=
1
.
0
f
;
set_rect
(
&
src_rect
,
0
.
0
f
,
0
.
0
f
,
2
.
0
f
,
1
.
0
f
);
hr
=
IMFVideoDisplayControl_SetVideoPosition
(
display_control
,
&
src_rect
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
src_rect
.
left
=
-
0
.
1
f
;
src_rect
.
top
=
0
.
0
f
;
src_rect
.
right
=
0
.
9
f
;
src_rect
.
bottom
=
1
.
0
f
;
set_rect
(
&
src_rect
,
-
0
.
1
f
,
0
.
0
f
,
0
.
9
f
,
1
.
0
f
);
hr
=
IMFVideoDisplayControl_SetVideoPosition
(
display_control
,
&
src_rect
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Flipped source rectangle. */
src_rect
.
left
=
0
.
5
f
;
src_rect
.
top
=
0
.
0
f
;
src_rect
.
right
=
0
.
4
f
;
src_rect
.
bottom
=
1
.
0
f
;
set_rect
(
&
src_rect
,
0
.
5
f
,
0
.
0
f
,
0
.
4
f
,
1
.
0
f
);
hr
=
IMFVideoDisplayControl_SetVideoPosition
(
display_control
,
&
src_rect
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
src_rect
.
left
=
0
.
0
f
;
src_rect
.
top
=
0
.
5
f
;
src_rect
.
right
=
0
.
4
f
;
src_rect
.
bottom
=
0
.
1
f
;
set_rect
(
&
src_rect
,
0
.
0
f
,
0
.
5
f
,
0
.
4
f
,
0
.
1
f
);
hr
=
IMFVideoDisplayControl_SetVideoPosition
(
display_control
,
&
src_rect
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
src_rect
.
left
=
0
.
1
f
;
src_rect
.
top
=
0
.
2
f
;
src_rect
.
right
=
0
.
8
f
;
src_rect
.
bottom
=
0
.
9
f
;
set_rect
(
&
src_rect
,
0
.
1
f
,
0
.
2
f
,
0
.
8
f
,
0
.
9
f
);
hr
=
IMFVideoDisplayControl_SetVideoPosition
(
display_control
,
&
src_rect
,
NULL
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
...
...
@@ -1559,6 +1553,122 @@ static void test_presenter_video_position(void)
DestroyWindow
(
hwnd
);
}
static
void
test_presenter_native_video_size
(
void
)
{
IMFTopologyServiceLookupClient
*
lookup_client
;
IMFVideoDisplayControl
*
display_control
;
IMFVideoPresenter
*
presenter
;
struct
test_host
host
;
IMFTransform
*
mixer
;
SIZE
size
,
ratio
;
HRESULT
hr
;
hr
=
MFCreateVideoMixer
(
NULL
,
&
IID_IDirect3DDevice9
,
&
IID_IMFTransform
,
(
void
**
)
&
mixer
);
ok
(
hr
==
S_OK
,
"Failed to create a mixer, hr %#x.
\n
"
,
hr
);
hr
=
MFCreateVideoPresenter
(
NULL
,
&
IID_IDirect3DDevice9
,
&
IID_IMFVideoPresenter
,
(
void
**
)
&
presenter
);
ok
(
hr
==
S_OK
,
"Failed to create default presenter, hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoPresenter_QueryInterface
(
presenter
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoPresenter_QueryInterface
(
presenter
,
&
IID_IMFVideoDisplayControl
,
(
void
**
)
&
display_control
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoDisplayControl_GetNativeVideoSize
(
display_control
,
NULL
,
NULL
);
todo_wine
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
memset
(
&
size
,
0xcc
,
sizeof
(
size
));
hr
=
IMFVideoDisplayControl_GetNativeVideoSize
(
display_control
,
&
size
,
NULL
);
todo_wine
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
size
.
cx
==
0
&&
size
.
cy
==
0
,
"Unexpected size.
\n
"
);
}
memset
(
&
ratio
,
0xcc
,
sizeof
(
ratio
));
hr
=
IMFVideoDisplayControl_GetNativeVideoSize
(
display_control
,
NULL
,
&
ratio
);
todo_wine
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
ratio
.
cx
==
0
&&
ratio
.
cy
==
0
,
"Unexpected ratio.
\n
"
);
}
hr
=
IMFVideoPresenter_QueryInterface
(
presenter
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
init_test_host
(
&
host
,
mixer
,
presenter
);
hr
=
IMFTopologyServiceLookupClient_InitServicePointers
(
lookup_client
,
&
host
.
IMFTopologyServiceLookup_iface
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoDisplayControl_GetNativeVideoSize
(
display_control
,
&
size
,
&
ratio
);
todo_wine
{
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
ok
(
size
.
cx
==
0
&&
size
.
cy
==
0
,
"Unexpected size.
\n
"
);
ok
(
ratio
.
cx
==
0
&&
ratio
.
cy
==
0
,
"Unexpected ratio.
\n
"
);
}
IMFVideoDisplayControl_Release
(
display_control
);
IMFVideoPresenter_Release
(
presenter
);
IMFTransform_Release
(
mixer
);
}
static
void
test_mixer_output_rectangle
(
void
)
{
IMFVideoMixerControl
*
mixer_control
;
MFVideoNormalizedRect
rect
;
IMFTransform
*
mixer
;
HRESULT
hr
;
hr
=
MFCreateVideoMixer
(
NULL
,
&
IID_IDirect3DDevice9
,
&
IID_IMFTransform
,
(
void
**
)
&
mixer
);
ok
(
hr
==
S_OK
,
"Failed to create a mixer, hr %#x.
\n
"
,
hr
);
hr
=
IMFTransform_QueryInterface
(
mixer
,
&
IID_IMFVideoMixerControl
,
(
void
**
)
&
mixer_control
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoMixerControl_GetStreamOutputRect
(
mixer_control
,
0
,
NULL
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
set_rect
(
&
rect
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
,
0
.
0
f
);
hr
=
IMFVideoMixerControl_GetStreamOutputRect
(
mixer_control
,
0
,
&
rect
);
ok
(
hr
==
S_OK
,
"Failed to get output rect, hr %#x.
\n
"
,
hr
);
ok
(
rect
.
left
==
0
.
0
f
&&
rect
.
top
==
0
.
0
f
&&
rect
.
right
==
1
.
0
f
&&
rect
.
bottom
==
1
.
0
f
,
"Unexpected rectangle.
\n
"
);
hr
=
IMFVideoMixerControl_GetStreamOutputRect
(
mixer_control
,
1
,
&
rect
);
ok
(
hr
==
MF_E_INVALIDSTREAMNUMBER
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoMixerControl_GetStreamOutputRect
(
mixer_control
,
1
,
NULL
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
1
,
&
rect
);
ok
(
hr
==
MF_E_INVALIDSTREAMNUMBER
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
1
,
NULL
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Wrong bounds. */
set_rect
(
&
rect
,
0
.
0
f
,
0
.
0
f
,
1
.
1
f
,
1
.
0
f
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
0
,
&
rect
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
set_rect
(
&
rect
,
-
0
.
1
f
,
0
.
0
f
,
0
.
5
f
,
1
.
0
f
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
0
,
&
rect
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
/* Flipped. */
set_rect
(
&
rect
,
1
.
0
f
,
0
.
0
f
,
0
.
0
f
,
1
.
0
f
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
0
,
&
rect
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
set_rect
(
&
rect
,
0
.
0
f
,
1
.
0
f
,
1
.
0
f
,
0
.
5
f
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
0
,
&
rect
);
ok
(
hr
==
E_INVALIDARG
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFVideoMixerControl_SetStreamOutputRect
(
mixer_control
,
0
,
NULL
);
ok
(
hr
==
E_POINTER
,
"Unexpected hr %#x.
\n
"
,
hr
);
IMFVideoMixerControl_Release
(
mixer_control
);
IMFTransform_Release
(
mixer
);
}
START_TEST
(
evr
)
{
CoInitialize
(
NULL
);
...
...
@@ -1577,6 +1687,8 @@ START_TEST(evr)
test_MFCreateVideoMixerAndPresenter
();
test_MFCreateVideoSampleAllocator
();
test_presenter_video_position
();
test_presenter_native_video_size
();
test_mixer_output_rectangle
();
CoUninitialize
();
}
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