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
e308d81a
Commit
e308d81a
authored
Jul 15, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jul 15, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mf/topoloader: Add a structure for iterative branch resolution.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
16d44b61
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
143 additions
and
4 deletions
+143
-4
mf.c
dlls/mf/tests/mf.c
+7
-2
topology.c
dlls/mf/topology.c
+136
-2
No files found.
dlls/mf/tests/mf.c
View file @
e308d81a
...
...
@@ -1400,6 +1400,7 @@ static void test_topology_loader(void)
IMFPresentationDescriptor
*
pd
;
IMFSourceResolver
*
resolver
;
IMFActivate
*
sink_activate
;
IMFStreamSink
*
stream_sink
;
unsigned
int
count
,
value
;
IMFMediaType
*
media_type
;
IMFStreamDescriptor
*
sd
;
...
...
@@ -1512,15 +1513,19 @@ todo_wine
hr
=
IMFActivate_ActivateObject
(
sink_activate
,
&
IID_IMFMediaSink
,
(
void
**
)
&
sink
);
ok
(
hr
==
S_OK
,
"Failed to activate, hr %#x.
\n
"
,
hr
);
hr
=
IMFTopologyNode_SetObject
(
sink_node
,
(
IUnknown
*
)
sink
);
hr
=
IMFMediaSink_GetStreamSinkByIndex
(
sink
,
0
,
&
stream_sink
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
IMFTopologyNode_SetObject
(
sink_node
,
(
IUnknown
*
)
stream_sink
);
ok
(
hr
==
S_OK
,
"Failed to set object, hr %#x.
\n
"
,
hr
);
IMFStreamSink_Release
(
stream_sink
);
hr
=
IMFTopology_GetCount
(
topology
,
&
count
);
ok
(
hr
==
S_OK
,
"Failed to get attribute count, hr %#x.
\n
"
,
hr
);
ok
(
count
==
0
,
"Unexpected count %u.
\n
"
,
count
);
hr
=
IMFTopoLoader_Load
(
loader
,
topology
,
&
full_topology
,
NULL
);
todo_wine
ok
(
hr
==
S_OK
,
"Failed to resolve topology, hr %#x.
\n
"
,
hr
);
ok
(
full_topology
!=
topology
,
"Unexpected instance.
\n
"
);
...
...
dlls/mf/topology.c
View file @
e308d81a
...
...
@@ -1935,17 +1935,41 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
struct
topoloader_context
{
IMFTopology
*
input_topology
;
IMFTopology
*
output_topology
;
unsigned
int
marker
;
GUID
key
;
};
static
IMFTopologyNode
*
topology_loader_get_node_for_marker
(
struct
topoloader_context
*
context
,
TOPOID
*
id
)
{
IMFTopologyNode
*
node
;
unsigned
short
i
=
0
;
unsigned
int
value
;
while
(
SUCCEEDED
(
IMFTopology_GetNode
(
context
->
output_topology
,
i
++
,
&
node
)))
{
if
(
SUCCEEDED
(
IMFTopologyNode_GetUINT32
(
node
,
&
context
->
key
,
&
value
))
&&
value
==
context
->
marker
)
{
IMFTopologyNode_GetTopoNodeID
(
node
,
id
);
return
node
;
}
IMFTopologyNode_Release
(
node
);
}
*
id
=
0
;
return
NULL
;
}
static
HRESULT
topology_loader_clone_node
(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
node
,
unsigned
int
marker
)
IMFTopologyNode
**
ret
,
unsigned
int
marker
)
{
IMFTopologyNode
*
cloned_node
;
MF_TOPOLOGY_TYPE
node_type
;
HRESULT
hr
;
if
(
ret
)
*
ret
=
NULL
;
IMFTopologyNode_GetNodeType
(
node
,
&
node_type
);
if
(
FAILED
(
hr
=
MFCreateTopologyNode
(
node_type
,
&
cloned_node
)))
...
...
@@ -1957,17 +1981,113 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM
if
(
SUCCEEDED
(
hr
))
hr
=
IMFTopology_AddNode
(
context
->
output_topology
,
cloned_node
);
if
(
SUCCEEDED
(
hr
)
&&
ret
)
{
*
ret
=
cloned_node
;
IMFTopologyNode_AddRef
(
*
ret
);
}
IMFTopologyNode_Release
(
cloned_node
);
return
hr
;
}
typedef
HRESULT
(
*
p_topology_loader_connect_func
)(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
upstream_node
,
unsigned
int
output_index
,
IMFTopologyNode
*
downstream_node
,
unsigned
int
input_index
);
static
HRESULT
topology_loader_connect_source_node
(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
upstream_node
,
unsigned
int
output_index
,
IMFTopologyNode
*
downstream_node
,
unsigned
int
input_index
)
{
FIXME
(
"Unimplemented.
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
topology_loader_resolve_branch
(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
upstream_node
,
unsigned
int
output_index
,
IMFTopologyNode
*
downstream_node
,
unsigned
input_index
)
{
static
const
p_topology_loader_connect_func
connectors
[
MF_TOPOLOGY_TEE_NODE
+
1
][
MF_TOPOLOGY_TEE_NODE
+
1
]
=
{
/* OUTPUT */
{
NULL
},
/* SOURCESTREAM */
{
topology_loader_connect_source_node
,
NULL
,
NULL
,
NULL
},
/* TRANSFORM */
{
NULL
},
/* TEE */
{
NULL
},
};
MF_TOPOLOGY_TYPE
u_type
,
d_type
;
IMFTopologyNode
*
node
;
TOPOID
id
;
/* Downstream node might have already been cloned. */
IMFTopologyNode_GetTopoNodeID
(
downstream_node
,
&
id
);
if
(
FAILED
(
IMFTopology_GetNodeByID
(
context
->
output_topology
,
id
,
&
node
)))
topology_loader_clone_node
(
context
,
downstream_node
,
&
node
,
context
->
marker
+
1
);
IMFTopologyNode_ConnectOutput
(
upstream_node
,
output_index
,
node
,
input_index
);
IMFTopologyNode_GetNodeType
(
upstream_node
,
&
u_type
);
IMFTopologyNode_GetNodeType
(
downstream_node
,
&
d_type
);
if
(
!
connectors
[
u_type
][
d_type
])
{
WARN
(
"Unsupported branch kind %d -> %d.
\n
"
,
u_type
,
d_type
);
return
E_FAIL
;
}
return
connectors
[
u_type
][
d_type
](
context
,
upstream_node
,
output_index
,
downstream_node
,
input_index
);
}
static
HRESULT
topology_loader_resolve_nodes
(
struct
topoloader_context
*
context
,
unsigned
int
*
layer_size
)
{
IMFTopologyNode
*
downstream_node
,
*
node
,
*
orig_node
;
unsigned
int
input_index
,
size
=
0
;
MF_TOPOLOGY_TYPE
node_type
;
HRESULT
hr
=
S_OK
;
TOPOID
id
;
while
((
node
=
topology_loader_get_node_for_marker
(
context
,
&
id
)))
{
++
size
;
IMFTopology_GetNodeByID
(
context
->
input_topology
,
id
,
&
orig_node
);
IMFTopologyNode_GetNodeType
(
node
,
&
node_type
);
switch
(
node_type
)
{
case
MF_TOPOLOGY_SOURCESTREAM_NODE
:
if
(
FAILED
(
IMFTopologyNode_GetOutput
(
orig_node
,
0
,
&
downstream_node
,
&
input_index
)))
{
IMFTopology_RemoveNode
(
context
->
output_topology
,
node
);
continue
;
}
hr
=
topology_loader_resolve_branch
(
context
,
node
,
0
,
downstream_node
,
input_index
);
break
;
case
MF_TOPOLOGY_TRANSFORM_NODE
:
case
MF_TOPOLOGY_TEE_NODE
:
FIXME
(
"Unsupported node type %d.
\n
"
,
node_type
);
break
;
default:
WARN
(
"Unexpected node type %d.
\n
"
,
node_type
);
}
IMFTopologyNode_DeleteItem
(
node
,
&
context
->
key
);
if
(
FAILED
(
hr
))
break
;
}
*
layer_size
=
size
;
return
hr
;
}
static
HRESULT
WINAPI
topology_loader_Load
(
IMFTopoLoader
*
iface
,
IMFTopology
*
input_topology
,
IMFTopology
**
ret_topology
,
IMFTopology
*
current_topology
)
{
struct
topoloader_context
context
=
{
0
};
IMFTopology
*
output_topology
;
MF_TOPOLOGY_TYPE
node_type
;
unsigned
int
layer_size
;
IMFTopologyNode
*
node
;
unsigned
short
i
=
0
;
IMFStreamSink
*
sink
;
...
...
@@ -2016,6 +2136,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
if
(
FAILED
(
hr
=
MFCreateTopology
(
&
output_topology
)))
return
hr
;
context
.
input_topology
=
input_topology
;
context
.
output_topology
=
output_topology
;
memset
(
&
context
.
key
,
0xff
,
sizeof
(
context
.
key
));
...
...
@@ -2027,13 +2148,26 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
if
(
node_type
==
MF_TOPOLOGY_SOURCESTREAM_NODE
)
{
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
&
context
,
node
,
0
)))
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
&
context
,
node
,
NULL
,
0
)))
WARN
(
"Failed to clone source node, hr %#x.
\n
"
,
hr
);
}
IMFTopologyNode_Release
(
node
);
}
for
(
context
.
marker
=
0
;;
++
context
.
marker
)
{
if
(
FAILED
(
hr
=
topology_loader_resolve_nodes
(
&
context
,
&
layer_size
)))
{
WARN
(
"Failed to resolve for marker %u, hr %#x.
\n
"
,
context
.
marker
,
hr
);
break
;
}
/* Reached last marker value. */
if
(
!
layer_size
)
break
;
}
/* For now return original topology. */
*
ret_topology
=
output_topology
;
...
...
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