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
e5b06613
Commit
e5b06613
authored
Jul 05, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
Jul 27, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mf: Use a branch list instead of node marker in the topology loader.
parent
1dc4c94e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
131 additions
and
106 deletions
+131
-106
mf.c
dlls/mf/tests/mf.c
+0
-1
topology_loader.c
dlls/mf/topology_loader.c
+131
-105
No files found.
dlls/mf/tests/mf.c
View file @
e5b06613
...
...
@@ -2324,7 +2324,6 @@ static void test_topology_loader(void)
/* Source node only. */
hr
=
IMFTopoLoader_Load
(
loader
,
topology
,
&
full_topology
,
NULL
);
todo_wine_if
(
hr
==
E_INVALIDARG
)
ok
(
hr
==
MF_E_TOPO_UNSUPPORTED
,
"Unexpected hr %#lx.
\n
"
,
hr
);
hr
=
MFCreateTopologyNode
(
MF_TOPOLOGY_OUTPUT_NODE
,
&
sink_node
);
...
...
dlls/mf/topology_loader.c
View file @
e5b06613
...
...
@@ -26,6 +26,7 @@
#include "mfidl.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "mf_private.h"
...
...
@@ -84,32 +85,9 @@ 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
,
IMFTopologyNode
**
clone
,
unsigned
int
marker
)
static
HRESULT
topology_loader_clone_node
(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
node
,
IMFTopologyNode
**
clone
)
{
MF_TOPOLOGY_TYPE
node_type
;
HRESULT
hr
;
...
...
@@ -124,9 +102,7 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM
if
(
FAILED
(
hr
=
MFCreateTopologyNode
(
node_type
,
clone
)))
return
hr
;
if
(
SUCCEEDED
(
hr
=
IMFTopologyNode_CloneFrom
(
*
clone
,
node
)))
hr
=
IMFTopologyNode_SetUINT32
(
*
clone
,
&
context
->
key
,
marker
);
hr
=
IMFTopologyNode_CloneFrom
(
*
clone
,
node
);
if
(
SUCCEEDED
(
hr
))
hr
=
IMFTopology_AddNode
(
context
->
output_topology
,
*
clone
);
...
...
@@ -157,6 +133,88 @@ struct connect_context
GUID
decoder_category
;
};
struct
topology_branch
{
struct
{
IMFTopologyNode
*
node
;
DWORD
stream
;
}
up
,
down
;
struct
list
entry
;
};
static
const
char
*
debugstr_topology_branch
(
struct
topology_branch
*
branch
)
{
return
wine_dbg_sprintf
(
"%p:%lu to %p:%lu"
,
branch
->
up
.
node
,
branch
->
up
.
stream
,
branch
->
down
.
node
,
branch
->
down
.
stream
);
}
static
HRESULT
topology_branch_create
(
IMFTopologyNode
*
source
,
DWORD
source_stream
,
IMFTopologyNode
*
sink
,
DWORD
sink_stream
,
struct
topology_branch
**
out
)
{
struct
topology_branch
*
branch
;
if
(
!
(
branch
=
calloc
(
1
,
sizeof
(
*
branch
))))
return
E_OUTOFMEMORY
;
IMFTopologyNode_AddRef
((
branch
->
up
.
node
=
source
));
branch
->
up
.
stream
=
source_stream
;
IMFTopologyNode_AddRef
((
branch
->
down
.
node
=
sink
));
branch
->
down
.
stream
=
sink_stream
;
*
out
=
branch
;
return
S_OK
;
}
static
void
topology_branch_destroy
(
struct
topology_branch
*
branch
)
{
IMFTopologyNode_Release
(
branch
->
up
.
node
);
IMFTopologyNode_Release
(
branch
->
down
.
node
);
free
(
branch
);
}
static
HRESULT
topology_branch_clone_nodes
(
struct
topoloader_context
*
context
,
struct
topology_branch
*
branch
)
{
IMFTopologyNode
*
up
,
*
down
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
context
,
branch
->
up
.
node
,
&
up
)))
return
hr
;
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
context
,
branch
->
down
.
node
,
&
down
)))
{
IMFTopologyNode_Release
(
up
);
return
hr
;
}
IMFTopologyNode_Release
(
branch
->
up
.
node
);
IMFTopologyNode_Release
(
branch
->
down
.
node
);
branch
->
up
.
node
=
up
;
branch
->
down
.
node
=
down
;
return
hr
;
}
static
HRESULT
topology_node_list_branches
(
IMFTopologyNode
*
node
,
struct
list
*
branches
)
{
struct
topology_branch
*
branch
;
DWORD
i
,
count
,
down_stream
;
IMFTopologyNode
*
down_node
;
HRESULT
hr
;
hr
=
IMFTopologyNode_GetOutputCount
(
node
,
&
count
);
for
(
i
=
0
;
SUCCEEDED
(
hr
)
&&
i
<
count
;
++
i
)
{
if
(
FAILED
(
IMFTopologyNode_GetOutput
(
node
,
i
,
&
down_node
,
&
down_stream
)))
continue
;
if
(
SUCCEEDED
(
hr
=
topology_branch_create
(
node
,
i
,
down_node
,
down_stream
,
&
branch
)))
list_add_tail
(
branches
,
&
branch
->
entry
);
IMFTopologyNode_Release
(
down_node
);
}
return
hr
;
}
typedef
HRESULT
(
*
p_connect_func
)(
struct
transform_output_type
*
output_type
,
struct
connect_context
*
context
);
static
void
topology_loader_release_transforms
(
IMFActivate
**
activates
,
unsigned
int
count
)
...
...
@@ -456,8 +514,7 @@ done:
return
hr
;
}
static
HRESULT
topology_loader_resolve_branch
(
struct
topoloader_context
*
context
,
IMFTopologyNode
*
upstream_node
,
unsigned
int
output_index
,
IMFTopologyNode
*
downstream_node
,
unsigned
input_index
)
static
HRESULT
topology_loader_resolve_branch
(
struct
topoloader_context
*
context
,
struct
topology_branch
*
branch
)
{
static
const
p_topology_loader_connect_func
connectors
[
MF_TOPOLOGY_TEE_NODE
+
1
][
MF_TOPOLOGY_TEE_NODE
+
1
]
=
{
...
...
@@ -467,77 +524,58 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context
/* TEE */
{
NULL
},
};
MF_TOPOLOGY_TYPE
u_type
,
d_type
;
IMFTopologyNode
*
node
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
context
,
downstream_node
,
&
node
,
context
->
marker
+
1
)))
return
hr
;
IMFTopologyNode_GetNodeType
(
upstream_
node
,
&
u_type
);
IMFTopologyNode_GetNodeType
(
downstream_
node
,
&
d_type
);
IMFTopologyNode_GetNodeType
(
branch
->
up
.
node
,
&
u_type
);
IMFTopologyNode_GetNodeType
(
branch
->
down
.
node
,
&
d_type
);
if
(
!
connectors
[
u_type
][
d_type
])
{
WARN
(
"Unsupported branch kind %d -> %d.
\n
"
,
u_type
,
d_type
);
IMFTopologyNode_Release
(
node
);
return
E_FAIL
;
}
hr
=
connectors
[
u_type
][
d_type
](
context
,
upstream_node
,
output_index
,
node
,
input_index
);
IMFTopologyNode_Release
(
node
);
return
hr
;
return
connectors
[
u_type
][
d_type
](
context
,
branch
->
up
.
node
,
branch
->
up
.
stream
,
branch
->
down
.
node
,
branch
->
down
.
stream
);
}
static
HRESULT
topology_loader_resolve_
nodes
(
struct
topoloader_context
*
context
,
unsigned
int
*
layer_size
)
static
HRESULT
topology_loader_resolve_
branches
(
struct
topoloader_context
*
context
,
struct
list
*
branches
)
{
IMFTopologyNode
*
downstream_node
,
*
node
,
*
orig_node
;
struct
list
new_branches
=
LIST_INIT
(
new_branches
);
struct
topology_branch
*
branch
,
*
next
;
MF_TOPOLOGY_TYPE
node_type
;
unsigned
int
size
=
0
;
DWORD
input_index
;
HRESULT
hr
=
S_OK
;
TOPOID
id
;
while
((
node
=
topology_loader_get_node_for_marker
(
context
,
&
id
))
)
LIST_FOR_EACH_ENTRY_SAFE
(
branch
,
next
,
branches
,
struct
topology_branch
,
entry
)
{
++
size
;
IMFTopologyNode_GetNodeType
(
node
,
&
node_type
);
switch
(
node_type
)
list_remove
(
&
branch
->
entry
);
if
(
FAILED
(
hr
=
topology_node_list_branches
(
branch
->
down
.
node
,
&
new_branches
)))
WARN
(
"Failed to list branches from branch %s
\n
"
,
debugstr_topology_branch
(
branch
));
else
if
(
FAILED
(
hr
=
IMFTopologyNode_GetNodeType
(
branch
->
up
.
node
,
&
node_type
)))
WARN
(
"Failed to get source node type for branch %s
\n
"
,
debugstr_topology_branch
(
branch
));
else
if
(
FAILED
(
hr
=
topology_branch_clone_nodes
(
context
,
branch
)))
WARN
(
"Failed to clone nodes for branch %s
\n
"
,
debugstr_topology_branch
(
branch
));
else
{
case
MF_TOPOLOGY_SOURCESTREAM_NODE
:
if
(
SUCCEEDED
(
hr
=
IMFTopology_GetNodeByID
(
context
->
input_topology
,
id
,
&
orig_node
)))
{
hr
=
IMFTopologyNode_GetOutput
(
orig_node
,
0
,
&
downstream_node
,
&
input_index
);
IMFTopologyNode_Release
(
orig_node
);
}
if
(
FAILED
(
hr
))
{
IMFTopology_RemoveNode
(
context
->
output_topology
,
node
);
IMFTopologyNode_Release
(
node
);
continue
;
}
hr
=
topology_loader_resolve_branch
(
context
,
node
,
0
,
downstream_node
,
input_index
);
IMFTopologyNode_Release
(
downstream_node
);
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
);
switch
(
node_type
)
{
case
MF_TOPOLOGY_SOURCESTREAM_NODE
:
hr
=
topology_loader_resolve_branch
(
context
,
branch
);
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
);
IMFTopologyNode_Release
(
node
);
topology_branch_destroy
(
branch
);
if
(
FAILED
(
hr
))
break
;
}
*
layer_size
=
size
;
list_move_tail
(
branches
,
&
new_branches
);
return
hr
;
}
...
...
@@ -692,10 +730,11 @@ static void topology_loader_resolve_complete(struct topoloader_context *context)
static
HRESULT
WINAPI
topology_loader_Load
(
IMFTopoLoader
*
iface
,
IMFTopology
*
input_topology
,
IMFTopology
**
ret_topology
,
IMFTopology
*
current_topology
)
{
struct
list
branches
=
LIST_INIT
(
branches
);
struct
topoloader_context
context
=
{
0
};
struct
topology_branch
*
branch
,
*
next
;
IMFTopology
*
output_topology
;
MF_TOPOLOGY_TYPE
node_type
;
unsigned
int
layer_size
;
IMFTopologyNode
*
node
;
unsigned
short
i
=
0
;
IMFStreamSink
*
sink
;
...
...
@@ -749,38 +788,25 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
context
.
input_topology
=
input_topology
;
context
.
output_topology
=
output_topology
;
memset
(
&
context
.
key
,
0xff
,
sizeof
(
context
.
key
));
/* Clone source nodes, use initial marker value. */
i
=
0
;
while
(
SUCCEEDED
(
IMFTopology_GetNode
(
input_topology
,
i
++
,
&
node
)))
for
(
i
=
0
;
SUCCEEDED
(
IMFTopology_GetNode
(
input_topology
,
i
,
&
node
));
i
++
)
{
IMFTopologyNode_GetNodeType
(
node
,
&
node_type
);
if
(
node_type
==
MF_TOPOLOGY_SOURCESTREAM_NODE
)
{
IMFTopologyNode
*
clone
;
if
(
FAILED
(
hr
=
topology_loader_clone_node
(
&
context
,
node
,
&
clone
,
0
)))
WARN
(
"Failed to clone source node, hr %#lx.
\n
"
,
hr
);
else
IMFTopologyNode_Release
(
clone
);
}
hr
=
topology_node_list_branches
(
node
,
&
branches
);
IMFTopologyNode_Release
(
node
);
if
(
FAILED
(
hr
))
break
;
}
if
(
SUCCEEDED
(
hr
)
&&
list_empty
(
&
branches
))
hr
=
MF_E_TOPO_UNSUPPORTED
;
for
(
context
.
marker
=
0
;;
++
context
.
marker
)
{
if
(
FAILED
(
hr
=
topology_loader_resolve_nodes
(
&
context
,
&
layer_size
)))
{
WARN
(
"Failed to resolve for marker %u, hr %#lx.
\n
"
,
context
.
marker
,
hr
);
break
;
}
while
(
SUCCEEDED
(
hr
)
&&
!
list_empty
(
&
branches
))
hr
=
topology_loader_resolve_branches
(
&
context
,
&
branches
);
/* Reached last marker value. */
if
(
!
layer_size
)
break
;
LIST_FOR_EACH_ENTRY_SAFE
(
branch
,
next
,
&
branches
,
struct
topology_branch
,
entry
)
{
WARN
(
"Failed to resolve branch %s
\n
"
,
debugstr_topology_branch
(
branch
));
list_remove
(
&
branch
->
entry
);
topology_branch_destroy
(
branch
);
}
if
(
FAILED
(
hr
))
...
...
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