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
f143af50
Commit
f143af50
authored
Aug 29, 2022
by
Nikolay Sivov
Committed by
Alexandre Julliard
Aug 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
evr/filter: Implement media type testing for QueryAccept().
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
parent
4d7b3c78
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
213 additions
and
4 deletions
+213
-4
evr.c
dlls/evr/evr.c
+159
-4
evr.c
dlls/evr/tests/evr.c
+54
-0
No files found.
dlls/evr/evr.c
View file @
f143af50
...
...
@@ -25,12 +25,20 @@
#include "evr_private.h"
#include "d3d9.h"
#include "mferror.h"
#include "mfapi.h"
#include "initguid.h"
#include "dxva2api.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
evr
);
enum
evr_flags
{
EVR_INIT_SERVICES
=
0x1
,
/* Currently in InitServices() call. */
EVR_MIXER_INITED_SERVICES
=
0x2
,
EVR_PRESENTER_INITED_SERVICES
=
0x4
,
};
struct
evr
{
struct
strmbase_renderer
renderer
;
...
...
@@ -43,6 +51,7 @@ struct evr
IMFTransform
*
mixer
;
IMFVideoPresenter
*
presenter
;
unsigned
int
flags
;
};
static
void
evr_uninitialize
(
struct
evr
*
filter
)
...
...
@@ -125,6 +134,96 @@ static HRESULT evr_query_interface(struct strmbase_renderer *iface, REFIID iid,
return
S_OK
;
}
static
BOOL
evr_is_mixer_d3d_aware
(
const
struct
evr
*
filter
)
{
IMFAttributes
*
attributes
;
unsigned
int
value
=
0
;
BOOL
ret
;
if
(
FAILED
(
IMFTransform_QueryInterface
(
filter
->
mixer
,
&
IID_IMFAttributes
,
(
void
**
)
&
attributes
)))
return
FALSE
;
ret
=
SUCCEEDED
(
IMFAttributes_GetUINT32
(
attributes
,
&
MF_SA_D3D_AWARE
,
&
value
))
&&
value
;
IMFAttributes_Release
(
attributes
);
return
ret
;
}
static
HRESULT
evr_init_services
(
struct
evr
*
filter
)
{
IMFTopologyServiceLookupClient
*
lookup_client
;
HRESULT
hr
;
if
(
SUCCEEDED
(
hr
=
IMFTransform_QueryInterface
(
filter
->
mixer
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
)))
{
filter
->
flags
|=
EVR_INIT_SERVICES
;
if
(
SUCCEEDED
(
hr
=
IMFTopologyServiceLookupClient_InitServicePointers
(
lookup_client
,
&
filter
->
IMFTopologyServiceLookup_iface
)))
{
filter
->
flags
|=
EVR_MIXER_INITED_SERVICES
;
}
filter
->
flags
&=
~
EVR_INIT_SERVICES
;
IMFTopologyServiceLookupClient_Release
(
lookup_client
);
}
if
(
FAILED
(
hr
))
return
hr
;
/* Set device manager that presenter should have created. */
if
(
evr_is_mixer_d3d_aware
(
filter
))
{
IUnknown
*
device_manager
;
IMFGetService
*
gs
;
if
(
SUCCEEDED
(
IUnknown_QueryInterface
(
filter
->
presenter
,
&
IID_IMFGetService
,
(
void
**
)
&
gs
)))
{
if
(
SUCCEEDED
(
IMFGetService_GetService
(
gs
,
&
MR_VIDEO_RENDER_SERVICE
,
&
IID_IDirect3DDeviceManager9
,
(
void
**
)
&
device_manager
)))
{
IMFTransform_ProcessMessage
(
filter
->
mixer
,
MFT_MESSAGE_SET_D3D_MANAGER
,
(
ULONG_PTR
)
device_manager
);
IUnknown_Release
(
device_manager
);
}
IMFGetService_Release
(
gs
);
}
}
if
(
SUCCEEDED
(
hr
=
IMFVideoPresenter_QueryInterface
(
filter
->
presenter
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
)))
{
filter
->
flags
|=
EVR_INIT_SERVICES
;
if
(
SUCCEEDED
(
hr
=
IMFTopologyServiceLookupClient_InitServicePointers
(
lookup_client
,
&
filter
->
IMFTopologyServiceLookup_iface
)))
{
filter
->
flags
|=
EVR_PRESENTER_INITED_SERVICES
;
}
filter
->
flags
&=
~
EVR_INIT_SERVICES
;
IMFTopologyServiceLookupClient_Release
(
lookup_client
);
}
return
hr
;
}
static
void
evr_release_services
(
struct
evr
*
filter
)
{
IMFTopologyServiceLookupClient
*
lookup_client
;
if
(
filter
->
flags
&
EVR_MIXER_INITED_SERVICES
&&
SUCCEEDED
(
IMFTransform_QueryInterface
(
filter
->
mixer
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
)))
{
IMFTopologyServiceLookupClient_ReleaseServicePointers
(
lookup_client
);
IMFTopologyServiceLookupClient_Release
(
lookup_client
);
filter
->
flags
&=
~
EVR_MIXER_INITED_SERVICES
;
}
if
(
filter
->
flags
&
EVR_PRESENTER_INITED_SERVICES
&&
SUCCEEDED
(
IMFVideoPresenter_QueryInterface
(
filter
->
presenter
,
&
IID_IMFTopologyServiceLookupClient
,
(
void
**
)
&
lookup_client
)))
{
IMFTopologyServiceLookupClient_ReleaseServicePointers
(
lookup_client
);
IMFTopologyServiceLookupClient_Release
(
lookup_client
);
filter
->
flags
&=
~
EVR_PRESENTER_INITED_SERVICES
;
}
}
static
void
evr_destroy
(
struct
strmbase_renderer
*
iface
)
{
struct
evr
*
filter
=
impl_from_strmbase_renderer
(
iface
);
...
...
@@ -142,8 +241,37 @@ static HRESULT evr_render(struct strmbase_renderer *iface, IMediaSample *sample)
static
HRESULT
evr_query_accept
(
struct
strmbase_renderer
*
iface
,
const
AM_MEDIA_TYPE
*
mt
)
{
FIXME
(
"Not implemented.
\n
"
);
return
E_NOTIMPL
;
struct
evr
*
filter
=
impl_from_strmbase_renderer
(
iface
);
IMFMediaType
*
media_type
;
HRESULT
hr
=
S_OK
;
EnterCriticalSection
(
&
filter
->
renderer
.
filter
.
filter_cs
);
if
(
!
filter
->
presenter
)
hr
=
evr_initialize
(
filter
,
NULL
,
NULL
);
if
(
SUCCEEDED
(
hr
))
hr
=
evr_init_services
(
filter
);
if
(
SUCCEEDED
(
hr
))
hr
=
MFCreateMediaType
(
&
media_type
);
if
(
SUCCEEDED
(
hr
))
{
if
(
SUCCEEDED
(
hr
=
MFInitMediaTypeFromAMMediaType
(
media_type
,
mt
)))
{
/* TODO: some pin -> mixer input mapping is necessary to test the substreams. */
hr
=
IMFTransform_SetInputType
(
filter
->
mixer
,
0
,
media_type
,
MFT_SET_TYPE_TEST_ONLY
);
}
IMFMediaType_Release
(
media_type
);
evr_release_services
(
filter
);
}
LeaveCriticalSection
(
&
filter
->
renderer
.
filter
.
filter_cs
);
return
hr
;
}
static
const
struct
strmbase_renderer_ops
renderer_ops
=
...
...
@@ -419,10 +547,37 @@ static ULONG WINAPI filter_service_lookup_Release(IMFTopologyServiceLookup *ifac
static
HRESULT
WINAPI
filter_service_lookup_LookupService
(
IMFTopologyServiceLookup
*
iface
,
MF_SERVICE_LOOKUP_TYPE
lookup_type
,
DWORD
index
,
REFGUID
service
,
REFIID
riid
,
void
**
objects
,
DWORD
*
num_objects
)
{
FIXME
(
"iface %p, lookup_type %d, index %lu, service %s, riid %s, objects %p, num_objects %p.
\n
"
,
struct
evr
*
filter
=
impl_from_IMFTopologyServiceLookup
(
iface
);
HRESULT
hr
=
S_OK
;
TRACE
(
"iface %p, lookup_type %d, index %lu, service %s, riid %s, objects %p, num_objects %p.
\n
"
,
iface
,
lookup_type
,
index
,
debugstr_guid
(
service
),
debugstr_guid
(
riid
),
objects
,
num_objects
);
return
MF_E_NOTACCEPTING
;
EnterCriticalSection
(
&
filter
->
renderer
.
filter
.
filter_cs
);
if
(
!
(
filter
->
flags
&
EVR_INIT_SERVICES
))
hr
=
MF_E_NOTACCEPTING
;
else
if
(
IsEqualGUID
(
service
,
&
MR_VIDEO_RENDER_SERVICE
))
{
if
(
IsEqualIID
(
riid
,
&
IID_IMediaEventSink
))
{
*
objects
=
&
filter
->
IMediaEventSink_iface
;
IUnknown_AddRef
((
IUnknown
*
)
*
objects
);
}
}
else
if
(
IsEqualGUID
(
service
,
&
MR_VIDEO_MIXER_SERVICE
))
{
hr
=
IMFTransform_QueryInterface
(
filter
->
mixer
,
riid
,
objects
);
}
else
{
WARN
(
"Unsupported service %s.
\n
"
,
debugstr_guid
(
service
));
hr
=
MF_E_UNSUPPORTED_SERVICE
;
}
LeaveCriticalSection
(
&
filter
->
renderer
.
filter
.
filter_cs
);
return
hr
;
}
static
const
IMFTopologyServiceLookupVtbl
filter_service_lookup_vtbl
=
...
...
dlls/evr/tests/evr.c
View file @
f143af50
...
...
@@ -637,6 +637,59 @@ static void test_service_lookup(void)
ok
(
!
ref
,
"Got outstanding refcount %ld.
\n
"
,
ref
);
}
static
void
test_query_accept
(
void
)
{
IBaseFilter
*
filter
=
create_evr
();
AM_MEDIA_TYPE
req_mt
=
{{
0
}};
VIDEOINFOHEADER
vih
=
{
{
0
},
{
0
},
0
,
0
,
0
,
{
sizeof
(
BITMAPINFOHEADER
),
32
,
24
,
1
,
0
,
0xdeadbeef
}
};
unsigned
int
i
;
HRESULT
hr
;
ULONG
ref
;
IPin
*
pin
;
static
const
GUID
*
subtype_tests
[]
=
{
&
MEDIASUBTYPE_RGB32
,
&
MEDIASUBTYPE_YUY2
,
};
static
const
GUID
*
unsupported_subtype_tests
[]
=
{
&
MEDIASUBTYPE_RGB8
,
};
IBaseFilter_FindPin
(
filter
,
L"EVR Input0"
,
&
pin
);
req_mt
.
majortype
=
MEDIATYPE_Video
;
req_mt
.
formattype
=
FORMAT_VideoInfo
;
req_mt
.
cbFormat
=
sizeof
(
VIDEOINFOHEADER
);
req_mt
.
pbFormat
=
(
BYTE
*
)
&
vih
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
subtype_tests
);
++
i
)
{
memcpy
(
&
req_mt
.
subtype
,
subtype_tests
[
i
],
sizeof
(
GUID
));
hr
=
IPin_QueryAccept
(
pin
,
&
req_mt
);
todo_wine_if
(
i
)
ok
(
hr
==
S_OK
,
"Got hr %#lx.
\n
"
,
hr
);
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
unsupported_subtype_tests
);
++
i
)
{
memcpy
(
&
req_mt
.
subtype
,
unsupported_subtype_tests
[
i
],
sizeof
(
GUID
));
hr
=
IPin_QueryAccept
(
pin
,
&
req_mt
);
ok
(
hr
==
S_FALSE
,
"Got hr %#lx.
\n
"
,
hr
);
}
IPin_Release
(
pin
);
ref
=
IBaseFilter_Release
(
filter
);
ok
(
!
ref
,
"Got outstanding refcount %ld.
\n
"
,
ref
);
}
static
IMFMediaType
*
create_video_type
(
const
GUID
*
subtype
)
{
IMFMediaType
*
video_type
;
...
...
@@ -3311,6 +3364,7 @@ START_TEST(evr)
test_misc_flags
();
test_display_control
();
test_service_lookup
();
test_query_accept
();
test_default_mixer
();
test_default_mixer_type_negotiation
();
...
...
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