2 * Copyright 2017 Nikolay Sivov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 #include "mf_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
37 static LONG next_node_id
;
38 static TOPOID next_topology_id
;
42 IMFMediaType
*preferred_type
;
43 struct topology_node
*connection
;
44 DWORD connection_stream
;
49 struct node_stream
*streams
;
56 IMFTopologyNode IMFTopologyNode_iface
;
58 IMFAttributes
*attributes
;
59 MF_TOPOLOGY_TYPE node_type
;
62 IMFMediaType
*input_type
; /* Only for tee nodes. */
63 struct node_streams inputs
;
64 struct node_streams outputs
;
70 IMFTopology IMFTopology_iface
;
72 IMFAttributes
*attributes
;
75 struct topology_node
**nodes
;
84 IMFSequencerSource IMFSequencerSource_iface
;
85 IMFMediaSourceTopologyProvider IMFMediaSourceTopologyProvider_iface
;
89 static inline struct topology
*impl_from_IMFTopology(IMFTopology
*iface
)
91 return CONTAINING_RECORD(iface
, struct topology
, IMFTopology_iface
);
94 static struct topology_node
*impl_from_IMFTopologyNode(IMFTopologyNode
*iface
)
96 return CONTAINING_RECORD(iface
, struct topology_node
, IMFTopologyNode_iface
);
99 static const IMFTopologyNodeVtbl topologynodevtbl
;
101 static struct topology_node
*unsafe_impl_from_IMFTopologyNode(IMFTopologyNode
*iface
)
103 if (!iface
|| iface
->lpVtbl
!= &topologynodevtbl
)
105 return impl_from_IMFTopologyNode(iface
);
108 static HRESULT
create_topology_node(MF_TOPOLOGY_TYPE node_type
, struct topology_node
**node
);
109 static HRESULT
topology_node_connect_output(struct topology_node
*node
, DWORD output_index
,
110 struct topology_node
*connection
, DWORD input_index
);
112 static struct topology
*unsafe_impl_from_IMFTopology(IMFTopology
*iface
);
114 static struct seq_source
*impl_from_IMFSequencerSource(IMFSequencerSource
*iface
)
116 return CONTAINING_RECORD(iface
, struct seq_source
, IMFSequencerSource_iface
);
119 static struct seq_source
*impl_from_IMFMediaSourceTopologyProvider(IMFMediaSourceTopologyProvider
*iface
)
121 return CONTAINING_RECORD(iface
, struct seq_source
, IMFMediaSourceTopologyProvider_iface
);
124 static HRESULT
topology_node_reserve_streams(struct node_streams
*streams
, DWORD index
)
126 if (!mf_array_reserve((void **)&streams
->streams
, &streams
->size
, index
+ 1, sizeof(*streams
->streams
)))
127 return E_OUTOFMEMORY
;
129 if (index
>= streams
->count
)
131 memset(&streams
->streams
[streams
->count
], 0, (index
- streams
->count
+ 1) * sizeof(*streams
->streams
));
132 streams
->count
= index
+ 1;
138 static HRESULT WINAPI
topology_QueryInterface(IMFTopology
*iface
, REFIID riid
, void **out
)
140 struct topology
*topology
= impl_from_IMFTopology(iface
);
142 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
144 if (IsEqualIID(riid
, &IID_IMFTopology
) ||
145 IsEqualIID(riid
, &IID_IMFAttributes
) ||
146 IsEqualIID(riid
, &IID_IUnknown
))
148 *out
= &topology
->IMFTopology_iface
;
152 FIXME("(%s, %p)\n", debugstr_guid(riid
), out
);
154 return E_NOINTERFACE
;
157 IUnknown_AddRef((IUnknown
*)*out
);
161 static ULONG WINAPI
topology_AddRef(IMFTopology
*iface
)
163 struct topology
*topology
= impl_from_IMFTopology(iface
);
164 ULONG refcount
= InterlockedIncrement(&topology
->refcount
);
166 TRACE("%p, refcount %lu.\n", iface
, refcount
);
171 static HRESULT
topology_node_disconnect_output(struct topology_node
*node
, DWORD output_index
)
173 struct topology_node
*connection
= NULL
;
174 struct node_stream
*stream
;
175 DWORD connection_stream
;
178 EnterCriticalSection(&node
->cs
);
180 if (output_index
< node
->outputs
.count
)
182 stream
= &node
->outputs
.streams
[output_index
];
184 if (stream
->connection
)
186 connection
= stream
->connection
;
187 connection_stream
= stream
->connection_stream
;
188 stream
->connection
= NULL
;
189 stream
->connection_stream
= 0;
197 LeaveCriticalSection(&node
->cs
);
201 EnterCriticalSection(&connection
->cs
);
203 if (connection_stream
< connection
->inputs
.count
)
205 stream
= &connection
->inputs
.streams
[connection_stream
];
207 if (stream
->connection
)
209 stream
->connection
= NULL
;
210 stream
->connection_stream
= 0;
214 LeaveCriticalSection(&connection
->cs
);
216 IMFTopologyNode_Release(&connection
->IMFTopologyNode_iface
);
217 IMFTopologyNode_Release(&node
->IMFTopologyNode_iface
);
223 static void topology_node_disconnect(struct topology_node
*node
)
225 struct node_stream
*stream
;
228 for (i
= 0; i
< node
->outputs
.count
; ++i
)
229 topology_node_disconnect_output(node
, i
);
231 for (i
= 0; i
< node
->inputs
.count
; ++i
)
233 stream
= &node
->inputs
.streams
[i
];
234 if (stream
->connection
)
235 topology_node_disconnect_output(stream
->connection
, stream
->connection_stream
);
239 static void topology_clear(struct topology
*topology
)
243 for (i
= 0; i
< topology
->nodes
.count
; ++i
)
245 topology_node_disconnect(topology
->nodes
.nodes
[i
]);
246 IMFTopologyNode_Release(&topology
->nodes
.nodes
[i
]->IMFTopologyNode_iface
);
248 free(topology
->nodes
.nodes
);
249 topology
->nodes
.nodes
= NULL
;
250 topology
->nodes
.count
= 0;
251 topology
->nodes
.size
= 0;
254 static ULONG WINAPI
topology_Release(IMFTopology
*iface
)
256 struct topology
*topology
= impl_from_IMFTopology(iface
);
257 ULONG refcount
= InterlockedDecrement(&topology
->refcount
);
259 TRACE("%p, refcount %lu.\n", iface
, refcount
);
263 if (topology
->attributes
)
264 IMFAttributes_Release(topology
->attributes
);
265 topology_clear(topology
);
272 static HRESULT WINAPI
topology_GetItem(IMFTopology
*iface
, REFGUID key
, PROPVARIANT
*value
)
274 struct topology
*topology
= impl_from_IMFTopology(iface
);
276 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
278 return IMFAttributes_GetItem(topology
->attributes
, key
, value
);
281 static HRESULT WINAPI
topology_GetItemType(IMFTopology
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
283 struct topology
*topology
= impl_from_IMFTopology(iface
);
285 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
287 return IMFAttributes_GetItemType(topology
->attributes
, key
, type
);
290 static HRESULT WINAPI
topology_CompareItem(IMFTopology
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
292 struct topology
*topology
= impl_from_IMFTopology(iface
);
294 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
296 return IMFAttributes_CompareItem(topology
->attributes
, key
, value
, result
);
299 static HRESULT WINAPI
topology_Compare(IMFTopology
*iface
, IMFAttributes
*theirs
, MF_ATTRIBUTES_MATCH_TYPE type
,
302 struct topology
*topology
= impl_from_IMFTopology(iface
);
304 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
306 return IMFAttributes_Compare(topology
->attributes
, theirs
, type
, result
);
309 static HRESULT WINAPI
topology_GetUINT32(IMFTopology
*iface
, REFGUID key
, UINT32
*value
)
311 struct topology
*topology
= impl_from_IMFTopology(iface
);
313 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
315 return IMFAttributes_GetUINT32(topology
->attributes
, key
, value
);
318 static HRESULT WINAPI
topology_GetUINT64(IMFTopology
*iface
, REFGUID key
, UINT64
*value
)
320 struct topology
*topology
= impl_from_IMFTopology(iface
);
322 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
324 return IMFAttributes_GetUINT64(topology
->attributes
, key
, value
);
327 static HRESULT WINAPI
topology_GetDouble(IMFTopology
*iface
, REFGUID key
, double *value
)
329 struct topology
*topology
= impl_from_IMFTopology(iface
);
331 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
333 return IMFAttributes_GetDouble(topology
->attributes
, key
, value
);
336 static HRESULT WINAPI
topology_GetGUID(IMFTopology
*iface
, REFGUID key
, GUID
*value
)
338 struct topology
*topology
= impl_from_IMFTopology(iface
);
340 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
342 return IMFAttributes_GetGUID(topology
->attributes
, key
, value
);
345 static HRESULT WINAPI
topology_GetStringLength(IMFTopology
*iface
, REFGUID key
, UINT32
*length
)
347 struct topology
*topology
= impl_from_IMFTopology(iface
);
349 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
351 return IMFAttributes_GetStringLength(topology
->attributes
, key
, length
);
354 static HRESULT WINAPI
topology_GetString(IMFTopology
*iface
, REFGUID key
, WCHAR
*value
,
355 UINT32 size
, UINT32
*length
)
357 struct topology
*topology
= impl_from_IMFTopology(iface
);
359 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
361 return IMFAttributes_GetString(topology
->attributes
, key
, value
, size
, length
);
364 static HRESULT WINAPI
topology_GetAllocatedString(IMFTopology
*iface
, REFGUID key
,
365 WCHAR
**value
, UINT32
*length
)
367 struct topology
*topology
= impl_from_IMFTopology(iface
);
369 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
371 return IMFAttributes_GetAllocatedString(topology
->attributes
, key
, value
, length
);
374 static HRESULT WINAPI
topology_GetBlobSize(IMFTopology
*iface
, REFGUID key
, UINT32
*size
)
376 struct topology
*topology
= impl_from_IMFTopology(iface
);
378 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
380 return IMFAttributes_GetBlobSize(topology
->attributes
, key
, size
);
383 static HRESULT WINAPI
topology_GetBlob(IMFTopology
*iface
, REFGUID key
, UINT8
*buf
,
384 UINT32 bufsize
, UINT32
*blobsize
)
386 struct topology
*topology
= impl_from_IMFTopology(iface
);
388 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
390 return IMFAttributes_GetBlob(topology
->attributes
, key
, buf
, bufsize
, blobsize
);
393 static HRESULT WINAPI
topology_GetAllocatedBlob(IMFTopology
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
395 struct topology
*topology
= impl_from_IMFTopology(iface
);
397 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
399 return IMFAttributes_GetAllocatedBlob(topology
->attributes
, key
, buf
, size
);
402 static HRESULT WINAPI
topology_GetUnknown(IMFTopology
*iface
, REFGUID key
, REFIID riid
, void **ppv
)
404 struct topology
*topology
= impl_from_IMFTopology(iface
);
406 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), ppv
);
408 return IMFAttributes_GetUnknown(topology
->attributes
, key
, riid
, ppv
);
411 static HRESULT WINAPI
topology_SetItem(IMFTopology
*iface
, REFGUID key
, REFPROPVARIANT value
)
413 struct topology
*topology
= impl_from_IMFTopology(iface
);
415 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
417 return IMFAttributes_SetItem(topology
->attributes
, key
, value
);
420 static HRESULT WINAPI
topology_DeleteItem(IMFTopology
*iface
, REFGUID key
)
422 struct topology
*topology
= impl_from_IMFTopology(iface
);
424 TRACE("%p, %s.\n", topology
, debugstr_guid(key
));
426 return IMFAttributes_DeleteItem(topology
->attributes
, key
);
429 static HRESULT WINAPI
topology_DeleteAllItems(IMFTopology
*iface
)
431 struct topology
*topology
= impl_from_IMFTopology(iface
);
433 TRACE("%p.\n", iface
);
435 return IMFAttributes_DeleteAllItems(topology
->attributes
);
438 static HRESULT WINAPI
topology_SetUINT32(IMFTopology
*iface
, REFGUID key
, UINT32 value
)
440 struct topology
*topology
= impl_from_IMFTopology(iface
);
442 TRACE("%p, %s, %d.\n", iface
, debugstr_guid(key
), value
);
444 return IMFAttributes_SetUINT32(topology
->attributes
, key
, value
);
447 static HRESULT WINAPI
topology_SetUINT64(IMFTopology
*iface
, REFGUID key
, UINT64 value
)
449 struct topology
*topology
= impl_from_IMFTopology(iface
);
451 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
453 return IMFAttributes_SetUINT64(topology
->attributes
, key
, value
);
456 static HRESULT WINAPI
topology_SetDouble(IMFTopology
*iface
, REFGUID key
, double value
)
458 struct topology
*topology
= impl_from_IMFTopology(iface
);
460 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
462 return IMFAttributes_SetDouble(topology
->attributes
, key
, value
);
465 static HRESULT WINAPI
topology_SetGUID(IMFTopology
*iface
, REFGUID key
, REFGUID value
)
467 struct topology
*topology
= impl_from_IMFTopology(iface
);
469 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
471 return IMFAttributes_SetGUID(topology
->attributes
, key
, value
);
474 static HRESULT WINAPI
topology_SetString(IMFTopology
*iface
, REFGUID key
, const WCHAR
*value
)
476 struct topology
*topology
= impl_from_IMFTopology(iface
);
478 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
480 return IMFAttributes_SetString(topology
->attributes
, key
, value
);
483 static HRESULT WINAPI
topology_SetBlob(IMFTopology
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
485 struct topology
*topology
= impl_from_IMFTopology(iface
);
487 TRACE("%p, %s, %p, %d.\n", iface
, debugstr_guid(key
), buf
, size
);
489 return IMFAttributes_SetBlob(topology
->attributes
, key
, buf
, size
);
492 static HRESULT WINAPI
topology_SetUnknown(IMFTopology
*iface
, REFGUID key
, IUnknown
*unknown
)
494 struct topology
*topology
= impl_from_IMFTopology(iface
);
496 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), unknown
);
498 return IMFAttributes_SetUnknown(topology
->attributes
, key
, unknown
);
501 static HRESULT WINAPI
topology_LockStore(IMFTopology
*iface
)
503 struct topology
*topology
= impl_from_IMFTopology(iface
);
505 TRACE("%p.\n", iface
);
507 return IMFAttributes_LockStore(topology
->attributes
);
510 static HRESULT WINAPI
topology_UnlockStore(IMFTopology
*iface
)
512 struct topology
*topology
= impl_from_IMFTopology(iface
);
514 TRACE("%p.\n", iface
);
516 return IMFAttributes_UnlockStore(topology
->attributes
);
519 static HRESULT WINAPI
topology_GetCount(IMFTopology
*iface
, UINT32
*count
)
521 struct topology
*topology
= impl_from_IMFTopology(iface
);
523 TRACE("%p, %p.\n", iface
, count
);
525 return IMFAttributes_GetCount(topology
->attributes
, count
);
528 static HRESULT WINAPI
topology_GetItemByIndex(IMFTopology
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
530 struct topology
*topology
= impl_from_IMFTopology(iface
);
532 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
534 return IMFAttributes_GetItemByIndex(topology
->attributes
, index
, key
, value
);
537 static HRESULT WINAPI
topology_CopyAllItems(IMFTopology
*iface
, IMFAttributes
*dest
)
539 struct topology
*topology
= impl_from_IMFTopology(iface
);
541 TRACE("%p, %p.\n", iface
, dest
);
543 return IMFAttributes_CopyAllItems(topology
->attributes
, dest
);
546 static HRESULT WINAPI
topology_GetTopologyID(IMFTopology
*iface
, TOPOID
*id
)
548 struct topology
*topology
= impl_from_IMFTopology(iface
);
550 TRACE("%p, %p.\n", iface
, id
);
560 static HRESULT
topology_get_node_by_id(const struct topology
*topology
, TOPOID id
, struct topology_node
**node
)
564 for (i
= 0; i
< topology
->nodes
.count
; ++i
)
566 if (topology
->nodes
.nodes
[i
]->id
== id
)
568 *node
= topology
->nodes
.nodes
[i
];
573 return MF_E_NOT_FOUND
;
576 static HRESULT
topology_add_node(struct topology
*topology
, struct topology_node
*node
)
578 struct topology_node
*match
;
583 if (SUCCEEDED(topology_get_node_by_id(topology
, node
->id
, &match
)))
586 if (!mf_array_reserve((void **)&topology
->nodes
.nodes
, &topology
->nodes
.size
, topology
->nodes
.count
+ 1,
587 sizeof(*topology
->nodes
.nodes
)))
589 return E_OUTOFMEMORY
;
592 topology
->nodes
.nodes
[topology
->nodes
.count
++] = node
;
593 IMFTopologyNode_AddRef(&node
->IMFTopologyNode_iface
);
598 static HRESULT WINAPI
topology_AddNode(IMFTopology
*iface
, IMFTopologyNode
*node_iface
)
600 struct topology
*topology
= impl_from_IMFTopology(iface
);
601 struct topology_node
*node
= unsafe_impl_from_IMFTopologyNode(node_iface
);
603 TRACE("%p, %p.\n", iface
, node_iface
);
605 return topology_add_node(topology
, node
);
608 static HRESULT WINAPI
topology_RemoveNode(IMFTopology
*iface
, IMFTopologyNode
*node
)
610 struct topology
*topology
= impl_from_IMFTopology(iface
);
613 TRACE("%p, %p.\n", iface
, node
);
615 for (i
= 0; i
< topology
->nodes
.count
; ++i
)
617 if (&topology
->nodes
.nodes
[i
]->IMFTopologyNode_iface
== node
)
619 topology_node_disconnect(topology
->nodes
.nodes
[i
]);
620 IMFTopologyNode_Release(&topology
->nodes
.nodes
[i
]->IMFTopologyNode_iface
);
621 count
= topology
->nodes
.count
- i
- 1;
624 memmove(&topology
->nodes
.nodes
[i
], &topology
->nodes
.nodes
[i
+ 1],
625 count
* sizeof(*topology
->nodes
.nodes
));
627 topology
->nodes
.count
--;
635 static HRESULT WINAPI
topology_GetNodeCount(IMFTopology
*iface
, WORD
*count
)
637 struct topology
*topology
= impl_from_IMFTopology(iface
);
639 TRACE("%p, %p.\n", iface
, count
);
644 *count
= topology
->nodes
.count
;
649 static HRESULT WINAPI
topology_GetNode(IMFTopology
*iface
, WORD index
, IMFTopologyNode
**node
)
651 struct topology
*topology
= impl_from_IMFTopology(iface
);
653 TRACE("%p, %u, %p.\n", iface
, index
, node
);
658 if (index
>= topology
->nodes
.count
)
659 return MF_E_INVALIDINDEX
;
661 *node
= &topology
->nodes
.nodes
[index
]->IMFTopologyNode_iface
;
662 IMFTopologyNode_AddRef(*node
);
667 static HRESULT WINAPI
topology_Clear(IMFTopology
*iface
)
669 struct topology
*topology
= impl_from_IMFTopology(iface
);
671 TRACE("%p.\n", iface
);
673 topology_clear(topology
);
677 static HRESULT WINAPI
topology_CloneFrom(IMFTopology
*iface
, IMFTopology
*src
)
679 struct topology
*topology
= impl_from_IMFTopology(iface
);
680 struct topology
*src_topology
= unsafe_impl_from_IMFTopology(src
);
681 struct topology_node
*node
;
685 TRACE("%p, %p.\n", iface
, src
);
687 topology_clear(topology
);
690 for (i
= 0; i
< src_topology
->nodes
.count
; ++i
)
692 if (FAILED(hr
= create_topology_node(src_topology
->nodes
.nodes
[i
]->node_type
, &node
)))
694 WARN("Failed to create a node, hr %#lx.\n", hr
);
698 if (SUCCEEDED(hr
= IMFTopologyNode_CloneFrom(&node
->IMFTopologyNode_iface
,
699 &src_topology
->nodes
.nodes
[i
]->IMFTopologyNode_iface
)))
701 topology_add_node(topology
, node
);
704 IMFTopologyNode_Release(&node
->IMFTopologyNode_iface
);
707 /* Clone connections. */
708 for (i
= 0; i
< src_topology
->nodes
.count
; ++i
)
710 const struct node_streams
*outputs
= &src_topology
->nodes
.nodes
[i
]->outputs
;
712 for (j
= 0; j
< outputs
->count
; ++j
)
714 DWORD input_index
= outputs
->streams
[j
].connection_stream
;
717 if (!outputs
->streams
[j
].connection
)
720 id
= outputs
->streams
[j
].connection
->id
;
722 /* Skip node lookup in destination topology, assuming same node order. */
723 if (SUCCEEDED(hr
= topology_get_node_by_id(topology
, id
, &node
)))
724 topology_node_connect_output(topology
->nodes
.nodes
[i
], j
, node
, input_index
);
728 /* Copy attributes and id. */
729 hr
= IMFTopology_CopyAllItems(src
, (IMFAttributes
*)&topology
->IMFTopology_iface
);
731 topology
->id
= src_topology
->id
;
736 static HRESULT WINAPI
topology_GetNodeByID(IMFTopology
*iface
, TOPOID id
, IMFTopologyNode
**ret
)
738 struct topology
*topology
= impl_from_IMFTopology(iface
);
739 struct topology_node
*node
;
742 TRACE("%p, %p.\n", iface
, ret
);
744 if (SUCCEEDED(hr
= topology_get_node_by_id(topology
, id
, &node
)))
746 *ret
= &node
->IMFTopologyNode_iface
;
747 IMFTopologyNode_AddRef(*ret
);
755 static HRESULT
topology_get_node_collection(const struct topology
*topology
, MF_TOPOLOGY_TYPE node_type
,
756 IMFCollection
**collection
)
764 if (FAILED(hr
= MFCreateCollection(collection
)))
767 for (i
= 0; i
< topology
->nodes
.count
; ++i
)
769 if (topology
->nodes
.nodes
[i
]->node_type
== node_type
)
771 if (FAILED(hr
= IMFCollection_AddElement(*collection
,
772 (IUnknown
*)&topology
->nodes
.nodes
[i
]->IMFTopologyNode_iface
)))
774 IMFCollection_Release(*collection
);
784 static HRESULT WINAPI
topology_GetSourceNodeCollection(IMFTopology
*iface
, IMFCollection
**collection
)
786 struct topology
*topology
= impl_from_IMFTopology(iface
);
788 TRACE("%p, %p.\n", iface
, collection
);
790 return topology_get_node_collection(topology
, MF_TOPOLOGY_SOURCESTREAM_NODE
, collection
);
793 static HRESULT WINAPI
topology_GetOutputNodeCollection(IMFTopology
*iface
, IMFCollection
**collection
)
795 struct topology
*topology
= impl_from_IMFTopology(iface
);
797 TRACE("%p, %p.\n", iface
, collection
);
799 return topology_get_node_collection(topology
, MF_TOPOLOGY_OUTPUT_NODE
, collection
);
802 static const IMFTopologyVtbl topologyvtbl
=
804 topology_QueryInterface
,
808 topology_GetItemType
,
809 topology_CompareItem
,
815 topology_GetStringLength
,
817 topology_GetAllocatedString
,
818 topology_GetBlobSize
,
820 topology_GetAllocatedBlob
,
824 topology_DeleteAllItems
,
833 topology_UnlockStore
,
835 topology_GetItemByIndex
,
836 topology_CopyAllItems
,
837 topology_GetTopologyID
,
840 topology_GetNodeCount
,
844 topology_GetNodeByID
,
845 topology_GetSourceNodeCollection
,
846 topology_GetOutputNodeCollection
,
849 static struct topology
*unsafe_impl_from_IMFTopology(IMFTopology
*iface
)
851 if (!iface
|| iface
->lpVtbl
!= &topologyvtbl
)
853 return impl_from_IMFTopology(iface
);
856 static TOPOID
topology_generate_id(void)
862 old
= next_topology_id
;
864 while (InterlockedCompareExchange64((LONG64
*)&next_topology_id
, old
+ 1, old
) != old
);
866 return next_topology_id
;
869 HRESULT
create_topology(TOPOID id
, IMFTopology
**topology
)
871 struct topology
*object
;
874 if (!(object
= calloc(1, sizeof(*object
))))
875 return E_OUTOFMEMORY
;
877 object
->IMFTopology_iface
.lpVtbl
= &topologyvtbl
;
878 object
->refcount
= 1;
880 hr
= MFCreateAttributes(&object
->attributes
, 0);
883 IMFTopology_Release(&object
->IMFTopology_iface
);
889 *topology
= &object
->IMFTopology_iface
;
894 /***********************************************************************
895 * MFCreateTopology (mf.@)
897 HRESULT WINAPI
MFCreateTopology(IMFTopology
**topology
)
899 TRACE("%p.\n", topology
);
904 return create_topology(topology_generate_id(), topology
);
907 static HRESULT WINAPI
topology_node_QueryInterface(IMFTopologyNode
*iface
, REFIID riid
, void **out
)
909 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
911 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
913 if (IsEqualIID(riid
, &IID_IMFTopologyNode
) ||
914 IsEqualIID(riid
, &IID_IMFAttributes
) ||
915 IsEqualIID(riid
, &IID_IUnknown
))
917 *out
= &node
->IMFTopologyNode_iface
;
918 IMFTopologyNode_AddRef(iface
);
922 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
925 return E_NOINTERFACE
;
928 static ULONG WINAPI
topology_node_AddRef(IMFTopologyNode
*iface
)
930 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
931 ULONG refcount
= InterlockedIncrement(&node
->refcount
);
933 TRACE("%p, refcount %lu.\n", iface
, refcount
);
938 static ULONG WINAPI
topology_node_Release(IMFTopologyNode
*iface
)
940 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
941 ULONG refcount
= InterlockedDecrement(&node
->refcount
);
944 TRACE("%p, refcount %lu.\n", iface
, refcount
);
949 IUnknown_Release(node
->object
);
950 if (node
->input_type
)
951 IMFMediaType_Release(node
->input_type
);
952 for (i
= 0; i
< node
->inputs
.count
; ++i
)
954 if (node
->inputs
.streams
[i
].preferred_type
)
955 IMFMediaType_Release(node
->inputs
.streams
[i
].preferred_type
);
957 for (i
= 0; i
< node
->outputs
.count
; ++i
)
959 if (node
->outputs
.streams
[i
].preferred_type
)
960 IMFMediaType_Release(node
->outputs
.streams
[i
].preferred_type
);
962 free(node
->inputs
.streams
);
963 free(node
->outputs
.streams
);
964 IMFAttributes_Release(node
->attributes
);
965 DeleteCriticalSection(&node
->cs
);
972 static HRESULT WINAPI
topology_node_GetItem(IMFTopologyNode
*iface
, REFGUID key
, PROPVARIANT
*value
)
974 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
976 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
978 return IMFAttributes_GetItem(node
->attributes
, key
, value
);
981 static HRESULT WINAPI
topology_node_GetItemType(IMFTopologyNode
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
983 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
985 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
987 return IMFAttributes_GetItemType(node
->attributes
, key
, type
);
990 static HRESULT WINAPI
topology_node_CompareItem(IMFTopologyNode
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
992 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
994 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
996 return IMFAttributes_CompareItem(node
->attributes
, key
, value
, result
);
999 static HRESULT WINAPI
topology_node_Compare(IMFTopologyNode
*iface
, IMFAttributes
*theirs
,
1000 MF_ATTRIBUTES_MATCH_TYPE type
, BOOL
*result
)
1002 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1004 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
1006 return IMFAttributes_Compare(node
->attributes
, theirs
, type
, result
);
1009 static HRESULT WINAPI
topology_node_GetUINT32(IMFTopologyNode
*iface
, REFGUID key
, UINT32
*value
)
1011 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1013 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1015 return IMFAttributes_GetUINT32(node
->attributes
, key
, value
);
1018 static HRESULT WINAPI
topology_node_GetUINT64(IMFTopologyNode
*iface
, REFGUID key
, UINT64
*value
)
1020 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1022 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1024 return IMFAttributes_GetUINT64(node
->attributes
, key
, value
);
1027 static HRESULT WINAPI
topology_node_GetDouble(IMFTopologyNode
*iface
, REFGUID key
, double *value
)
1029 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1031 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1033 return IMFAttributes_GetDouble(node
->attributes
, key
, value
);
1036 static HRESULT WINAPI
topology_node_GetGUID(IMFTopologyNode
*iface
, REFGUID key
, GUID
*value
)
1038 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1040 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1042 return IMFAttributes_GetGUID(node
->attributes
, key
, value
);
1045 static HRESULT WINAPI
topology_node_GetStringLength(IMFTopologyNode
*iface
, REFGUID key
, UINT32
*length
)
1047 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1049 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
1051 return IMFAttributes_GetStringLength(node
->attributes
, key
, length
);
1054 static HRESULT WINAPI
topology_node_GetString(IMFTopologyNode
*iface
, REFGUID key
, WCHAR
*value
,
1055 UINT32 size
, UINT32
*length
)
1057 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1059 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
1061 return IMFAttributes_GetString(node
->attributes
, key
, value
, size
, length
);
1064 static HRESULT WINAPI
topology_node_GetAllocatedString(IMFTopologyNode
*iface
, REFGUID key
,
1065 WCHAR
**value
, UINT32
*length
)
1067 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1069 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
1071 return IMFAttributes_GetAllocatedString(node
->attributes
, key
, value
, length
);
1074 static HRESULT WINAPI
topology_node_GetBlobSize(IMFTopologyNode
*iface
, REFGUID key
, UINT32
*size
)
1076 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1078 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
1080 return IMFAttributes_GetBlobSize(node
->attributes
, key
, size
);
1083 static HRESULT WINAPI
topology_node_GetBlob(IMFTopologyNode
*iface
, REFGUID key
, UINT8
*buf
,
1084 UINT32 bufsize
, UINT32
*blobsize
)
1086 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1088 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
1090 return IMFAttributes_GetBlob(node
->attributes
, key
, buf
, bufsize
, blobsize
);
1093 static HRESULT WINAPI
topology_node_GetAllocatedBlob(IMFTopologyNode
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
1095 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1097 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
1099 return IMFAttributes_GetAllocatedBlob(node
->attributes
, key
, buf
, size
);
1102 static HRESULT WINAPI
topology_node_GetUnknown(IMFTopologyNode
*iface
, REFGUID key
, REFIID riid
, void **ppv
)
1104 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1106 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), ppv
);
1108 return IMFAttributes_GetUnknown(node
->attributes
, key
, riid
, ppv
);
1111 static HRESULT WINAPI
topology_node_SetItem(IMFTopologyNode
*iface
, REFGUID key
, REFPROPVARIANT value
)
1113 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1115 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
1117 return IMFAttributes_SetItem(node
->attributes
, key
, value
);
1120 static HRESULT WINAPI
topology_node_DeleteItem(IMFTopologyNode
*iface
, REFGUID key
)
1122 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1124 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
1126 return IMFAttributes_DeleteItem(node
->attributes
, key
);
1129 static HRESULT WINAPI
topology_node_DeleteAllItems(IMFTopologyNode
*iface
)
1131 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1133 TRACE("%p.\n", iface
);
1135 return IMFAttributes_DeleteAllItems(node
->attributes
);
1138 static HRESULT WINAPI
topology_node_SetUINT32(IMFTopologyNode
*iface
, REFGUID key
, UINT32 value
)
1140 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1142 TRACE("%p, %s, %d.\n", iface
, debugstr_guid(key
), value
);
1144 return IMFAttributes_SetUINT32(node
->attributes
, key
, value
);
1147 static HRESULT WINAPI
topology_node_SetUINT64(IMFTopologyNode
*iface
, REFGUID key
, UINT64 value
)
1149 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1151 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
1153 return IMFAttributes_SetUINT64(node
->attributes
, key
, value
);
1156 static HRESULT WINAPI
topology_node_SetDouble(IMFTopologyNode
*iface
, REFGUID key
, double value
)
1158 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1160 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
1162 return IMFAttributes_SetDouble(node
->attributes
, key
, value
);
1165 static HRESULT WINAPI
topology_node_SetGUID(IMFTopologyNode
*iface
, REFGUID key
, REFGUID value
)
1167 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1169 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
1171 return IMFAttributes_SetGUID(node
->attributes
, key
, value
);
1174 static HRESULT WINAPI
topology_node_SetString(IMFTopologyNode
*iface
, REFGUID key
, const WCHAR
*value
)
1176 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1178 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
1180 return IMFAttributes_SetString(node
->attributes
, key
, value
);
1183 static HRESULT WINAPI
topology_node_SetBlob(IMFTopologyNode
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
1185 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1187 TRACE("%p, %s, %p, %d.\n", iface
, debugstr_guid(key
), buf
, size
);
1189 return IMFAttributes_SetBlob(node
->attributes
, key
, buf
, size
);
1192 static HRESULT WINAPI
topology_node_SetUnknown(IMFTopologyNode
*iface
, REFGUID key
, IUnknown
*unknown
)
1194 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1196 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), unknown
);
1198 return IMFAttributes_SetUnknown(node
->attributes
, key
, unknown
);
1201 static HRESULT WINAPI
topology_node_LockStore(IMFTopologyNode
*iface
)
1203 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1205 TRACE("%p.\n", iface
);
1207 return IMFAttributes_LockStore(node
->attributes
);
1210 static HRESULT WINAPI
topology_node_UnlockStore(IMFTopologyNode
*iface
)
1212 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1214 TRACE("%p.\n", iface
);
1216 return IMFAttributes_UnlockStore(node
->attributes
);
1219 static HRESULT WINAPI
topology_node_GetCount(IMFTopologyNode
*iface
, UINT32
*count
)
1221 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1223 TRACE("%p, %p.\n", iface
, count
);
1225 return IMFAttributes_GetCount(node
->attributes
, count
);
1228 static HRESULT WINAPI
topology_node_GetItemByIndex(IMFTopologyNode
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
1230 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1232 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
1234 return IMFAttributes_GetItemByIndex(node
->attributes
, index
, key
, value
);
1237 static HRESULT WINAPI
topology_node_CopyAllItems(IMFTopologyNode
*iface
, IMFAttributes
*dest
)
1239 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1241 TRACE("%p, %p.\n", iface
, dest
);
1243 return IMFAttributes_CopyAllItems(node
->attributes
, dest
);
1246 static HRESULT
topology_node_set_object(struct topology_node
*node
, IUnknown
*object
)
1248 static const GUID
*iids
[3] = { &IID_IPersist
, &IID_IPersistStorage
, &IID_IPersistPropertyBag
};
1249 IPersist
*persist
= NULL
;
1255 has_object_id
= IMFAttributes_GetGUID(node
->attributes
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &object_id
) == S_OK
;
1257 if (object
&& !has_object_id
)
1259 for (i
= 0; i
< ARRAY_SIZE(iids
); ++i
)
1262 if (SUCCEEDED(hr
= IUnknown_QueryInterface(object
, iids
[i
], (void **)&persist
)))
1268 if (FAILED(hr
= IPersist_GetClassID(persist
, &object_id
)))
1270 IPersist_Release(persist
);
1276 EnterCriticalSection(&node
->cs
);
1279 IUnknown_Release(node
->object
);
1280 node
->object
= object
;
1282 IUnknown_AddRef(node
->object
);
1285 IMFAttributes_SetGUID(node
->attributes
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &object_id
);
1287 LeaveCriticalSection(&node
->cs
);
1290 IPersist_Release(persist
);
1295 static HRESULT WINAPI
topology_node_SetObject(IMFTopologyNode
*iface
, IUnknown
*object
)
1297 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1299 TRACE("%p, %p.\n", iface
, object
);
1301 return topology_node_set_object(node
, object
);
1304 static HRESULT WINAPI
topology_node_GetObject(IMFTopologyNode
*iface
, IUnknown
**object
)
1306 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1308 TRACE("%p, %p.\n", iface
, object
);
1313 EnterCriticalSection(&node
->cs
);
1315 *object
= node
->object
;
1317 IUnknown_AddRef(*object
);
1319 LeaveCriticalSection(&node
->cs
);
1321 return *object
? S_OK
: E_FAIL
;
1324 static HRESULT WINAPI
topology_node_GetNodeType(IMFTopologyNode
*iface
, MF_TOPOLOGY_TYPE
*node_type
)
1326 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1328 TRACE("%p, %p.\n", iface
, node_type
);
1330 *node_type
= node
->node_type
;
1335 static HRESULT WINAPI
topology_node_GetTopoNodeID(IMFTopologyNode
*iface
, TOPOID
*id
)
1337 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1339 TRACE("%p, %p.\n", iface
, id
);
1346 static HRESULT WINAPI
topology_node_SetTopoNodeID(IMFTopologyNode
*iface
, TOPOID id
)
1348 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1350 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(id
));
1357 static HRESULT WINAPI
topology_node_GetInputCount(IMFTopologyNode
*iface
, DWORD
*count
)
1359 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1361 TRACE("%p, %p.\n", iface
, count
);
1363 *count
= node
->inputs
.count
;
1368 static HRESULT WINAPI
topology_node_GetOutputCount(IMFTopologyNode
*iface
, DWORD
*count
)
1370 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1372 TRACE("%p, %p.\n", iface
, count
);
1374 *count
= node
->outputs
.count
;
1379 static void topology_node_set_stream_type(struct node_stream
*stream
, IMFMediaType
*mediatype
)
1381 if (stream
->preferred_type
)
1382 IMFMediaType_Release(stream
->preferred_type
);
1383 stream
->preferred_type
= mediatype
;
1384 if (stream
->preferred_type
)
1385 IMFMediaType_AddRef(stream
->preferred_type
);
1388 static HRESULT
topology_node_connect_output(struct topology_node
*node
, DWORD output_index
,
1389 struct topology_node
*connection
, DWORD input_index
)
1391 struct node_stream
*stream
;
1394 if (node
->node_type
== MF_TOPOLOGY_OUTPUT_NODE
|| connection
->node_type
== MF_TOPOLOGY_SOURCESTREAM_NODE
)
1397 EnterCriticalSection(&node
->cs
);
1398 EnterCriticalSection(&connection
->cs
);
1400 topology_node_disconnect_output(node
, output_index
);
1401 if (input_index
< connection
->inputs
.count
)
1403 stream
= &connection
->inputs
.streams
[input_index
];
1404 if (stream
->connection
)
1405 topology_node_disconnect_output(stream
->connection
, stream
->connection_stream
);
1408 hr
= topology_node_reserve_streams(&node
->outputs
, output_index
);
1411 size_t old_count
= connection
->inputs
.count
;
1412 hr
= topology_node_reserve_streams(&connection
->inputs
, input_index
);
1413 if (SUCCEEDED(hr
) && !old_count
&& connection
->input_type
)
1415 topology_node_set_stream_type(connection
->inputs
.streams
, connection
->input_type
);
1416 IMFMediaType_Release(connection
->input_type
);
1417 connection
->input_type
= NULL
;
1423 node
->outputs
.streams
[output_index
].connection
= connection
;
1424 IMFTopologyNode_AddRef(&node
->outputs
.streams
[output_index
].connection
->IMFTopologyNode_iface
);
1425 node
->outputs
.streams
[output_index
].connection_stream
= input_index
;
1426 connection
->inputs
.streams
[input_index
].connection
= node
;
1427 IMFTopologyNode_AddRef(&connection
->inputs
.streams
[input_index
].connection
->IMFTopologyNode_iface
);
1428 connection
->inputs
.streams
[input_index
].connection_stream
= output_index
;
1431 LeaveCriticalSection(&connection
->cs
);
1432 LeaveCriticalSection(&node
->cs
);
1437 static HRESULT WINAPI
topology_node_ConnectOutput(IMFTopologyNode
*iface
, DWORD output_index
,
1438 IMFTopologyNode
*peer
, DWORD input_index
)
1440 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1441 struct topology_node
*connection
= unsafe_impl_from_IMFTopologyNode(peer
);
1443 TRACE("%p, %lu, %p, %lu.\n", iface
, output_index
, peer
, input_index
);
1447 WARN("External node implementations are not supported.\n");
1448 return E_UNEXPECTED
;
1451 return topology_node_connect_output(node
, output_index
, connection
, input_index
);
1454 static HRESULT WINAPI
topology_node_DisconnectOutput(IMFTopologyNode
*iface
, DWORD output_index
)
1456 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1458 TRACE("%p, %lu.\n", iface
, output_index
);
1460 return topology_node_disconnect_output(node
, output_index
);
1463 static HRESULT WINAPI
topology_node_GetInput(IMFTopologyNode
*iface
, DWORD input_index
, IMFTopologyNode
**ret
,
1464 DWORD
*output_index
)
1466 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1469 TRACE("%p, %lu, %p, %p.\n", iface
, input_index
, ret
, output_index
);
1471 EnterCriticalSection(&node
->cs
);
1473 if (input_index
< node
->inputs
.count
)
1475 const struct node_stream
*stream
= &node
->inputs
.streams
[input_index
];
1477 if (stream
->connection
)
1479 *ret
= &stream
->connection
->IMFTopologyNode_iface
;
1480 IMFTopologyNode_AddRef(*ret
);
1481 *output_index
= stream
->connection_stream
;
1484 hr
= MF_E_NOT_FOUND
;
1489 LeaveCriticalSection(&node
->cs
);
1494 static HRESULT WINAPI
topology_node_GetOutput(IMFTopologyNode
*iface
, DWORD output_index
, IMFTopologyNode
**ret
,
1497 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1500 TRACE("%p, %lu, %p, %p.\n", iface
, output_index
, ret
, input_index
);
1502 EnterCriticalSection(&node
->cs
);
1504 if (output_index
< node
->outputs
.count
)
1506 const struct node_stream
*stream
= &node
->outputs
.streams
[output_index
];
1508 if (stream
->connection
)
1510 *ret
= &stream
->connection
->IMFTopologyNode_iface
;
1511 IMFTopologyNode_AddRef(*ret
);
1512 *input_index
= stream
->connection_stream
;
1515 hr
= MF_E_NOT_FOUND
;
1520 LeaveCriticalSection(&node
->cs
);
1525 static HRESULT WINAPI
topology_node_SetOutputPrefType(IMFTopologyNode
*iface
, DWORD index
, IMFMediaType
*mediatype
)
1527 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1530 TRACE("%p, %lu, %p.\n", iface
, index
, mediatype
);
1532 EnterCriticalSection(&node
->cs
);
1534 if (node
->node_type
!= MF_TOPOLOGY_OUTPUT_NODE
)
1536 if (SUCCEEDED(hr
= topology_node_reserve_streams(&node
->outputs
, index
)))
1537 topology_node_set_stream_type(&node
->outputs
.streams
[index
], mediatype
);
1542 LeaveCriticalSection(&node
->cs
);
1547 static HRESULT
topology_node_get_pref_type(struct node_streams
*streams
, unsigned int index
, IMFMediaType
**mediatype
)
1549 *mediatype
= streams
->streams
[index
].preferred_type
;
1552 IMFMediaType_AddRef(*mediatype
);
1559 static HRESULT WINAPI
topology_node_GetOutputPrefType(IMFTopologyNode
*iface
, DWORD index
, IMFMediaType
**mediatype
)
1561 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1564 TRACE("%p, %lu, %p.\n", iface
, index
, mediatype
);
1566 EnterCriticalSection(&node
->cs
);
1568 if (index
< node
->outputs
.count
)
1569 hr
= topology_node_get_pref_type(&node
->outputs
, index
, mediatype
);
1573 LeaveCriticalSection(&node
->cs
);
1578 static HRESULT WINAPI
topology_node_SetInputPrefType(IMFTopologyNode
*iface
, DWORD index
, IMFMediaType
*mediatype
)
1580 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1583 TRACE("%p, %lu, %p.\n", iface
, index
, mediatype
);
1585 EnterCriticalSection(&node
->cs
);
1587 switch (node
->node_type
)
1589 case MF_TOPOLOGY_TEE_NODE
:
1592 hr
= MF_E_INVALIDTYPE
;
1595 if (node
->inputs
.count
)
1596 topology_node_set_stream_type(&node
->inputs
.streams
[index
], mediatype
);
1599 if (node
->input_type
)
1600 IMFMediaType_Release(node
->input_type
);
1601 node
->input_type
= mediatype
;
1602 if (node
->input_type
)
1603 IMFMediaType_AddRef(node
->input_type
);
1606 case MF_TOPOLOGY_SOURCESTREAM_NODE
:
1610 if (SUCCEEDED(hr
= topology_node_reserve_streams(&node
->inputs
, index
)))
1611 topology_node_set_stream_type(&node
->inputs
.streams
[index
], mediatype
);
1614 LeaveCriticalSection(&node
->cs
);
1619 static HRESULT WINAPI
topology_node_GetInputPrefType(IMFTopologyNode
*iface
, DWORD index
, IMFMediaType
**mediatype
)
1621 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1624 TRACE("%p, %lu, %p.\n", iface
, index
, mediatype
);
1626 EnterCriticalSection(&node
->cs
);
1628 if (index
< node
->inputs
.count
)
1630 hr
= topology_node_get_pref_type(&node
->inputs
, index
, mediatype
);
1632 else if (node
->node_type
== MF_TOPOLOGY_TEE_NODE
&& node
->input_type
)
1634 *mediatype
= node
->input_type
;
1635 IMFMediaType_AddRef(*mediatype
);
1640 LeaveCriticalSection(&node
->cs
);
1645 static HRESULT WINAPI
topology_node_CloneFrom(IMFTopologyNode
*iface
, IMFTopologyNode
*src_node
)
1647 struct topology_node
*node
= impl_from_IMFTopologyNode(iface
);
1648 MF_TOPOLOGY_TYPE node_type
;
1649 IMFMediaType
*mediatype
;
1655 TRACE("%p, %p.\n", iface
, src_node
);
1657 if (FAILED(hr
= IMFTopologyNode_GetNodeType(src_node
, &node_type
)))
1660 if (node
->node_type
!= node_type
)
1661 return MF_E_INVALIDREQUEST
;
1663 if (FAILED(hr
= IMFTopologyNode_GetTopoNodeID(src_node
, &topoid
)))
1667 IMFTopologyNode_GetObject(src_node
, &object
);
1669 EnterCriticalSection(&node
->cs
);
1671 hr
= IMFTopologyNode_CopyAllItems(src_node
, node
->attributes
);
1674 hr
= topology_node_set_object(node
, object
);
1679 if (SUCCEEDED(IMFTopologyNode_GetInputCount(src_node
, &count
)))
1681 for (i
= 0; i
< count
; ++i
)
1683 if (SUCCEEDED(IMFTopologyNode_GetInputPrefType(src_node
, i
, &mediatype
)))
1685 IMFTopologyNode_SetInputPrefType(iface
, i
, mediatype
);
1686 IMFMediaType_Release(mediatype
);
1691 if (SUCCEEDED(IMFTopologyNode_GetOutputCount(src_node
, &count
)))
1693 for (i
= 0; i
< count
; ++i
)
1695 if (SUCCEEDED(IMFTopologyNode_GetOutputPrefType(src_node
, i
, &mediatype
)))
1697 IMFTopologyNode_SetOutputPrefType(iface
, i
, mediatype
);
1698 IMFMediaType_Release(mediatype
);
1703 LeaveCriticalSection(&node
->cs
);
1706 IUnknown_Release(object
);
1711 static const IMFTopologyNodeVtbl topologynodevtbl
=
1713 topology_node_QueryInterface
,
1714 topology_node_AddRef
,
1715 topology_node_Release
,
1716 topology_node_GetItem
,
1717 topology_node_GetItemType
,
1718 topology_node_CompareItem
,
1719 topology_node_Compare
,
1720 topology_node_GetUINT32
,
1721 topology_node_GetUINT64
,
1722 topology_node_GetDouble
,
1723 topology_node_GetGUID
,
1724 topology_node_GetStringLength
,
1725 topology_node_GetString
,
1726 topology_node_GetAllocatedString
,
1727 topology_node_GetBlobSize
,
1728 topology_node_GetBlob
,
1729 topology_node_GetAllocatedBlob
,
1730 topology_node_GetUnknown
,
1731 topology_node_SetItem
,
1732 topology_node_DeleteItem
,
1733 topology_node_DeleteAllItems
,
1734 topology_node_SetUINT32
,
1735 topology_node_SetUINT64
,
1736 topology_node_SetDouble
,
1737 topology_node_SetGUID
,
1738 topology_node_SetString
,
1739 topology_node_SetBlob
,
1740 topology_node_SetUnknown
,
1741 topology_node_LockStore
,
1742 topology_node_UnlockStore
,
1743 topology_node_GetCount
,
1744 topology_node_GetItemByIndex
,
1745 topology_node_CopyAllItems
,
1746 topology_node_SetObject
,
1747 topology_node_GetObject
,
1748 topology_node_GetNodeType
,
1749 topology_node_GetTopoNodeID
,
1750 topology_node_SetTopoNodeID
,
1751 topology_node_GetInputCount
,
1752 topology_node_GetOutputCount
,
1753 topology_node_ConnectOutput
,
1754 topology_node_DisconnectOutput
,
1755 topology_node_GetInput
,
1756 topology_node_GetOutput
,
1757 topology_node_SetOutputPrefType
,
1758 topology_node_GetOutputPrefType
,
1759 topology_node_SetInputPrefType
,
1760 topology_node_GetInputPrefType
,
1761 topology_node_CloneFrom
,
1764 static HRESULT
create_topology_node(MF_TOPOLOGY_TYPE node_type
, struct topology_node
**node
)
1768 if (!(*node
= calloc(1, sizeof(**node
))))
1769 return E_OUTOFMEMORY
;
1771 (*node
)->IMFTopologyNode_iface
.lpVtbl
= &topologynodevtbl
;
1772 (*node
)->refcount
= 1;
1773 (*node
)->node_type
= node_type
;
1774 hr
= MFCreateAttributes(&(*node
)->attributes
, 0);
1780 (*node
)->id
= ((TOPOID
)GetCurrentProcessId() << 32) | InterlockedIncrement(&next_node_id
);
1781 InitializeCriticalSection(&(*node
)->cs
);
1786 HRESULT
topology_node_get_object(IMFTopologyNode
*node
, REFIID riid
, void **obj
)
1793 if (SUCCEEDED(hr
= IMFTopologyNode_GetObject(node
, &unk
)))
1795 hr
= IUnknown_QueryInterface(unk
, riid
, obj
);
1796 IUnknown_Release(unk
);
1802 /***********************************************************************
1803 * MFCreateTopologyNode (mf.@)
1805 HRESULT WINAPI
MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type
, IMFTopologyNode
**node
)
1807 struct topology_node
*object
;
1810 TRACE("%d, %p.\n", node_type
, node
);
1815 hr
= create_topology_node(node_type
, &object
);
1817 *node
= &object
->IMFTopologyNode_iface
;
1822 /* private helper for node types without an actual IMFMediaTypeHandler */
1825 IMFMediaTypeHandler IMFMediaTypeHandler_iface
;
1828 IMFTopologyNode
*node
;
1832 IMFTransform
*transform
;
1835 static struct type_handler
*impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler
*iface
)
1837 return CONTAINING_RECORD(iface
, struct type_handler
, IMFMediaTypeHandler_iface
);
1840 static HRESULT WINAPI
type_handler_QueryInterface(IMFMediaTypeHandler
*iface
, REFIID riid
, void **obj
)
1842 if (IsEqualIID(riid
, &IID_IMFMediaTypeHandler
)
1843 || IsEqualIID(riid
, &IID_IUnknown
))
1845 IMFMediaTypeHandler_AddRef((*obj
= iface
));
1850 return E_NOINTERFACE
;
1853 static ULONG WINAPI
type_handler_AddRef(IMFMediaTypeHandler
*iface
)
1855 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1856 ULONG refcount
= InterlockedIncrement(&handler
->refcount
);
1860 static ULONG WINAPI
type_handler_Release(IMFMediaTypeHandler
*iface
)
1862 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1863 ULONG refcount
= InterlockedDecrement(&handler
->refcount
);
1867 if (handler
->transform
)
1868 IMFTransform_Release(handler
->transform
);
1869 IMFTopologyNode_Release(handler
->node
);
1876 static HRESULT WINAPI
type_handler_IsMediaTypeSupported(IMFMediaTypeHandler
*iface
, IMFMediaType
*in_type
,
1877 IMFMediaType
**out_type
)
1879 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1887 if (handler
->transform
)
1889 if (handler
->output
)
1890 return IMFTransform_SetOutputType(handler
->transform
, handler
->stream
, in_type
, MFT_SET_TYPE_TEST_ONLY
);
1892 return IMFTransform_SetInputType(handler
->transform
, handler
->stream
, in_type
, MFT_SET_TYPE_TEST_ONLY
);
1895 if (FAILED(hr
= IMFMediaTypeHandler_GetCurrentMediaType(iface
, &type
)))
1898 hr
= IMFMediaType_IsEqual(type
, in_type
, &flags
);
1899 IMFMediaType_Release(type
);
1903 static HRESULT WINAPI
type_handler_GetMediaTypeCount(IMFMediaTypeHandler
*iface
, DWORD
*count
)
1908 static HRESULT WINAPI
type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler
*iface
, DWORD index
,
1909 IMFMediaType
**type
)
1911 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1913 if (handler
->transform
)
1915 if (handler
->output
)
1916 return IMFTransform_GetOutputAvailableType(handler
->transform
, handler
->stream
, index
, type
);
1918 return IMFTransform_GetInputAvailableType(handler
->transform
, handler
->stream
, index
, type
);
1922 return MF_E_NO_MORE_TYPES
;
1924 return IMFMediaTypeHandler_GetCurrentMediaType(iface
, type
);
1927 static HRESULT WINAPI
type_handler_SetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
*type
)
1929 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1931 if (handler
->transform
)
1933 if (handler
->output
)
1934 return IMFTransform_SetOutputType(handler
->transform
, handler
->stream
, type
, 0);
1936 return IMFTransform_SetInputType(handler
->transform
, handler
->stream
, type
, 0);
1939 return IMFTopologyNode_SetInputPrefType(handler
->node
, handler
->stream
, type
);
1942 static HRESULT WINAPI
type_handler_GetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
**type
)
1944 struct type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1947 if (handler
->transform
)
1949 if (handler
->output
)
1950 return IMFTransform_GetOutputCurrentType(handler
->transform
, handler
->stream
, type
);
1952 return IMFTransform_GetInputCurrentType(handler
->transform
, handler
->stream
, type
);
1955 if (SUCCEEDED(IMFTopologyNode_GetInputPrefType(handler
->node
, 0, type
)))
1958 if (FAILED(IMFTopologyNode_GetUINT32(handler
->node
, &MF_TOPONODE_PRIMARYOUTPUT
, &output
)))
1961 return IMFTopologyNode_GetOutputPrefType(handler
->node
, output
, type
);
1964 static HRESULT WINAPI
type_handler_GetMajorType(IMFMediaTypeHandler
*iface
, GUID
*type
)
1966 IMFMediaType
*media_type
;
1969 if (FAILED(hr
= IMFMediaTypeHandler_GetCurrentMediaType(iface
, &media_type
)))
1972 hr
= IMFMediaType_GetMajorType(media_type
, type
);
1973 IMFMediaType_Release(media_type
);
1977 static const IMFMediaTypeHandlerVtbl type_handler_vtbl
=
1979 type_handler_QueryInterface
,
1980 type_handler_AddRef
,
1981 type_handler_Release
,
1982 type_handler_IsMediaTypeSupported
,
1983 type_handler_GetMediaTypeCount
,
1984 type_handler_GetMediaTypeByIndex
,
1985 type_handler_SetCurrentMediaType
,
1986 type_handler_GetCurrentMediaType
,
1987 type_handler_GetMajorType
,
1990 static HRESULT
type_handler_create(IMFTopologyNode
*node
, DWORD stream
, BOOL output
, IMFTransform
*transform
, IMFMediaTypeHandler
**out
)
1992 struct type_handler
*handler
;
1994 if (!(handler
= calloc(1, sizeof(*handler
)))) return E_OUTOFMEMORY
;
1995 handler
->IMFMediaTypeHandler_iface
.lpVtbl
= &type_handler_vtbl
;
1996 handler
->refcount
= 1;
1997 handler
->stream
= stream
;
1998 handler
->output
= output
;
1999 IMFTopologyNode_AddRef((handler
->node
= node
));
2001 IMFTransform_AddRef((handler
->transform
= transform
));
2003 *out
= &handler
->IMFMediaTypeHandler_iface
;
2007 HRESULT
topology_node_get_type_handler(IMFTopologyNode
*node
, DWORD stream
,
2008 BOOL output
, IMFMediaTypeHandler
**handler
)
2010 MF_TOPOLOGY_TYPE node_type
;
2011 IMFStreamSink
*stream_sink
;
2012 IMFStreamDescriptor
*sd
;
2013 IMFTransform
*transform
;
2016 if (FAILED(hr
= IMFTopologyNode_GetNodeType(node
, &node_type
)))
2021 case MF_TOPOLOGY_OUTPUT_NODE
:
2022 if (output
|| stream
)
2023 return MF_E_INVALIDSTREAMNUMBER
;
2025 if (SUCCEEDED(hr
= topology_node_get_object(node
, &IID_IMFStreamSink
, (void **)&stream_sink
)))
2027 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, handler
);
2028 IMFStreamSink_Release(stream_sink
);
2031 case MF_TOPOLOGY_SOURCESTREAM_NODE
:
2032 if (!output
|| stream
)
2033 return MF_E_INVALIDSTREAMNUMBER
;
2035 if (SUCCEEDED(hr
= IMFTopologyNode_GetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
,
2036 &IID_IMFStreamDescriptor
, (void **)&sd
)))
2038 hr
= IMFStreamDescriptor_GetMediaTypeHandler(sd
, handler
);
2039 IMFStreamDescriptor_Release(sd
);
2042 case MF_TOPOLOGY_TRANSFORM_NODE
:
2043 if (SUCCEEDED(hr
= topology_node_get_object(node
, &IID_IMFTransform
, (void **)&transform
)))
2045 hr
= type_handler_create(node
, stream
, output
, transform
, handler
);
2046 IMFTransform_Release(transform
);
2049 case MF_TOPOLOGY_TEE_NODE
:
2050 hr
= type_handler_create(node
, stream
, output
, NULL
, handler
);
2053 WARN("Unexpected node type %u.\n", node_type
);
2054 return MF_E_UNEXPECTED
;
2060 /***********************************************************************
2061 * MFGetTopoNodeCurrentType (mf.@)
2063 HRESULT WINAPI
MFGetTopoNodeCurrentType(IMFTopologyNode
*node
, DWORD stream
, BOOL output
, IMFMediaType
**type
)
2065 IMFMediaTypeHandler
*handler
;
2068 TRACE("%p, %lu, %d, %p.\n", node
, stream
, output
, type
);
2070 if (FAILED(hr
= topology_node_get_type_handler(node
, stream
, output
, &handler
)))
2073 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, type
);
2074 IMFMediaTypeHandler_Release(handler
);
2078 static HRESULT WINAPI
seq_source_QueryInterface(IMFSequencerSource
*iface
, REFIID riid
, void **out
)
2080 struct seq_source
*seq_source
= impl_from_IMFSequencerSource(iface
);
2082 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2086 if (IsEqualIID(riid
, &IID_IMFSequencerSource
) ||
2087 IsEqualIID(riid
, &IID_IUnknown
))
2089 *out
= &seq_source
->IMFSequencerSource_iface
;
2091 else if (IsEqualIID(riid
, &IID_IMFMediaSourceTopologyProvider
))
2093 *out
= &seq_source
->IMFMediaSourceTopologyProvider_iface
;
2097 WARN("Unimplemented %s.\n", debugstr_guid(riid
));
2098 return E_NOINTERFACE
;
2102 IUnknown_AddRef((IUnknown
*)*out
);
2107 static ULONG WINAPI
seq_source_AddRef(IMFSequencerSource
*iface
)
2109 struct seq_source
*seq_source
= impl_from_IMFSequencerSource(iface
);
2110 ULONG refcount
= InterlockedIncrement(&seq_source
->refcount
);
2112 TRACE("%p, refcount %lu.\n", iface
, refcount
);
2117 static ULONG WINAPI
seq_source_Release(IMFSequencerSource
*iface
)
2119 struct seq_source
*seq_source
= impl_from_IMFSequencerSource(iface
);
2120 ULONG refcount
= InterlockedDecrement(&seq_source
->refcount
);
2122 TRACE("%p, refcount %lu.\n", iface
, refcount
);
2130 static HRESULT WINAPI
seq_source_AppendTopology(IMFSequencerSource
*iface
, IMFTopology
*topology
,
2131 DWORD flags
, MFSequencerElementId
*id
)
2133 FIXME("%p, %p, %lx, %p.\n", iface
, topology
, flags
, id
);
2138 static HRESULT WINAPI
seq_source_DeleteTopology(IMFSequencerSource
*iface
, MFSequencerElementId id
)
2140 FIXME("%p, %#lx.\n", iface
, id
);
2145 static HRESULT WINAPI
seq_source_GetPresentationContext(IMFSequencerSource
*iface
,
2146 IMFPresentationDescriptor
*descriptor
, MFSequencerElementId
*id
, IMFTopology
**topology
)
2148 FIXME("%p, %p, %p, %p.\n", iface
, descriptor
, id
, topology
);
2153 static HRESULT WINAPI
seq_source_UpdateTopology(IMFSequencerSource
*iface
, MFSequencerElementId id
,
2154 IMFTopology
*topology
)
2156 FIXME("%p, %#lx, %p.\n", iface
, id
, topology
);
2161 static HRESULT WINAPI
seq_source_UpdateTopologyFlags(IMFSequencerSource
*iface
, MFSequencerElementId id
, DWORD flags
)
2163 FIXME("%p, %#lx, %#lx.\n", iface
, id
, flags
);
2168 static HRESULT WINAPI
seq_source_topology_provider_QueryInterface(IMFMediaSourceTopologyProvider
*iface
, REFIID riid
,
2171 struct seq_source
*seq_source
= impl_from_IMFMediaSourceTopologyProvider(iface
);
2172 return IMFSequencerSource_QueryInterface(&seq_source
->IMFSequencerSource_iface
, riid
, obj
);
2175 static ULONG WINAPI
seq_source_topology_provider_AddRef(IMFMediaSourceTopologyProvider
*iface
)
2177 struct seq_source
*seq_source
= impl_from_IMFMediaSourceTopologyProvider(iface
);
2178 return IMFSequencerSource_AddRef(&seq_source
->IMFSequencerSource_iface
);
2181 static ULONG WINAPI
seq_source_topology_provider_Release(IMFMediaSourceTopologyProvider
*iface
)
2183 struct seq_source
*seq_source
= impl_from_IMFMediaSourceTopologyProvider(iface
);
2184 return IMFSequencerSource_Release(&seq_source
->IMFSequencerSource_iface
);
2187 static HRESULT WINAPI
seq_source_topology_provider_GetMediaSourceTopology(IMFMediaSourceTopologyProvider
*iface
,
2188 IMFPresentationDescriptor
*pd
, IMFTopology
**topology
)
2190 FIXME("%p, %p, %p.\n", iface
, pd
, topology
);
2195 static const IMFMediaSourceTopologyProviderVtbl seq_source_topology_provider_vtbl
=
2197 seq_source_topology_provider_QueryInterface
,
2198 seq_source_topology_provider_AddRef
,
2199 seq_source_topology_provider_Release
,
2200 seq_source_topology_provider_GetMediaSourceTopology
,
2203 static const IMFSequencerSourceVtbl seqsourcevtbl
=
2205 seq_source_QueryInterface
,
2208 seq_source_AppendTopology
,
2209 seq_source_DeleteTopology
,
2210 seq_source_GetPresentationContext
,
2211 seq_source_UpdateTopology
,
2212 seq_source_UpdateTopologyFlags
,
2215 /***********************************************************************
2216 * MFCreateSequencerSource (mf.@)
2218 HRESULT WINAPI
MFCreateSequencerSource(IUnknown
*reserved
, IMFSequencerSource
**seq_source
)
2220 struct seq_source
*object
;
2222 TRACE("%p, %p.\n", reserved
, seq_source
);
2227 if (!(object
= calloc(1, sizeof(*object
))))
2228 return E_OUTOFMEMORY
;
2230 object
->IMFSequencerSource_iface
.lpVtbl
= &seqsourcevtbl
;
2231 object
->IMFMediaSourceTopologyProvider_iface
.lpVtbl
= &seq_source_topology_provider_vtbl
;
2232 object
->refcount
= 1;
2234 *seq_source
= &object
->IMFSequencerSource_iface
;
2239 struct segment_offset
2241 IUnknown IUnknown_iface
;
2243 MFSequencerElementId id
;
2247 static inline struct segment_offset
*impl_offset_from_IUnknown(IUnknown
*iface
)
2249 return CONTAINING_RECORD(iface
, struct segment_offset
, IUnknown_iface
);
2252 static HRESULT WINAPI
segment_offset_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
2254 if (IsEqualIID(riid
, &IID_IUnknown
))
2257 IUnknown_AddRef(iface
);
2262 return E_NOINTERFACE
;
2265 static ULONG WINAPI
segment_offset_AddRef(IUnknown
*iface
)
2267 struct segment_offset
*offset
= impl_offset_from_IUnknown(iface
);
2268 return InterlockedIncrement(&offset
->refcount
);
2271 static ULONG WINAPI
segment_offset_Release(IUnknown
*iface
)
2273 struct segment_offset
*offset
= impl_offset_from_IUnknown(iface
);
2274 ULONG refcount
= InterlockedDecrement(&offset
->refcount
);
2282 static const IUnknownVtbl segment_offset_vtbl
=
2284 segment_offset_QueryInterface
,
2285 segment_offset_AddRef
,
2286 segment_offset_Release
,
2289 /***********************************************************************
2290 * MFCreateSequencerSegmentOffset (mf.@)
2292 HRESULT WINAPI
MFCreateSequencerSegmentOffset(MFSequencerElementId id
, MFTIME timeoffset
, PROPVARIANT
*ret
)
2294 struct segment_offset
*offset
;
2296 TRACE("%#lx, %s, %p.\n", id
, debugstr_time(timeoffset
), ret
);
2301 if (!(offset
= calloc(1, sizeof(*offset
))))
2302 return E_OUTOFMEMORY
;
2304 offset
->IUnknown_iface
.lpVtbl
= &segment_offset_vtbl
;
2305 offset
->refcount
= 1;
2307 offset
->timeoffset
= timeoffset
;
2309 V_VT(ret
) = VT_UNKNOWN
;
2310 V_UNKNOWN(ret
) = &offset
->IUnknown_iface
;