2 * Copyright 2014 Austin English
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
25 #define NONAMELESSUNION
39 #include "wine/debug.h"
40 #include "wine/list.h"
42 #include "mfplat_private.h"
43 #include "mfreadwrite.h"
44 #include "mfmediaengine.h"
45 #include "propvarutil.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
64 IMFActivate
*activate
;
67 static CRITICAL_SECTION local_handlers_section
= { NULL
, -1, 0, 0, 0, 0 };
69 static struct list local_scheme_handlers
= LIST_INIT(local_scheme_handlers
);
70 static struct list local_bytestream_handlers
= LIST_INIT(local_bytestream_handlers
);
72 struct mft_registration
75 IClassFactory
*factory
;
80 MFT_REGISTER_TYPE_INFO
*input_types
;
81 UINT32 input_types_count
;
82 MFT_REGISTER_TYPE_INFO
*output_types
;
83 UINT32 output_types_count
;
87 static CRITICAL_SECTION local_mfts_section
= { NULL
, -1, 0, 0, 0, 0 };
89 static struct list local_mfts
= LIST_INIT(local_mfts
);
91 struct transform_activate
93 struct attributes attributes
;
94 IMFActivate IMFActivate_iface
;
95 IClassFactory
*factory
;
96 IMFTransform
*transform
;
101 IMFClock IMFClock_iface
;
105 struct system_time_source
107 IMFPresentationTimeSource IMFPresentationTimeSource_iface
;
108 IMFClockStateSink IMFClockStateSink_iface
;
112 LONGLONG start_offset
;
118 static void system_time_source_apply_rate(const struct system_time_source
*source
, LONGLONG
*value
)
121 *value
*= source
->i_rate
;
123 *value
*= source
->rate
;
126 static struct system_time_source
*impl_from_IMFPresentationTimeSource(IMFPresentationTimeSource
*iface
)
128 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFPresentationTimeSource_iface
);
131 static struct system_time_source
*impl_from_IMFClockStateSink(IMFClockStateSink
*iface
)
133 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFClockStateSink_iface
);
136 static struct system_clock
*impl_from_IMFClock(IMFClock
*iface
)
138 return CONTAINING_RECORD(iface
, struct system_clock
, IMFClock_iface
);
141 static struct transform_activate
*impl_from_IMFActivate(IMFActivate
*iface
)
143 return CONTAINING_RECORD(iface
, struct transform_activate
, IMFActivate_iface
);
146 static HRESULT WINAPI
transform_activate_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **out
)
148 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
150 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
151 IsEqualIID(riid
, &IID_IMFAttributes
) ||
152 IsEqualIID(riid
, &IID_IUnknown
))
155 IMFActivate_AddRef(iface
);
159 WARN("Unsupported %s.\n", debugstr_guid(riid
));
161 return E_NOINTERFACE
;
164 static ULONG WINAPI
transform_activate_AddRef(IMFActivate
*iface
)
166 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
167 ULONG refcount
= InterlockedIncrement(&activate
->attributes
.ref
);
169 TRACE("%p, refcount %u.\n", iface
, refcount
);
174 static ULONG WINAPI
transform_activate_Release(IMFActivate
*iface
)
176 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
177 ULONG refcount
= InterlockedDecrement(&activate
->attributes
.ref
);
179 TRACE("%p, refcount %u.\n", iface
, refcount
);
183 clear_attributes_object(&activate
->attributes
);
184 if (activate
->factory
)
185 IClassFactory_Release(activate
->factory
);
186 if (activate
->transform
)
187 IMFTransform_Release(activate
->transform
);
194 static HRESULT WINAPI
transform_activate_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
196 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
198 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
200 return attributes_GetItem(&activate
->attributes
, key
, value
);
203 static HRESULT WINAPI
transform_activate_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
205 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
207 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
209 return attributes_GetItemType(&activate
->attributes
, key
, type
);
212 static HRESULT WINAPI
transform_activate_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
,
215 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
217 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
219 return attributes_CompareItem(&activate
->attributes
, key
, value
, result
);
222 static HRESULT WINAPI
transform_activate_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
,
223 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
225 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
227 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
229 return attributes_Compare(&activate
->attributes
, theirs
, match_type
, ret
);
232 static HRESULT WINAPI
transform_activate_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
234 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
236 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
238 return attributes_GetUINT32(&activate
->attributes
, key
, value
);
241 static HRESULT WINAPI
transform_activate_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
243 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
245 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
247 return attributes_GetUINT64(&activate
->attributes
, key
, value
);
250 static HRESULT WINAPI
transform_activate_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
252 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
254 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
256 return attributes_GetDouble(&activate
->attributes
, key
, value
);
259 static HRESULT WINAPI
transform_activate_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
261 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
263 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
265 return attributes_GetGUID(&activate
->attributes
, key
, value
);
268 static HRESULT WINAPI
transform_activate_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
270 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
272 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
274 return attributes_GetStringLength(&activate
->attributes
, key
, length
);
277 static HRESULT WINAPI
transform_activate_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
278 UINT32 size
, UINT32
*length
)
280 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
282 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
284 return attributes_GetString(&activate
->attributes
, key
, value
, size
, length
);
287 static HRESULT WINAPI
transform_activate_GetAllocatedString(IMFActivate
*iface
, REFGUID key
, WCHAR
**value
,
290 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
292 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
294 return attributes_GetAllocatedString(&activate
->attributes
, key
, value
, length
);
297 static HRESULT WINAPI
transform_activate_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
299 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
301 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
303 return attributes_GetBlobSize(&activate
->attributes
, key
, size
);
306 static HRESULT WINAPI
transform_activate_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
,
309 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
311 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
313 return attributes_GetBlob(&activate
->attributes
, key
, buf
, bufsize
, blobsize
);
316 static HRESULT WINAPI
transform_activate_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
318 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
320 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
322 return attributes_GetAllocatedBlob(&activate
->attributes
, key
, buf
, size
);
325 static HRESULT WINAPI
transform_activate_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **out
)
327 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
329 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
331 return attributes_GetUnknown(&activate
->attributes
, key
, riid
, out
);
334 static HRESULT WINAPI
transform_activate_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
336 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
338 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
340 return attributes_SetItem(&activate
->attributes
, key
, value
);
343 static HRESULT WINAPI
transform_activate_DeleteItem(IMFActivate
*iface
, REFGUID key
)
345 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
347 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
349 return attributes_DeleteItem(&activate
->attributes
, key
);
352 static HRESULT WINAPI
transform_activate_DeleteAllItems(IMFActivate
*iface
)
354 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
356 TRACE("%p.\n", iface
);
358 return attributes_DeleteAllItems(&activate
->attributes
);
361 static HRESULT WINAPI
transform_activate_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
363 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
365 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
367 return attributes_SetUINT32(&activate
->attributes
, key
, value
);
370 static HRESULT WINAPI
transform_activate_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
372 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
374 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
376 return attributes_SetUINT64(&activate
->attributes
, key
, value
);
379 static HRESULT WINAPI
transform_activate_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
381 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
383 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
385 return attributes_SetDouble(&activate
->attributes
, key
, value
);
388 static HRESULT WINAPI
transform_activate_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
390 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
392 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
394 return attributes_SetGUID(&activate
->attributes
, key
, value
);
397 static HRESULT WINAPI
transform_activate_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
399 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
401 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
403 return attributes_SetString(&activate
->attributes
, key
, value
);
406 static HRESULT WINAPI
transform_activate_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
408 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
410 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
412 return attributes_SetBlob(&activate
->attributes
, key
, buf
, size
);
415 static HRESULT WINAPI
transform_activate_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
417 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
419 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
421 return attributes_SetUnknown(&activate
->attributes
, key
, unknown
);
424 static HRESULT WINAPI
transform_activate_LockStore(IMFActivate
*iface
)
426 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
428 TRACE("%p.\n", iface
);
430 return attributes_LockStore(&activate
->attributes
);
433 static HRESULT WINAPI
transform_activate_UnlockStore(IMFActivate
*iface
)
435 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
437 TRACE("%p.\n", iface
);
439 return attributes_UnlockStore(&activate
->attributes
);
442 static HRESULT WINAPI
transform_activate_GetCount(IMFActivate
*iface
, UINT32
*count
)
444 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
446 TRACE("%p, %p.\n", iface
, count
);
448 return attributes_GetCount(&activate
->attributes
, count
);
451 static HRESULT WINAPI
transform_activate_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
,
454 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
456 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
458 return attributes_GetItemByIndex(&activate
->attributes
, index
, key
, value
);
461 static HRESULT WINAPI
transform_activate_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
463 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
465 TRACE("%p, %p.\n", iface
, dest
);
467 return attributes_CopyAllItems(&activate
->attributes
, dest
);
470 static HRESULT WINAPI
transform_activate_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
472 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
476 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
478 EnterCriticalSection(&activate
->attributes
.cs
);
480 if (!activate
->transform
)
482 if (activate
->factory
)
484 if (FAILED(hr
= IClassFactory_CreateInstance(activate
->factory
, NULL
, &IID_IMFTransform
,
485 (void **)&activate
->transform
)))
487 hr
= MF_E_INVALIDREQUEST
;
492 if (SUCCEEDED(hr
= attributes_GetGUID(&activate
->attributes
, &MFT_TRANSFORM_CLSID_Attribute
, &clsid
)))
494 if (FAILED(hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
495 (void **)&activate
->transform
)))
497 hr
= MF_E_INVALIDREQUEST
;
503 if (activate
->transform
)
504 hr
= IMFTransform_QueryInterface(activate
->transform
, riid
, obj
);
506 LeaveCriticalSection(&activate
->attributes
.cs
);
511 static HRESULT WINAPI
transform_activate_ShutdownObject(IMFActivate
*iface
)
513 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
515 TRACE("%p.\n", iface
);
517 EnterCriticalSection(&activate
->attributes
.cs
);
519 if (activate
->transform
)
521 IMFTransform_Release(activate
->transform
);
522 activate
->transform
= NULL
;
525 LeaveCriticalSection(&activate
->attributes
.cs
);
530 static HRESULT WINAPI
transform_activate_DetachObject(IMFActivate
*iface
)
532 TRACE("%p.\n", iface
);
537 static const IMFActivateVtbl transform_activate_vtbl
=
539 transform_activate_QueryInterface
,
540 transform_activate_AddRef
,
541 transform_activate_Release
,
542 transform_activate_GetItem
,
543 transform_activate_GetItemType
,
544 transform_activate_CompareItem
,
545 transform_activate_Compare
,
546 transform_activate_GetUINT32
,
547 transform_activate_GetUINT64
,
548 transform_activate_GetDouble
,
549 transform_activate_GetGUID
,
550 transform_activate_GetStringLength
,
551 transform_activate_GetString
,
552 transform_activate_GetAllocatedString
,
553 transform_activate_GetBlobSize
,
554 transform_activate_GetBlob
,
555 transform_activate_GetAllocatedBlob
,
556 transform_activate_GetUnknown
,
557 transform_activate_SetItem
,
558 transform_activate_DeleteItem
,
559 transform_activate_DeleteAllItems
,
560 transform_activate_SetUINT32
,
561 transform_activate_SetUINT64
,
562 transform_activate_SetDouble
,
563 transform_activate_SetGUID
,
564 transform_activate_SetString
,
565 transform_activate_SetBlob
,
566 transform_activate_SetUnknown
,
567 transform_activate_LockStore
,
568 transform_activate_UnlockStore
,
569 transform_activate_GetCount
,
570 transform_activate_GetItemByIndex
,
571 transform_activate_CopyAllItems
,
572 transform_activate_ActivateObject
,
573 transform_activate_ShutdownObject
,
574 transform_activate_DetachObject
,
577 static HRESULT
create_transform_activate(IClassFactory
*factory
, IMFActivate
**activate
)
579 struct transform_activate
*object
;
582 if (!(object
= calloc(1, sizeof(*object
))))
583 return E_OUTOFMEMORY
;
585 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
591 object
->IMFActivate_iface
.lpVtbl
= &transform_activate_vtbl
;
592 object
->factory
= factory
;
594 IClassFactory_AddRef(object
->factory
);
596 *activate
= &object
->IMFActivate_iface
;
601 HRESULT WINAPI
MFCreateTransformActivate(IMFActivate
**activate
)
603 TRACE("%p.\n", activate
);
605 return create_transform_activate(NULL
, activate
);
608 static const WCHAR transform_keyW
[] = L
"MediaFoundation\\Transforms";
609 static const WCHAR categories_keyW
[] = L
"MediaFoundation\\Transforms\\Categories";
611 static const BYTE guid_conv_table
[256] =
613 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
614 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
615 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
616 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
617 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
618 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
619 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
622 static WCHAR
* GUIDToString(WCHAR
*str
, REFGUID guid
)
624 swprintf(str
, 39, L
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
625 guid
->Data1
, guid
->Data2
, guid
->Data3
, guid
->Data4
[0], guid
->Data4
[1],
626 guid
->Data4
[2], guid
->Data4
[3], guid
->Data4
[4], guid
->Data4
[5],
627 guid
->Data4
[6], guid
->Data4
[7]);
632 static inline BOOL
is_valid_hex(WCHAR c
)
634 if (!(((c
>= '0') && (c
<= '9')) ||
635 ((c
>= 'a') && (c
<= 'f')) ||
636 ((c
>= 'A') && (c
<= 'F'))))
641 static BOOL
GUIDFromString(LPCWSTR s
, GUID
*id
)
645 /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
648 for (i
= 0; i
< 8; i
++)
650 if (!is_valid_hex(s
[i
])) return FALSE
;
651 id
->Data1
= (id
->Data1
<< 4) | guid_conv_table
[s
[i
]];
653 if (s
[8]!='-') return FALSE
;
656 for (i
= 9; i
< 13; i
++)
658 if (!is_valid_hex(s
[i
])) return FALSE
;
659 id
->Data2
= (id
->Data2
<< 4) | guid_conv_table
[s
[i
]];
661 if (s
[13]!='-') return FALSE
;
664 for (i
= 14; i
< 18; i
++)
666 if (!is_valid_hex(s
[i
])) return FALSE
;
667 id
->Data3
= (id
->Data3
<< 4) | guid_conv_table
[s
[i
]];
669 if (s
[18]!='-') return FALSE
;
671 for (i
= 19; i
< 36; i
+=2)
675 if (s
[i
]!='-') return FALSE
;
678 if (!is_valid_hex(s
[i
]) || !is_valid_hex(s
[i
+1])) return FALSE
;
679 id
->Data4
[(i
-19)/2] = guid_conv_table
[s
[i
]] << 4 | guid_conv_table
[s
[i
+1]];
682 if (!s
[36]) return TRUE
;
686 static HRESULT
register_transform(const CLSID
*clsid
, const WCHAR
*name
, UINT32 flags
,
687 UINT32 cinput
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
688 const MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
697 GUIDToString(buffer
, clsid
);
698 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s", transform_keyW
, buffer
);
700 if ((ret
= RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &hclsid
)))
701 hr
= HRESULT_FROM_WIN32(ret
);
705 size
= (lstrlenW(name
) + 1) * sizeof(WCHAR
);
706 if ((ret
= RegSetValueExW(hclsid
, NULL
, 0, REG_SZ
, (BYTE
*)name
, size
)))
707 hr
= HRESULT_FROM_WIN32(ret
);
710 if (SUCCEEDED(hr
) && cinput
&& input_types
)
712 size
= cinput
* sizeof(MFT_REGISTER_TYPE_INFO
);
713 if ((ret
= RegSetValueExW(hclsid
, L
"InputTypes", 0, REG_BINARY
, (BYTE
*)input_types
, size
)))
714 hr
= HRESULT_FROM_WIN32(ret
);
717 if (SUCCEEDED(hr
) && coutput
&& output_types
)
719 size
= coutput
* sizeof(MFT_REGISTER_TYPE_INFO
);
720 if ((ret
= RegSetValueExW(hclsid
, L
"OutputTypes", 0, REG_BINARY
, (BYTE
*)output_types
, size
)))
721 hr
= HRESULT_FROM_WIN32(ret
);
724 if (SUCCEEDED(hr
) && attributes
)
726 if (SUCCEEDED(hr
= MFGetAttributesAsBlobSize(attributes
, &size
)))
728 if ((blob
= malloc(size
)))
730 if (SUCCEEDED(hr
= MFGetAttributesAsBlob(attributes
, blob
, size
)))
732 if ((ret
= RegSetValueExW(hclsid
, L
"Attributes", 0, REG_BINARY
, blob
, size
)))
733 hr
= HRESULT_FROM_WIN32(ret
);
742 if (SUCCEEDED(hr
) && flags
)
744 if ((ret
= RegSetValueExW(hclsid
, L
"MFTFlags", 0, REG_DWORD
, (BYTE
*)&flags
, sizeof(flags
))))
745 hr
= HRESULT_FROM_WIN32(ret
);
752 static HRESULT
register_category(CLSID
*clsid
, GUID
*category
)
755 WCHAR guid1
[64], guid2
[64];
758 GUIDToString(guid1
, category
);
759 GUIDToString(guid2
, clsid
);
761 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s\\%s", categories_keyW
, guid1
, guid2
);
763 if (RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &htmp1
))
770 /***********************************************************************
771 * MFTRegister (mfplat.@)
773 HRESULT WINAPI
MFTRegister(CLSID clsid
, GUID category
, LPWSTR name
, UINT32 flags
, UINT32 cinput
,
774 MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
775 MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
779 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p, %p.\n", debugstr_guid(&clsid
), debugstr_guid(&category
),
780 debugstr_w(name
), flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
782 hr
= register_transform(&clsid
, name
, flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
784 ERR("Failed to write register transform\n");
787 hr
= register_category(&clsid
, &category
);
792 static void release_mft_registration(struct mft_registration
*mft
)
795 IClassFactory_Release(mft
->factory
);
797 free(mft
->input_types
);
798 free(mft
->output_types
);
802 static HRESULT
mft_register_local(IClassFactory
*factory
, REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
803 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
804 const MFT_REGISTER_TYPE_INFO
*output_types
)
806 struct mft_registration
*mft
, *cur
, *unreg_mft
= NULL
;
809 if (!factory
&& !clsid
)
811 WARN("Can't register without factory or CLSID.\n");
815 if (!(mft
= calloc(1, sizeof(*mft
))))
816 return E_OUTOFMEMORY
;
818 mft
->factory
= factory
;
820 IClassFactory_AddRef(mft
->factory
);
823 mft
->category
= *category
;
824 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
825 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
828 if (name
&& !(mft
->name
= wcsdup(name
)))
834 if (input_count
&& input_types
)
836 mft
->input_types_count
= input_count
;
837 if (!(mft
->input_types
= calloc(mft
->input_types_count
, sizeof(*input_types
))))
842 memcpy(mft
->input_types
, input_types
, mft
->input_types_count
* sizeof(*input_types
));
845 if (output_count
&& output_types
)
847 mft
->output_types_count
= output_count
;
848 if (!(mft
->output_types
= calloc(mft
->output_types_count
, sizeof(*output_types
))))
853 memcpy(mft
->output_types
, output_types
, mft
->output_types_count
* sizeof(*output_types
));
856 EnterCriticalSection(&local_mfts_section
);
858 LIST_FOR_EACH_ENTRY(cur
, &local_mfts
, struct mft_registration
, entry
)
860 if (cur
->factory
== factory
)
863 list_remove(&cur
->entry
);
867 list_add_tail(&local_mfts
, &mft
->entry
);
869 LeaveCriticalSection(&local_mfts_section
);
872 release_mft_registration(unreg_mft
);
876 release_mft_registration(mft
);
881 HRESULT WINAPI
MFTRegisterLocal(IClassFactory
*factory
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
882 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
883 const MFT_REGISTER_TYPE_INFO
*output_types
)
885 TRACE("%p, %s, %s, %#x, %u, %p, %u, %p.\n", factory
, debugstr_guid(category
), debugstr_w(name
), flags
, input_count
,
886 input_types
, output_count
, output_types
);
888 return mft_register_local(factory
, NULL
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
891 HRESULT WINAPI
MFTRegisterLocalByCLSID(REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
892 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
893 const MFT_REGISTER_TYPE_INFO
*output_types
)
895 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p.\n", debugstr_guid(clsid
), debugstr_guid(category
), debugstr_w(name
), flags
,
896 input_count
, input_types
, output_count
, output_types
);
898 return mft_register_local(NULL
, clsid
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
901 static HRESULT
mft_unregister_local(IClassFactory
*factory
, REFCLSID clsid
)
903 struct mft_registration
*cur
, *cur2
;
904 BOOL unregister_all
= !factory
&& !clsid
;
909 EnterCriticalSection(&local_mfts_section
);
911 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &local_mfts
, struct mft_registration
, entry
)
915 if ((factory
&& cur
->factory
== factory
) || IsEqualCLSID(&cur
->clsid
, clsid
))
917 list_remove(&cur
->entry
);
918 list_add_tail(&unreg
, &cur
->entry
);
924 list_remove(&cur
->entry
);
925 list_add_tail(&unreg
, &cur
->entry
);
929 LeaveCriticalSection(&local_mfts_section
);
931 if (!unregister_all
&& list_empty(&unreg
))
932 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND
);
934 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &unreg
, struct mft_registration
, entry
)
936 list_remove(&cur
->entry
);
937 release_mft_registration(cur
);
943 HRESULT WINAPI
MFTUnregisterLocalByCLSID(CLSID clsid
)
945 TRACE("%s.\n", debugstr_guid(&clsid
));
947 return mft_unregister_local(NULL
, &clsid
);
950 HRESULT WINAPI
MFTUnregisterLocal(IClassFactory
*factory
)
952 TRACE("%p.\n", factory
);
954 return mft_unregister_local(factory
, NULL
);
957 MFTIME WINAPI
MFGetSystemTime(void)
961 GetSystemTimeAsFileTime( (FILETIME
*)&mf
);
966 static BOOL
mft_is_type_info_match(struct mft_registration
*mft
, const GUID
*category
, UINT32 flags
,
967 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
968 const MFT_REGISTER_TYPE_INFO
*output_type
)
970 BOOL matching
= TRUE
;
974 if (!IsEqualGUID(category
, &mft
->category
))
977 /* Default model is synchronous. */
978 model
= mft
->flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
);
980 model
= MFT_ENUM_FLAG_SYNCMFT
;
981 if (!(model
& flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
984 /* These flags should be explicitly enabled. */
985 if (mft
->flags
& ~flags
& (MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_TRANSCODE_ONLY
))
988 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
&& !mft
->factory
&& plugin_control
989 && IMFPluginControl_IsDisabled(plugin_control
, MF_Plugin_Type_MFT
, &mft
->clsid
) == S_OK
)
996 for (i
= 0, matching
= FALSE
; input_type
&& i
< mft
->input_types_count
; ++i
)
998 if (!memcmp(&mft
->input_types
[i
], input_type
, sizeof(*input_type
)))
1006 if (output_type
&& matching
)
1008 for (i
= 0, matching
= FALSE
; i
< mft
->output_types_count
; ++i
)
1010 if (!memcmp(&mft
->output_types
[i
], output_type
, sizeof(*output_type
)))
1021 static void mft_get_reg_type_info(const WCHAR
*clsidW
, const WCHAR
*typeW
, MFT_REGISTER_TYPE_INFO
**type
,
1024 HKEY htransform
, hfilter
;
1025 DWORD reg_type
, size
;
1030 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1033 if (RegOpenKeyW(htransform
, clsidW
, &hfilter
))
1035 RegCloseKey(htransform
);
1039 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, NULL
, &size
))
1042 if (reg_type
!= REG_BINARY
)
1045 if (!size
|| size
% sizeof(**type
))
1048 if (!(*type
= malloc(size
)))
1051 *count
= size
/ sizeof(**type
);
1053 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, (BYTE
*)*type
, &size
))
1061 RegCloseKey(hfilter
);
1062 RegCloseKey(htransform
);
1065 static void mft_get_reg_flags(const WCHAR
*clsidW
, const WCHAR
*nameW
, DWORD
*flags
)
1067 DWORD ret
, reg_type
, size
;
1072 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
))
1075 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1081 if (!RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, NULL
, &size
) && reg_type
== REG_DWORD
)
1082 RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, (BYTE
*)flags
, &size
);
1087 static HRESULT
mft_collect_machine_reg(struct list
*mfts
, const GUID
*category
, UINT32 flags
,
1088 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1089 const MFT_REGISTER_TYPE_INFO
*output_type
)
1091 struct mft_registration mft
, *cur
;
1092 HKEY hcategory
, hlist
;
1097 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1100 GUIDToString(clsidW
, category
);
1101 ret
= RegOpenKeyW(hcategory
, clsidW
, &hlist
);
1102 RegCloseKey(hcategory
);
1106 size
= ARRAY_SIZE(clsidW
);
1107 while (!RegEnumKeyExW(hlist
, index
, clsidW
, &size
, NULL
, NULL
, NULL
, NULL
))
1109 memset(&mft
, 0, sizeof(mft
));
1110 mft
.category
= *category
;
1111 if (!GUIDFromString(clsidW
, &mft
.clsid
))
1114 mft_get_reg_flags(clsidW
, L
"MFTFlags", &mft
.flags
);
1117 mft_get_reg_type_info(clsidW
, L
"OutputTypes", &mft
.output_types
, &mft
.output_types_count
);
1120 mft_get_reg_type_info(clsidW
, L
"InputTypes", &mft
.input_types
, &mft
.input_types_count
);
1122 if (!mft_is_type_info_match(&mft
, category
, flags
, plugin_control
, input_type
, output_type
))
1124 free(mft
.input_types
);
1125 free(mft
.output_types
);
1129 cur
= malloc(sizeof(*cur
));
1130 /* Reuse allocated type arrays. */
1132 list_add_tail(mfts
, &cur
->entry
);
1135 size
= ARRAY_SIZE(clsidW
);
1142 static BOOL
mft_is_preferred(IMFPluginControl
*plugin_control
, const CLSID
*clsid
)
1148 while (SUCCEEDED(IMFPluginControl_GetPreferredClsidByIndex(plugin_control
, MF_Plugin_Type_MFT
, index
++, &selector
,
1151 CoTaskMemFree(selector
);
1153 if (IsEqualGUID(&preferred
, clsid
))
1160 static HRESULT
mft_enum(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1161 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1163 IMFPluginControl
*plugin_control
= NULL
;
1164 struct list mfts
, mfts_sorted
, *result
= &mfts
;
1165 struct mft_registration
*mft
, *mft2
;
1166 unsigned int obj_count
;
1173 flags
= MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_SORTANDFILTER
;
1175 /* Synchronous processing is default. */
1176 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1177 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
1179 if (FAILED(hr
= MFGetPluginControl(&plugin_control
)))
1181 WARN("Failed to get plugin control instance, hr %#x.\n", hr
);
1187 /* Collect from registry */
1188 mft_collect_machine_reg(&mfts
, &category
, flags
, plugin_control
, input_type
, output_type
);
1190 /* Collect locally registered ones. */
1191 if (flags
& MFT_ENUM_FLAG_LOCALMFT
)
1193 struct mft_registration
*local
;
1195 EnterCriticalSection(&local_mfts_section
);
1197 LIST_FOR_EACH_ENTRY(local
, &local_mfts
, struct mft_registration
, entry
)
1199 if (mft_is_type_info_match(local
, &category
, flags
, plugin_control
, input_type
, output_type
))
1201 mft
= calloc(1, sizeof(*mft
));
1203 mft
->clsid
= local
->clsid
;
1204 mft
->factory
= local
->factory
;
1206 IClassFactory_AddRef(mft
->factory
);
1207 mft
->flags
= local
->flags
;
1208 mft
->local
= local
->local
;
1210 list_add_tail(&mfts
, &mft
->entry
);
1214 LeaveCriticalSection(&local_mfts_section
);
1217 list_init(&mfts_sorted
);
1219 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
)
1221 /* Local registrations. */
1222 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1226 list_remove(&mft
->entry
);
1227 list_add_tail(&mfts_sorted
, &mft
->entry
);
1231 /* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */
1233 /* Preferred transforms. */
1234 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1236 if (!mft
->factory
&& mft_is_preferred(plugin_control
, &mft
->clsid
))
1238 list_remove(&mft
->entry
);
1239 list_add_tail(&mfts_sorted
, &mft
->entry
);
1243 /* Append the rest. */
1244 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1246 list_remove(&mft
->entry
);
1247 list_add_tail(&mfts_sorted
, &mft
->entry
);
1250 result
= &mfts_sorted
;
1253 IMFPluginControl_Release(plugin_control
);
1255 /* Create activation objects from CLSID/IClassFactory. */
1257 obj_count
= list_count(result
);
1261 if (!(*activate
= CoTaskMemAlloc(obj_count
* sizeof(**activate
))))
1266 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, result
, struct mft_registration
, entry
)
1268 IMFActivate
*mft_activate
;
1272 if (SUCCEEDED(create_transform_activate(mft
->factory
, &mft_activate
)))
1274 (*activate
)[obj_count
] = mft_activate
;
1278 IMFActivate_SetUINT32(mft_activate
, &MFT_PROCESS_LOCAL_Attribute
, 1);
1283 IMFActivate_SetString(mft_activate
, &MFT_FRIENDLY_NAME_Attribute
, mft
->name
);
1284 if (mft
->input_types
)
1285 IMFActivate_SetBlob(mft_activate
, &MFT_INPUT_TYPES_Attributes
, (const UINT8
*)mft
->input_types
,
1286 sizeof(*mft
->input_types
) * mft
->input_types_count
);
1287 if (mft
->output_types
)
1288 IMFActivate_SetBlob(mft_activate
, &MFT_OUTPUT_TYPES_Attributes
, (const UINT8
*)mft
->output_types
,
1289 sizeof(*mft
->output_types
) * mft
->output_types_count
);
1293 IMFActivate_SetGUID(mft_activate
, &MFT_TRANSFORM_CLSID_Attribute
, &mft
->clsid
);
1295 IMFActivate_SetUINT32(mft_activate
, &MF_TRANSFORM_FLAGS_Attribute
, mft
->flags
);
1296 IMFActivate_SetGUID(mft_activate
, &MF_TRANSFORM_CATEGORY_Attribute
, &mft
->category
);
1302 list_remove(&mft
->entry
);
1303 release_mft_registration(mft
);
1309 CoTaskMemFree(*activate
);
1317 /***********************************************************************
1318 * MFTEnum (mfplat.@)
1320 HRESULT WINAPI
MFTEnum(GUID category
, UINT32 flags
, MFT_REGISTER_TYPE_INFO
*input_type
,
1321 MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, CLSID
**clsids
, UINT32
*count
)
1323 struct mft_registration
*mft
, *mft2
;
1324 unsigned int mft_count
;
1328 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1331 if (!clsids
|| !count
)
1332 return E_INVALIDARG
;
1338 if (FAILED(hr
= mft_collect_machine_reg(&mfts
, &category
, MFT_ENUM_FLAG_SYNCMFT
, NULL
, input_type
, output_type
)))
1341 mft_count
= list_count(&mfts
);
1345 if (!(*clsids
= CoTaskMemAlloc(mft_count
* sizeof(**clsids
))))
1349 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1352 (*clsids
)[mft_count
++] = mft
->clsid
;
1353 list_remove(&mft
->entry
);
1354 release_mft_registration(mft
);
1360 CoTaskMemFree(*clsids
);
1368 /***********************************************************************
1369 * MFTEnumEx (mfplat.@)
1371 HRESULT WINAPI
MFTEnumEx(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1372 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFActivate
***activate
, UINT32
*count
)
1374 TRACE("%s, %#x, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, activate
, count
);
1376 return mft_enum(category
, flags
, input_type
, output_type
, NULL
, activate
, count
);
1379 /***********************************************************************
1380 * MFTEnum2 (mfplat.@)
1382 HRESULT WINAPI
MFTEnum2(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1383 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1385 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1389 FIXME("Ignoring attributes.\n");
1391 return mft_enum(category
, flags
, input_type
, output_type
, attributes
, activate
, count
);
1394 /***********************************************************************
1395 * MFTUnregister (mfplat.@)
1397 HRESULT WINAPI
MFTUnregister(CLSID clsid
)
1399 WCHAR buffer
[64], category
[MAX_PATH
];
1400 HKEY htransform
, hcategory
, htmp
;
1401 DWORD size
= MAX_PATH
;
1404 TRACE("(%s)\n", debugstr_guid(&clsid
));
1406 GUIDToString(buffer
, &clsid
);
1408 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1410 RegDeleteKeyW(htransform
, buffer
);
1411 RegCloseKey(htransform
);
1414 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1416 while (RegEnumKeyExW(hcategory
, index
, category
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1418 if (!RegOpenKeyW(hcategory
, category
, &htmp
))
1420 RegDeleteKeyW(htmp
, buffer
);
1426 RegCloseKey(hcategory
);
1432 /***********************************************************************
1433 * MFStartup (mfplat.@)
1435 HRESULT WINAPI
MFStartup(ULONG version
, DWORD flags
)
1437 #define MF_VERSION_XP MAKELONG( MF_API_VERSION, 1 )
1438 #define MF_VERSION_WIN7 MAKELONG( MF_API_VERSION, 2 )
1440 TRACE("%#x, %#x.\n", version
, flags
);
1442 if (version
!= MF_VERSION_XP
&& version
!= MF_VERSION_WIN7
)
1443 return MF_E_BAD_STARTUP_VERSION
;
1450 /***********************************************************************
1451 * MFShutdown (mfplat.@)
1453 HRESULT WINAPI
MFShutdown(void)
1462 /***********************************************************************
1463 * MFCopyImage (mfplat.@)
1465 HRESULT WINAPI
MFCopyImage(BYTE
*dest
, LONG deststride
, const BYTE
*src
, LONG srcstride
, DWORD width
, DWORD lines
)
1467 TRACE("%p, %d, %p, %d, %u, %u.\n", dest
, deststride
, src
, srcstride
, width
, lines
);
1471 memcpy(dest
, src
, width
);
1485 static int __cdecl
debug_compare_guid(const void *a
, const void *b
)
1487 const GUID
*guid
= a
;
1488 const struct guid_def
*guid_def
= b
;
1489 return memcmp(guid
, guid_def
->guid
, sizeof(*guid
));
1492 const char *debugstr_attr(const GUID
*guid
)
1494 static const struct guid_def guid_defs
[] =
1496 #define X(g) { &(g), #g }
1497 #define MF_READER_WRITER_D3D_MANAGER MF_SOURCE_READER_D3D_MANAGER
1498 X(MF_READWRITE_MMCSS_CLASS
),
1499 X(MF_TOPONODE_MARKIN_HERE
),
1500 X(MF_MT_H264_SUPPORTED_SYNC_FRAME_TYPES
),
1501 X(MF_TOPONODE_MARKOUT_HERE
),
1502 X(EVRConfig_ForceBob
),
1503 X(MF_TOPONODE_DECODER
),
1504 X(EVRConfig_AllowDropToBob
),
1505 X(MF_TOPOLOGY_PROJECTSTART
),
1506 X(EVRConfig_ForceThrottle
),
1507 X(MF_VIDEO_MAX_MB_PER_SEC
),
1508 X(MF_TOPOLOGY_PROJECTSTOP
),
1509 X(MF_SINK_WRITER_ENCODER_CONFIG
),
1510 X(EVRConfig_AllowDropToThrottle
),
1511 X(MF_TOPOLOGY_NO_MARKIN_MARKOUT
),
1512 X(EVRConfig_ForceHalfInterlace
),
1513 X(EVRConfig_AllowDropToHalfInterlace
),
1514 X(EVRConfig_ForceScaling
),
1515 X(MF_MT_H264_CAPABILITIES
),
1516 X(EVRConfig_AllowScaling
),
1517 X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS
),
1518 X(MFT_PREFERRED_ENCODER_PROFILE
),
1519 X(EVRConfig_ForceBatching
),
1520 X(EVRConfig_AllowBatching
),
1521 X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED
),
1522 X(MF_MT_VIDEO_PROFILE
),
1523 X(MF_MT_DV_AAUX_CTRL_PACK_1
),
1524 X(MF_MT_ALPHA_MODE
),
1525 X(MF_MT_MPEG2_TIMECODE
),
1526 X(MF_PMP_SERVER_CONTEXT
),
1527 X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
),
1528 X(MF_MEDIA_ENGINE_TRACK_ID
),
1529 X(MF_MT_CUSTOM_VIDEO_PRIMARIES
),
1530 X(MF_MT_TIMESTAMP_CAN_BE_DTS
),
1531 X(MFT_CODEC_MERIT_Attribute
),
1532 X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS
),
1533 X(MF_XVP_DISABLE_FRC
),
1535 X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
),
1536 X(MF_MT_MPEG2_FLAGS
),
1537 X(MF_MEDIA_ENGINE_AUDIO_CATEGORY
),
1538 X(MF_MT_PIXEL_ASPECT_RATIO
),
1539 X(MF_VIDEO_PROCESSOR_ALGORITHM
),
1540 X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK
),
1541 X(MFT_CONNECTED_STREAM_ATTRIBUTE
),
1542 X(MF_MT_REALTIME_CONTENT
),
1543 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
),
1544 X(MF_MT_WRAPPED_TYPE
),
1546 X(MF_MT_AVG_BITRATE
),
1547 X(MF_MT_DECODER_USE_MAX_RESOLUTION
),
1548 X(MF_MT_MAX_LUMINANCE_LEVEL
),
1549 X(MFT_CONNECTED_TO_HW_STREAM
),
1551 X(MF_XVP_SAMPLE_LOCK_TIMEOUT
),
1552 X(MF_MT_MAX_KEYFRAME_SPACING
),
1553 X(MFT_TRANSFORM_CLSID_Attribute
),
1554 X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
),
1555 X(MF_MT_AM_FORMAT_TYPE
),
1556 X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME
),
1557 X(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
),
1558 X(MF_MT_H264_MAX_MB_PER_SEC
),
1559 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS
),
1560 X(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
1561 X(MF_PD_PMPHOST_CONTEXT
),
1562 X(MF_PD_APP_CONTEXT
),
1564 X(MF_PD_TOTAL_FILE_SIZE
),
1565 X(MF_PD_AUDIO_ENCODING_BITRATE
),
1566 X(MF_PD_VIDEO_ENCODING_BITRATE
),
1567 X(MFSampleExtension_TargetGlobalLuminance
),
1569 X(MF_MT_H264_SUPPORTED_SLICE_MODES
),
1570 X(MF_PD_LAST_MODIFIED_TIME
),
1572 X(MF_PD_PLAYBACK_ELEMENT_ID
),
1573 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
),
1574 X(MF_MT_ALL_SAMPLES_INDEPENDENT
),
1575 X(MF_PD_PREFERRED_LANGUAGE
),
1576 X(MF_PD_PLAYBACK_BOUNDARY_TIME
),
1577 X(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
),
1578 X(MF_ACTIVATE_MFT_LOCKED
),
1579 X(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
),
1580 X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
),
1581 X(MF_MT_FRAME_SIZE
),
1582 X(MF_MT_H264_SIMULCAST_SUPPORT
),
1583 X(MF_SINK_WRITER_ASYNC_CALLBACK
),
1584 X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH
),
1585 X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
),
1586 X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
),
1587 X(MF_MT_FRAME_RATE_RANGE_MAX
),
1589 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID
),
1590 X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS
),
1591 X(MF_SA_D3D11_USAGE
),
1592 X(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
),
1593 X(MF_MT_GEOMETRIC_APERTURE
),
1594 X(MF_MT_ORIGINAL_WAVE_FORMAT_TAG
),
1595 X(MF_MT_DV_AAUX_SRC_PACK_1
),
1596 X(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
),
1597 X(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
),
1598 X(MF_MEDIA_ENGINE_EXTENSION
),
1599 X(MF_MT_DEFAULT_STRIDE
),
1600 X(MF_MT_ARBITRARY_FORMAT
),
1601 X(MF_TRANSFORM_CATEGORY_Attribute
),
1602 X(MF_MT_MPEG2_HDCP
),
1603 X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
1604 X(MF_MT_SPATIAL_AUDIO_MAX_DYNAMIC_OBJECTS
),
1605 X(MF_MT_DECODER_MAX_DPB_COUNT
),
1606 X(MFSampleExtension_ForwardedDecodeUnits
),
1607 X(MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
1608 X(MF_MT_DV_AAUX_CTRL_PACK_0
),
1609 X(MF_MT_YUV_MATRIX
),
1610 X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED
),
1611 X(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY
),
1612 X(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL
),
1613 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID
),
1614 X(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
),
1615 X(MF_MT_VIDEO_ROTATION
),
1616 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK
),
1617 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
),
1619 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
),
1620 X(MF_MT_MIN_MASTERING_LUMINANCE
),
1621 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
),
1622 X(MF_SA_REQUIRED_SAMPLE_COUNT
),
1623 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
),
1624 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
),
1625 X(MF_EVENT_STREAM_METADATA_SYSTEMID
),
1626 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
),
1627 X(MF_MT_AUDIO_CHANNEL_MASK
),
1628 X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN
),
1629 X(MF_READWRITE_DISABLE_CONVERTERS
),
1630 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
),
1631 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
),
1632 X(MF_MT_MINIMUM_DISPLAY_APERTURE
),
1633 X(MFSampleExtension_Token
),
1634 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY
),
1635 X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
1636 X(MF_TRANSFORM_ASYNC_UNLOCK
),
1637 X(MF_DISABLE_FRAME_CORRUPTION_INFO
),
1638 X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
),
1639 X(MF_MT_VIDEO_NO_FRAME_ORDERING
),
1640 X(MF_MEDIA_ENGINE_PLAYBACK_VISUAL
),
1641 X(MF_MT_VIDEO_CHROMA_SITING
),
1642 X(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY
),
1643 X(MF_SA_BUFFERS_PER_SAMPLE
),
1644 X(MFSampleExtension_3DVideo_SampleFormat
),
1645 X(MF_MT_H264_RESOLUTION_SCALING
),
1646 X(MF_MT_VIDEO_LEVEL
),
1647 X(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET
),
1648 X(MF_MT_SAMPLE_SIZE
),
1649 X(MF_MT_AAC_PAYLOAD_TYPE
),
1650 X(MF_TOPOLOGY_PLAYBACK_FRAMERATE
),
1651 X(MF_SOURCE_READER_D3D11_BIND_FLAGS
),
1652 X(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
1653 X(MF_MT_AUDIO_WMADRC_PEAKREF
),
1654 X(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
1655 X(MF_TRANSFORM_FLAGS_Attribute
),
1656 X(MF_MT_H264_SUPPORTED_RATE_CONTROL_MODES
),
1657 X(MF_PD_SAMI_STYLELIST
),
1658 X(MF_MT_AUDIO_WMADRC_AVGREF
),
1659 X(MF_MT_AUDIO_BITS_PER_SAMPLE
),
1661 X(MF_MT_AUDIO_WMADRC_AVGTARGET
),
1663 X(MF_SESSION_TOPOLOADER
),
1664 X(MF_SESSION_GLOBAL_TIME
),
1665 X(MF_SESSION_QUALITY_MANAGER
),
1666 X(MF_SESSION_CONTENT_PROTECTION_MANAGER
),
1667 X(MF_MT_MPEG4_SAMPLE_DESCRIPTION
),
1668 X(MF_MT_MPEG_START_TIME_CODE
),
1669 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1670 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1671 X(MF_READWRITE_MMCSS_PRIORITY_AUDIO
),
1672 X(MF_MT_H264_MAX_CODEC_CONFIG_DELAY
),
1673 X(MF_MT_DV_AAUX_SRC_PACK_0
),
1674 X(MF_BYTESTREAM_ORIGIN_NAME
),
1675 X(MF_BYTESTREAM_CONTENT_TYPE
),
1676 X(MF_MT_DEPTH_MEASUREMENT
),
1677 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
),
1678 X(MF_MT_VIDEO_3D_NUM_VIEWS
),
1679 X(MF_BYTESTREAM_DURATION
),
1680 X(MF_SD_SAMI_LANGUAGE
),
1681 X(MF_EVENT_OUTPUT_NODE
),
1682 X(MF_BYTESTREAM_LAST_MODIFIED_TIME
),
1683 X(MFT_ENUM_ADAPTER_LUID
),
1684 X(MF_MT_FRAME_RATE_RANGE_MIN
),
1685 X(MF_BYTESTREAM_IFO_FILE_URI
),
1686 X(MF_EVENT_TOPOLOGY_STATUS
),
1687 X(MF_BYTESTREAM_DLNA_PROFILE_ID
),
1688 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE
),
1689 X(MF_MT_MAJOR_TYPE
),
1690 X(MF_SA_REQUIRED_SAMPLE_COUNT_PROGRESSIVE
),
1691 X(MF_MT_IN_BAND_PARAMETER_SET
),
1692 X(MF_EVENT_SOURCE_CHARACTERISTICS
),
1693 X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD
),
1694 X(MF_SESSION_SERVER_CONTEXT
),
1695 X(MF_MT_VIDEO_3D_FIRST_IS_LEFT
),
1696 X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT
),
1697 X(MF_PD_ADAPTIVE_STREAMING
),
1698 X(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
),
1699 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
),
1700 X(MF_MT_H264_SUPPORTED_USAGES
),
1701 X(MFT_PREFERRED_OUTPUTTYPE_Attribute
),
1702 X(MFSampleExtension_Timestamp
),
1703 X(MF_TOPONODE_PRIMARYOUTPUT
),
1705 X(MF_TRANSFORM_ASYNC
),
1706 X(MF_TOPONODE_STREAMID
),
1707 X(MF_MEDIA_ENGINE_PLAYBACK_HWND
),
1708 X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
),
1709 X(MF_MT_VIDEO_LIGHTING
),
1710 X(MF_SD_MUTUALLY_EXCLUSIVE
),
1711 X(MF_SD_STREAM_NAME
),
1712 X(MF_MT_DV_VAUX_SRC_PACK
),
1713 X(MF_TOPONODE_RATELESS
),
1714 X(MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS
),
1715 X(MF_TOPONODE_DISABLE_PREROLL
),
1716 X(MF_SA_D3D11_ALLOW_DYNAMIC_YUV_TEXTURE
),
1717 X(MF_MT_VIDEO_3D_FORMAT
),
1718 X(MF_EVENT_STREAM_METADATA_KEYDATA
),
1719 X(MF_READER_WRITER_D3D_MANAGER
),
1720 X(MFSampleExtension_3DVideo
),
1721 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE
),
1722 X(MF_MT_H264_USAGE
),
1723 X(MF_MEDIA_ENGINE_EME_CALLBACK
),
1724 X(MF_EVENT_SOURCE_FAKE_START
),
1725 X(MF_EVENT_SOURCE_PROJECTSTART
),
1726 X(MF_EVENT_SOURCE_ACTUAL_START
),
1727 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
),
1728 X(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
1729 X(MFT_ENUM_HARDWARE_URL_Attribute
),
1730 X(MF_SOURCE_READER_ASYNC_CALLBACK
),
1731 X(MF_MT_OUTPUT_BUFFER_NUM
),
1732 X(MF_SA_D3D11_BINDFLAGS
),
1733 X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT
),
1734 X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE
),
1735 X(MFT_FRIENDLY_NAME_Attribute
),
1736 X(MF_MT_FIXED_SIZE_SAMPLES
),
1737 X(MFT_SUPPORT_3DVIDEO
),
1738 X(MFT_SUPPORT_3DVIDEO
),
1739 X(MFT_INPUT_TYPES_Attributes
),
1740 X(MF_MT_H264_LAYOUT_PER_STREAM
),
1741 X(MF_EVENT_SCRUBSAMPLE_TIME
),
1742 X(MF_MT_SPATIAL_AUDIO_MAX_METADATA_ITEMS
),
1743 X(MF_MT_MPEG2_ONE_FRAME_PER_PACKET
),
1744 X(MF_MT_INTERLACE_MODE
),
1745 X(MF_MEDIA_ENGINE_CALLBACK
),
1746 X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE
),
1747 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE
),
1748 X(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
1749 X(MF_XVP_CALLER_ALLOCATES_OUTPUT
),
1750 X(MF_MT_H264_SVC_CAPABILITIES
),
1751 X(MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
),
1752 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_LENGTH
),
1753 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_FORMAT_ID
),
1754 X(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
),
1755 X(MF_SA_D3D11_SHARED
),
1756 X(MF_MT_PAN_SCAN_ENABLED
),
1757 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
),
1758 X(MF_MT_DV_VAUX_CTRL_PACK
),
1759 X(MFSampleExtension_ForwardedDecodeUnitType
),
1760 X(MF_SA_D3D11_AWARE
),
1761 X(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
1762 X(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS
),
1763 X(MF_MT_SPATIAL_AUDIO_MIN_METADATA_ITEM_OFFSET_SPACING
),
1764 X(MF_TOPONODE_TRANSFORM_OBJECTID
),
1765 X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE
),
1766 X(MF_EVENT_MFT_INPUT_STREAM_ID
),
1767 X(MF_MT_SOURCE_CONTENT_HINT
),
1768 X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute
),
1769 X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE
),
1770 X(MF_READWRITE_MMCSS_PRIORITY
),
1772 X(MF_EVENT_START_PRESENTATION_TIME
),
1773 X(MF_EVENT_SESSIONCAPS
),
1774 X(MF_EVENT_PRESENTATION_TIME_OFFSET
),
1775 X(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
),
1776 X(MF_EVENT_SESSIONCAPS_DELTA
),
1777 X(MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT
),
1778 X(MFSampleExtension_DecodeTimestamp
),
1779 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE
),
1780 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT
),
1781 X(MF_MT_VIDEO_H264_NO_FMOASO
),
1782 X(MF_MT_AVG_BIT_ERROR_RATE
),
1783 X(MF_MT_VIDEO_PRIMARIES
),
1784 X(MF_SINK_WRITER_DISABLE_THROTTLING
),
1785 X(MF_MT_H264_RATE_CONTROL_MODES
),
1786 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
),
1787 X(MF_READWRITE_D3D_OPTIONAL
),
1788 X(MF_SA_D3D11_HW_PROTECTED
),
1789 X(MF_MEDIA_ENGINE_DXGI_MANAGER
),
1790 X(MF_READWRITE_MMCSS_CLASS_AUDIO
),
1791 X(MF_MEDIA_ENGINE_COREWINDOW
),
1792 X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS
),
1793 X(MF_MT_MPEG4_TRACK_TYPE
),
1794 X(MF_ACTIVATE_VIDEO_WINDOW
),
1795 X(MF_MT_PAN_SCAN_APERTURE
),
1796 X(MF_TOPOLOGY_RESOLUTION_STATUS
),
1797 X(MF_MT_ORIGINAL_4CC
),
1798 X(MF_PD_AUDIO_ISVARIABLEBITRATE
),
1799 X(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS
),
1800 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
),
1801 X(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID
),
1802 X(MF_MT_MPEG2_CONTENT_PACKET
),
1803 X(MFT_PROCESS_LOCAL_Attribute
),
1804 X(MFT_PROCESS_LOCAL_Attribute
),
1805 X(MF_MT_PAD_CONTROL_FLAGS
),
1806 X(MF_MT_VIDEO_NOMINAL_RANGE
),
1807 X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
1808 X(MF_MT_MPEG_SEQUENCE_HEADER
),
1809 X(MF_MEDIA_ENGINE_OPM_HWND
),
1810 X(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
1811 X(MF_MT_SPATIAL_AUDIO_DATA_PRESENT
),
1812 X(MF_MT_FRAME_RATE
),
1813 X(MF_TOPONODE_FLUSH
),
1814 X(MF_MT_MPEG2_STANDARD
),
1815 X(MF_TOPONODE_DRAIN
),
1816 X(MF_MT_TRANSFER_FUNCTION
),
1817 X(MF_TOPONODE_MEDIASTART
),
1818 X(MF_TOPONODE_MEDIASTOP
),
1819 X(MF_SOURCE_READER_MEDIASOURCE_CONFIG
),
1820 X(MF_TOPONODE_SOURCE
),
1821 X(MF_TOPONODE_PRESENTATION_DESCRIPTOR
),
1822 X(MF_TOPONODE_D3DAWARE
),
1823 X(MF_MT_COMPRESSED
),
1824 X(MF_TOPONODE_STREAM_DESCRIPTOR
),
1825 X(MF_TOPONODE_ERRORCODE
),
1826 X(MF_TOPONODE_SEQUENCE_ELEMENTID
),
1827 X(MF_EVENT_MFT_CONTEXT
),
1828 X(MF_MT_FORWARD_CUSTOM_SEI
),
1829 X(MF_TOPONODE_CONNECT_METHOD
),
1830 X(MFT_OUTPUT_TYPES_Attributes
),
1831 X(MF_MT_IMAGE_LOSS_TOLERANT
),
1832 X(MF_SESSION_REMOTE_SOURCE_MODE
),
1833 X(MF_MT_DEPTH_VALUE_UNIT
),
1834 X(MF_MT_AUDIO_NUM_CHANNELS
),
1835 X(MF_MT_ARBITRARY_HEADER
),
1836 X(MF_TOPOLOGY_DXVA_MODE
),
1837 X(MF_TOPONODE_LOCKED
),
1838 X(MF_TOPONODE_WORKQUEUE_ID
),
1839 X(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
),
1840 X(MF_TOPONODE_WORKQUEUE_MMCSS_CLASS
),
1841 X(MF_TOPONODE_DECRYPTOR
),
1842 X(MF_EVENT_DO_THINNING
),
1843 X(MF_TOPONODE_DISCARDABLE
),
1844 X(MF_TOPOLOGY_HARDWARE_MODE
),
1845 X(MF_SOURCE_READER_DISABLE_DXVA
),
1846 X(MF_MT_FORWARD_CUSTOM_NALU
),
1847 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
),
1848 X(MF_TOPONODE_ERROR_MAJORTYPE
),
1850 X(MFT_FIELDOFUSE_UNLOCK_Attribute
),
1851 X(MF_TOPONODE_ERROR_SUBTYPE
),
1852 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
),
1853 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
),
1854 X(MF_MT_VIDEO_3D_LEFT_IS_BASE
),
1855 X(MF_TOPONODE_WORKQUEUE_MMCSS_TASKID
),
1856 #undef MF_READER_WRITER_D3D_MANAGER
1859 struct guid_def
*ret
= NULL
;
1862 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
1864 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
1867 const char *debugstr_mf_guid(const GUID
*guid
)
1869 static const struct guid_def guid_defs
[] =
1871 #define X(g) { &(g), #g }
1872 X(MFAudioFormat_ADTS
),
1873 X(MFAudioFormat_PCM
),
1874 X(MFAudioFormat_PCM_HDCP
),
1875 X(MFAudioFormat_Float
),
1876 X(MFAudioFormat_DTS
),
1877 X(MFAudioFormat_DRM
),
1878 X(MFAudioFormat_MSP1
),
1879 X(MFAudioFormat_Vorbis
),
1880 X(MFAudioFormat_AAC
),
1881 X(MFVideoFormat_RGB24
),
1882 X(MFVideoFormat_ARGB32
),
1883 X(MFVideoFormat_RGB32
),
1884 X(MFVideoFormat_RGB565
),
1885 X(MFVideoFormat_RGB555
),
1886 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
),
1887 X(MFVideoFormat_A2R10G10B10
),
1888 X(MFMediaType_Script
),
1889 X(MFMediaType_Image
),
1890 X(MFMediaType_HTML
),
1891 X(MFMediaType_Binary
),
1892 X(MFVideoFormat_MPEG2
),
1893 X(MFMediaType_FileTransfer
),
1894 X(MFVideoFormat_RGB8
),
1895 X(MFAudioFormat_Dolby_AC3
),
1896 X(MFVideoFormat_L8
),
1897 X(MFAudioFormat_LPCM
),
1898 X(MFVideoFormat_420O
),
1899 X(MFVideoFormat_AI44
),
1900 X(MFVideoFormat_AV1
),
1901 X(MFVideoFormat_AYUV
),
1902 X(MFVideoFormat_H263
),
1903 X(MFVideoFormat_H264
),
1904 X(MFVideoFormat_H265
),
1905 X(MFVideoFormat_HEVC
),
1906 X(MFVideoFormat_HEVC_ES
),
1907 X(MFVideoFormat_I420
),
1908 X(MFVideoFormat_IYUV
),
1909 X(MFVideoFormat_M4S2
),
1910 X(MFVideoFormat_MJPG
),
1911 X(MFVideoFormat_MP43
),
1912 X(MFVideoFormat_MP4S
),
1913 X(MFVideoFormat_MP4V
),
1914 X(MFVideoFormat_MPG1
),
1915 X(MFVideoFormat_MSS1
),
1916 X(MFVideoFormat_MSS2
),
1917 X(MFVideoFormat_NV11
),
1918 X(MFVideoFormat_NV12
),
1919 X(MFVideoFormat_ORAW
),
1920 X(MFAudioFormat_Opus
),
1921 X(MFVideoFormat_D16
),
1922 X(MFAudioFormat_MPEG
),
1923 X(MFVideoFormat_P010
),
1924 X(MFVideoFormat_P016
),
1925 X(MFVideoFormat_P210
),
1926 X(MFVideoFormat_P216
),
1927 X(MFVideoFormat_L16
),
1928 X(MFAudioFormat_MP3
),
1929 X(MFVideoFormat_UYVY
),
1930 X(MFVideoFormat_VP10
),
1931 X(MFVideoFormat_VP80
),
1932 X(MFVideoFormat_VP90
),
1933 X(MFVideoFormat_WMV1
),
1934 X(MFVideoFormat_WMV2
),
1935 X(MFVideoFormat_WMV3
),
1936 X(MFVideoFormat_WVC1
),
1937 X(MFVideoFormat_Y210
),
1938 X(MFVideoFormat_Y216
),
1939 X(MFVideoFormat_Y410
),
1940 X(MFVideoFormat_Y416
),
1941 X(MFVideoFormat_Y41P
),
1942 X(MFVideoFormat_Y41T
),
1943 X(MFVideoFormat_Y42T
),
1944 X(MFVideoFormat_YUY2
),
1945 X(MFVideoFormat_YV12
),
1946 X(MFVideoFormat_YVU9
),
1947 X(MFVideoFormat_YVYU
),
1948 X(MFAudioFormat_WMAudioV8
),
1949 X(MFAudioFormat_ALAC
),
1950 X(MFAudioFormat_AMR_NB
),
1951 X(MFMediaType_Audio
),
1952 X(MFAudioFormat_WMAudioV9
),
1953 X(MFAudioFormat_AMR_WB
),
1954 X(MFAudioFormat_WMAudio_Lossless
),
1955 X(MFAudioFormat_AMR_WP
),
1956 X(MFAudioFormat_WMASPDIF
),
1957 X(MFVideoFormat_DV25
),
1958 X(MFVideoFormat_DV50
),
1959 X(MFVideoFormat_DVC
),
1960 X(MFVideoFormat_DVH1
),
1961 X(MFVideoFormat_DVHD
),
1962 X(MFVideoFormat_DVSD
),
1963 X(MFVideoFormat_DVSL
),
1964 X(MFVideoFormat_A16B16G16R16F
),
1965 X(MFVideoFormat_v210
),
1966 X(MFVideoFormat_v216
),
1967 X(MFVideoFormat_v410
),
1968 X(MFMediaType_Video
),
1969 X(MFAudioFormat_AAC_HDCP
),
1970 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
),
1971 X(MFAudioFormat_Dolby_AC3_HDCP
),
1972 X(MFMediaType_Subtitle
),
1973 X(MFMediaType_Stream
),
1974 X(MFAudioFormat_Dolby_AC3_SPDIF
),
1975 X(MFAudioFormat_Float_SpatialObjects
),
1976 X(MFMediaType_SAMI
),
1977 X(MFAudioFormat_ADTS_HDCP
),
1978 X(MFAudioFormat_FLAC
),
1979 X(MFAudioFormat_Dolby_DDPlus
),
1980 X(MFMediaType_MultiplexedFrames
),
1981 X(MFAudioFormat_Base_HDCP
),
1982 X(MFVideoFormat_Base_HDCP
),
1983 X(MFVideoFormat_H264_HDCP
),
1984 X(MFVideoFormat_HEVC_HDCP
),
1985 X(MFMediaType_Default
),
1986 X(MFMediaType_Protected
),
1987 X(MFVideoFormat_H264_ES
),
1988 X(MFMediaType_Perception
),
1991 struct guid_def
*ret
= NULL
;
1994 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
1996 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2005 static int __cdecl
debug_event_id(const void *a
, const void *b
)
2007 const DWORD
*id
= a
;
2008 const struct event_id
*event_id
= b
;
2009 return *id
- event_id
->id
;
2012 static const char *debugstr_eventid(DWORD event
)
2014 static const struct event_id
2021 #define X(e) { e, #e }
2026 X(MESessionUnknown
),
2027 X(MESessionTopologySet
),
2028 X(MESessionTopologiesCleared
),
2029 X(MESessionStarted
),
2031 X(MESessionStopped
),
2034 X(MESessionRateChanged
),
2035 X(MESessionScrubSampleComplete
),
2036 X(MESessionCapabilitiesChanged
),
2037 X(MESessionTopologyStatus
),
2038 X(MESessionNotifyPresentationTime
),
2039 X(MENewPresentation
),
2040 X(MELicenseAcquisitionStart
),
2041 X(MELicenseAcquisitionCompleted
),
2042 X(MEIndividualizationStart
),
2043 X(MEIndividualizationCompleted
),
2044 X(MEEnablerProgress
),
2045 X(MEEnablerCompleted
),
2048 X(MEBufferingStarted
),
2049 X(MEBufferingStopped
),
2052 X(MEReconnectStart
),
2055 X(MESessionStreamSinkFormatChanged
),
2067 X(MEEndOfPresentation
),
2071 X(MEStreamThinMode
),
2072 X(MEStreamFormatChanged
),
2073 X(MESourceRateChanged
),
2074 X(MEEndOfPresentationSegment
),
2075 X(MESourceCharacteristicsChanged
),
2076 X(MESourceRateChangeRequested
),
2077 X(MESourceMetadataChanged
),
2078 X(MESequencerSourceTopologyUpdated
),
2080 X(MEStreamSinkStarted
),
2081 X(MEStreamSinkStopped
),
2082 X(MEStreamSinkPaused
),
2083 X(MEStreamSinkRateChanged
),
2084 X(MEStreamSinkRequestSample
),
2085 X(MEStreamSinkMarker
),
2086 X(MEStreamSinkPrerolled
),
2087 X(MEStreamSinkScrubSampleComplete
),
2088 X(MEStreamSinkFormatChanged
),
2089 X(MEStreamSinkDeviceChanged
),
2091 X(MESinkInvalidated
),
2092 X(MEAudioSessionNameChanged
),
2093 X(MEAudioSessionVolumeChanged
),
2094 X(MEAudioSessionDeviceRemoved
),
2095 X(MEAudioSessionServerShutdown
),
2096 X(MEAudioSessionGroupingParamChanged
),
2097 X(MEAudioSessionIconChanged
),
2098 X(MEAudioSessionFormatChanged
),
2099 X(MEAudioSessionDisconnected
),
2100 X(MEAudioSessionExclusiveModeOverride
),
2103 X(MEContentProtectionMessage
),
2105 X(MEWMDRMLicenseBackupCompleted
),
2106 X(MEWMDRMLicenseBackupProgress
),
2107 X(MEWMDRMLicenseRestoreCompleted
),
2108 X(MEWMDRMLicenseRestoreProgress
),
2109 X(MEWMDRMLicenseAcquisitionCompleted
),
2110 X(MEWMDRMIndividualizationCompleted
),
2111 X(MEWMDRMIndividualizationProgress
),
2112 X(MEWMDRMProximityCompleted
),
2113 X(MEWMDRMLicenseStoreCleaned
),
2114 X(MEWMDRMRevocationDownloadCompleted
),
2115 X(METransformUnknown
),
2116 X(METransformNeedInput
),
2117 X(METransformHaveOutput
),
2118 X(METransformDrainComplete
),
2119 X(METransformMarker
),
2120 X(METransformInputStreamStateChanged
),
2121 X(MEByteStreamCharacteristicsChanged
),
2122 X(MEVideoCaptureDeviceRemoved
),
2123 X(MEVideoCaptureDevicePreempted
),
2124 X(MEStreamSinkFormatInvalidated
),
2125 X(MEEncodingParameters
),
2126 X(MEContentProtectionMetadata
),
2127 X(MEDeviceThermalStateChanged
),
2131 struct event_id
*ret
= bsearch(&event
, event_ids
, ARRAY_SIZE(event_ids
), sizeof(*event_ids
), debug_event_id
);
2132 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbg_sprintf("%u", event
);
2135 static inline struct attributes
*impl_from_IMFAttributes(IMFAttributes
*iface
)
2137 return CONTAINING_RECORD(iface
, struct attributes
, IMFAttributes_iface
);
2140 static HRESULT WINAPI
mfattributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
2142 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2144 if (IsEqualIID(riid
, &IID_IMFAttributes
) ||
2145 IsEqualGUID(riid
, &IID_IUnknown
))
2148 IMFAttributes_AddRef(iface
);
2152 WARN("Unsupported %s.\n", debugstr_guid(riid
));
2154 return E_NOINTERFACE
;
2157 static ULONG WINAPI
mfattributes_AddRef(IMFAttributes
*iface
)
2159 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2160 ULONG refcount
= InterlockedIncrement(&attributes
->ref
);
2162 TRACE("%p, refcount %d.\n", iface
, refcount
);
2167 static ULONG WINAPI
mfattributes_Release(IMFAttributes
*iface
)
2169 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2170 ULONG refcount
= InterlockedDecrement(&attributes
->ref
);
2172 TRACE("%p, refcount %d.\n", iface
, refcount
);
2176 clear_attributes_object(attributes
);
2183 static struct attribute
*attributes_find_item(struct attributes
*attributes
, REFGUID key
, size_t *index
)
2187 for (i
= 0; i
< attributes
->count
; ++i
)
2189 if (IsEqualGUID(key
, &attributes
->attributes
[i
].key
))
2193 return &attributes
->attributes
[i
];
2200 static HRESULT
attributes_get_item(struct attributes
*attributes
, const GUID
*key
, PROPVARIANT
*value
)
2202 struct attribute
*attribute
;
2205 EnterCriticalSection(&attributes
->cs
);
2207 attribute
= attributes_find_item(attributes
, key
, NULL
);
2210 if (attribute
->value
.vt
== value
->vt
&& !(value
->vt
== VT_UNKNOWN
&& !attribute
->value
.punkVal
))
2211 hr
= PropVariantCopy(value
, &attribute
->value
);
2213 hr
= MF_E_INVALIDTYPE
;
2216 hr
= MF_E_ATTRIBUTENOTFOUND
;
2218 LeaveCriticalSection(&attributes
->cs
);
2223 HRESULT
attributes_GetItem(struct attributes
*attributes
, REFGUID key
, PROPVARIANT
*value
)
2225 struct attribute
*attribute
;
2228 EnterCriticalSection(&attributes
->cs
);
2230 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2231 hr
= value
? PropVariantCopy(value
, &attribute
->value
) : S_OK
;
2233 hr
= MF_E_ATTRIBUTENOTFOUND
;
2235 LeaveCriticalSection(&attributes
->cs
);
2240 HRESULT
attributes_GetItemType(struct attributes
*attributes
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2242 struct attribute
*attribute
;
2245 EnterCriticalSection(&attributes
->cs
);
2247 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2249 *type
= attribute
->value
.vt
;
2252 hr
= MF_E_ATTRIBUTENOTFOUND
;
2254 LeaveCriticalSection(&attributes
->cs
);
2259 HRESULT
attributes_CompareItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2261 struct attribute
*attribute
;
2265 EnterCriticalSection(&attributes
->cs
);
2267 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2269 *result
= attribute
->value
.vt
== value
->vt
&&
2270 !PropVariantCompareEx(&attribute
->value
, value
, PVCU_DEFAULT
, PVCF_DEFAULT
);
2273 LeaveCriticalSection(&attributes
->cs
);
2278 HRESULT
attributes_Compare(struct attributes
*attributes
, IMFAttributes
*theirs
,
2279 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2281 IMFAttributes
*smaller
, *other
;
2282 MF_ATTRIBUTE_TYPE type
;
2288 if (FAILED(hr
= IMFAttributes_GetCount(theirs
, &count
)))
2291 EnterCriticalSection(&attributes
->cs
);
2297 case MF_ATTRIBUTES_MATCH_OUR_ITEMS
:
2298 for (i
= 0; i
< attributes
->count
; ++i
)
2300 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2301 &attributes
->attributes
[i
].value
, &result
)))
2307 case MF_ATTRIBUTES_MATCH_THEIR_ITEMS
:
2308 hr
= IMFAttributes_Compare(theirs
, &attributes
->IMFAttributes_iface
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2310 case MF_ATTRIBUTES_MATCH_ALL_ITEMS
:
2311 if (count
!= attributes
->count
)
2316 for (i
= 0; i
< count
; ++i
)
2318 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2319 &attributes
->attributes
[i
].value
, &result
)))
2325 case MF_ATTRIBUTES_MATCH_INTERSECTION
:
2326 for (i
= 0; i
< attributes
->count
; ++i
)
2328 if (FAILED(IMFAttributes_GetItemType(theirs
, &attributes
->attributes
[i
].key
, &type
)))
2331 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2332 &attributes
->attributes
[i
].value
, &result
)))
2339 case MF_ATTRIBUTES_MATCH_SMALLER
:
2340 smaller
= attributes
->count
> count
? theirs
: &attributes
->IMFAttributes_iface
;
2341 other
= attributes
->count
> count
? &attributes
->IMFAttributes_iface
: theirs
;
2342 hr
= IMFAttributes_Compare(smaller
, other
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2345 WARN("Unknown match type %d.\n", match_type
);
2349 LeaveCriticalSection(&attributes
->cs
);
2357 HRESULT
attributes_GetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32
*value
)
2359 PROPVARIANT attrval
;
2362 PropVariantInit(&attrval
);
2363 attrval
.vt
= VT_UI4
;
2364 hr
= attributes_get_item(attributes
, key
, &attrval
);
2366 *value
= attrval
.ulVal
;
2371 HRESULT
attributes_GetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64
*value
)
2373 PROPVARIANT attrval
;
2376 PropVariantInit(&attrval
);
2377 attrval
.vt
= VT_UI8
;
2378 hr
= attributes_get_item(attributes
, key
, &attrval
);
2380 *value
= attrval
.uhVal
.QuadPart
;
2385 HRESULT
attributes_GetDouble(struct attributes
*attributes
, REFGUID key
, double *value
)
2387 PROPVARIANT attrval
;
2390 PropVariantInit(&attrval
);
2392 hr
= attributes_get_item(attributes
, key
, &attrval
);
2394 *value
= attrval
.dblVal
;
2399 HRESULT
attributes_GetGUID(struct attributes
*attributes
, REFGUID key
, GUID
*value
)
2401 struct attribute
*attribute
;
2404 EnterCriticalSection(&attributes
->cs
);
2406 attribute
= attributes_find_item(attributes
, key
, NULL
);
2409 if (attribute
->value
.vt
== MF_ATTRIBUTE_GUID
)
2410 *value
= *attribute
->value
.puuid
;
2412 hr
= MF_E_INVALIDTYPE
;
2415 hr
= MF_E_ATTRIBUTENOTFOUND
;
2417 LeaveCriticalSection(&attributes
->cs
);
2422 HRESULT
attributes_GetStringLength(struct attributes
*attributes
, REFGUID key
, UINT32
*length
)
2424 struct attribute
*attribute
;
2427 EnterCriticalSection(&attributes
->cs
);
2429 attribute
= attributes_find_item(attributes
, key
, NULL
);
2432 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2433 *length
= lstrlenW(attribute
->value
.pwszVal
);
2435 hr
= MF_E_INVALIDTYPE
;
2438 hr
= MF_E_ATTRIBUTENOTFOUND
;
2440 LeaveCriticalSection(&attributes
->cs
);
2445 HRESULT
attributes_GetString(struct attributes
*attributes
, REFGUID key
, WCHAR
*value
,
2446 UINT32 size
, UINT32
*length
)
2448 struct attribute
*attribute
;
2451 EnterCriticalSection(&attributes
->cs
);
2453 attribute
= attributes_find_item(attributes
, key
, NULL
);
2456 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2458 int len
= lstrlenW(attribute
->value
.pwszVal
);
2464 hr
= STRSAFE_E_INSUFFICIENT_BUFFER
;
2466 memcpy(value
, attribute
->value
.pwszVal
, (len
+ 1) * sizeof(WCHAR
));
2469 hr
= MF_E_INVALIDTYPE
;
2472 hr
= MF_E_ATTRIBUTENOTFOUND
;
2474 LeaveCriticalSection(&attributes
->cs
);
2479 HRESULT
attributes_GetAllocatedString(struct attributes
*attributes
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2481 PROPVARIANT attrval
;
2484 PropVariantInit(&attrval
);
2485 attrval
.vt
= VT_LPWSTR
;
2486 hr
= attributes_get_item(attributes
, key
, &attrval
);
2489 *value
= attrval
.pwszVal
;
2490 *length
= lstrlenW(*value
);
2496 HRESULT
attributes_GetBlobSize(struct attributes
*attributes
, REFGUID key
, UINT32
*size
)
2498 struct attribute
*attribute
;
2501 EnterCriticalSection(&attributes
->cs
);
2503 attribute
= attributes_find_item(attributes
, key
, NULL
);
2506 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2507 *size
= attribute
->value
.caub
.cElems
;
2509 hr
= MF_E_INVALIDTYPE
;
2512 hr
= MF_E_ATTRIBUTENOTFOUND
;
2514 LeaveCriticalSection(&attributes
->cs
);
2519 HRESULT
attributes_GetBlob(struct attributes
*attributes
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
, UINT32
*blobsize
)
2521 struct attribute
*attribute
;
2524 EnterCriticalSection(&attributes
->cs
);
2526 attribute
= attributes_find_item(attributes
, key
, NULL
);
2529 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2531 UINT32 size
= attribute
->value
.caub
.cElems
;
2533 if (bufsize
>= size
)
2534 hr
= PropVariantToBuffer(&attribute
->value
, buf
, size
);
2536 hr
= E_NOT_SUFFICIENT_BUFFER
;
2542 hr
= MF_E_INVALIDTYPE
;
2545 hr
= MF_E_ATTRIBUTENOTFOUND
;
2547 LeaveCriticalSection(&attributes
->cs
);
2552 HRESULT
attributes_GetAllocatedBlob(struct attributes
*attributes
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2554 PROPVARIANT attrval
;
2557 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2558 hr
= attributes_get_item(attributes
, key
, &attrval
);
2561 *buf
= attrval
.caub
.pElems
;
2562 *size
= attrval
.caub
.cElems
;
2568 HRESULT
attributes_GetUnknown(struct attributes
*attributes
, REFGUID key
, REFIID riid
, void **out
)
2570 PROPVARIANT attrval
;
2573 PropVariantInit(&attrval
);
2574 attrval
.vt
= VT_UNKNOWN
;
2575 hr
= attributes_get_item(attributes
, key
, &attrval
);
2577 hr
= IUnknown_QueryInterface(attrval
.punkVal
, riid
, out
);
2578 PropVariantClear(&attrval
);
2582 static HRESULT
attributes_set_item(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2584 struct attribute
*attribute
;
2586 EnterCriticalSection(&attributes
->cs
);
2588 attribute
= attributes_find_item(attributes
, key
, NULL
);
2591 if (!mf_array_reserve((void **)&attributes
->attributes
, &attributes
->capacity
, attributes
->count
+ 1,
2592 sizeof(*attributes
->attributes
)))
2594 LeaveCriticalSection(&attributes
->cs
);
2595 return E_OUTOFMEMORY
;
2597 attributes
->attributes
[attributes
->count
].key
= *key
;
2598 attribute
= &attributes
->attributes
[attributes
->count
++];
2601 PropVariantClear(&attribute
->value
);
2603 PropVariantCopy(&attribute
->value
, value
);
2605 LeaveCriticalSection(&attributes
->cs
);
2610 HRESULT
attributes_SetItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2616 case MF_ATTRIBUTE_UINT32
:
2617 case MF_ATTRIBUTE_UINT64
:
2618 case MF_ATTRIBUTE_DOUBLE
:
2619 case MF_ATTRIBUTE_GUID
:
2620 case MF_ATTRIBUTE_STRING
:
2621 case MF_ATTRIBUTE_BLOB
:
2622 case MF_ATTRIBUTE_IUNKNOWN
:
2623 return attributes_set_item(attributes
, key
, value
);
2625 PropVariantInit(&empty
);
2626 attributes_set_item(attributes
, key
, &empty
);
2627 return MF_E_INVALIDTYPE
;
2631 HRESULT
attributes_DeleteItem(struct attributes
*attributes
, REFGUID key
)
2633 struct attribute
*attribute
;
2636 EnterCriticalSection(&attributes
->cs
);
2638 if ((attribute
= attributes_find_item(attributes
, key
, &index
)))
2642 PropVariantClear(&attribute
->value
);
2644 attributes
->count
--;
2645 count
= attributes
->count
- index
;
2647 memmove(&attributes
->attributes
[index
], &attributes
->attributes
[index
+ 1], count
* sizeof(*attributes
->attributes
));
2650 LeaveCriticalSection(&attributes
->cs
);
2655 HRESULT
attributes_DeleteAllItems(struct attributes
*attributes
)
2657 EnterCriticalSection(&attributes
->cs
);
2659 while (attributes
->count
)
2661 PropVariantClear(&attributes
->attributes
[--attributes
->count
].value
);
2663 free(attributes
->attributes
);
2664 attributes
->attributes
= NULL
;
2665 attributes
->capacity
= 0;
2667 LeaveCriticalSection(&attributes
->cs
);
2672 HRESULT
attributes_SetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32 value
)
2674 PROPVARIANT attrval
;
2676 attrval
.vt
= VT_UI4
;
2677 attrval
.ulVal
= value
;
2678 return attributes_set_item(attributes
, key
, &attrval
);
2681 HRESULT
attributes_SetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64 value
)
2683 PROPVARIANT attrval
;
2685 attrval
.vt
= VT_UI8
;
2686 attrval
.uhVal
.QuadPart
= value
;
2687 return attributes_set_item(attributes
, key
, &attrval
);
2690 HRESULT
attributes_SetDouble(struct attributes
*attributes
, REFGUID key
, double value
)
2692 PROPVARIANT attrval
;
2695 attrval
.dblVal
= value
;
2696 return attributes_set_item(attributes
, key
, &attrval
);
2699 HRESULT
attributes_SetGUID(struct attributes
*attributes
, REFGUID key
, REFGUID value
)
2701 PROPVARIANT attrval
;
2703 attrval
.vt
= VT_CLSID
;
2704 attrval
.puuid
= (CLSID
*)value
;
2705 return attributes_set_item(attributes
, key
, &attrval
);
2708 HRESULT
attributes_SetString(struct attributes
*attributes
, REFGUID key
, const WCHAR
*value
)
2710 PROPVARIANT attrval
;
2712 attrval
.vt
= VT_LPWSTR
;
2713 attrval
.pwszVal
= (WCHAR
*)value
;
2714 return attributes_set_item(attributes
, key
, &attrval
);
2717 HRESULT
attributes_SetBlob(struct attributes
*attributes
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
2719 PROPVARIANT attrval
;
2721 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2722 attrval
.caub
.cElems
= size
;
2723 attrval
.caub
.pElems
= (UINT8
*)buf
;
2724 return attributes_set_item(attributes
, key
, &attrval
);
2727 HRESULT
attributes_SetUnknown(struct attributes
*attributes
, REFGUID key
, IUnknown
*unknown
)
2729 PROPVARIANT attrval
;
2731 attrval
.vt
= VT_UNKNOWN
;
2732 attrval
.punkVal
= unknown
;
2733 return attributes_set_item(attributes
, key
, &attrval
);
2736 HRESULT
attributes_LockStore(struct attributes
*attributes
)
2738 EnterCriticalSection(&attributes
->cs
);
2743 HRESULT
attributes_UnlockStore(struct attributes
*attributes
)
2745 LeaveCriticalSection(&attributes
->cs
);
2750 HRESULT
attributes_GetCount(struct attributes
*attributes
, UINT32
*count
)
2752 EnterCriticalSection(&attributes
->cs
);
2753 *count
= attributes
->count
;
2754 LeaveCriticalSection(&attributes
->cs
);
2759 HRESULT
attributes_GetItemByIndex(struct attributes
*attributes
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
2763 EnterCriticalSection(&attributes
->cs
);
2765 if (index
< attributes
->count
)
2767 *key
= attributes
->attributes
[index
].key
;
2769 PropVariantCopy(value
, &attributes
->attributes
[index
].value
);
2774 LeaveCriticalSection(&attributes
->cs
);
2779 HRESULT
attributes_CopyAllItems(struct attributes
*attributes
, IMFAttributes
*dest
)
2784 EnterCriticalSection(&attributes
->cs
);
2786 IMFAttributes_LockStore(dest
);
2788 IMFAttributes_DeleteAllItems(dest
);
2790 for (i
= 0; i
< attributes
->count
; ++i
)
2792 hr
= IMFAttributes_SetItem(dest
, &attributes
->attributes
[i
].key
, &attributes
->attributes
[i
].value
);
2797 IMFAttributes_UnlockStore(dest
);
2799 LeaveCriticalSection(&attributes
->cs
);
2804 static HRESULT WINAPI
mfattributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
2806 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2808 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2810 return attributes_GetItem(attributes
, key
, value
);
2813 static HRESULT WINAPI
mfattributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2815 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2817 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
2819 return attributes_GetItemType(attributes
, key
, type
);
2822 static HRESULT WINAPI
mfattributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2824 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2826 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
2828 return attributes_CompareItem(attributes
, key
, value
, result
);
2831 static HRESULT WINAPI
mfattributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
2832 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2834 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2836 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
2838 return attributes_Compare(attributes
, theirs
, match_type
, ret
);
2841 static HRESULT WINAPI
mfattributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
2843 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2845 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2847 return attributes_GetUINT32(attributes
, key
, value
);
2850 static HRESULT WINAPI
mfattributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
2852 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2854 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2856 return attributes_GetUINT64(attributes
, key
, value
);
2859 static HRESULT WINAPI
mfattributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
2861 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2863 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2865 return attributes_GetDouble(attributes
, key
, value
);
2868 static HRESULT WINAPI
mfattributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
2870 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2872 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2874 return attributes_GetGUID(attributes
, key
, value
);
2877 static HRESULT WINAPI
mfattributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
2879 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2881 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
2883 return attributes_GetStringLength(attributes
, key
, length
);
2886 static HRESULT WINAPI
mfattributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
2887 UINT32 size
, UINT32
*length
)
2889 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2891 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
2893 return attributes_GetString(attributes
, key
, value
, size
, length
);
2896 static HRESULT WINAPI
mfattributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2898 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2900 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
2902 return attributes_GetAllocatedString(attributes
, key
, value
, length
);
2905 static HRESULT WINAPI
mfattributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
2907 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2909 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
2911 return attributes_GetBlobSize(attributes
, key
, size
);
2914 static HRESULT WINAPI
mfattributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
2915 UINT32 bufsize
, UINT32
*blobsize
)
2917 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2919 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
2921 return attributes_GetBlob(attributes
, key
, buf
, bufsize
, blobsize
);
2924 static HRESULT WINAPI
mfattributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2926 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2928 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
2930 return attributes_GetAllocatedBlob(attributes
, key
, buf
, size
);
2933 static HRESULT WINAPI
mfattributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
2935 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2937 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
2939 return attributes_GetUnknown(attributes
, key
, riid
, out
);
2942 static HRESULT WINAPI
mfattributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
2944 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2946 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
2948 return attributes_SetItem(attributes
, key
, value
);
2951 static HRESULT WINAPI
mfattributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
2953 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2955 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
2957 return attributes_DeleteItem(attributes
, key
);
2960 static HRESULT WINAPI
mfattributes_DeleteAllItems(IMFAttributes
*iface
)
2962 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2964 TRACE("%p.\n", iface
);
2966 return attributes_DeleteAllItems(attributes
);
2969 static HRESULT WINAPI
mfattributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
2971 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2973 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
2975 return attributes_SetUINT32(attributes
, key
, value
);
2978 static HRESULT WINAPI
mfattributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
2980 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2982 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
2984 return attributes_SetUINT64(attributes
, key
, value
);
2987 static HRESULT WINAPI
mfattributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
2989 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2991 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
2993 return attributes_SetDouble(attributes
, key
, value
);
2996 static HRESULT WINAPI
mfattributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
2998 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3000 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
3002 return attributes_SetGUID(attributes
, key
, value
);
3005 static HRESULT WINAPI
mfattributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
3007 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3009 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
3011 return attributes_SetString(attributes
, key
, value
);
3014 static HRESULT WINAPI
mfattributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
3016 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3018 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
3020 return attributes_SetBlob(attributes
, key
, buf
, size
);
3023 static HRESULT WINAPI
mfattributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
3025 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3027 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
3029 return attributes_SetUnknown(attributes
, key
, unknown
);
3032 static HRESULT WINAPI
mfattributes_LockStore(IMFAttributes
*iface
)
3034 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3036 TRACE("%p.\n", iface
);
3038 return attributes_LockStore(attributes
);
3041 static HRESULT WINAPI
mfattributes_UnlockStore(IMFAttributes
*iface
)
3043 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3045 TRACE("%p.\n", iface
);
3047 return attributes_UnlockStore(attributes
);
3050 static HRESULT WINAPI
mfattributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
3052 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3054 TRACE("%p, %p.\n", iface
, count
);
3056 return attributes_GetCount(attributes
, count
);
3059 static HRESULT WINAPI
mfattributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
3061 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3063 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
3065 return attributes_GetItemByIndex(attributes
, index
, key
, value
);
3068 static HRESULT WINAPI
mfattributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
3070 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3072 TRACE("%p, %p.\n", iface
, dest
);
3074 return attributes_CopyAllItems(attributes
, dest
);
3077 static const IMFAttributesVtbl mfattributes_vtbl
=
3079 mfattributes_QueryInterface
,
3080 mfattributes_AddRef
,
3081 mfattributes_Release
,
3082 mfattributes_GetItem
,
3083 mfattributes_GetItemType
,
3084 mfattributes_CompareItem
,
3085 mfattributes_Compare
,
3086 mfattributes_GetUINT32
,
3087 mfattributes_GetUINT64
,
3088 mfattributes_GetDouble
,
3089 mfattributes_GetGUID
,
3090 mfattributes_GetStringLength
,
3091 mfattributes_GetString
,
3092 mfattributes_GetAllocatedString
,
3093 mfattributes_GetBlobSize
,
3094 mfattributes_GetBlob
,
3095 mfattributes_GetAllocatedBlob
,
3096 mfattributes_GetUnknown
,
3097 mfattributes_SetItem
,
3098 mfattributes_DeleteItem
,
3099 mfattributes_DeleteAllItems
,
3100 mfattributes_SetUINT32
,
3101 mfattributes_SetUINT64
,
3102 mfattributes_SetDouble
,
3103 mfattributes_SetGUID
,
3104 mfattributes_SetString
,
3105 mfattributes_SetBlob
,
3106 mfattributes_SetUnknown
,
3107 mfattributes_LockStore
,
3108 mfattributes_UnlockStore
,
3109 mfattributes_GetCount
,
3110 mfattributes_GetItemByIndex
,
3111 mfattributes_CopyAllItems
3114 HRESULT
init_attributes_object(struct attributes
*object
, UINT32 size
)
3116 object
->IMFAttributes_iface
.lpVtbl
= &mfattributes_vtbl
;
3118 InitializeCriticalSection(&object
->cs
);
3120 object
->attributes
= NULL
;
3122 object
->capacity
= 0;
3123 if (!mf_array_reserve((void **)&object
->attributes
, &object
->capacity
, size
,
3124 sizeof(*object
->attributes
)))
3126 DeleteCriticalSection(&object
->cs
);
3127 return E_OUTOFMEMORY
;
3133 void clear_attributes_object(struct attributes
*object
)
3137 for (i
= 0; i
< object
->count
; i
++)
3138 PropVariantClear(&object
->attributes
[i
].value
);
3139 free(object
->attributes
);
3141 DeleteCriticalSection(&object
->cs
);
3144 /***********************************************************************
3145 * MFCreateAttributes (mfplat.@)
3147 HRESULT WINAPI
MFCreateAttributes(IMFAttributes
**attributes
, UINT32 size
)
3149 struct attributes
*object
;
3152 TRACE("%p, %d\n", attributes
, size
);
3154 if (!(object
= calloc(1, sizeof(*object
))))
3155 return E_OUTOFMEMORY
;
3157 if (FAILED(hr
= init_attributes_object(object
, size
)))
3162 *attributes
= &object
->IMFAttributes_iface
;
3167 #define ATTRIBUTES_STORE_MAGIC 0x494d4641 /* IMFA */
3169 struct attributes_store_header
3175 struct attributes_store_item
3192 /***********************************************************************
3193 * MFGetAttributesAsBlobSize (mfplat.@)
3195 HRESULT WINAPI
MFGetAttributesAsBlobSize(IMFAttributes
*attributes
, UINT32
*size
)
3197 unsigned int i
, count
, length
;
3201 TRACE("%p, %p.\n", attributes
, size
);
3203 IMFAttributes_LockStore(attributes
);
3205 hr
= IMFAttributes_GetCount(attributes
, &count
);
3207 *size
= sizeof(struct attributes_store_header
);
3209 for (i
= 0; i
< count
; ++i
)
3211 MF_ATTRIBUTE_TYPE type
;
3213 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &key
, NULL
);
3217 *size
+= sizeof(struct attributes_store_item
);
3219 IMFAttributes_GetItemType(attributes
, &key
, &type
);
3223 case MF_ATTRIBUTE_GUID
:
3224 *size
+= sizeof(GUID
);
3226 case MF_ATTRIBUTE_STRING
:
3227 IMFAttributes_GetStringLength(attributes
, &key
, &length
);
3228 *size
+= (length
+ 1) * sizeof(WCHAR
);
3230 case MF_ATTRIBUTE_BLOB
:
3231 IMFAttributes_GetBlobSize(attributes
, &key
, &length
);
3234 case MF_ATTRIBUTE_UINT32
:
3235 case MF_ATTRIBUTE_UINT64
:
3236 case MF_ATTRIBUTE_DOUBLE
:
3237 case MF_ATTRIBUTE_IUNKNOWN
:
3243 IMFAttributes_UnlockStore(attributes
);
3248 struct attr_serialize_context
3255 static void attributes_serialize_write(struct attr_serialize_context
*context
, const void *value
, unsigned int size
)
3257 memcpy(context
->ptr
, value
, size
);
3258 context
->ptr
+= size
;
3261 static BOOL
attributes_serialize_write_item(struct attr_serialize_context
*context
, struct attributes_store_item
*item
,
3266 case MF_ATTRIBUTE_UINT32
:
3267 case MF_ATTRIBUTE_UINT64
:
3268 case MF_ATTRIBUTE_DOUBLE
:
3269 attributes_serialize_write(context
, item
, sizeof(*item
));
3271 case MF_ATTRIBUTE_GUID
:
3272 case MF_ATTRIBUTE_STRING
:
3273 case MF_ATTRIBUTE_BLOB
:
3274 item
->u
.subheader
.offset
= context
->size
- item
->u
.subheader
.size
;
3275 attributes_serialize_write(context
, item
, sizeof(*item
));
3276 memcpy(context
->buffer
+ item
->u
.subheader
.offset
, value
, item
->u
.subheader
.size
);
3277 context
->size
-= item
->u
.subheader
.size
;
3286 /***********************************************************************
3287 * MFGetAttributesAsBlob (mfplat.@)
3289 HRESULT WINAPI
MFGetAttributesAsBlob(IMFAttributes
*attributes
, UINT8
*buffer
, UINT size
)
3291 struct attributes_store_header header
;
3292 struct attr_serialize_context context
;
3293 unsigned int required_size
, i
;
3298 TRACE("%p, %p, %u.\n", attributes
, buffer
, size
);
3300 if (FAILED(hr
= MFGetAttributesAsBlobSize(attributes
, &required_size
)))
3303 if (required_size
> size
)
3304 return MF_E_BUFFERTOOSMALL
;
3306 context
.buffer
= buffer
;
3307 context
.ptr
= buffer
;
3308 context
.size
= required_size
;
3310 IMFAttributes_LockStore(attributes
);
3312 header
.magic
= ATTRIBUTES_STORE_MAGIC
;
3313 header
.count
= 0; /* Will be updated later */
3314 IMFAttributes_GetCount(attributes
, &count
);
3316 attributes_serialize_write(&context
, &header
, sizeof(header
));
3318 for (i
= 0; i
< count
; ++i
)
3320 struct attributes_store_item item
;
3321 const void *data
= NULL
;
3323 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &item
.key
, &value
);
3327 item
.type
= value
.vt
;
3331 case MF_ATTRIBUTE_UINT32
:
3332 case MF_ATTRIBUTE_UINT64
:
3333 item
.u
.i64
= value
.uhVal
.QuadPart
;
3335 case MF_ATTRIBUTE_DOUBLE
:
3336 item
.u
.f
= value
.dblVal
;
3338 case MF_ATTRIBUTE_GUID
:
3339 item
.u
.subheader
.size
= sizeof(*value
.puuid
);
3342 case MF_ATTRIBUTE_STRING
:
3343 item
.u
.subheader
.size
= (lstrlenW(value
.pwszVal
) + 1) * sizeof(WCHAR
);
3344 data
= value
.pwszVal
;
3346 case MF_ATTRIBUTE_BLOB
:
3347 item
.u
.subheader
.size
= value
.caub
.cElems
;
3348 data
= value
.caub
.pElems
;
3350 case MF_ATTRIBUTE_IUNKNOWN
:
3353 WARN("Unknown attribute type %#x.\n", value
.vt
);
3356 if (attributes_serialize_write_item(&context
, &item
, data
))
3359 PropVariantClear(&value
);
3362 memcpy(context
.buffer
, &header
, sizeof(header
));
3364 IMFAttributes_UnlockStore(attributes
);
3369 static HRESULT
attributes_deserialize_read(struct attr_serialize_context
*context
, void *value
, unsigned int size
)
3371 if (context
->size
< (context
->ptr
- context
->buffer
) + size
)
3372 return E_INVALIDARG
;
3374 memcpy(value
, context
->ptr
, size
);
3375 context
->ptr
+= size
;
3380 /***********************************************************************
3381 * MFInitAttributesFromBlob (mfplat.@)
3383 HRESULT WINAPI
MFInitAttributesFromBlob(IMFAttributes
*dest
, const UINT8
*buffer
, UINT size
)
3385 struct attr_serialize_context context
;
3386 struct attributes_store_header header
;
3387 struct attributes_store_item item
;
3388 IMFAttributes
*attributes
;
3392 TRACE("%p, %p, %u.\n", dest
, buffer
, size
);
3394 context
.buffer
= (UINT8
*)buffer
;
3395 context
.ptr
= (UINT8
*)buffer
;
3396 context
.size
= size
;
3398 /* Validate buffer structure. */
3399 if (FAILED(hr
= attributes_deserialize_read(&context
, &header
, sizeof(header
))))
3402 if (header
.magic
!= ATTRIBUTES_STORE_MAGIC
)
3403 return E_UNEXPECTED
;
3405 if (FAILED(hr
= MFCreateAttributes(&attributes
, header
.count
)))
3408 for (i
= 0; i
< header
.count
; ++i
)
3410 if (FAILED(hr
= attributes_deserialize_read(&context
, &item
, sizeof(item
))))
3417 case MF_ATTRIBUTE_UINT32
:
3418 hr
= IMFAttributes_SetUINT32(attributes
, &item
.key
, item
.u
.i32
);
3420 case MF_ATTRIBUTE_UINT64
:
3421 hr
= IMFAttributes_SetUINT64(attributes
, &item
.key
, item
.u
.i64
);
3423 case MF_ATTRIBUTE_DOUBLE
:
3424 hr
= IMFAttributes_SetDouble(attributes
, &item
.key
, item
.u
.f
);
3426 case MF_ATTRIBUTE_GUID
:
3427 if (item
.u
.subheader
.size
== sizeof(GUID
) &&
3428 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3430 hr
= IMFAttributes_SetGUID(attributes
, &item
.key
,
3431 (const GUID
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3434 case MF_ATTRIBUTE_STRING
:
3435 if (item
.u
.subheader
.size
>= sizeof(WCHAR
) &&
3436 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3438 hr
= IMFAttributes_SetString(attributes
, &item
.key
,
3439 (const WCHAR
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3442 case MF_ATTRIBUTE_BLOB
:
3443 if (item
.u
.subheader
.size
> 0 && item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3445 hr
= IMFAttributes_SetBlob(attributes
, &item
.key
, context
.buffer
+ item
.u
.subheader
.offset
,
3446 item
.u
.subheader
.size
);
3459 IMFAttributes_DeleteAllItems(dest
);
3460 hr
= IMFAttributes_CopyAllItems(attributes
, dest
);
3463 IMFAttributes_Release(attributes
);
3470 struct attributes attributes
;
3471 IMFByteStream IMFByteStream_iface
;
3472 IMFGetService IMFGetService_iface
;
3473 IRtwqAsyncCallback read_callback
;
3474 IRtwqAsyncCallback write_callback
;
3479 struct list pending
;
3480 CRITICAL_SECTION cs
;
3483 static inline struct bytestream
*impl_from_IMFByteStream(IMFByteStream
*iface
)
3485 return CONTAINING_RECORD(iface
, struct bytestream
, IMFByteStream_iface
);
3488 static struct bytestream
*impl_bytestream_from_IMFGetService(IMFGetService
*iface
)
3490 return CONTAINING_RECORD(iface
, struct bytestream
, IMFGetService_iface
);
3493 static struct bytestream
*impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3495 return CONTAINING_RECORD(iface
, struct bytestream
, read_callback
);
3498 static struct bytestream
*impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3500 return CONTAINING_RECORD(iface
, struct bytestream
, write_callback
);
3503 enum async_stream_op_type
3505 ASYNC_STREAM_OP_READ
,
3506 ASYNC_STREAM_OP_WRITE
,
3509 struct async_stream_op
3511 IUnknown IUnknown_iface
;
3519 ULONG requested_length
;
3520 ULONG actual_length
;
3521 IMFAsyncResult
*caller
;
3523 enum async_stream_op_type type
;
3526 static struct async_stream_op
*impl_async_stream_op_from_IUnknown(IUnknown
*iface
)
3528 return CONTAINING_RECORD(iface
, struct async_stream_op
, IUnknown_iface
);
3531 static HRESULT WINAPI
async_stream_op_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
3533 if (IsEqualIID(riid
, &IID_IUnknown
))
3536 IUnknown_AddRef(iface
);
3540 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3542 return E_NOINTERFACE
;
3545 static ULONG WINAPI
async_stream_op_AddRef(IUnknown
*iface
)
3547 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3548 ULONG refcount
= InterlockedIncrement(&op
->refcount
);
3550 TRACE("%p, refcount %d.\n", iface
, refcount
);
3555 static ULONG WINAPI
async_stream_op_Release(IUnknown
*iface
)
3557 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3558 ULONG refcount
= InterlockedDecrement(&op
->refcount
);
3560 TRACE("%p, refcount %d.\n", iface
, refcount
);
3565 IMFAsyncResult_Release(op
->caller
);
3572 static const IUnknownVtbl async_stream_op_vtbl
=
3574 async_stream_op_QueryInterface
,
3575 async_stream_op_AddRef
,
3576 async_stream_op_Release
,
3579 static HRESULT
bytestream_create_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3580 const BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
, IUnknown
*state
)
3582 struct async_stream_op
*op
;
3583 IRtwqAsyncResult
*request
;
3586 op
= malloc(sizeof(*op
));
3588 return E_OUTOFMEMORY
;
3590 op
->IUnknown_iface
.lpVtbl
= &async_stream_op_vtbl
;
3593 op
->position
= stream
->position
;
3594 op
->requested_length
= size
;
3596 if (FAILED(hr
= RtwqCreateAsyncResult((IUnknown
*)&stream
->IMFByteStream_iface
, (IRtwqAsyncCallback
*)callback
, state
,
3597 (IRtwqAsyncResult
**)&op
->caller
)))
3602 if (FAILED(hr
= RtwqCreateAsyncResult(&op
->IUnknown_iface
, type
== ASYNC_STREAM_OP_READ
? &stream
->read_callback
:
3603 &stream
->write_callback
, NULL
, &request
)))
3606 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, request
);
3607 IRtwqAsyncResult_Release(request
);
3610 IUnknown_Release(&op
->IUnknown_iface
);
3614 static HRESULT
bytestream_complete_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3615 IMFAsyncResult
*result
, ULONG
*actual_length
)
3617 struct async_stream_op
*op
= NULL
, *cur
;
3620 EnterCriticalSection(&stream
->cs
);
3621 LIST_FOR_EACH_ENTRY(cur
, &stream
->pending
, struct async_stream_op
, entry
)
3623 if (cur
->caller
== result
&& cur
->type
== type
)
3626 list_remove(&cur
->entry
);
3630 LeaveCriticalSection(&stream
->cs
);
3633 return E_INVALIDARG
;
3635 if (SUCCEEDED(hr
= IMFAsyncResult_GetStatus(result
)))
3636 *actual_length
= op
->actual_length
;
3638 IUnknown_Release(&op
->IUnknown_iface
);
3643 static HRESULT WINAPI
bytestream_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
3645 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
3646 IsEqualIID(riid
, &IID_IUnknown
))
3649 IRtwqAsyncCallback_AddRef(iface
);
3653 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3655 return E_NOINTERFACE
;
3658 static ULONG WINAPI
bytestream_read_callback_AddRef(IRtwqAsyncCallback
*iface
)
3660 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3661 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3664 static ULONG WINAPI
bytestream_read_callback_Release(IRtwqAsyncCallback
*iface
)
3666 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3667 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3670 static HRESULT WINAPI
bytestream_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
3675 static ULONG WINAPI
bytestream_write_callback_AddRef(IRtwqAsyncCallback
*iface
)
3677 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3678 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3681 static ULONG WINAPI
bytestream_write_callback_Release(IRtwqAsyncCallback
*iface
)
3683 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3684 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3687 static HRESULT WINAPI
bytestream_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
3689 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3691 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
3693 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
3694 IsEqualIID(riid
, &IID_IUnknown
))
3696 *out
= &stream
->IMFByteStream_iface
;
3698 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
3700 *out
= &stream
->attributes
.IMFAttributes_iface
;
3702 else if (stream
->IMFGetService_iface
.lpVtbl
&& IsEqualIID(riid
, &IID_IMFGetService
))
3704 *out
= &stream
->IMFGetService_iface
;
3708 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3710 return E_NOINTERFACE
;
3713 IUnknown_AddRef((IUnknown
*)*out
);
3717 static ULONG WINAPI
bytestream_AddRef(IMFByteStream
*iface
)
3719 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3720 ULONG refcount
= InterlockedIncrement(&stream
->attributes
.ref
);
3722 TRACE("%p, refcount %d.\n", iface
, refcount
);
3727 static ULONG WINAPI
bytestream_Release(IMFByteStream
*iface
)
3729 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3730 ULONG refcount
= InterlockedDecrement(&stream
->attributes
.ref
);
3731 struct async_stream_op
*cur
, *cur2
;
3733 TRACE("%p, refcount %d.\n", iface
, refcount
);
3737 clear_attributes_object(&stream
->attributes
);
3738 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &stream
->pending
, struct async_stream_op
, entry
)
3740 list_remove(&cur
->entry
);
3741 IUnknown_Release(&cur
->IUnknown_iface
);
3743 DeleteCriticalSection(&stream
->cs
);
3745 IStream_Release(stream
->stream
);
3747 CloseHandle(stream
->hfile
);
3754 static HRESULT WINAPI
bytestream_stream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3756 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3760 TRACE("%p, %p.\n", iface
, capabilities
);
3762 if (FAILED(hr
= IStream_Stat(stream
->stream
, &stat
, STATFLAG_NONAME
)))
3765 *capabilities
= MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_SEEKABLE
;
3766 if (stat
.grfMode
& (STGM_WRITE
| STGM_READWRITE
))
3767 *capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
3772 static HRESULT WINAPI
bytestream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3774 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3776 TRACE("%p, %p.\n", iface
, capabilities
);
3778 *capabilities
= stream
->capabilities
;
3783 static HRESULT WINAPI
bytestream_SetLength(IMFByteStream
*iface
, QWORD length
)
3785 FIXME("%p, %s\n", iface
, wine_dbgstr_longlong(length
));
3790 static HRESULT WINAPI
bytestream_file_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
3792 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3794 TRACE("%p, %p.\n", iface
, position
);
3797 return E_INVALIDARG
;
3799 *position
= stream
->position
;
3804 static HRESULT WINAPI
bytestream_file_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3806 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3809 TRACE("%p, %p.\n", iface
, length
);
3812 return E_INVALIDARG
;
3814 if (GetFileSizeEx(stream
->hfile
, &li
))
3815 *length
= li
.QuadPart
;
3817 return HRESULT_FROM_WIN32(GetLastError());
3822 static HRESULT WINAPI
bytestream_file_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
3824 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3825 LARGE_INTEGER position
, length
;
3828 TRACE("%p, %p.\n", iface
, ret
);
3830 EnterCriticalSection(&stream
->cs
);
3832 position
.QuadPart
= 0;
3833 if (SetFilePointerEx(stream
->hfile
, position
, &length
, FILE_END
))
3834 *ret
= stream
->position
>= length
.QuadPart
;
3836 hr
= HRESULT_FROM_WIN32(GetLastError());
3838 LeaveCriticalSection(&stream
->cs
);
3843 static HRESULT WINAPI
bytestream_file_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
3845 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3846 LARGE_INTEGER position
;
3850 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
3852 EnterCriticalSection(&stream
->cs
);
3854 position
.QuadPart
= stream
->position
;
3855 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
3857 if ((ret
= ReadFile(stream
->hfile
, buffer
, size
, read_len
, NULL
)))
3858 stream
->position
+= *read_len
;
3862 hr
= HRESULT_FROM_WIN32(GetLastError());
3864 LeaveCriticalSection(&stream
->cs
);
3869 static HRESULT WINAPI
bytestream_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
,
3872 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3874 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3876 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_READ
, data
, size
, callback
, state
);
3879 static HRESULT WINAPI
bytestream_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
3881 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3883 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
3885 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_READ
, result
, byte_read
);
3888 static HRESULT WINAPI
bytestream_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
3890 FIXME("%p, %p, %u, %p\n", iface
, data
, count
, written
);
3895 static HRESULT WINAPI
bytestream_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
3896 IMFAsyncCallback
*callback
, IUnknown
*state
)
3898 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3900 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3902 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_WRITE
, data
, size
, callback
, state
);
3905 static HRESULT WINAPI
bytestream_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
3907 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3909 TRACE("%p, %p, %p.\n", iface
, result
, written
);
3911 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_WRITE
, result
, written
);
3914 static HRESULT WINAPI
bytestream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
3915 DWORD flags
, QWORD
*current
)
3917 FIXME("%p, %u, %s, 0x%08x, %p\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
3922 static HRESULT WINAPI
bytestream_Flush(IMFByteStream
*iface
)
3924 FIXME("%p\n", iface
);
3929 static HRESULT WINAPI
bytestream_Close(IMFByteStream
*iface
)
3931 FIXME("%p\n", iface
);
3936 static HRESULT WINAPI
bytestream_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
3938 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3940 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
3942 EnterCriticalSection(&stream
->cs
);
3943 stream
->position
= position
;
3944 LeaveCriticalSection(&stream
->cs
);
3949 static const IMFByteStreamVtbl bytestream_file_vtbl
=
3951 bytestream_QueryInterface
,
3954 bytestream_GetCapabilities
,
3955 bytestream_file_GetLength
,
3956 bytestream_SetLength
,
3957 bytestream_file_GetCurrentPosition
,
3958 bytestream_SetCurrentPosition
,
3959 bytestream_file_IsEndOfStream
,
3960 bytestream_file_Read
,
3961 bytestream_BeginRead
,
3964 bytestream_BeginWrite
,
3965 bytestream_EndWrite
,
3971 static HRESULT WINAPI
bytestream_stream_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3973 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3977 TRACE("%p, %p.\n", iface
, length
);
3979 if (FAILED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
3982 *length
= statstg
.cbSize
.QuadPart
;
3987 static HRESULT WINAPI
bytestream_stream_SetLength(IMFByteStream
*iface
, QWORD length
)
3989 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3990 ULARGE_INTEGER size
;
3993 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
3995 EnterCriticalSection(&stream
->cs
);
3997 size
.QuadPart
= length
;
3998 hr
= IStream_SetSize(stream
->stream
, size
);
4000 LeaveCriticalSection(&stream
->cs
);
4005 static HRESULT WINAPI
bytestream_stream_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4007 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4009 TRACE("%p, %p.\n", iface
, position
);
4011 *position
= stream
->position
;
4016 static HRESULT WINAPI
bytestream_stream_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4018 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4022 TRACE("%p, %p.\n", iface
, ret
);
4024 EnterCriticalSection(&stream
->cs
);
4026 if (SUCCEEDED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4027 *ret
= stream
->position
>= statstg
.cbSize
.QuadPart
;
4029 LeaveCriticalSection(&stream
->cs
);
4034 static HRESULT WINAPI
bytestream_stream_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4036 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4037 LARGE_INTEGER position
;
4040 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
4042 EnterCriticalSection(&stream
->cs
);
4044 position
.QuadPart
= stream
->position
;
4045 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4047 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, buffer
, size
, read_len
)))
4048 stream
->position
+= *read_len
;
4051 LeaveCriticalSection(&stream
->cs
);
4056 static HRESULT WINAPI
bytestream_stream_Write(IMFByteStream
*iface
, const BYTE
*buffer
, ULONG size
, ULONG
*written
)
4058 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4059 LARGE_INTEGER position
;
4062 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, written
);
4064 EnterCriticalSection(&stream
->cs
);
4066 position
.QuadPart
= stream
->position
;
4067 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4069 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, buffer
, size
, written
)))
4070 stream
->position
+= *written
;
4073 LeaveCriticalSection(&stream
->cs
);
4078 static HRESULT WINAPI
bytestream_stream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN origin
, LONGLONG offset
,
4079 DWORD flags
, QWORD
*current
)
4081 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4084 TRACE("%p, %u, %s, %#x, %p.\n", iface
, origin
, wine_dbgstr_longlong(offset
), flags
, current
);
4086 EnterCriticalSection(&stream
->cs
);
4091 stream
->position
= offset
;
4094 stream
->position
+= offset
;
4097 WARN("Unknown origin mode %d.\n", origin
);
4101 *current
= stream
->position
;
4103 LeaveCriticalSection(&stream
->cs
);
4108 static HRESULT WINAPI
bytestream_stream_Flush(IMFByteStream
*iface
)
4110 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4112 TRACE("%p.\n", iface
);
4114 return IStream_Commit(stream
->stream
, STGC_DEFAULT
);
4117 static HRESULT WINAPI
bytestream_stream_Close(IMFByteStream
*iface
)
4119 TRACE("%p.\n", iface
);
4124 static const IMFByteStreamVtbl bytestream_stream_vtbl
=
4126 bytestream_QueryInterface
,
4129 bytestream_stream_GetCapabilities
,
4130 bytestream_stream_GetLength
,
4131 bytestream_stream_SetLength
,
4132 bytestream_stream_GetCurrentPosition
,
4133 bytestream_SetCurrentPosition
,
4134 bytestream_stream_IsEndOfStream
,
4135 bytestream_stream_Read
,
4136 bytestream_BeginRead
,
4138 bytestream_stream_Write
,
4139 bytestream_BeginWrite
,
4140 bytestream_EndWrite
,
4141 bytestream_stream_Seek
,
4142 bytestream_stream_Flush
,
4143 bytestream_stream_Close
,
4146 static inline struct bytestream
*impl_from_IMFByteStream_IMFAttributes(IMFAttributes
*iface
)
4148 return CONTAINING_RECORD(iface
, struct bytestream
, attributes
.IMFAttributes_iface
);
4151 static HRESULT WINAPI
bytestream_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
4153 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4154 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, out
);
4157 static ULONG WINAPI
bytestream_attributes_AddRef(IMFAttributes
*iface
)
4159 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4160 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4163 static ULONG WINAPI
bytestream_attributes_Release(IMFAttributes
*iface
)
4165 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4166 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4169 static const IMFAttributesVtbl bytestream_attributes_vtbl
=
4171 bytestream_attributes_QueryInterface
,
4172 bytestream_attributes_AddRef
,
4173 bytestream_attributes_Release
,
4174 mfattributes_GetItem
,
4175 mfattributes_GetItemType
,
4176 mfattributes_CompareItem
,
4177 mfattributes_Compare
,
4178 mfattributes_GetUINT32
,
4179 mfattributes_GetUINT64
,
4180 mfattributes_GetDouble
,
4181 mfattributes_GetGUID
,
4182 mfattributes_GetStringLength
,
4183 mfattributes_GetString
,
4184 mfattributes_GetAllocatedString
,
4185 mfattributes_GetBlobSize
,
4186 mfattributes_GetBlob
,
4187 mfattributes_GetAllocatedBlob
,
4188 mfattributes_GetUnknown
,
4189 mfattributes_SetItem
,
4190 mfattributes_DeleteItem
,
4191 mfattributes_DeleteAllItems
,
4192 mfattributes_SetUINT32
,
4193 mfattributes_SetUINT64
,
4194 mfattributes_SetDouble
,
4195 mfattributes_SetGUID
,
4196 mfattributes_SetString
,
4197 mfattributes_SetBlob
,
4198 mfattributes_SetUnknown
,
4199 mfattributes_LockStore
,
4200 mfattributes_UnlockStore
,
4201 mfattributes_GetCount
,
4202 mfattributes_GetItemByIndex
,
4203 mfattributes_CopyAllItems
4206 static HRESULT WINAPI
bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4208 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4209 struct async_stream_op
*op
;
4210 LARGE_INTEGER position
;
4214 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4217 op
= impl_async_stream_op_from_IUnknown(object
);
4219 EnterCriticalSection(&stream
->cs
);
4221 position
.QuadPart
= op
->position
;
4222 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4224 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, op
->u
.dest
, op
->requested_length
, &op
->actual_length
)))
4225 stream
->position
+= op
->actual_length
;
4228 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4229 list_add_tail(&stream
->pending
, &op
->entry
);
4231 LeaveCriticalSection(&stream
->cs
);
4233 MFInvokeCallback(op
->caller
);
4238 static HRESULT WINAPI
bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4240 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4241 struct async_stream_op
*op
;
4242 LARGE_INTEGER position
;
4246 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4249 op
= impl_async_stream_op_from_IUnknown(object
);
4251 EnterCriticalSection(&stream
->cs
);
4253 position
.QuadPart
= op
->position
;
4254 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4256 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, op
->u
.src
, op
->requested_length
, &op
->actual_length
)))
4257 stream
->position
+= op
->actual_length
;
4260 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4261 list_add_tail(&stream
->pending
, &op
->entry
);
4263 LeaveCriticalSection(&stream
->cs
);
4265 MFInvokeCallback(op
->caller
);
4270 static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl
=
4272 bytestream_callback_QueryInterface
,
4273 bytestream_read_callback_AddRef
,
4274 bytestream_read_callback_Release
,
4275 bytestream_callback_GetParameters
,
4276 bytestream_stream_read_callback_Invoke
,
4279 static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl
=
4281 bytestream_callback_QueryInterface
,
4282 bytestream_write_callback_AddRef
,
4283 bytestream_write_callback_Release
,
4284 bytestream_callback_GetParameters
,
4285 bytestream_stream_write_callback_Invoke
,
4288 /***********************************************************************
4289 * MFCreateMFByteStreamOnStream (mfplat.@)
4291 HRESULT WINAPI
MFCreateMFByteStreamOnStream(IStream
*stream
, IMFByteStream
**bytestream
)
4293 struct bytestream
*object
;
4294 LARGE_INTEGER position
;
4298 TRACE("%p, %p.\n", stream
, bytestream
);
4300 if (!(object
= calloc(1, sizeof(*object
))))
4301 return E_OUTOFMEMORY
;
4303 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
4309 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_stream_vtbl
;
4310 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4311 object
->read_callback
.lpVtbl
= &bytestream_stream_read_callback_vtbl
;
4312 object
->write_callback
.lpVtbl
= &bytestream_stream_write_callback_vtbl
;
4313 InitializeCriticalSection(&object
->cs
);
4314 list_init(&object
->pending
);
4316 object
->stream
= stream
;
4317 IStream_AddRef(object
->stream
);
4318 position
.QuadPart
= 0;
4319 IStream_Seek(object
->stream
, position
, STREAM_SEEK_SET
, NULL
);
4321 if (SUCCEEDED(IStream_Stat(object
->stream
, &stat
, 0)))
4325 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
,
4327 CoTaskMemFree(stat
.pwcsName
);
4331 *bytestream
= &object
->IMFByteStream_iface
;
4336 static HRESULT WINAPI
bytestream_file_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4338 FIXME("%p, %p.\n", iface
, result
);
4343 static HRESULT WINAPI
bytestream_file_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4345 FIXME("%p, %p.\n", iface
, result
);
4350 static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl
=
4352 bytestream_callback_QueryInterface
,
4353 bytestream_read_callback_AddRef
,
4354 bytestream_read_callback_Release
,
4355 bytestream_callback_GetParameters
,
4356 bytestream_file_read_callback_Invoke
,
4359 static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl
=
4361 bytestream_callback_QueryInterface
,
4362 bytestream_write_callback_AddRef
,
4363 bytestream_write_callback_Release
,
4364 bytestream_callback_GetParameters
,
4365 bytestream_file_write_callback_Invoke
,
4368 static HRESULT WINAPI
bytestream_file_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
4370 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4371 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, obj
);
4374 static ULONG WINAPI
bytestream_file_getservice_AddRef(IMFGetService
*iface
)
4376 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4377 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4380 static ULONG WINAPI
bytestream_file_getservice_Release(IMFGetService
*iface
)
4382 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4383 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4386 static HRESULT WINAPI
bytestream_file_getservice_GetService(IMFGetService
*iface
, REFGUID service
,
4387 REFIID riid
, void **obj
)
4389 FIXME("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
4394 static const IMFGetServiceVtbl bytestream_file_getservice_vtbl
=
4396 bytestream_file_getservice_QueryInterface
,
4397 bytestream_file_getservice_AddRef
,
4398 bytestream_file_getservice_Release
,
4399 bytestream_file_getservice_GetService
,
4402 /***********************************************************************
4403 * MFCreateFile (mfplat.@)
4405 HRESULT WINAPI
MFCreateFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4406 LPCWSTR url
, IMFByteStream
**bytestream
)
4408 DWORD capabilities
= MFBYTESTREAM_IS_SEEKABLE
| MFBYTESTREAM_DOES_NOT_USE_NETWORK
;
4409 DWORD filecreation_disposition
= 0, fileaccessmode
= 0, fileattributes
= 0;
4410 DWORD filesharemode
= FILE_SHARE_READ
;
4411 struct bytestream
*object
;
4416 TRACE("%d, %d, %#x, %s, %p.\n", accessmode
, openmode
, flags
, debugstr_w(url
), bytestream
);
4420 case MF_ACCESSMODE_READ
:
4421 fileaccessmode
= GENERIC_READ
;
4422 capabilities
|= MFBYTESTREAM_IS_READABLE
;
4424 case MF_ACCESSMODE_WRITE
:
4425 fileaccessmode
= GENERIC_WRITE
;
4426 capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
4428 case MF_ACCESSMODE_READWRITE
:
4429 fileaccessmode
= GENERIC_READ
| GENERIC_WRITE
;
4430 capabilities
|= (MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_WRITABLE
);
4436 case MF_OPENMODE_FAIL_IF_NOT_EXIST
:
4437 filecreation_disposition
= OPEN_EXISTING
;
4439 case MF_OPENMODE_FAIL_IF_EXIST
:
4440 filecreation_disposition
= CREATE_NEW
;
4442 case MF_OPENMODE_RESET_IF_EXIST
:
4443 filecreation_disposition
= TRUNCATE_EXISTING
;
4445 case MF_OPENMODE_APPEND_IF_EXIST
:
4446 filecreation_disposition
= OPEN_ALWAYS
;
4447 fileaccessmode
|= FILE_APPEND_DATA
;
4449 case MF_OPENMODE_DELETE_IF_EXIST
:
4450 filecreation_disposition
= CREATE_ALWAYS
;
4454 if (flags
& MF_FILEFLAGS_NOBUFFERING
)
4455 fileattributes
|= FILE_FLAG_NO_BUFFERING
;
4457 /* Open HANDLE to file */
4458 file
= CreateFileW(url
, fileaccessmode
, filesharemode
, NULL
,
4459 filecreation_disposition
, fileattributes
, 0);
4461 if(file
== INVALID_HANDLE_VALUE
)
4462 return HRESULT_FROM_WIN32(GetLastError());
4464 if (!(object
= calloc(1, sizeof(*object
))))
4467 return E_OUTOFMEMORY
;
4470 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 2)))
4476 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_file_vtbl
;
4477 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4478 object
->IMFGetService_iface
.lpVtbl
= &bytestream_file_getservice_vtbl
;
4479 object
->read_callback
.lpVtbl
= &bytestream_file_read_callback_vtbl
;
4480 object
->write_callback
.lpVtbl
= &bytestream_file_write_callback_vtbl
;
4481 InitializeCriticalSection(&object
->cs
);
4482 list_init(&object
->pending
);
4483 object
->capabilities
= capabilities
;
4484 object
->hfile
= file
;
4486 if (GetFileTime(file
, NULL
, NULL
, &writetime
))
4488 IMFAttributes_SetBlob(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_LAST_MODIFIED_TIME
,
4489 (const UINT8
*)&writetime
, sizeof(writetime
));
4492 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
, url
);
4494 *bytestream
= &object
->IMFByteStream_iface
;
4499 struct bytestream_wrapper
4501 IMFByteStreamCacheControl IMFByteStreamCacheControl_iface
;
4502 IMFByteStreamBuffering IMFByteStreamBuffering_iface
;
4503 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
4504 IMFByteStreamTimeSeek IMFByteStreamTimeSeek_iface
;
4505 IMFSampleOutputStream IMFSampleOutputStream_iface
;
4506 IPropertyStore IPropertyStore_iface
;
4507 IMFByteStream IMFByteStream_iface
;
4508 IMFAttributes IMFAttributes_iface
;
4511 IMFByteStreamCacheControl
*cache_control
;
4512 IMFByteStreamBuffering
*stream_buffering
;
4513 IMFMediaEventGenerator
*event_generator
;
4514 IMFByteStreamTimeSeek
*time_seek
;
4515 IMFSampleOutputStream
*sample_output
;
4516 IPropertyStore
*propstore
;
4517 IMFByteStream
*stream
;
4518 IMFAttributes
*attributes
;
4522 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStream(IMFByteStream
*iface
)
4524 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStream_iface
);
4527 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamCacheControl(IMFByteStreamCacheControl
*iface
)
4529 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamCacheControl_iface
);
4532 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamBuffering(IMFByteStreamBuffering
*iface
)
4534 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamBuffering_iface
);
4537 static struct bytestream_wrapper
*impl_wrapper_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
4539 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFMediaEventGenerator_iface
);
4542 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamTimeSeek(IMFByteStreamTimeSeek
*iface
)
4544 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamTimeSeek_iface
);
4547 static struct bytestream_wrapper
*impl_wrapper_from_IMFSampleOutputStream(IMFSampleOutputStream
*iface
)
4549 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFSampleOutputStream_iface
);
4552 static struct bytestream_wrapper
*impl_wrapper_from_IPropertyStore(IPropertyStore
*iface
)
4554 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IPropertyStore_iface
);
4557 static struct bytestream_wrapper
*impl_wrapper_from_IMFAttributes(IMFAttributes
*iface
)
4559 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFAttributes_iface
);
4562 static HRESULT WINAPI
bytestream_wrapper_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
4564 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4566 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
4568 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
4569 IsEqualIID(riid
, &IID_IUnknown
))
4571 *out
= &wrapper
->IMFByteStream_iface
;
4573 else if (wrapper
->cache_control
&& IsEqualIID(riid
, &IID_IMFByteStreamCacheControl
))
4575 *out
= &wrapper
->IMFByteStreamCacheControl_iface
;
4577 else if (wrapper
->stream_buffering
&& IsEqualIID(riid
, &IID_IMFByteStreamBuffering
))
4579 *out
= &wrapper
->IMFByteStreamBuffering_iface
;
4581 else if (wrapper
->event_generator
&& IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
4583 *out
= &wrapper
->IMFMediaEventGenerator_iface
;
4585 else if (wrapper
->time_seek
&& IsEqualIID(riid
, &IID_IMFByteStreamTimeSeek
))
4587 *out
= &wrapper
->IMFByteStreamTimeSeek_iface
;
4589 else if (wrapper
->sample_output
&& IsEqualIID(riid
, &IID_IMFSampleOutputStream
))
4591 *out
= &wrapper
->IMFSampleOutputStream_iface
;
4593 else if (wrapper
->propstore
&& IsEqualIID(riid
, &IID_IPropertyStore
))
4595 *out
= &wrapper
->IPropertyStore_iface
;
4597 else if (wrapper
->attributes
&& IsEqualIID(riid
, &IID_IMFAttributes
))
4599 *out
= &wrapper
->IMFAttributes_iface
;
4603 WARN("Unsupported %s.\n", debugstr_guid(riid
));
4605 return E_NOINTERFACE
;
4608 IUnknown_AddRef((IUnknown
*)*out
);
4612 static ULONG WINAPI
bytestream_wrapper_AddRef(IMFByteStream
*iface
)
4614 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4615 ULONG refcount
= InterlockedIncrement(&wrapper
->refcount
);
4617 TRACE("%p, refcount %d.\n", iface
, refcount
);
4622 static ULONG WINAPI
bytestream_wrapper_Release(IMFByteStream
*iface
)
4624 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4625 ULONG refcount
= InterlockedDecrement(&wrapper
->refcount
);
4627 TRACE("%p, refcount %d.\n", iface
, refcount
);
4631 if (wrapper
->cache_control
)
4632 IMFByteStreamCacheControl_Release(wrapper
->cache_control
);
4633 if (wrapper
->stream_buffering
)
4634 IMFByteStreamBuffering_Release(wrapper
->stream_buffering
);
4635 if (wrapper
->event_generator
)
4636 IMFMediaEventGenerator_Release(wrapper
->event_generator
);
4637 if (wrapper
->time_seek
)
4638 IMFByteStreamTimeSeek_Release(wrapper
->time_seek
);
4639 if (wrapper
->sample_output
)
4640 IMFSampleOutputStream_Release(wrapper
->sample_output
);
4641 if (wrapper
->propstore
)
4642 IPropertyStore_Release(wrapper
->propstore
);
4643 if (wrapper
->attributes
)
4644 IMFAttributes_Release(wrapper
->attributes
);
4645 IMFByteStream_Release(wrapper
->stream
);
4652 static HRESULT WINAPI
bytestream_wrapper_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
4654 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4656 TRACE("%p, %p.\n", iface
, capabilities
);
4658 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4659 IMFByteStream_GetCapabilities(wrapper
->stream
, capabilities
);
4662 static HRESULT WINAPI
bytestream_wrapper_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4664 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4666 TRACE("%p, %p.\n", iface
, length
);
4668 if (wrapper
->is_closed
)
4669 return MF_E_INVALIDREQUEST
;
4671 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4672 IMFByteStream_GetLength(wrapper
->stream
, length
);
4675 static HRESULT WINAPI
bytestream_wrapper_SetLength(IMFByteStream
*iface
, QWORD length
)
4677 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4679 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4681 if (wrapper
->is_closed
)
4682 return MF_E_INVALIDREQUEST
;
4684 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4685 IMFByteStream_SetLength(wrapper
->stream
, length
);
4688 static HRESULT WINAPI
bytestream_wrapper_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4690 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4692 TRACE("%p, %p.\n", iface
, position
);
4694 if (wrapper
->is_closed
)
4695 return MF_E_INVALIDREQUEST
;
4697 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4698 IMFByteStream_GetCurrentPosition(wrapper
->stream
, position
);
4701 static HRESULT WINAPI
bytestream_wrapper_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4703 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4705 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4707 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4708 IMFByteStream_SetCurrentPosition(wrapper
->stream
, position
);
4711 static HRESULT WINAPI
bytestream_wrapper_IsEndOfStream(IMFByteStream
*iface
, BOOL
*eos
)
4713 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4715 TRACE("%p, %p.\n", iface
, eos
);
4717 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4718 IMFByteStream_IsEndOfStream(wrapper
->stream
, eos
);
4721 static HRESULT WINAPI
bytestream_wrapper_Read(IMFByteStream
*iface
, BYTE
*data
, ULONG count
, ULONG
*byte_read
)
4723 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4725 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, byte_read
);
4727 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4728 IMFByteStream_Read(wrapper
->stream
, data
, count
, byte_read
);
4731 static HRESULT WINAPI
bytestream_wrapper_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
,
4732 IMFAsyncCallback
*callback
, IUnknown
*state
)
4734 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4736 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4738 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4739 IMFByteStream_BeginRead(wrapper
->stream
, data
, size
, callback
, state
);
4742 static HRESULT WINAPI
bytestream_wrapper_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4744 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4746 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4748 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4749 IMFByteStream_EndRead(wrapper
->stream
, result
, byte_read
);
4752 static HRESULT WINAPI
bytestream_wrapper_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4754 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4756 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, written
);
4758 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4759 IMFByteStream_Write(wrapper
->stream
, data
, count
, written
);
4762 static HRESULT WINAPI
bytestream_wrapper_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4763 IMFAsyncCallback
*callback
, IUnknown
*state
)
4765 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4767 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4769 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4770 IMFByteStream_BeginWrite(wrapper
->stream
, data
, size
, callback
, state
);
4773 static HRESULT WINAPI
bytestream_wrapper_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4775 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4777 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4779 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4780 IMFByteStream_EndWrite(wrapper
->stream
, result
, written
);
4783 static HRESULT WINAPI
bytestream_wrapper_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
4784 DWORD flags
, QWORD
*current
)
4786 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4788 TRACE("%p, %u, %s, %#x, %p.\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
4790 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4791 IMFByteStream_Seek(wrapper
->stream
, seek
, offset
, flags
, current
);
4794 static HRESULT WINAPI
bytestream_wrapper_Flush(IMFByteStream
*iface
)
4796 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4798 TRACE("%p\n", iface
);
4800 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
: IMFByteStream_Flush(wrapper
->stream
);
4803 static HRESULT WINAPI
bytestream_wrapper_Close(IMFByteStream
*iface
)
4805 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4807 TRACE("%p\n", iface
);
4809 wrapper
->is_closed
= TRUE
;
4814 static const IMFByteStreamVtbl bytestream_wrapper_vtbl
=
4816 bytestream_wrapper_QueryInterface
,
4817 bytestream_wrapper_AddRef
,
4818 bytestream_wrapper_Release
,
4819 bytestream_wrapper_GetCapabilities
,
4820 bytestream_wrapper_GetLength
,
4821 bytestream_wrapper_SetLength
,
4822 bytestream_wrapper_GetCurrentPosition
,
4823 bytestream_wrapper_SetCurrentPosition
,
4824 bytestream_wrapper_IsEndOfStream
,
4825 bytestream_wrapper_Read
,
4826 bytestream_wrapper_BeginRead
,
4827 bytestream_wrapper_EndRead
,
4828 bytestream_wrapper_Write
,
4829 bytestream_wrapper_BeginWrite
,
4830 bytestream_wrapper_EndWrite
,
4831 bytestream_wrapper_Seek
,
4832 bytestream_wrapper_Flush
,
4833 bytestream_wrapper_Close
,
4836 static HRESULT WINAPI
bytestream_wrapper_cache_control_QueryInterface(IMFByteStreamCacheControl
*iface
,
4837 REFIID riid
, void **obj
)
4839 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4840 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4843 static ULONG WINAPI
bytestream_wrapper_cache_control_AddRef(IMFByteStreamCacheControl
*iface
)
4845 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4846 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4849 static ULONG WINAPI
bytestream_wrapper_cache_control_Release(IMFByteStreamCacheControl
*iface
)
4851 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4852 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4855 static HRESULT WINAPI
bytestream_wrapper_cache_control_StopBackgroundTransfer(IMFByteStreamCacheControl
*iface
)
4857 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4859 TRACE("%p.\n", iface
);
4861 return IMFByteStreamCacheControl_StopBackgroundTransfer(wrapper
->cache_control
);
4864 static const IMFByteStreamCacheControlVtbl bytestream_wrapper_cache_control_vtbl
=
4866 bytestream_wrapper_cache_control_QueryInterface
,
4867 bytestream_wrapper_cache_control_AddRef
,
4868 bytestream_wrapper_cache_control_Release
,
4869 bytestream_wrapper_cache_control_StopBackgroundTransfer
,
4872 static HRESULT WINAPI
bytestream_wrapper_buffering_QueryInterface(IMFByteStreamBuffering
*iface
,
4873 REFIID riid
, void **obj
)
4875 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4876 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4879 static ULONG WINAPI
bytestream_wrapper_buffering_AddRef(IMFByteStreamBuffering
*iface
)
4881 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4882 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4885 static ULONG WINAPI
bytestream_wrapper_buffering_Release(IMFByteStreamBuffering
*iface
)
4887 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4888 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4891 static HRESULT WINAPI
bytestream_wrapper_buffering_SetBufferingParams(IMFByteStreamBuffering
*iface
,
4892 MFBYTESTREAM_BUFFERING_PARAMS
*params
)
4894 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4896 TRACE("%p, %p.\n", iface
, params
);
4898 return IMFByteStreamBuffering_SetBufferingParams(wrapper
->stream_buffering
, params
);
4901 static HRESULT WINAPI
bytestream_wrapper_buffering_EnableBuffering(IMFByteStreamBuffering
*iface
,
4904 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4906 TRACE("%p, %d.\n", iface
, enable
);
4908 return IMFByteStreamBuffering_EnableBuffering(wrapper
->stream_buffering
, enable
);
4911 static HRESULT WINAPI
bytestream_wrapper_buffering_StopBuffering(IMFByteStreamBuffering
*iface
)
4913 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4915 TRACE("%p.\n", iface
);
4917 return IMFByteStreamBuffering_StopBuffering(wrapper
->stream_buffering
);
4920 static const IMFByteStreamBufferingVtbl bytestream_wrapper_buffering_vtbl
=
4922 bytestream_wrapper_buffering_QueryInterface
,
4923 bytestream_wrapper_buffering_AddRef
,
4924 bytestream_wrapper_buffering_Release
,
4925 bytestream_wrapper_buffering_SetBufferingParams
,
4926 bytestream_wrapper_buffering_EnableBuffering
,
4927 bytestream_wrapper_buffering_StopBuffering
,
4930 static HRESULT WINAPI
bytestream_wrapper_timeseek_QueryInterface(IMFByteStreamTimeSeek
*iface
,
4931 REFIID riid
, void **obj
)
4933 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4934 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4937 static ULONG WINAPI
bytestream_wrapper_timeseek_AddRef(IMFByteStreamTimeSeek
*iface
)
4939 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4940 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4943 static ULONG WINAPI
bytestream_wrapper_timeseek_Release(IMFByteStreamTimeSeek
*iface
)
4945 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4946 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4949 static HRESULT WINAPI
bytestream_wrapper_timeseek_IsTimeSeekSupported(IMFByteStreamTimeSeek
*iface
, BOOL
*result
)
4951 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4953 TRACE("%p, %p.\n", iface
, result
);
4955 return IMFByteStreamTimeSeek_IsTimeSeekSupported(wrapper
->time_seek
, result
);
4958 static HRESULT WINAPI
bytestream_wrapper_timeseek_TimeSeek(IMFByteStreamTimeSeek
*iface
, QWORD position
)
4960 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4962 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4964 return IMFByteStreamTimeSeek_TimeSeek(wrapper
->time_seek
, position
);
4967 static HRESULT WINAPI
bytestream_wrapper_timeseek_GetTimeSeekResult(IMFByteStreamTimeSeek
*iface
, QWORD
*start_time
,
4968 QWORD
*stop_time
, QWORD
*duration
)
4970 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4972 TRACE("%p, %p, %p, %p.\n", iface
, start_time
, stop_time
, duration
);
4974 return IMFByteStreamTimeSeek_GetTimeSeekResult(wrapper
->time_seek
, start_time
, stop_time
, duration
);
4977 static const IMFByteStreamTimeSeekVtbl bytestream_wrapper_timeseek_vtbl
=
4979 bytestream_wrapper_timeseek_QueryInterface
,
4980 bytestream_wrapper_timeseek_AddRef
,
4981 bytestream_wrapper_timeseek_Release
,
4982 bytestream_wrapper_timeseek_IsTimeSeekSupported
,
4983 bytestream_wrapper_timeseek_TimeSeek
,
4984 bytestream_wrapper_timeseek_GetTimeSeekResult
,
4987 static HRESULT WINAPI
bytestream_wrapper_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
4989 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
4990 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4993 static ULONG WINAPI
bytestream_wrapper_events_AddRef(IMFMediaEventGenerator
*iface
)
4995 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
4996 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4999 static ULONG WINAPI
bytestream_wrapper_events_Release(IMFMediaEventGenerator
*iface
)
5001 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5002 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5005 static HRESULT WINAPI
bytestream_wrapper_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
5007 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5009 TRACE("%p, %#x, %p.\n", iface
, flags
, event
);
5011 return IMFMediaEventGenerator_GetEvent(wrapper
->event_generator
, flags
, event
);
5014 static HRESULT WINAPI
bytestream_wrapper_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
5016 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5018 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
5020 return IMFMediaEventGenerator_BeginGetEvent(wrapper
->event_generator
, callback
, state
);
5023 static HRESULT WINAPI
bytestream_wrapper_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
5025 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5027 TRACE("%p, %p, %p.\n", iface
, result
, event
);
5029 return IMFMediaEventGenerator_EndGetEvent(wrapper
->event_generator
, result
, event
);
5032 static HRESULT WINAPI
bytestream_wrapper_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType type
,
5033 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
5035 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5037 TRACE("%p, %d, %s, %#x, %s.\n", iface
, type
, debugstr_guid(ext_type
), hr
, debugstr_propvar(value
));
5039 return IMFMediaEventGenerator_QueueEvent(wrapper
->event_generator
, type
, ext_type
, hr
, value
);
5042 static const IMFMediaEventGeneratorVtbl bytestream_wrapper_events_vtbl
=
5044 bytestream_wrapper_events_QueryInterface
,
5045 bytestream_wrapper_events_AddRef
,
5046 bytestream_wrapper_events_Release
,
5047 bytestream_wrapper_events_GetEvent
,
5048 bytestream_wrapper_events_BeginGetEvent
,
5049 bytestream_wrapper_events_EndGetEvent
,
5050 bytestream_wrapper_events_QueueEvent
,
5053 static HRESULT WINAPI
bytestream_wrapper_sample_output_QueryInterface(IMFSampleOutputStream
*iface
, REFIID riid
, void **obj
)
5055 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5056 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5059 static ULONG WINAPI
bytestream_wrapper_sample_output_AddRef(IMFSampleOutputStream
*iface
)
5061 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5062 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5065 static ULONG WINAPI
bytestream_wrapper_sample_output_Release(IMFSampleOutputStream
*iface
)
5067 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5068 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5071 static HRESULT WINAPI
bytestream_wrapper_sample_output_BeginWriteSample(IMFSampleOutputStream
*iface
, IMFSample
*sample
,
5072 IMFAsyncCallback
*callback
, IUnknown
*state
)
5074 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5076 TRACE("%p, %p, %p, %p.\n", iface
, sample
, callback
, state
);
5078 return IMFSampleOutputStream_BeginWriteSample(wrapper
->sample_output
, sample
, callback
, state
);
5081 static HRESULT WINAPI
bytestream_wrapper_sample_output_EndWriteSample(IMFSampleOutputStream
*iface
, IMFAsyncResult
*result
)
5083 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5085 TRACE("%p, %p.\n", iface
, result
);
5087 return IMFSampleOutputStream_EndWriteSample(wrapper
->sample_output
, result
);
5090 static HRESULT WINAPI
bytestream_wrapper_sample_output_Close(IMFSampleOutputStream
*iface
)
5092 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5094 TRACE("%p.\n", iface
);
5096 return IMFSampleOutputStream_Close(wrapper
->sample_output
);
5099 static const IMFSampleOutputStreamVtbl bytestream_wrapper_sample_output_vtbl
=
5101 bytestream_wrapper_sample_output_QueryInterface
,
5102 bytestream_wrapper_sample_output_AddRef
,
5103 bytestream_wrapper_sample_output_Release
,
5104 bytestream_wrapper_sample_output_BeginWriteSample
,
5105 bytestream_wrapper_sample_output_EndWriteSample
,
5106 bytestream_wrapper_sample_output_Close
,
5109 static HRESULT WINAPI
bytestream_wrapper_propstore_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
5111 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5112 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5115 static ULONG WINAPI
bytestream_wrapper_propstore_AddRef(IPropertyStore
*iface
)
5117 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5118 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5121 static ULONG WINAPI
bytestream_wrapper_propstore_Release(IPropertyStore
*iface
)
5123 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5124 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5127 static HRESULT WINAPI
bytestream_wrapper_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
5129 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5131 TRACE("%p, %p.\n", iface
, count
);
5133 return IPropertyStore_GetCount(wrapper
->propstore
, count
);
5136 static HRESULT WINAPI
bytestream_wrapper_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
5138 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5140 TRACE("%p, %u, %p.\n", iface
, prop
, key
);
5142 return IPropertyStore_GetAt(wrapper
->propstore
, prop
, key
);
5145 static HRESULT WINAPI
bytestream_wrapper_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
5147 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5149 TRACE("%p, %p, %p.\n", iface
, key
, value
);
5151 return IPropertyStore_GetValue(wrapper
->propstore
, key
, value
);
5154 static HRESULT WINAPI
bytestream_wrapper_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
,
5155 const PROPVARIANT
*value
)
5157 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5159 TRACE("%p, %p, %s.\n", iface
, key
, debugstr_propvar(value
));
5161 return IPropertyStore_SetValue(wrapper
->propstore
, key
, value
);
5164 static HRESULT WINAPI
bytestream_wrapper_propstore_Commit(IPropertyStore
*iface
)
5166 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5168 TRACE("%p.\n", iface
);
5170 return IPropertyStore_Commit(wrapper
->propstore
);
5173 static const IPropertyStoreVtbl bytestream_wrapper_propstore_vtbl
=
5175 bytestream_wrapper_propstore_QueryInterface
,
5176 bytestream_wrapper_propstore_AddRef
,
5177 bytestream_wrapper_propstore_Release
,
5178 bytestream_wrapper_propstore_GetCount
,
5179 bytestream_wrapper_propstore_GetAt
,
5180 bytestream_wrapper_propstore_GetValue
,
5181 bytestream_wrapper_propstore_SetValue
,
5182 bytestream_wrapper_propstore_Commit
,
5185 static HRESULT WINAPI
bytestream_wrapper_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
5187 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5188 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5191 static ULONG WINAPI
bytestream_wrapper_attributes_AddRef(IMFAttributes
*iface
)
5193 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5194 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5197 static ULONG WINAPI
bytestream_wrapper_attributes_Release(IMFAttributes
*iface
)
5199 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5200 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5203 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
5205 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5207 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5209 return IMFAttributes_GetItem(wrapper
->attributes
, key
, value
);
5212 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
5214 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5216 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
5218 return IMFAttributes_GetItemType(wrapper
->attributes
, key
, type
);
5221 static HRESULT WINAPI
bytestream_wrapper_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
5222 REFPROPVARIANT value
, BOOL
*result
)
5224 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5226 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
5228 return IMFAttributes_CompareItem(wrapper
->attributes
, key
, value
, result
);
5231 static HRESULT WINAPI
bytestream_wrapper_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
5232 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
5234 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5236 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
5238 return IMFAttributes_Compare(wrapper
->attributes
, theirs
, match_type
, ret
);
5241 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
5243 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5245 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5247 return IMFAttributes_GetUINT32(wrapper
->attributes
, key
, value
);
5250 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
5252 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5254 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5256 return IMFAttributes_GetUINT64(wrapper
->attributes
, key
, value
);
5259 static HRESULT WINAPI
bytestream_wrapper_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
5261 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5263 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5265 return IMFAttributes_GetDouble(wrapper
->attributes
, key
, value
);
5268 static HRESULT WINAPI
bytestream_wrapper_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
5270 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5272 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5274 return IMFAttributes_GetGUID(wrapper
->attributes
, key
, value
);
5277 static HRESULT WINAPI
bytestream_wrapper_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
5279 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5281 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
5283 return IMFAttributes_GetStringLength(wrapper
->attributes
, key
, length
);
5286 static HRESULT WINAPI
bytestream_wrapper_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
5287 UINT32 size
, UINT32
*length
)
5289 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5291 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
5293 return IMFAttributes_GetString(wrapper
->attributes
, key
, value
, size
, length
);
5296 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
5298 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5300 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
5302 return IMFAttributes_GetAllocatedString(wrapper
->attributes
, key
, value
, length
);
5305 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
5307 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5309 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
5311 return IMFAttributes_GetBlobSize(wrapper
->attributes
, key
, size
);
5314 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
5315 UINT32 bufsize
, UINT32
*blobsize
)
5317 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5319 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
5321 return IMFAttributes_GetBlob(wrapper
->attributes
, key
, buf
, bufsize
, blobsize
);
5324 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
5326 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5328 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
5330 return IMFAttributes_GetAllocatedBlob(wrapper
->attributes
, key
, buf
, size
);
5333 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **obj
)
5335 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5337 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), obj
);
5339 return IMFAttributes_GetUnknown(wrapper
->attributes
, key
, riid
, obj
);
5342 static HRESULT WINAPI
bytestream_wrapper_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
5344 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5346 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
5348 return IMFAttributes_SetItem(wrapper
->attributes
, key
, value
);
5351 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
5353 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5355 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
5357 return IMFAttributes_DeleteItem(wrapper
->attributes
, key
);
5360 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteAllItems(IMFAttributes
*iface
)
5362 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5364 TRACE("%p.\n", iface
);
5366 return IMFAttributes_DeleteAllItems(wrapper
->attributes
);
5369 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
5371 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5373 TRACE("%p, %s, %d.\n", iface
, debugstr_attr(key
), value
);
5375 return IMFAttributes_SetUINT32(wrapper
->attributes
, key
, value
);
5378 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
5380 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5382 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
5384 return IMFAttributes_SetUINT64(wrapper
->attributes
, key
, value
);
5387 static HRESULT WINAPI
bytestream_wrapper_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
5389 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5391 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
5393 return IMFAttributes_SetDouble(wrapper
->attributes
, key
, value
);
5396 static HRESULT WINAPI
bytestream_wrapper_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
5398 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5400 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
5402 return IMFAttributes_SetGUID(wrapper
->attributes
, key
, value
);
5405 static HRESULT WINAPI
bytestream_wrapper_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
5407 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5409 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
5411 return IMFAttributes_SetString(wrapper
->attributes
, key
, value
);
5414 static HRESULT WINAPI
bytestream_wrapper_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
5416 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5418 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
5420 return IMFAttributes_SetBlob(wrapper
->attributes
, key
, buf
, size
);
5423 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
5425 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5427 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
5429 return IMFAttributes_SetUnknown(wrapper
->attributes
, key
, unknown
);
5432 static HRESULT WINAPI
bytestream_wrapper_attributes_LockStore(IMFAttributes
*iface
)
5434 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5436 TRACE("%p.\n", iface
);
5438 return IMFAttributes_LockStore(wrapper
->attributes
);
5441 static HRESULT WINAPI
bytestream_wrapper_attributes_UnlockStore(IMFAttributes
*iface
)
5443 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5445 TRACE("%p.\n", iface
);
5447 return IMFAttributes_UnlockStore(wrapper
->attributes
);
5450 static HRESULT WINAPI
bytestream_wrapper_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
5452 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5454 TRACE("%p, %p.\n", iface
, count
);
5456 return IMFAttributes_GetCount(wrapper
->attributes
, count
);
5459 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
5461 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5463 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
5465 return IMFAttributes_GetItemByIndex(wrapper
->attributes
, index
, key
, value
);
5468 static HRESULT WINAPI
bytestream_wrapper_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
5470 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5472 TRACE("%p, %p.\n", iface
, dest
);
5474 return IMFAttributes_CopyAllItems(wrapper
->attributes
, dest
);
5477 static const IMFAttributesVtbl bytestream_wrapper_attributes_vtbl
=
5479 bytestream_wrapper_attributes_QueryInterface
,
5480 bytestream_wrapper_attributes_AddRef
,
5481 bytestream_wrapper_attributes_Release
,
5482 bytestream_wrapper_attributes_GetItem
,
5483 bytestream_wrapper_attributes_GetItemType
,
5484 bytestream_wrapper_attributes_CompareItem
,
5485 bytestream_wrapper_attributes_Compare
,
5486 bytestream_wrapper_attributes_GetUINT32
,
5487 bytestream_wrapper_attributes_GetUINT64
,
5488 bytestream_wrapper_attributes_GetDouble
,
5489 bytestream_wrapper_attributes_GetGUID
,
5490 bytestream_wrapper_attributes_GetStringLength
,
5491 bytestream_wrapper_attributes_GetString
,
5492 bytestream_wrapper_attributes_GetAllocatedString
,
5493 bytestream_wrapper_attributes_GetBlobSize
,
5494 bytestream_wrapper_attributes_GetBlob
,
5495 bytestream_wrapper_attributes_GetAllocatedBlob
,
5496 bytestream_wrapper_attributes_GetUnknown
,
5497 bytestream_wrapper_attributes_SetItem
,
5498 bytestream_wrapper_attributes_DeleteItem
,
5499 bytestream_wrapper_attributes_DeleteAllItems
,
5500 bytestream_wrapper_attributes_SetUINT32
,
5501 bytestream_wrapper_attributes_SetUINT64
,
5502 bytestream_wrapper_attributes_SetDouble
,
5503 bytestream_wrapper_attributes_SetGUID
,
5504 bytestream_wrapper_attributes_SetString
,
5505 bytestream_wrapper_attributes_SetBlob
,
5506 bytestream_wrapper_attributes_SetUnknown
,
5507 bytestream_wrapper_attributes_LockStore
,
5508 bytestream_wrapper_attributes_UnlockStore
,
5509 bytestream_wrapper_attributes_GetCount
,
5510 bytestream_wrapper_attributes_GetItemByIndex
,
5511 bytestream_wrapper_attributes_CopyAllItems
5514 /***********************************************************************
5515 * MFCreateMFByteStreamWrapper (mfplat.@)
5517 HRESULT WINAPI
MFCreateMFByteStreamWrapper(IMFByteStream
*stream
, IMFByteStream
**wrapper
)
5519 struct bytestream_wrapper
*object
;
5521 TRACE("%p, %p.\n", stream
, wrapper
);
5523 if (!(object
= calloc(1, sizeof(*object
))))
5524 return E_OUTOFMEMORY
;
5526 object
->IMFByteStreamCacheControl_iface
.lpVtbl
= &bytestream_wrapper_cache_control_vtbl
;
5527 object
->IMFByteStreamBuffering_iface
.lpVtbl
= &bytestream_wrapper_buffering_vtbl
;
5528 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &bytestream_wrapper_events_vtbl
;
5529 object
->IMFByteStreamTimeSeek_iface
.lpVtbl
= &bytestream_wrapper_timeseek_vtbl
;
5530 object
->IMFSampleOutputStream_iface
.lpVtbl
= &bytestream_wrapper_sample_output_vtbl
;
5531 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_wrapper_vtbl
;
5532 object
->IPropertyStore_iface
.lpVtbl
= &bytestream_wrapper_propstore_vtbl
;
5533 object
->IMFAttributes_iface
.lpVtbl
= &bytestream_wrapper_attributes_vtbl
;
5535 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamCacheControl
, (void **)&object
->cache_control
);
5536 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamBuffering
, (void **)&object
->stream_buffering
);
5537 IMFByteStream_QueryInterface(stream
, &IID_IMFMediaEventGenerator
, (void **)&object
->event_generator
);
5538 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamTimeSeek
, (void **)&object
->time_seek
);
5539 IMFByteStream_QueryInterface(stream
, &IID_IMFSampleOutputStream
, (void **)&object
->sample_output
);
5540 IMFByteStream_QueryInterface(stream
, &IID_IPropertyStore
, (void **)&object
->propstore
);
5541 IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&object
->attributes
);
5543 object
->stream
= stream
;
5544 IMFByteStream_AddRef(object
->stream
);
5546 object
->refcount
= 1;
5548 *wrapper
= &object
->IMFByteStream_iface
;
5553 static HRESULT WINAPI
MFPluginControl_QueryInterface(IMFPluginControl
*iface
, REFIID riid
, void **ppv
)
5555 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
5556 TRACE("(IID_IUnknown %p)\n", ppv
);
5558 }else if(IsEqualGUID(riid
, &IID_IMFPluginControl
)) {
5559 TRACE("(IID_IMFPluginControl %p)\n", ppv
);
5562 FIXME("(%s %p)\n", debugstr_guid(riid
), ppv
);
5564 return E_NOINTERFACE
;
5567 IUnknown_AddRef((IUnknown
*)*ppv
);
5571 static ULONG WINAPI
MFPluginControl_AddRef(IMFPluginControl
*iface
)
5577 static ULONG WINAPI
MFPluginControl_Release(IMFPluginControl
*iface
)
5583 static HRESULT WINAPI
MFPluginControl_GetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5584 const WCHAR
*selector
, CLSID
*clsid
)
5586 FIXME("(%d %s %p)\n", plugin_type
, debugstr_w(selector
), clsid
);
5590 static HRESULT WINAPI
MFPluginControl_GetPreferredClsidByIndex(IMFPluginControl
*iface
, DWORD plugin_type
,
5591 DWORD index
, WCHAR
**selector
, CLSID
*clsid
)
5593 FIXME("(%d %d %p %p)\n", plugin_type
, index
, selector
, clsid
);
5597 static HRESULT WINAPI
MFPluginControl_SetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5598 const WCHAR
*selector
, const CLSID
*clsid
)
5600 FIXME("(%d %s %s)\n", plugin_type
, debugstr_w(selector
), debugstr_guid(clsid
));
5604 static HRESULT WINAPI
MFPluginControl_IsDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
)
5606 FIXME("(%d %s)\n", plugin_type
, debugstr_guid(clsid
));
5610 static HRESULT WINAPI
MFPluginControl_GetDisabledByIndex(IMFPluginControl
*iface
, DWORD plugin_type
, DWORD index
, CLSID
*clsid
)
5612 FIXME("(%d %d %p)\n", plugin_type
, index
, clsid
);
5616 static HRESULT WINAPI
MFPluginControl_SetDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
, BOOL disabled
)
5618 FIXME("(%d %s %x)\n", plugin_type
, debugstr_guid(clsid
), disabled
);
5622 static const IMFPluginControlVtbl MFPluginControlVtbl
= {
5623 MFPluginControl_QueryInterface
,
5624 MFPluginControl_AddRef
,
5625 MFPluginControl_Release
,
5626 MFPluginControl_GetPreferredClsid
,
5627 MFPluginControl_GetPreferredClsidByIndex
,
5628 MFPluginControl_SetPreferredClsid
,
5629 MFPluginControl_IsDisabled
,
5630 MFPluginControl_GetDisabledByIndex
,
5631 MFPluginControl_SetDisabled
5634 static IMFPluginControl plugin_control
= { &MFPluginControlVtbl
};
5636 /***********************************************************************
5637 * MFGetPluginControl (mfplat.@)
5639 HRESULT WINAPI
MFGetPluginControl(IMFPluginControl
**ret
)
5641 TRACE("(%p)\n", ret
);
5643 *ret
= &plugin_control
;
5647 enum resolved_object_origin
5649 OBJECT_FROM_BYTESTREAM
,
5653 struct resolver_queued_result
5657 MF_OBJECT_TYPE obj_type
;
5659 IRtwqAsyncResult
*inner_result
;
5660 enum resolved_object_origin origin
;
5663 struct resolver_cancel_object
5665 IUnknown IUnknown_iface
;
5670 IMFByteStreamHandler
*stream_handler
;
5671 IMFSchemeHandler
*scheme_handler
;
5673 IUnknown
*cancel_cookie
;
5674 enum resolved_object_origin origin
;
5677 struct source_resolver
5679 IMFSourceResolver IMFSourceResolver_iface
;
5681 IRtwqAsyncCallback stream_callback
;
5682 IRtwqAsyncCallback url_callback
;
5683 CRITICAL_SECTION cs
;
5684 struct list pending
;
5687 static struct source_resolver
*impl_from_IMFSourceResolver(IMFSourceResolver
*iface
)
5689 return CONTAINING_RECORD(iface
, struct source_resolver
, IMFSourceResolver_iface
);
5692 static struct source_resolver
*impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5694 return CONTAINING_RECORD(iface
, struct source_resolver
, stream_callback
);
5697 static struct source_resolver
*impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5699 return CONTAINING_RECORD(iface
, struct source_resolver
, url_callback
);
5702 static HRESULT
resolver_handler_end_create(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
5703 IRtwqAsyncResult
*result
)
5705 IRtwqAsyncResult
*inner_result
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
5706 RTWQASYNCRESULT
*data
= (RTWQASYNCRESULT
*)inner_result
;
5707 struct resolver_queued_result
*queued_result
;
5711 IMFByteStreamHandler
*stream_handler
;
5712 IMFSchemeHandler
*scheme_handler
;
5715 if (!(queued_result
= calloc(1, sizeof(*queued_result
))))
5716 return E_OUTOFMEMORY
;
5718 queued_result
->origin
= origin
;
5720 IRtwqAsyncResult_GetObject(inner_result
, &handler
.handler
);
5724 case OBJECT_FROM_BYTESTREAM
:
5725 queued_result
->hr
= IMFByteStreamHandler_EndCreateObject(handler
.stream_handler
, (IMFAsyncResult
*)result
,
5726 &queued_result
->obj_type
, &queued_result
->object
);
5728 case OBJECT_FROM_URL
:
5729 queued_result
->hr
= IMFSchemeHandler_EndCreateObject(handler
.scheme_handler
, (IMFAsyncResult
*)result
,
5730 &queued_result
->obj_type
, &queued_result
->object
);
5733 queued_result
->hr
= E_FAIL
;
5736 IUnknown_Release(handler
.handler
);
5740 queued_result
->inner_result
= inner_result
;
5741 IRtwqAsyncResult_AddRef(queued_result
->inner_result
);
5744 /* Push resolved object type and created object, so we don't have to guess on End*() call. */
5745 EnterCriticalSection(&resolver
->cs
);
5746 list_add_tail(&resolver
->pending
, &queued_result
->entry
);
5747 LeaveCriticalSection(&resolver
->cs
);
5750 SetEvent(data
->hEvent
);
5753 IUnknown
*caller_state
= IRtwqAsyncResult_GetStateNoAddRef(inner_result
);
5754 IRtwqAsyncResult
*caller_result
;
5756 if (SUCCEEDED(RtwqCreateAsyncResult(queued_result
->object
, data
->pCallback
, caller_state
, &caller_result
)))
5758 RtwqInvokeCallback(caller_result
);
5759 IRtwqAsyncResult_Release(caller_result
);
5766 static struct resolver_cancel_object
*impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5768 return CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
);
5771 static HRESULT WINAPI
resolver_cancel_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
5773 if (IsEqualIID(riid
, &IID_IUnknown
))
5776 IUnknown_AddRef(iface
);
5781 return E_NOINTERFACE
;
5784 static ULONG WINAPI
resolver_cancel_object_AddRef(IUnknown
*iface
)
5786 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5787 return InterlockedIncrement(&object
->refcount
);
5790 static ULONG WINAPI
resolver_cancel_object_Release(IUnknown
*iface
)
5792 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5793 ULONG refcount
= InterlockedDecrement(&object
->refcount
);
5797 if (object
->cancel_cookie
)
5798 IUnknown_Release(object
->cancel_cookie
);
5799 IUnknown_Release(object
->u
.handler
);
5806 static const IUnknownVtbl resolver_cancel_object_vtbl
=
5808 resolver_cancel_object_QueryInterface
,
5809 resolver_cancel_object_AddRef
,
5810 resolver_cancel_object_Release
,
5813 static struct resolver_cancel_object
*unsafe_impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5818 return (iface
->lpVtbl
== &resolver_cancel_object_vtbl
) ?
5819 CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
) : NULL
;
5822 static HRESULT
resolver_create_cancel_object(IUnknown
*handler
, enum resolved_object_origin origin
,
5823 IUnknown
*cancel_cookie
, IUnknown
**cancel_object
)
5825 struct resolver_cancel_object
*object
;
5827 if (!(object
= calloc(1, sizeof(*object
))))
5828 return E_OUTOFMEMORY
;
5830 object
->IUnknown_iface
.lpVtbl
= &resolver_cancel_object_vtbl
;
5831 object
->refcount
= 1;
5832 object
->u
.handler
= handler
;
5833 IUnknown_AddRef(object
->u
.handler
);
5834 object
->cancel_cookie
= cancel_cookie
;
5835 IUnknown_AddRef(object
->cancel_cookie
);
5836 object
->origin
= origin
;
5838 *cancel_object
= &object
->IUnknown_iface
;
5843 static HRESULT WINAPI
source_resolver_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
5845 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
5846 IsEqualIID(riid
, &IID_IUnknown
))
5849 IRtwqAsyncCallback_AddRef(iface
);
5854 return E_NOINTERFACE
;
5857 static ULONG WINAPI
source_resolver_callback_stream_AddRef(IRtwqAsyncCallback
*iface
)
5859 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5860 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5863 static ULONG WINAPI
source_resolver_callback_stream_Release(IRtwqAsyncCallback
*iface
)
5865 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5866 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5869 static HRESULT WINAPI
source_resolver_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
5874 static HRESULT WINAPI
source_resolver_callback_stream_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5876 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5878 return resolver_handler_end_create(resolver
, OBJECT_FROM_BYTESTREAM
, result
);
5881 static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl
=
5883 source_resolver_callback_QueryInterface
,
5884 source_resolver_callback_stream_AddRef
,
5885 source_resolver_callback_stream_Release
,
5886 source_resolver_callback_GetParameters
,
5887 source_resolver_callback_stream_Invoke
,
5890 static ULONG WINAPI
source_resolver_callback_url_AddRef(IRtwqAsyncCallback
*iface
)
5892 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5893 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5896 static ULONG WINAPI
source_resolver_callback_url_Release(IRtwqAsyncCallback
*iface
)
5898 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5899 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5902 static HRESULT WINAPI
source_resolver_callback_url_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5904 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5906 return resolver_handler_end_create(resolver
, OBJECT_FROM_URL
, result
);
5909 static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl
=
5911 source_resolver_callback_QueryInterface
,
5912 source_resolver_callback_url_AddRef
,
5913 source_resolver_callback_url_Release
,
5914 source_resolver_callback_GetParameters
,
5915 source_resolver_callback_url_Invoke
,
5918 static HRESULT
resolver_create_registered_handler(HKEY hkey
, REFIID riid
, void **handler
)
5920 unsigned int j
= 0, name_length
, type
;
5921 HRESULT hr
= E_FAIL
;
5925 name_length
= ARRAY_SIZE(clsidW
);
5926 while (!RegEnumValueW(hkey
, j
++, clsidW
, &name_length
, NULL
, &type
, NULL
, NULL
))
5930 if (SUCCEEDED(CLSIDFromString(clsidW
, &clsid
)))
5932 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, handler
);
5938 name_length
= ARRAY_SIZE(clsidW
);
5944 static HRESULT
resolver_get_bytestream_handler(IMFByteStream
*stream
, const WCHAR
*url
, DWORD flags
,
5945 IMFByteStreamHandler
**handler
)
5947 static const char streamhandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers";
5948 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
5949 IMFAttributes
*attributes
;
5950 const WCHAR
*url_ext
;
5951 WCHAR
*mimeW
= NULL
;
5952 HRESULT hr
= E_FAIL
;
5959 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
5961 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &mimeW
, &length
);
5962 IMFAttributes_Release(attributes
);
5966 url_ext
= url
? wcsrchr(url
, '.') : NULL
;
5968 if (!url_ext
&& !mimeW
)
5970 CoTaskMemFree(mimeW
);
5971 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
5974 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
5976 struct local_handler
*local_handler
;
5978 EnterCriticalSection(&local_handlers_section
);
5980 LIST_FOR_EACH_ENTRY(local_handler
, &local_bytestream_handlers
, struct local_handler
, entry
)
5982 if ((mimeW
&& !lstrcmpiW(mimeW
, local_handler
->u
.bytestream
.mime
))
5983 || (url_ext
&& !lstrcmpiW(url_ext
, local_handler
->u
.bytestream
.extension
)))
5985 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFByteStreamHandler
,
5991 LeaveCriticalSection(&local_handlers_section
);
5997 for (i
= 0, hr
= E_FAIL
; i
< ARRAY_SIZE(hkey_roots
); ++i
)
5999 const WCHAR
*namesW
[2] = { mimeW
, url_ext
};
6000 HKEY hkey
, hkey_handler
;
6002 if (RegOpenKeyA(hkey_roots
[i
], streamhandlerspath
, &hkey
))
6005 for (j
= 0; j
< ARRAY_SIZE(namesW
); ++j
)
6010 if (!RegOpenKeyW(hkey
, namesW
[j
], &hkey_handler
))
6012 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFByteStreamHandler
, (void **)handler
);
6013 RegCloseKey(hkey_handler
);
6028 static const GUID CLSID_GStreamerByteStreamHandler
= {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
6029 hr
= CoCreateInstance(&CLSID_GStreamerByteStreamHandler
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFByteStreamHandler
, (void **)handler
);
6032 CoTaskMemFree(mimeW
);
6036 static HRESULT
resolver_create_scheme_handler(const WCHAR
*scheme
, DWORD flags
, IMFSchemeHandler
**handler
)
6038 static const char schemehandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers";
6039 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6040 HRESULT hr
= MF_E_UNSUPPORTED_SCHEME
;
6043 TRACE("%s, %#x, %p.\n", debugstr_w(scheme
), flags
, handler
);
6047 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6049 struct local_handler
*local_handler
;
6051 EnterCriticalSection(&local_handlers_section
);
6053 LIST_FOR_EACH_ENTRY(local_handler
, &local_scheme_handlers
, struct local_handler
, entry
)
6055 if (!lstrcmpiW(scheme
, local_handler
->u
.scheme
))
6057 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFSchemeHandler
,
6063 LeaveCriticalSection(&local_handlers_section
);
6069 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6071 HKEY hkey
, hkey_handler
;
6073 hr
= MF_E_UNSUPPORTED_SCHEME
;
6075 if (RegOpenKeyA(hkey_roots
[i
], schemehandlerspath
, &hkey
))
6078 if (!RegOpenKeyW(hkey
, scheme
, &hkey_handler
))
6080 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFSchemeHandler
, (void **)handler
);
6081 RegCloseKey(hkey_handler
);
6093 static HRESULT
resolver_get_scheme_handler(const WCHAR
*url
, DWORD flags
, IMFSchemeHandler
**handler
)
6095 static const WCHAR fileschemeW
[] = L
"file:";
6096 const WCHAR
*ptr
= url
;
6101 /* RFC 3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
6104 WCHAR ch
= towlower(*ptr
);
6106 if (*ptr
== '*' && ptr
== url
)
6111 else if (!(*ptr
>= '0' && *ptr
<= '9') &&
6112 !(ch
>= 'a' && ch
<= 'z') &&
6113 *ptr
!= '+' && *ptr
!= '-' && *ptr
!= '.')
6121 /* Schemes must end with a ':', if not found try "file:" */
6122 if (ptr
== url
|| *ptr
!= ':')
6125 ptr
= fileschemeW
+ ARRAY_SIZE(fileschemeW
) - 1;
6129 scheme
= malloc((len
+ 1) * sizeof(WCHAR
));
6131 return E_OUTOFMEMORY
;
6133 memcpy(scheme
, url
, len
* sizeof(WCHAR
));
6136 hr
= resolver_create_scheme_handler(scheme
, flags
, handler
);
6137 if (FAILED(hr
) && url
!= fileschemeW
)
6138 hr
= resolver_create_scheme_handler(fileschemeW
, flags
, handler
);
6145 static HRESULT
resolver_end_create_object(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
6146 IRtwqAsyncResult
*result
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**out
)
6148 struct resolver_queued_result
*queued_result
= NULL
, *iter
;
6152 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
6155 EnterCriticalSection(&resolver
->cs
);
6157 LIST_FOR_EACH_ENTRY(iter
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6159 if (iter
->inner_result
== result
|| (iter
->object
== object
&& iter
->origin
== origin
))
6161 list_remove(&iter
->entry
);
6162 queued_result
= iter
;
6167 LeaveCriticalSection(&resolver
->cs
);
6169 IUnknown_Release(object
);
6173 *out
= queued_result
->object
;
6174 *obj_type
= queued_result
->obj_type
;
6175 hr
= queued_result
->hr
;
6176 if (queued_result
->inner_result
)
6177 IRtwqAsyncResult_Release(queued_result
->inner_result
);
6178 free(queued_result
);
6186 static HRESULT WINAPI
source_resolver_QueryInterface(IMFSourceResolver
*iface
, REFIID riid
, void **obj
)
6188 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6190 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
6192 if (IsEqualIID(riid
, &IID_IMFSourceResolver
) ||
6193 IsEqualIID(riid
, &IID_IUnknown
))
6195 *obj
= &resolver
->IMFSourceResolver_iface
;
6200 FIXME("unsupported interface %s\n", debugstr_guid(riid
));
6201 return E_NOINTERFACE
;
6204 IUnknown_AddRef((IUnknown
*)*obj
);
6208 static ULONG WINAPI
source_resolver_AddRef(IMFSourceResolver
*iface
)
6210 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6211 ULONG refcount
= InterlockedIncrement(&resolver
->refcount
);
6213 TRACE("%p, refcount %d.\n", iface
, refcount
);
6218 static ULONG WINAPI
source_resolver_Release(IMFSourceResolver
*iface
)
6220 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6221 ULONG refcount
= InterlockedDecrement(&resolver
->refcount
);
6222 struct resolver_queued_result
*result
, *result2
;
6224 TRACE("%p, refcount %d.\n", iface
, refcount
);
6228 LIST_FOR_EACH_ENTRY_SAFE(result
, result2
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6231 IUnknown_Release(result
->object
);
6232 list_remove(&result
->entry
);
6235 DeleteCriticalSection(&resolver
->cs
);
6242 static HRESULT WINAPI
source_resolver_CreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6243 DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6245 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6246 IMFSchemeHandler
*handler
;
6247 IRtwqAsyncResult
*result
;
6248 RTWQASYNCRESULT
*data
;
6251 TRACE("%p, %s, %#x, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6253 if (!url
|| !obj_type
|| !object
)
6256 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6259 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6260 IMFSchemeHandler_Release(handler
);
6264 data
= (RTWQASYNCRESULT
*)result
;
6265 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6267 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, NULL
, (IMFAsyncCallback
*)&resolver
->url_callback
,
6268 (IUnknown
*)result
);
6271 IRtwqAsyncResult_Release(result
);
6275 WaitForSingleObject(data
->hEvent
, INFINITE
);
6277 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_URL
, result
, obj_type
, object
);
6278 IRtwqAsyncResult_Release(result
);
6283 static HRESULT WINAPI
source_resolver_CreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6284 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6286 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6287 IMFByteStreamHandler
*handler
;
6288 IRtwqAsyncResult
*result
;
6289 RTWQASYNCRESULT
*data
;
6292 TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6294 if (!stream
|| !obj_type
|| !object
)
6297 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6298 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6300 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6301 IMFByteStreamHandler_Release(handler
);
6305 data
= (RTWQASYNCRESULT
*)result
;
6306 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6308 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
, NULL
,
6309 (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6312 IRtwqAsyncResult_Release(result
);
6316 WaitForSingleObject(data
->hEvent
, INFINITE
);
6318 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, result
, obj_type
, object
);
6319 IRtwqAsyncResult_Release(result
);
6324 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6325 DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
6327 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6328 IMFSchemeHandler
*handler
;
6329 IUnknown
*inner_cookie
= NULL
;
6330 IRtwqAsyncResult
*result
;
6333 TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
6335 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6339 *cancel_cookie
= NULL
;
6341 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6342 IMFSchemeHandler_Release(handler
);
6346 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, cancel_cookie
? &inner_cookie
: NULL
,
6347 (IMFAsyncCallback
*)&resolver
->url_callback
, (IUnknown
*)result
);
6349 if (SUCCEEDED(hr
) && inner_cookie
)
6350 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_URL
, inner_cookie
, cancel_cookie
);
6352 IRtwqAsyncResult_Release(result
);
6357 static HRESULT WINAPI
source_resolver_EndCreateObjectFromURL(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6358 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6360 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6362 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6364 return resolver_end_create_object(resolver
, OBJECT_FROM_URL
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6367 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6368 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
,
6371 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6372 IMFByteStreamHandler
*handler
;
6373 IUnknown
*inner_cookie
= NULL
;
6374 IRtwqAsyncResult
*result
;
6377 TRACE("%p, %p, %s, %#x, %p, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, cancel_cookie
,
6380 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6384 *cancel_cookie
= NULL
;
6386 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6387 IMFByteStreamHandler_Release(handler
);
6391 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
,
6392 cancel_cookie
? &inner_cookie
: NULL
, (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6394 /* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */
6395 if (SUCCEEDED(hr
) && inner_cookie
)
6396 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_BYTESTREAM
, inner_cookie
, cancel_cookie
);
6398 IRtwqAsyncResult_Release(result
);
6403 static HRESULT WINAPI
source_resolver_EndCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6404 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6406 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6408 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6410 return resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6413 static HRESULT WINAPI
source_resolver_CancelObjectCreation(IMFSourceResolver
*iface
, IUnknown
*cancel_cookie
)
6415 struct resolver_cancel_object
*object
;
6418 TRACE("%p, %p.\n", iface
, cancel_cookie
);
6420 if (!(object
= unsafe_impl_cancel_obj_from_IUnknown(cancel_cookie
)))
6421 return E_UNEXPECTED
;
6423 switch (object
->origin
)
6425 case OBJECT_FROM_BYTESTREAM
:
6426 hr
= IMFByteStreamHandler_CancelObjectCreation(object
->u
.stream_handler
, object
->cancel_cookie
);
6428 case OBJECT_FROM_URL
:
6429 hr
= IMFSchemeHandler_CancelObjectCreation(object
->u
.scheme_handler
, object
->cancel_cookie
);
6438 static const IMFSourceResolverVtbl mfsourceresolvervtbl
=
6440 source_resolver_QueryInterface
,
6441 source_resolver_AddRef
,
6442 source_resolver_Release
,
6443 source_resolver_CreateObjectFromURL
,
6444 source_resolver_CreateObjectFromByteStream
,
6445 source_resolver_BeginCreateObjectFromURL
,
6446 source_resolver_EndCreateObjectFromURL
,
6447 source_resolver_BeginCreateObjectFromByteStream
,
6448 source_resolver_EndCreateObjectFromByteStream
,
6449 source_resolver_CancelObjectCreation
,
6452 /***********************************************************************
6453 * MFCreateSourceResolver (mfplat.@)
6455 HRESULT WINAPI
MFCreateSourceResolver(IMFSourceResolver
**resolver
)
6457 struct source_resolver
*object
;
6459 TRACE("%p\n", resolver
);
6464 if (!(object
= calloc(1, sizeof(*object
))))
6465 return E_OUTOFMEMORY
;
6467 object
->IMFSourceResolver_iface
.lpVtbl
= &mfsourceresolvervtbl
;
6468 object
->stream_callback
.lpVtbl
= &source_resolver_callback_stream_vtbl
;
6469 object
->url_callback
.lpVtbl
= &source_resolver_callback_url_vtbl
;
6470 object
->refcount
= 1;
6471 list_init(&object
->pending
);
6472 InitializeCriticalSection(&object
->cs
);
6474 *resolver
= &object
->IMFSourceResolver_iface
;
6481 struct attributes attributes
;
6482 IMFMediaEvent IMFMediaEvent_iface
;
6484 MediaEventType type
;
6490 static inline struct media_event
*impl_from_IMFMediaEvent(IMFMediaEvent
*iface
)
6492 return CONTAINING_RECORD(iface
, struct media_event
, IMFMediaEvent_iface
);
6495 static HRESULT WINAPI
mfmediaevent_QueryInterface(IMFMediaEvent
*iface
, REFIID riid
, void **out
)
6497 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6499 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
6501 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
6502 IsEqualGUID(riid
, &IID_IMFAttributes
) ||
6503 IsEqualGUID(riid
, &IID_IMFMediaEvent
))
6505 *out
= &event
->IMFMediaEvent_iface
;
6509 FIXME("%s, %p.\n", debugstr_guid(riid
), out
);
6511 return E_NOINTERFACE
;
6514 IUnknown_AddRef((IUnknown
*)*out
);
6518 static ULONG WINAPI
mfmediaevent_AddRef(IMFMediaEvent
*iface
)
6520 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6521 ULONG refcount
= InterlockedIncrement(&event
->attributes
.ref
);
6523 TRACE("%p, refcount %u.\n", iface
, refcount
);
6528 static ULONG WINAPI
mfmediaevent_Release(IMFMediaEvent
*iface
)
6530 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6531 ULONG refcount
= InterlockedDecrement(&event
->attributes
.ref
);
6533 TRACE("%p, refcount %u.\n", iface
, refcount
);
6537 clear_attributes_object(&event
->attributes
);
6538 PropVariantClear(&event
->value
);
6545 static HRESULT WINAPI
mfmediaevent_GetItem(IMFMediaEvent
*iface
, REFGUID key
, PROPVARIANT
*value
)
6547 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6549 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6551 return attributes_GetItem(&event
->attributes
, key
, value
);
6554 static HRESULT WINAPI
mfmediaevent_GetItemType(IMFMediaEvent
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
6556 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6558 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
6560 return attributes_GetItemType(&event
->attributes
, key
, type
);
6563 static HRESULT WINAPI
mfmediaevent_CompareItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
6565 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6567 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
6569 return attributes_CompareItem(&event
->attributes
, key
, value
, result
);
6572 static HRESULT WINAPI
mfmediaevent_Compare(IMFMediaEvent
*iface
, IMFAttributes
*attrs
, MF_ATTRIBUTES_MATCH_TYPE type
,
6575 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6577 TRACE("%p, %p, %d, %p.\n", iface
, attrs
, type
, result
);
6579 return attributes_Compare(&event
->attributes
, attrs
, type
, result
);
6582 static HRESULT WINAPI
mfmediaevent_GetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*value
)
6584 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6586 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6588 return attributes_GetUINT32(&event
->attributes
, key
, value
);
6591 static HRESULT WINAPI
mfmediaevent_GetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64
*value
)
6593 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6595 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6597 return attributes_GetUINT64(&event
->attributes
, key
, value
);
6600 static HRESULT WINAPI
mfmediaevent_GetDouble(IMFMediaEvent
*iface
, REFGUID key
, double *value
)
6602 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6604 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6606 return attributes_GetDouble(&event
->attributes
, key
, value
);
6609 static HRESULT WINAPI
mfmediaevent_GetGUID(IMFMediaEvent
*iface
, REFGUID key
, GUID
*value
)
6611 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6613 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6615 return attributes_GetGUID(&event
->attributes
, key
, value
);
6618 static HRESULT WINAPI
mfmediaevent_GetStringLength(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*length
)
6620 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6622 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
6624 return attributes_GetStringLength(&event
->attributes
, key
, length
);
6627 static HRESULT WINAPI
mfmediaevent_GetString(IMFMediaEvent
*iface
, REFGUID key
, WCHAR
*value
,
6628 UINT32 size
, UINT32
*length
)
6630 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6632 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
6634 return attributes_GetString(&event
->attributes
, key
, value
, size
, length
);
6637 static HRESULT WINAPI
mfmediaevent_GetAllocatedString(IMFMediaEvent
*iface
, REFGUID key
,
6638 WCHAR
**value
, UINT32
*length
)
6640 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6642 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
6644 return attributes_GetAllocatedString(&event
->attributes
, key
, value
, length
);
6647 static HRESULT WINAPI
mfmediaevent_GetBlobSize(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*size
)
6649 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6651 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
6653 return attributes_GetBlobSize(&event
->attributes
, key
, size
);
6656 static HRESULT WINAPI
mfmediaevent_GetBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
*buf
,
6657 UINT32 bufsize
, UINT32
*blobsize
)
6659 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6661 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
6663 return attributes_GetBlob(&event
->attributes
, key
, buf
, bufsize
, blobsize
);
6666 static HRESULT WINAPI
mfmediaevent_GetAllocatedBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
6668 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6670 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
6672 return attributes_GetAllocatedBlob(&event
->attributes
, key
, buf
, size
);
6675 static HRESULT WINAPI
mfmediaevent_GetUnknown(IMFMediaEvent
*iface
, REFGUID key
, REFIID riid
, void **out
)
6677 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6679 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
6681 return attributes_GetUnknown(&event
->attributes
, key
, riid
, out
);
6684 static HRESULT WINAPI
mfmediaevent_SetItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
)
6686 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6688 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
6690 return attributes_SetItem(&event
->attributes
, key
, value
);
6693 static HRESULT WINAPI
mfmediaevent_DeleteItem(IMFMediaEvent
*iface
, REFGUID key
)
6695 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6697 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
6699 return attributes_DeleteItem(&event
->attributes
, key
);
6702 static HRESULT WINAPI
mfmediaevent_DeleteAllItems(IMFMediaEvent
*iface
)
6704 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6706 TRACE("%p.\n", iface
);
6708 return attributes_DeleteAllItems(&event
->attributes
);
6711 static HRESULT WINAPI
mfmediaevent_SetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32 value
)
6713 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6715 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
6717 return attributes_SetUINT32(&event
->attributes
, key
, value
);
6720 static HRESULT WINAPI
mfmediaevent_SetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64 value
)
6722 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6724 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
6726 return attributes_SetUINT64(&event
->attributes
, key
, value
);
6729 static HRESULT WINAPI
mfmediaevent_SetDouble(IMFMediaEvent
*iface
, REFGUID key
, double value
)
6731 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6733 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
6735 return attributes_SetDouble(&event
->attributes
, key
, value
);
6738 static HRESULT WINAPI
mfmediaevent_SetGUID(IMFMediaEvent
*iface
, REFGUID key
, REFGUID value
)
6740 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6742 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
6744 return attributes_SetGUID(&event
->attributes
, key
, value
);
6747 static HRESULT WINAPI
mfmediaevent_SetString(IMFMediaEvent
*iface
, REFGUID key
, const WCHAR
*value
)
6749 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6751 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
6753 return attributes_SetString(&event
->attributes
, key
, value
);
6756 static HRESULT WINAPI
mfmediaevent_SetBlob(IMFMediaEvent
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
6758 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6760 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
6762 return attributes_SetBlob(&event
->attributes
, key
, buf
, size
);
6765 static HRESULT WINAPI
mfmediaevent_SetUnknown(IMFMediaEvent
*iface
, REFGUID key
, IUnknown
*unknown
)
6767 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6769 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
6771 return attributes_SetUnknown(&event
->attributes
, key
, unknown
);
6774 static HRESULT WINAPI
mfmediaevent_LockStore(IMFMediaEvent
*iface
)
6776 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6778 TRACE("%p.\n", iface
);
6780 return attributes_LockStore(&event
->attributes
);
6783 static HRESULT WINAPI
mfmediaevent_UnlockStore(IMFMediaEvent
*iface
)
6785 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6787 TRACE("%p.\n", iface
);
6789 return attributes_UnlockStore(&event
->attributes
);
6792 static HRESULT WINAPI
mfmediaevent_GetCount(IMFMediaEvent
*iface
, UINT32
*count
)
6794 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6796 TRACE("%p, %p.\n", iface
, count
);
6798 return attributes_GetCount(&event
->attributes
, count
);
6801 static HRESULT WINAPI
mfmediaevent_GetItemByIndex(IMFMediaEvent
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
6803 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6805 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
6807 return attributes_GetItemByIndex(&event
->attributes
, index
, key
, value
);
6810 static HRESULT WINAPI
mfmediaevent_CopyAllItems(IMFMediaEvent
*iface
, IMFAttributes
*dest
)
6812 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6814 TRACE("%p, %p.\n", iface
, dest
);
6816 return attributes_CopyAllItems(&event
->attributes
, dest
);
6819 static HRESULT WINAPI
mfmediaevent_GetType(IMFMediaEvent
*iface
, MediaEventType
*type
)
6821 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6823 TRACE("%p, %p.\n", iface
, type
);
6825 *type
= event
->type
;
6830 static HRESULT WINAPI
mfmediaevent_GetExtendedType(IMFMediaEvent
*iface
, GUID
*extended_type
)
6832 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6834 TRACE("%p, %p.\n", iface
, extended_type
);
6836 *extended_type
= event
->extended_type
;
6841 static HRESULT WINAPI
mfmediaevent_GetStatus(IMFMediaEvent
*iface
, HRESULT
*status
)
6843 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6845 TRACE("%p, %p.\n", iface
, status
);
6847 *status
= event
->status
;
6852 static HRESULT WINAPI
mfmediaevent_GetValue(IMFMediaEvent
*iface
, PROPVARIANT
*value
)
6854 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6856 TRACE("%p, %p.\n", iface
, value
);
6858 PropVariantCopy(value
, &event
->value
);
6863 static const IMFMediaEventVtbl mfmediaevent_vtbl
=
6865 mfmediaevent_QueryInterface
,
6866 mfmediaevent_AddRef
,
6867 mfmediaevent_Release
,
6868 mfmediaevent_GetItem
,
6869 mfmediaevent_GetItemType
,
6870 mfmediaevent_CompareItem
,
6871 mfmediaevent_Compare
,
6872 mfmediaevent_GetUINT32
,
6873 mfmediaevent_GetUINT64
,
6874 mfmediaevent_GetDouble
,
6875 mfmediaevent_GetGUID
,
6876 mfmediaevent_GetStringLength
,
6877 mfmediaevent_GetString
,
6878 mfmediaevent_GetAllocatedString
,
6879 mfmediaevent_GetBlobSize
,
6880 mfmediaevent_GetBlob
,
6881 mfmediaevent_GetAllocatedBlob
,
6882 mfmediaevent_GetUnknown
,
6883 mfmediaevent_SetItem
,
6884 mfmediaevent_DeleteItem
,
6885 mfmediaevent_DeleteAllItems
,
6886 mfmediaevent_SetUINT32
,
6887 mfmediaevent_SetUINT64
,
6888 mfmediaevent_SetDouble
,
6889 mfmediaevent_SetGUID
,
6890 mfmediaevent_SetString
,
6891 mfmediaevent_SetBlob
,
6892 mfmediaevent_SetUnknown
,
6893 mfmediaevent_LockStore
,
6894 mfmediaevent_UnlockStore
,
6895 mfmediaevent_GetCount
,
6896 mfmediaevent_GetItemByIndex
,
6897 mfmediaevent_CopyAllItems
,
6898 mfmediaevent_GetType
,
6899 mfmediaevent_GetExtendedType
,
6900 mfmediaevent_GetStatus
,
6901 mfmediaevent_GetValue
,
6904 /***********************************************************************
6905 * MFCreateMediaEvent (mfplat.@)
6907 HRESULT WINAPI
MFCreateMediaEvent(MediaEventType type
, REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
,
6908 IMFMediaEvent
**event
)
6910 struct media_event
*object
;
6913 TRACE("%s, %s, %#x, %s, %p.\n", debugstr_eventid(type
), debugstr_guid(extended_type
), status
,
6914 debugstr_propvar(value
), event
);
6916 object
= malloc(sizeof(*object
));
6918 return E_OUTOFMEMORY
;
6920 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
6925 object
->IMFMediaEvent_iface
.lpVtbl
= &mfmediaevent_vtbl
;
6927 object
->type
= type
;
6928 object
->extended_type
= *extended_type
;
6929 object
->status
= status
;
6931 PropVariantInit(&object
->value
);
6933 PropVariantCopy(&object
->value
, value
);
6935 *event
= &object
->IMFMediaEvent_iface
;
6937 TRACE("Created event %p.\n", *event
);
6944 IMFMediaEventQueue IMFMediaEventQueue_iface
;
6947 CRITICAL_SECTION cs
;
6948 CONDITION_VARIABLE update_event
;
6952 IRtwqAsyncResult
*subscriber
;
6958 IMFMediaEvent
*event
;
6961 static inline struct event_queue
*impl_from_IMFMediaEventQueue(IMFMediaEventQueue
*iface
)
6963 return CONTAINING_RECORD(iface
, struct event_queue
, IMFMediaEventQueue_iface
);
6966 static IMFMediaEvent
*queue_pop_event(struct event_queue
*queue
)
6968 struct list
*head
= list_head(&queue
->events
);
6969 struct queued_event
*queued_event
;
6970 IMFMediaEvent
*event
;
6975 queued_event
= LIST_ENTRY(head
, struct queued_event
, entry
);
6976 event
= queued_event
->event
;
6977 list_remove(&queued_event
->entry
);
6982 static void event_queue_clear_subscriber(struct event_queue
*queue
)
6984 if (queue
->subscriber
)
6985 IRtwqAsyncResult_Release(queue
->subscriber
);
6986 queue
->subscriber
= NULL
;
6989 static void event_queue_cleanup(struct event_queue
*queue
)
6991 IMFMediaEvent
*event
;
6993 while ((event
= queue_pop_event(queue
)))
6994 IMFMediaEvent_Release(event
);
6995 event_queue_clear_subscriber(queue
);
6998 static HRESULT WINAPI
eventqueue_QueryInterface(IMFMediaEventQueue
*iface
, REFIID riid
, void **out
)
7000 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7002 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7004 if (IsEqualIID(riid
, &IID_IMFMediaEventQueue
) ||
7005 IsEqualIID(riid
, &IID_IUnknown
))
7007 *out
= &queue
->IMFMediaEventQueue_iface
;
7008 IMFMediaEventQueue_AddRef(iface
);
7012 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7014 return E_NOINTERFACE
;
7017 static ULONG WINAPI
eventqueue_AddRef(IMFMediaEventQueue
*iface
)
7019 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7020 ULONG refcount
= InterlockedIncrement(&queue
->refcount
);
7022 TRACE("%p, refcount %u.\n", iface
, refcount
);
7027 static ULONG WINAPI
eventqueue_Release(IMFMediaEventQueue
*iface
)
7029 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7030 ULONG refcount
= InterlockedDecrement(&queue
->refcount
);
7032 TRACE("%p, refcount %u.\n", queue
, refcount
);
7036 event_queue_cleanup(queue
);
7037 DeleteCriticalSection(&queue
->cs
);
7044 static HRESULT WINAPI
eventqueue_GetEvent(IMFMediaEventQueue
*iface
, DWORD flags
, IMFMediaEvent
**event
)
7046 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7049 TRACE("%p, %p.\n", iface
, event
);
7051 EnterCriticalSection(&queue
->cs
);
7053 if (queue
->is_shut_down
)
7055 else if (queue
->subscriber
)
7056 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7059 if (flags
& MF_EVENT_FLAG_NO_WAIT
)
7061 if (!(*event
= queue_pop_event(queue
)))
7062 hr
= MF_E_NO_EVENTS_AVAILABLE
;
7066 while (list_empty(&queue
->events
) && !queue
->is_shut_down
)
7068 SleepConditionVariableCS(&queue
->update_event
, &queue
->cs
, INFINITE
);
7070 *event
= queue_pop_event(queue
);
7071 if (queue
->is_shut_down
)
7076 LeaveCriticalSection(&queue
->cs
);
7081 static void queue_notify_subscriber(struct event_queue
*queue
)
7083 if (list_empty(&queue
->events
) || !queue
->subscriber
|| queue
->notified
)
7086 queue
->notified
= TRUE
;
7087 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, queue
->subscriber
);
7090 static HRESULT WINAPI
eventqueue_BeginGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
7092 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7093 RTWQASYNCRESULT
*result_data
;
7096 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
7099 return E_INVALIDARG
;
7101 EnterCriticalSection(&queue
->cs
);
7103 if (queue
->is_shut_down
)
7105 else if ((result_data
= (RTWQASYNCRESULT
*)queue
->subscriber
))
7107 if (result_data
->pCallback
== (IRtwqAsyncCallback
*)callback
)
7108 hr
= IRtwqAsyncResult_GetStateNoAddRef(queue
->subscriber
) == state
?
7109 MF_S_MULTIPLE_BEGIN
: MF_E_MULTIPLE_BEGIN
;
7111 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7115 hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &queue
->subscriber
);
7117 queue_notify_subscriber(queue
);
7120 LeaveCriticalSection(&queue
->cs
);
7125 static HRESULT WINAPI
eventqueue_EndGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
7127 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7128 HRESULT hr
= E_FAIL
;
7130 TRACE("%p, %p, %p.\n", iface
, result
, event
);
7132 EnterCriticalSection(&queue
->cs
);
7134 if (queue
->is_shut_down
)
7136 else if (queue
->subscriber
== (IRtwqAsyncResult
*)result
)
7138 *event
= queue_pop_event(queue
);
7139 event_queue_clear_subscriber(queue
);
7140 queue
->notified
= FALSE
;
7141 hr
= *event
? S_OK
: E_FAIL
;
7144 LeaveCriticalSection(&queue
->cs
);
7149 static HRESULT
eventqueue_queue_event(struct event_queue
*queue
, IMFMediaEvent
*event
)
7151 struct queued_event
*queued_event
;
7154 queued_event
= malloc(sizeof(*queued_event
));
7156 return E_OUTOFMEMORY
;
7158 queued_event
->event
= event
;
7160 EnterCriticalSection(&queue
->cs
);
7162 if (queue
->is_shut_down
)
7166 IMFMediaEvent_AddRef(queued_event
->event
);
7167 list_add_tail(&queue
->events
, &queued_event
->entry
);
7168 queue_notify_subscriber(queue
);
7171 LeaveCriticalSection(&queue
->cs
);
7176 WakeAllConditionVariable(&queue
->update_event
);
7181 static HRESULT WINAPI
eventqueue_QueueEvent(IMFMediaEventQueue
*iface
, IMFMediaEvent
*event
)
7183 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7185 TRACE("%p, %p.\n", iface
, event
);
7187 return eventqueue_queue_event(queue
, event
);
7190 static HRESULT WINAPI
eventqueue_QueueEventParamVar(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7191 REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
)
7193 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7194 IMFMediaEvent
*event
;
7197 TRACE("%p, %s, %s, %#x, %s\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
,
7198 debugstr_propvar(value
));
7200 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, value
, &event
)))
7203 hr
= eventqueue_queue_event(queue
, event
);
7204 IMFMediaEvent_Release(event
);
7208 static HRESULT WINAPI
eventqueue_QueueEventParamUnk(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7209 REFGUID extended_type
, HRESULT status
, IUnknown
*unk
)
7211 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7212 IMFMediaEvent
*event
;
7216 TRACE("%p, %s, %s, %#x, %p.\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
, unk
);
7218 value
.vt
= VT_UNKNOWN
;
7219 value
.punkVal
= unk
;
7221 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, &value
, &event
)))
7224 hr
= eventqueue_queue_event(queue
, event
);
7225 IMFMediaEvent_Release(event
);
7229 static HRESULT WINAPI
eventqueue_Shutdown(IMFMediaEventQueue
*iface
)
7231 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7233 TRACE("%p\n", queue
);
7235 EnterCriticalSection(&queue
->cs
);
7237 if (!queue
->is_shut_down
)
7239 event_queue_cleanup(queue
);
7240 queue
->is_shut_down
= TRUE
;
7243 LeaveCriticalSection(&queue
->cs
);
7245 WakeAllConditionVariable(&queue
->update_event
);
7250 static const IMFMediaEventQueueVtbl eventqueuevtbl
=
7252 eventqueue_QueryInterface
,
7255 eventqueue_GetEvent
,
7256 eventqueue_BeginGetEvent
,
7257 eventqueue_EndGetEvent
,
7258 eventqueue_QueueEvent
,
7259 eventqueue_QueueEventParamVar
,
7260 eventqueue_QueueEventParamUnk
,
7264 /***********************************************************************
7265 * MFCreateEventQueue (mfplat.@)
7267 HRESULT WINAPI
MFCreateEventQueue(IMFMediaEventQueue
**queue
)
7269 struct event_queue
*object
;
7271 TRACE("%p\n", queue
);
7273 if (!(object
= calloc(1, sizeof(*object
))))
7274 return E_OUTOFMEMORY
;
7276 object
->IMFMediaEventQueue_iface
.lpVtbl
= &eventqueuevtbl
;
7277 object
->refcount
= 1;
7278 list_init(&object
->events
);
7279 InitializeCriticalSection(&object
->cs
);
7280 InitializeConditionVariable(&object
->update_event
);
7282 *queue
= &object
->IMFMediaEventQueue_iface
;
7289 IMFCollection IMFCollection_iface
;
7291 IUnknown
**elements
;
7296 static struct collection
*impl_from_IMFCollection(IMFCollection
*iface
)
7298 return CONTAINING_RECORD(iface
, struct collection
, IMFCollection_iface
);
7301 static void collection_clear(struct collection
*collection
)
7305 for (i
= 0; i
< collection
->count
; ++i
)
7307 if (collection
->elements
[i
])
7308 IUnknown_Release(collection
->elements
[i
]);
7311 free(collection
->elements
);
7312 collection
->elements
= NULL
;
7313 collection
->count
= 0;
7314 collection
->capacity
= 0;
7317 static HRESULT WINAPI
collection_QueryInterface(IMFCollection
*iface
, REFIID riid
, void **out
)
7319 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7321 if (IsEqualIID(riid
, &IID_IMFCollection
) ||
7322 IsEqualIID(riid
, &IID_IUnknown
))
7325 IMFCollection_AddRef(iface
);
7329 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
7331 return E_NOINTERFACE
;
7334 static ULONG WINAPI
collection_AddRef(IMFCollection
*iface
)
7336 struct collection
*collection
= impl_from_IMFCollection(iface
);
7337 ULONG refcount
= InterlockedIncrement(&collection
->refcount
);
7339 TRACE("%p, %d.\n", collection
, refcount
);
7344 static ULONG WINAPI
collection_Release(IMFCollection
*iface
)
7346 struct collection
*collection
= impl_from_IMFCollection(iface
);
7347 ULONG refcount
= InterlockedDecrement(&collection
->refcount
);
7349 TRACE("%p, %d.\n", collection
, refcount
);
7353 collection_clear(collection
);
7354 free(collection
->elements
);
7361 static HRESULT WINAPI
collection_GetElementCount(IMFCollection
*iface
, DWORD
*count
)
7363 struct collection
*collection
= impl_from_IMFCollection(iface
);
7365 TRACE("%p, %p.\n", iface
, count
);
7370 *count
= collection
->count
;
7375 static HRESULT WINAPI
collection_GetElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7377 struct collection
*collection
= impl_from_IMFCollection(iface
);
7379 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7384 if (idx
>= collection
->count
)
7385 return E_INVALIDARG
;
7387 *element
= collection
->elements
[idx
];
7389 IUnknown_AddRef(*element
);
7391 return *element
? S_OK
: E_UNEXPECTED
;
7394 static HRESULT WINAPI
collection_AddElement(IMFCollection
*iface
, IUnknown
*element
)
7396 struct collection
*collection
= impl_from_IMFCollection(iface
);
7398 TRACE("%p, %p.\n", iface
, element
);
7400 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, collection
->count
+ 1,
7401 sizeof(*collection
->elements
)))
7402 return E_OUTOFMEMORY
;
7404 collection
->elements
[collection
->count
++] = element
;
7406 IUnknown_AddRef(element
);
7411 static HRESULT WINAPI
collection_RemoveElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7413 struct collection
*collection
= impl_from_IMFCollection(iface
);
7416 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7421 if (idx
>= collection
->count
)
7422 return E_INVALIDARG
;
7424 *element
= collection
->elements
[idx
];
7426 count
= collection
->count
- idx
- 1;
7428 memmove(&collection
->elements
[idx
], &collection
->elements
[idx
+ 1], count
* sizeof(*collection
->elements
));
7429 collection
->count
--;
7434 static HRESULT WINAPI
collection_InsertElementAt(IMFCollection
*iface
, DWORD idx
, IUnknown
*element
)
7436 struct collection
*collection
= impl_from_IMFCollection(iface
);
7439 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7441 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, idx
+ 1,
7442 sizeof(*collection
->elements
)))
7443 return E_OUTOFMEMORY
;
7445 if (idx
< collection
->count
)
7447 memmove(&collection
->elements
[idx
+ 1], &collection
->elements
[idx
],
7448 (collection
->count
- idx
) * sizeof(*collection
->elements
));
7449 collection
->count
++;
7453 for (i
= collection
->count
; i
< idx
; ++i
)
7454 collection
->elements
[i
] = NULL
;
7455 collection
->count
= idx
+ 1;
7458 collection
->elements
[idx
] = element
;
7459 if (collection
->elements
[idx
])
7460 IUnknown_AddRef(collection
->elements
[idx
]);
7465 static HRESULT WINAPI
collection_RemoveAllElements(IMFCollection
*iface
)
7467 struct collection
*collection
= impl_from_IMFCollection(iface
);
7469 TRACE("%p.\n", iface
);
7471 collection_clear(collection
);
7476 static const IMFCollectionVtbl mfcollectionvtbl
=
7478 collection_QueryInterface
,
7481 collection_GetElementCount
,
7482 collection_GetElement
,
7483 collection_AddElement
,
7484 collection_RemoveElement
,
7485 collection_InsertElementAt
,
7486 collection_RemoveAllElements
,
7489 /***********************************************************************
7490 * MFCreateCollection (mfplat.@)
7492 HRESULT WINAPI
MFCreateCollection(IMFCollection
**collection
)
7494 struct collection
*object
;
7496 TRACE("%p\n", collection
);
7501 if (!(object
= calloc(1, sizeof(*object
))))
7502 return E_OUTOFMEMORY
;
7504 object
->IMFCollection_iface
.lpVtbl
= &mfcollectionvtbl
;
7505 object
->refcount
= 1;
7507 *collection
= &object
->IMFCollection_iface
;
7512 /***********************************************************************
7513 * MFHeapAlloc (mfplat.@)
7515 void *WINAPI
MFHeapAlloc(SIZE_T size
, ULONG flags
, char *file
, int line
, EAllocationType type
)
7517 TRACE("%lu, %#x, %s, %d, %#x.\n", size
, flags
, debugstr_a(file
), line
, type
);
7518 return HeapAlloc(GetProcessHeap(), flags
, size
);
7521 /***********************************************************************
7522 * MFHeapFree (mfplat.@)
7524 void WINAPI
MFHeapFree(void *p
)
7527 HeapFree(GetProcessHeap(), 0, p
);
7530 /***********************************************************************
7531 * MFCreateMFByteStreamOnStreamEx (mfplat.@)
7533 HRESULT WINAPI
MFCreateMFByteStreamOnStreamEx(IUnknown
*stream
, IMFByteStream
**bytestream
)
7535 FIXME("(%p, %p): stub\n", stream
, bytestream
);
7540 static HRESULT WINAPI
system_clock_QueryInterface(IMFClock
*iface
, REFIID riid
, void **obj
)
7542 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7544 if (IsEqualIID(riid
, &IID_IMFClock
) ||
7545 IsEqualIID(riid
, &IID_IUnknown
))
7548 IMFClock_AddRef(iface
);
7552 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7554 return E_NOINTERFACE
;
7557 static ULONG WINAPI
system_clock_AddRef(IMFClock
*iface
)
7559 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7560 ULONG refcount
= InterlockedIncrement(&clock
->refcount
);
7562 TRACE("%p, refcount %u.\n", iface
, refcount
);
7567 static ULONG WINAPI
system_clock_Release(IMFClock
*iface
)
7569 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7570 ULONG refcount
= InterlockedDecrement(&clock
->refcount
);
7572 TRACE("%p, refcount %u.\n", iface
, refcount
);
7580 static HRESULT WINAPI
system_clock_GetClockCharacteristics(IMFClock
*iface
, DWORD
*flags
)
7582 TRACE("%p, %p.\n", iface
, flags
);
7584 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING
|
7585 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7590 static HRESULT WINAPI
system_clock_GetCorrelatedTime(IMFClock
*iface
, DWORD reserved
, LONGLONG
*clock_time
,
7591 MFTIME
*system_time
)
7593 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7595 *clock_time
= *system_time
= MFGetSystemTime();
7600 static HRESULT WINAPI
system_clock_GetContinuityKey(IMFClock
*iface
, DWORD
*key
)
7602 TRACE("%p, %p.\n", iface
, key
);
7609 static HRESULT WINAPI
system_clock_GetState(IMFClock
*iface
, DWORD reserved
, MFCLOCK_STATE
*state
)
7611 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7613 *state
= MFCLOCK_STATE_RUNNING
;
7618 static HRESULT WINAPI
system_clock_GetProperties(IMFClock
*iface
, MFCLOCK_PROPERTIES
*props
)
7620 TRACE("%p, %p.\n", iface
, props
);
7625 memset(props
, 0, sizeof(*props
));
7626 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7627 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7628 props
->dwClockJitter
= 1;
7633 static const IMFClockVtbl system_clock_vtbl
=
7635 system_clock_QueryInterface
,
7636 system_clock_AddRef
,
7637 system_clock_Release
,
7638 system_clock_GetClockCharacteristics
,
7639 system_clock_GetCorrelatedTime
,
7640 system_clock_GetContinuityKey
,
7641 system_clock_GetState
,
7642 system_clock_GetProperties
,
7645 static HRESULT
create_system_clock(IMFClock
**clock
)
7647 struct system_clock
*object
;
7649 if (!(object
= malloc(sizeof(*object
))))
7650 return E_OUTOFMEMORY
;
7652 object
->IMFClock_iface
.lpVtbl
= &system_clock_vtbl
;
7653 object
->refcount
= 1;
7655 *clock
= &object
->IMFClock_iface
;
7660 static HRESULT WINAPI
system_time_source_QueryInterface(IMFPresentationTimeSource
*iface
, REFIID riid
, void **obj
)
7662 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7664 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7666 if (IsEqualIID(riid
, &IID_IMFPresentationTimeSource
) ||
7667 IsEqualIID(riid
, &IID_IUnknown
))
7669 *obj
= &source
->IMFPresentationTimeSource_iface
;
7671 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
7673 *obj
= &source
->IMFClockStateSink_iface
;
7677 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7679 return E_NOINTERFACE
;
7682 IUnknown_AddRef((IUnknown
*)*obj
);
7686 static ULONG WINAPI
system_time_source_AddRef(IMFPresentationTimeSource
*iface
)
7688 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7689 ULONG refcount
= InterlockedIncrement(&source
->refcount
);
7691 TRACE("%p, refcount %u.\n", iface
, refcount
);
7696 static ULONG WINAPI
system_time_source_Release(IMFPresentationTimeSource
*iface
)
7698 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7699 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
7701 TRACE("%p, refcount %u.\n", iface
, refcount
);
7706 IMFClock_Release(source
->clock
);
7707 DeleteCriticalSection(&source
->cs
);
7714 static HRESULT WINAPI
system_time_source_GetClockCharacteristics(IMFPresentationTimeSource
*iface
, DWORD
*flags
)
7716 TRACE("%p, %p.\n", iface
, flags
);
7718 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7723 static HRESULT WINAPI
system_time_source_GetCorrelatedTime(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7724 LONGLONG
*clock_time
, MFTIME
*system_time
)
7726 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7729 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7731 EnterCriticalSection(&source
->cs
);
7732 if (SUCCEEDED(hr
= IMFClock_GetCorrelatedTime(source
->clock
, 0, clock_time
, system_time
)))
7734 if (source
->state
== MFCLOCK_STATE_RUNNING
)
7736 system_time_source_apply_rate(source
, clock_time
);
7737 *clock_time
+= source
->start_offset
;
7740 *clock_time
= source
->start_offset
;
7742 LeaveCriticalSection(&source
->cs
);
7747 static HRESULT WINAPI
system_time_source_GetContinuityKey(IMFPresentationTimeSource
*iface
, DWORD
*key
)
7749 TRACE("%p, %p.\n", iface
, key
);
7756 static HRESULT WINAPI
system_time_source_GetState(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7757 MFCLOCK_STATE
*state
)
7759 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7761 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7763 EnterCriticalSection(&source
->cs
);
7764 *state
= source
->state
;
7765 LeaveCriticalSection(&source
->cs
);
7770 static HRESULT WINAPI
system_time_source_GetProperties(IMFPresentationTimeSource
*iface
, MFCLOCK_PROPERTIES
*props
)
7772 TRACE("%p, %p.\n", iface
, props
);
7777 memset(props
, 0, sizeof(*props
));
7778 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7779 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7780 props
->dwClockJitter
= 1;
7785 static HRESULT WINAPI
system_time_source_GetUnderlyingClock(IMFPresentationTimeSource
*iface
, IMFClock
**clock
)
7787 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7789 TRACE("%p, %p.\n", iface
, clock
);
7791 *clock
= source
->clock
;
7792 IMFClock_AddRef(*clock
);
7797 static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl
=
7799 system_time_source_QueryInterface
,
7800 system_time_source_AddRef
,
7801 system_time_source_Release
,
7802 system_time_source_GetClockCharacteristics
,
7803 system_time_source_GetCorrelatedTime
,
7804 system_time_source_GetContinuityKey
,
7805 system_time_source_GetState
,
7806 system_time_source_GetProperties
,
7807 system_time_source_GetUnderlyingClock
,
7810 static HRESULT WINAPI
system_time_source_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **out
)
7812 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7813 return IMFPresentationTimeSource_QueryInterface(&source
->IMFPresentationTimeSource_iface
, riid
, out
);
7816 static ULONG WINAPI
system_time_source_sink_AddRef(IMFClockStateSink
*iface
)
7818 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7819 return IMFPresentationTimeSource_AddRef(&source
->IMFPresentationTimeSource_iface
);
7822 static ULONG WINAPI
system_time_source_sink_Release(IMFClockStateSink
*iface
)
7824 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7825 return IMFPresentationTimeSource_Release(&source
->IMFPresentationTimeSource_iface
);
7830 CLOCK_CMD_START
= 0,
7837 static HRESULT
system_time_source_change_state(struct system_time_source
*source
, enum clock_command command
)
7839 static const BYTE state_change_is_allowed
[MFCLOCK_STATE_PAUSED
+1][CLOCK_CMD_MAX
] =
7841 /* INVALID */ { 1, 0, 1, 0 },
7842 /* RUNNING */ { 1, 1, 1, 0 },
7843 /* STOPPED */ { 1, 1, 0, 0 },
7844 /* PAUSED */ { 1, 1, 0, 1 },
7846 static const MFCLOCK_STATE states
[CLOCK_CMD_MAX
] =
7848 /* CLOCK_CMD_START */ MFCLOCK_STATE_RUNNING
,
7849 /* CLOCK_CMD_STOP */ MFCLOCK_STATE_STOPPED
,
7850 /* CLOCK_CMD_PAUSE */ MFCLOCK_STATE_PAUSED
,
7851 /* CLOCK_CMD_RESTART */ MFCLOCK_STATE_RUNNING
,
7854 /* Special case that go against usual state change vs return value behavior. */
7855 if (source
->state
== MFCLOCK_STATE_INVALID
&& command
== CLOCK_CMD_STOP
)
7858 if (!state_change_is_allowed
[source
->state
][command
])
7859 return MF_E_INVALIDREQUEST
;
7861 source
->state
= states
[command
];
7866 static HRESULT WINAPI
system_time_source_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
,
7867 LONGLONG start_offset
)
7869 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7870 MFCLOCK_STATE state
;
7873 TRACE("%p, %s, %s.\n", iface
, debugstr_time(system_time
), debugstr_time(start_offset
));
7875 EnterCriticalSection(&source
->cs
);
7876 state
= source
->state
;
7877 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_START
)))
7879 system_time_source_apply_rate(source
, &system_time
);
7880 if (start_offset
== PRESENTATION_CURRENT_POSITION
)
7884 case MFCLOCK_STATE_RUNNING
:
7886 case MFCLOCK_STATE_PAUSED
:
7887 source
->start_offset
-= system_time
;
7890 source
->start_offset
= -system_time
;
7897 source
->start_offset
= -system_time
+ start_offset
;
7900 LeaveCriticalSection(&source
->cs
);
7905 static HRESULT WINAPI
system_time_source_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
7907 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7910 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7912 EnterCriticalSection(&source
->cs
);
7913 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_STOP
)))
7914 source
->start_offset
= 0;
7915 LeaveCriticalSection(&source
->cs
);
7920 static HRESULT WINAPI
system_time_source_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
7922 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7925 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7927 EnterCriticalSection(&source
->cs
);
7928 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_PAUSE
)))
7930 system_time_source_apply_rate(source
, &system_time
);
7931 source
->start_offset
+= system_time
;
7933 LeaveCriticalSection(&source
->cs
);
7938 static HRESULT WINAPI
system_time_source_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
7940 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7943 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7945 EnterCriticalSection(&source
->cs
);
7946 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_RESTART
)))
7948 system_time_source_apply_rate(source
, &system_time
);
7949 source
->start_offset
-= system_time
;
7951 LeaveCriticalSection(&source
->cs
);
7956 static HRESULT WINAPI
system_time_source_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
7958 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7961 TRACE("%p, %s, %f.\n", iface
, debugstr_time(system_time
), rate
);
7964 return MF_E_UNSUPPORTED_RATE
;
7966 modf(rate
, &intpart
);
7968 EnterCriticalSection(&source
->cs
);
7969 source
->rate
= rate
;
7970 source
->i_rate
= rate
== intpart
? rate
: 0;
7971 LeaveCriticalSection(&source
->cs
);
7976 static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl
=
7978 system_time_source_sink_QueryInterface
,
7979 system_time_source_sink_AddRef
,
7980 system_time_source_sink_Release
,
7981 system_time_source_sink_OnClockStart
,
7982 system_time_source_sink_OnClockStop
,
7983 system_time_source_sink_OnClockPause
,
7984 system_time_source_sink_OnClockRestart
,
7985 system_time_source_sink_OnClockSetRate
,
7988 /***********************************************************************
7989 * MFCreateSystemTimeSource (mfplat.@)
7991 HRESULT WINAPI
MFCreateSystemTimeSource(IMFPresentationTimeSource
**time_source
)
7993 struct system_time_source
*object
;
7996 TRACE("%p.\n", time_source
);
7998 object
= calloc(1, sizeof(*object
));
8000 return E_OUTOFMEMORY
;
8002 object
->IMFPresentationTimeSource_iface
.lpVtbl
= &systemtimesourcevtbl
;
8003 object
->IMFClockStateSink_iface
.lpVtbl
= &systemtimesourcesinkvtbl
;
8004 object
->refcount
= 1;
8005 object
->rate
= 1.0f
;
8007 InitializeCriticalSection(&object
->cs
);
8009 if (FAILED(hr
= create_system_clock(&object
->clock
)))
8011 IMFPresentationTimeSource_Release(&object
->IMFPresentationTimeSource_iface
);
8015 *time_source
= &object
->IMFPresentationTimeSource_iface
;
8020 struct async_create_file
8022 IRtwqAsyncCallback IRtwqAsyncCallback_iface
;
8024 MF_FILE_ACCESSMODE access_mode
;
8025 MF_FILE_OPENMODE open_mode
;
8026 MF_FILE_FLAGS flags
;
8030 struct async_create_file_result
8033 IRtwqAsyncResult
*result
;
8034 IMFByteStream
*stream
;
8037 static struct list async_create_file_results
= LIST_INIT(async_create_file_results
);
8038 static CRITICAL_SECTION async_create_file_cs
= { NULL
, -1, 0, 0, 0, 0 };
8040 static struct async_create_file
*impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
8042 return CONTAINING_RECORD(iface
, struct async_create_file
, IRtwqAsyncCallback_iface
);
8045 static HRESULT WINAPI
async_create_file_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
8047 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
8048 IsEqualIID(riid
, &IID_IUnknown
))
8051 IRtwqAsyncCallback_AddRef(iface
);
8056 return E_NOINTERFACE
;
8059 static ULONG WINAPI
async_create_file_callback_AddRef(IRtwqAsyncCallback
*iface
)
8061 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8062 ULONG refcount
= InterlockedIncrement(&async
->refcount
);
8064 TRACE("%p, refcount %u.\n", iface
, refcount
);
8069 static ULONG WINAPI
async_create_file_callback_Release(IRtwqAsyncCallback
*iface
)
8071 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8072 ULONG refcount
= InterlockedDecrement(&async
->refcount
);
8074 TRACE("%p, refcount %u.\n", iface
, refcount
);
8085 static HRESULT WINAPI
async_create_file_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
8090 static HRESULT WINAPI
async_create_file_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
8092 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8093 IRtwqAsyncResult
*caller
;
8094 IMFByteStream
*stream
;
8097 caller
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
8099 hr
= MFCreateFile(async
->access_mode
, async
->open_mode
, async
->flags
, async
->path
, &stream
);
8102 struct async_create_file_result
*result_item
;
8104 result_item
= malloc(sizeof(*result_item
));
8107 result_item
->result
= caller
;
8108 IRtwqAsyncResult_AddRef(caller
);
8109 result_item
->stream
= stream
;
8110 IMFByteStream_AddRef(stream
);
8112 EnterCriticalSection(&async_create_file_cs
);
8113 list_add_tail(&async_create_file_results
, &result_item
->entry
);
8114 LeaveCriticalSection(&async_create_file_cs
);
8117 IMFByteStream_Release(stream
);
8120 IRtwqAsyncResult_SetStatus(caller
, hr
);
8122 RtwqInvokeCallback(caller
);
8127 static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl
=
8129 async_create_file_callback_QueryInterface
,
8130 async_create_file_callback_AddRef
,
8131 async_create_file_callback_Release
,
8132 async_create_file_callback_GetParameters
,
8133 async_create_file_callback_Invoke
,
8136 /***********************************************************************
8137 * MFBeginCreateFile (mfplat.@)
8139 HRESULT WINAPI
MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode
, MF_FILE_OPENMODE open_mode
, MF_FILE_FLAGS flags
,
8140 const WCHAR
*path
, IMFAsyncCallback
*callback
, IUnknown
*state
, IUnknown
**cancel_cookie
)
8142 struct async_create_file
*async
= NULL
;
8143 IRtwqAsyncResult
*caller
, *item
= NULL
;
8146 TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode
, open_mode
, flags
, debugstr_w(path
), callback
, state
,
8150 *cancel_cookie
= NULL
;
8152 if (FAILED(hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &caller
)))
8155 if (!(async
= malloc(sizeof(*async
))))
8161 async
->IRtwqAsyncCallback_iface
.lpVtbl
= &async_create_file_callback_vtbl
;
8162 async
->refcount
= 1;
8163 async
->access_mode
= access_mode
;
8164 async
->open_mode
= open_mode
;
8165 async
->flags
= flags
;
8166 if (!(async
->path
= wcsdup(path
)))
8172 hr
= RtwqCreateAsyncResult(NULL
, &async
->IRtwqAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
8178 *cancel_cookie
= (IUnknown
*)caller
;
8179 IUnknown_AddRef(*cancel_cookie
);
8182 hr
= RtwqInvokeCallback(item
);
8186 IRtwqAsyncCallback_Release(&async
->IRtwqAsyncCallback_iface
);
8188 IRtwqAsyncResult_Release(item
);
8190 IRtwqAsyncResult_Release(caller
);
8195 static HRESULT
async_create_file_pull_result(IUnknown
*unk
, IMFByteStream
**stream
)
8197 struct async_create_file_result
*item
;
8198 HRESULT hr
= MF_E_UNEXPECTED
;
8199 IRtwqAsyncResult
*result
;
8203 if (FAILED(IUnknown_QueryInterface(unk
, &IID_IRtwqAsyncResult
, (void **)&result
)))
8206 EnterCriticalSection(&async_create_file_cs
);
8208 LIST_FOR_EACH_ENTRY(item
, &async_create_file_results
, struct async_create_file_result
, entry
)
8210 if (result
== item
->result
)
8212 *stream
= item
->stream
;
8213 IRtwqAsyncResult_Release(item
->result
);
8214 list_remove(&item
->entry
);
8220 LeaveCriticalSection(&async_create_file_cs
);
8223 hr
= IRtwqAsyncResult_GetStatus(result
);
8225 IRtwqAsyncResult_Release(result
);
8230 /***********************************************************************
8231 * MFEndCreateFile (mfplat.@)
8233 HRESULT WINAPI
MFEndCreateFile(IMFAsyncResult
*result
, IMFByteStream
**stream
)
8235 TRACE("%p, %p.\n", result
, stream
);
8237 return async_create_file_pull_result((IUnknown
*)result
, stream
);
8240 /***********************************************************************
8241 * MFCancelCreateFile (mfplat.@)
8243 HRESULT WINAPI
MFCancelCreateFile(IUnknown
*cancel_cookie
)
8245 IMFByteStream
*stream
= NULL
;
8248 TRACE("%p.\n", cancel_cookie
);
8250 hr
= async_create_file_pull_result(cancel_cookie
, &stream
);
8253 IMFByteStream_Release(stream
);
8258 /***********************************************************************
8259 * MFRegisterLocalSchemeHandler (mfplat.@)
8261 HRESULT WINAPI
MFRegisterLocalSchemeHandler(const WCHAR
*scheme
, IMFActivate
*activate
)
8263 struct local_handler
*handler
;
8265 TRACE("%s, %p.\n", debugstr_w(scheme
), activate
);
8267 if (!scheme
|| !activate
)
8268 return E_INVALIDARG
;
8270 if (!(handler
= malloc(sizeof(*handler
))))
8271 return E_OUTOFMEMORY
;
8273 if (!(handler
->u
.scheme
= wcsdup(scheme
)))
8276 return E_OUTOFMEMORY
;
8278 handler
->activate
= activate
;
8279 IMFActivate_AddRef(handler
->activate
);
8281 EnterCriticalSection(&local_handlers_section
);
8282 list_add_head(&local_scheme_handlers
, &handler
->entry
);
8283 LeaveCriticalSection(&local_handlers_section
);
8288 /***********************************************************************
8289 * MFRegisterLocalByteStreamHandler (mfplat.@)
8291 HRESULT WINAPI
MFRegisterLocalByteStreamHandler(const WCHAR
*extension
, const WCHAR
*mime
, IMFActivate
*activate
)
8293 struct local_handler
*handler
;
8295 TRACE("%s, %s, %p.\n", debugstr_w(extension
), debugstr_w(mime
), activate
);
8297 if ((!extension
&& !mime
) || !activate
)
8298 return E_INVALIDARG
;
8300 if (!(handler
= calloc(1, sizeof(*handler
))))
8301 return E_OUTOFMEMORY
;
8303 if (extension
&& !(handler
->u
.bytestream
.extension
= wcsdup(extension
)))
8305 if (mime
&& !(handler
->u
.bytestream
.mime
= wcsdup(mime
)))
8308 EnterCriticalSection(&local_handlers_section
);
8309 list_add_head(&local_bytestream_handlers
, &handler
->entry
);
8310 LeaveCriticalSection(&local_handlers_section
);
8315 free(handler
->u
.bytestream
.extension
);
8316 free(handler
->u
.bytestream
.mime
);
8319 return E_OUTOFMEMORY
;
8322 struct property_store
8324 IPropertyStore IPropertyStore_iface
;
8326 CRITICAL_SECTION cs
;
8327 size_t count
, capacity
;
8335 static struct property_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
8337 return CONTAINING_RECORD(iface
, struct property_store
, IPropertyStore_iface
);
8340 static HRESULT WINAPI
property_store_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
8342 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8344 if (IsEqualIID(riid
, &IID_IPropertyStore
) || IsEqualIID(riid
, &IID_IUnknown
))
8347 IPropertyStore_AddRef(iface
);
8352 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
8353 return E_NOINTERFACE
;
8356 static ULONG WINAPI
property_store_AddRef(IPropertyStore
*iface
)
8358 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8359 ULONG refcount
= InterlockedIncrement(&store
->refcount
);
8361 TRACE("%p, refcount %d.\n", iface
, refcount
);
8366 static ULONG WINAPI
property_store_Release(IPropertyStore
*iface
)
8368 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8369 ULONG refcount
= InterlockedDecrement(&store
->refcount
);
8371 TRACE("%p, refcount %d.\n", iface
, refcount
);
8375 DeleteCriticalSection(&store
->cs
);
8376 free(store
->values
);
8383 static HRESULT WINAPI
property_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
8385 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8387 TRACE("%p, %p.\n", iface
, count
);
8390 return E_INVALIDARG
;
8392 EnterCriticalSection(&store
->cs
);
8393 *count
= store
->count
;
8394 LeaveCriticalSection(&store
->cs
);
8398 static HRESULT WINAPI
property_store_GetAt(IPropertyStore
*iface
, DWORD index
, PROPERTYKEY
*key
)
8400 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8402 TRACE("%p, %u, %p.\n", iface
, index
, key
);
8404 EnterCriticalSection(&store
->cs
);
8406 if (index
>= store
->count
)
8408 LeaveCriticalSection(&store
->cs
);
8409 return E_INVALIDARG
;
8412 *key
= store
->values
[index
].key
;
8414 LeaveCriticalSection(&store
->cs
);
8418 static HRESULT WINAPI
property_store_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
8420 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8423 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8426 return E_INVALIDARG
;
8431 EnterCriticalSection(&store
->cs
);
8433 for (i
= 0; i
< store
->count
; ++i
)
8435 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8437 PropVariantCopy(value
, &store
->values
[i
].value
);
8438 LeaveCriticalSection(&store
->cs
);
8443 LeaveCriticalSection(&store
->cs
);
8447 static HRESULT WINAPI
property_store_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
8449 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8452 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8454 EnterCriticalSection(&store
->cs
);
8456 for (i
= 0; i
< store
->count
; ++i
)
8458 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8460 PropVariantCopy(&store
->values
[i
].value
, value
);
8461 LeaveCriticalSection(&store
->cs
);
8466 if (!mf_array_reserve((void **)&store
->values
, &store
->capacity
, store
->count
+ 1, sizeof(*store
->values
)))
8468 LeaveCriticalSection(&store
->cs
);
8469 return E_OUTOFMEMORY
;
8472 store
->values
[store
->count
].key
= *key
;
8473 PropVariantCopy(&store
->values
[store
->count
].value
, value
);
8476 LeaveCriticalSection(&store
->cs
);
8480 static HRESULT WINAPI
property_store_Commit(IPropertyStore
*iface
)
8482 TRACE("%p.\n", iface
);
8487 static const IPropertyStoreVtbl property_store_vtbl
=
8489 property_store_QueryInterface
,
8490 property_store_AddRef
,
8491 property_store_Release
,
8492 property_store_GetCount
,
8493 property_store_GetAt
,
8494 property_store_GetValue
,
8495 property_store_SetValue
,
8496 property_store_Commit
,
8499 /***********************************************************************
8500 * CreatePropertyStore (mfplat.@)
8502 HRESULT WINAPI
CreatePropertyStore(IPropertyStore
**store
)
8504 struct property_store
*object
;
8506 TRACE("%p.\n", store
);
8509 return E_INVALIDARG
;
8511 if (!(object
= calloc(1, sizeof(*object
))))
8512 return E_OUTOFMEMORY
;
8514 object
->IPropertyStore_iface
.lpVtbl
= &property_store_vtbl
;
8515 object
->refcount
= 1;
8516 InitializeCriticalSection(&object
->cs
);
8518 TRACE("Created store %p.\n", object
);
8519 *store
= &object
->IPropertyStore_iface
;
8524 struct shared_dxgi_manager
8526 IMFDXGIDeviceManager
*manager
;
8531 static struct shared_dxgi_manager shared_dm
;
8532 static CRITICAL_SECTION shared_dm_cs
= { NULL
, -1, 0, 0, 0, 0 };
8534 enum dxgi_device_handle_flags
8536 DXGI_DEVICE_HANDLE_FLAG_OPEN
= 0x1,
8537 DXGI_DEVICE_HANDLE_FLAG_INVALID
= 0x2,
8538 DXGI_DEVICE_HANDLE_FLAG_LOCKED
= 0x4,
8541 struct dxgi_device_manager
8543 IMFDXGIDeviceManager IMFDXGIDeviceManager_iface
;
8546 IDXGIDevice
*device
;
8548 unsigned int *handles
;
8553 unsigned int locking_tid
;
8555 CRITICAL_SECTION cs
;
8556 CONDITION_VARIABLE lock
;
8559 static struct dxgi_device_manager
*impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager
*iface
)
8561 return CONTAINING_RECORD(iface
, struct dxgi_device_manager
, IMFDXGIDeviceManager_iface
);
8564 static HRESULT
dxgi_device_manager_get_handle_index(struct dxgi_device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
8566 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
8568 *idx
= (ULONG_PTR
)hdevice
- 1;
8572 static HRESULT WINAPI
dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager
*iface
, REFIID riid
, void **obj
)
8574 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8576 if (IsEqualIID(riid
, &IID_IMFDXGIDeviceManager
) ||
8577 IsEqualGUID(riid
, &IID_IUnknown
))
8580 IMFDXGIDeviceManager_AddRef(iface
);
8584 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8586 return E_NOINTERFACE
;
8589 static ULONG WINAPI
dxgi_device_manager_AddRef(IMFDXGIDeviceManager
*iface
)
8591 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8592 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
8594 TRACE("%p, refcount %u.\n", iface
, refcount
);
8599 static ULONG WINAPI
dxgi_device_manager_Release(IMFDXGIDeviceManager
*iface
)
8601 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8602 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
8604 TRACE("%p, refcount %u.\n", iface
, refcount
);
8608 if (manager
->device
)
8609 IDXGIDevice_Release(manager
->device
);
8610 DeleteCriticalSection(&manager
->cs
);
8611 free(manager
->handles
);
8618 static void dxgi_device_manager_lock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8620 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
)
8623 manager
->handles
[idx
] |= DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8627 static void dxgi_device_manager_unlock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8629 if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
))
8632 manager
->handles
[idx
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8633 if (!--manager
->locks
)
8634 manager
->locking_tid
= 0;
8637 static HRESULT WINAPI
dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8639 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8643 TRACE("%p, %p.\n", iface
, hdevice
);
8645 EnterCriticalSection(&manager
->cs
);
8647 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8649 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8651 dxgi_device_manager_unlock_handle(manager
, idx
);
8652 manager
->handles
[idx
] = 0;
8653 if (idx
== manager
->count
- 1)
8660 LeaveCriticalSection(&manager
->cs
);
8662 WakeAllConditionVariable(&manager
->lock
);
8667 static HRESULT WINAPI
dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8668 REFIID riid
, void **service
)
8670 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8674 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), service
);
8676 EnterCriticalSection(&manager
->cs
);
8678 if (!manager
->device
)
8679 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8680 else if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8682 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8683 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8684 else if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8685 hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, service
);
8690 LeaveCriticalSection(&manager
->cs
);
8695 static HRESULT WINAPI
dxgi_device_manager_LockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8696 REFIID riid
, void **obj
, BOOL block
)
8698 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8702 TRACE("%p, %p, %s, %p, %d.\n", iface
, hdevice
, wine_dbgstr_guid(riid
), obj
, block
);
8704 EnterCriticalSection(&manager
->cs
);
8706 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8708 if (!manager
->device
)
8710 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8712 else if (manager
->locking_tid
== GetCurrentThreadId())
8714 if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8715 dxgi_device_manager_lock_handle(manager
, idx
);
8717 else if (manager
->locking_tid
&& !block
)
8719 hr
= MF_E_DXGI_VIDEO_DEVICE_LOCKED
;
8723 while (manager
->locking_tid
)
8725 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
8728 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8730 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8731 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8732 else if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8734 manager
->locking_tid
= GetCurrentThreadId();
8735 dxgi_device_manager_lock_handle(manager
, idx
);
8741 LeaveCriticalSection(&manager
->cs
);
8746 static HRESULT WINAPI
dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE
*hdevice
)
8748 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8752 TRACE("%p, %p.\n", iface
, hdevice
);
8756 EnterCriticalSection(&manager
->cs
);
8758 if (!manager
->device
)
8759 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8762 for (i
= 0; i
< manager
->count
; ++i
)
8764 if (!(manager
->handles
[i
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8766 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8767 *hdevice
= ULongToHandle(i
+ 1);
8772 if (mf_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
8773 sizeof(*manager
->handles
)))
8775 *hdevice
= ULongToHandle(manager
->count
+ 1);
8776 manager
->handles
[manager
->count
++] = DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8782 LeaveCriticalSection(&manager
->cs
);
8787 static HRESULT WINAPI
dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager
*iface
, IUnknown
*device
, UINT token
)
8789 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8790 IDXGIDevice
*dxgi_device
;
8793 TRACE("%p, %p, %u.\n", iface
, device
, token
);
8795 if (!device
|| token
!= manager
->token
)
8796 return E_INVALIDARG
;
8798 if (FAILED(IUnknown_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
)))
8799 return E_INVALIDARG
;
8801 EnterCriticalSection(&manager
->cs
);
8803 if (manager
->device
)
8805 for (i
= 0; i
< manager
->count
; ++i
)
8807 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_INVALID
;
8808 manager
->handles
[i
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8810 manager
->locking_tid
= 0;
8812 IDXGIDevice_Release(manager
->device
);
8814 manager
->device
= dxgi_device
;
8816 LeaveCriticalSection(&manager
->cs
);
8818 WakeAllConditionVariable(&manager
->lock
);
8823 static HRESULT WINAPI
dxgi_device_manager_TestDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8825 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8829 TRACE("%p, %p.\n", iface
, hdevice
);
8831 EnterCriticalSection(&manager
->cs
);
8833 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8835 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8836 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8837 else if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8841 LeaveCriticalSection(&manager
->cs
);
8846 static HRESULT WINAPI
dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8849 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8850 HRESULT hr
= E_FAIL
;
8853 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
8855 EnterCriticalSection(&manager
->cs
);
8857 if (SUCCEEDED(dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8859 hr
= manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
? S_OK
: E_INVALIDARG
;
8861 dxgi_device_manager_unlock_handle(manager
, idx
);
8864 LeaveCriticalSection(&manager
->cs
);
8866 WakeAllConditionVariable(&manager
->lock
);
8871 static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl
=
8873 dxgi_device_manager_QueryInterface
,
8874 dxgi_device_manager_AddRef
,
8875 dxgi_device_manager_Release
,
8876 dxgi_device_manager_CloseDeviceHandle
,
8877 dxgi_device_manager_GetVideoService
,
8878 dxgi_device_manager_LockDevice
,
8879 dxgi_device_manager_OpenDeviceHandle
,
8880 dxgi_device_manager_ResetDevice
,
8881 dxgi_device_manager_TestDevice
,
8882 dxgi_device_manager_UnlockDevice
,
8885 /***********************************************************************
8886 * MFCreateDXGIDeviceManager (mfplat.@)
8888 HRESULT WINAPI
MFCreateDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
8890 struct dxgi_device_manager
*object
;
8892 TRACE("%p, %p.\n", token
, manager
);
8894 if (!token
|| !manager
)
8897 if (!(object
= calloc(1, sizeof(*object
))))
8898 return E_OUTOFMEMORY
;
8900 object
->IMFDXGIDeviceManager_iface
.lpVtbl
= &dxgi_device_manager_vtbl
;
8901 object
->refcount
= 1;
8902 object
->token
= GetTickCount();
8903 InitializeCriticalSection(&object
->cs
);
8904 InitializeConditionVariable(&object
->lock
);
8906 TRACE("Created device manager: %p, token: %u.\n", object
, object
->token
);
8908 *token
= object
->token
;
8909 *manager
= &object
->IMFDXGIDeviceManager_iface
;
8914 /***********************************************************************
8915 * MFLockDXGIDeviceManager (mfplat.@)
8917 HRESULT WINAPI
MFLockDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
8921 TRACE("%p, %p.\n", token
, manager
);
8923 EnterCriticalSection(&shared_dm_cs
);
8925 if (!shared_dm
.manager
)
8926 hr
= MFCreateDXGIDeviceManager(&shared_dm
.token
, &shared_dm
.manager
);
8930 *manager
= shared_dm
.manager
;
8931 IMFDXGIDeviceManager_AddRef(*manager
);
8934 if (token
) *token
= shared_dm
.token
;
8937 LeaveCriticalSection(&shared_dm_cs
);
8942 /***********************************************************************
8943 * MFUnlockDXGIDeviceManager (mfplat.@)
8945 HRESULT WINAPI
MFUnlockDXGIDeviceManager(void)
8949 EnterCriticalSection(&shared_dm_cs
);
8951 if (shared_dm
.manager
)
8953 IMFDXGIDeviceManager_Release(shared_dm
.manager
);
8954 if (!--shared_dm
.locks
)
8956 shared_dm
.manager
= NULL
;
8957 shared_dm
.token
= 0;
8961 LeaveCriticalSection(&shared_dm_cs
);
8968 * MFllMulDiv implementation is derived from gstreamer utility functions code (gstutils.c),
8969 * released under LGPL2. Full authors list follows.
8970 * ===================================================================================
8971 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
8972 * 2000 Wim Taymans <wtay@chello.be>
8973 * 2002 Thomas Vander Stichele <thomas@apestaart.org>
8974 * 2004 Wim Taymans <wim@fluendo.com>
8975 * 2015 Jan Schmidt <jan@centricular.com>
8976 * ===================================================================================
8979 static void llmult128(ULARGE_INTEGER
*c1
, ULARGE_INTEGER
*c0
, LONGLONG val
, LONGLONG num
)
8981 ULARGE_INTEGER a1
, b0
, v
, n
;
8983 v
.QuadPart
= llabs(val
);
8984 n
.QuadPart
= llabs(num
);
8986 /* do 128 bits multiply
8994 * -------------------
8997 * "a0" is optimized away, result is stored directly in c0. "b1" is
8998 * optimized away, result is stored directly in c1.
9000 c0
->QuadPart
= (ULONGLONG
)v
.LowPart
* n
.LowPart
;
9001 a1
.QuadPart
= (ULONGLONG
)v
.LowPart
* n
.HighPart
;
9002 b0
.QuadPart
= (ULONGLONG
)v
.HighPart
* n
.LowPart
;
9004 /* add the high word of a0 to the low words of a1 and b0 using c1 as
9005 * scratch space to capture the carry. the low word of the result becomes
9006 * the final high word of c0 */
9007 c1
->QuadPart
= (ULONGLONG
)c0
->HighPart
+ a1
.LowPart
+ b0
.LowPart
;
9008 c0
->HighPart
= c1
->LowPart
;
9010 /* add the carry from the result above (found in the high word of c1) and
9011 * the high words of a1 and b0 to b1, the result is c1. */
9012 c1
->QuadPart
= (ULONGLONG
)v
.HighPart
* n
.HighPart
+ c1
->HighPart
+ a1
.HighPart
+ b0
.HighPart
;
9015 static ULONGLONG
lldiv128(ULARGE_INTEGER c1
, ULARGE_INTEGER c0
, LONGLONG denom
)
9017 ULARGE_INTEGER q1
, q0
, rhat
;
9018 ULARGE_INTEGER v
, cmp1
, cmp2
;
9021 v
.QuadPart
= llabs(denom
);
9023 /* 64bit numerator */
9024 if (c1
.QuadPart
== 0)
9025 return c0
.QuadPart
/ v
.QuadPart
;
9027 /* 96bit numerator, 32bit denominator */
9028 if (v
.HighPart
== 0 && c1
.HighPart
== 0)
9030 ULONGLONG low
= c0
.LowPart
, high
= c0
.HighPart
+ ((ULONGLONG
)c1
.LowPart
<< 32);
9031 low
+= (high
% v
.LowPart
) << 32;
9032 return ((high
/ v
.LowPart
) << 32) + (low
/ v
.LowPart
);
9035 /* 128bit numerator, 32bit denominator */
9036 if (v
.HighPart
== 0)
9039 /* count number of leading zeroes */
9040 BitScanReverse(&s
, v
.HighPart
);
9045 /* normalize divisor and dividend */
9047 c1
.QuadPart
= (c1
.QuadPart
<< s
) | (c0
.HighPart
>> (32 - s
));
9051 q1
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9052 rhat
.QuadPart
= c1
.QuadPart
- q1
.QuadPart
* v
.HighPart
;
9054 cmp1
.HighPart
= rhat
.LowPart
;
9055 cmp1
.LowPart
= c0
.HighPart
;
9056 cmp2
.QuadPart
= q1
.QuadPart
* v
.LowPart
;
9058 while (q1
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9061 rhat
.QuadPart
+= v
.HighPart
;
9064 cmp1
.HighPart
= rhat
.LowPart
;
9065 cmp2
.QuadPart
-= v
.LowPart
;
9067 c1
.HighPart
= c1
.LowPart
;
9068 c1
.LowPart
= c0
.HighPart
;
9069 c1
.QuadPart
-= q1
.QuadPart
* v
.QuadPart
;
9070 q0
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9071 rhat
.QuadPart
= c1
.QuadPart
- q0
.QuadPart
* v
.HighPart
;
9073 cmp1
.HighPart
= rhat
.LowPart
;
9074 cmp1
.LowPart
= c0
.LowPart
;
9075 cmp2
.QuadPart
= q0
.QuadPart
* v
.LowPart
;
9077 while (q0
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9080 rhat
.QuadPart
+= v
.HighPart
;
9083 cmp1
.HighPart
= rhat
.LowPart
;
9084 cmp2
.QuadPart
-= v
.LowPart
;
9086 q0
.HighPart
+= q1
.LowPart
;
9091 /***********************************************************************
9092 * MFllMulDiv (mfplat.@)
9094 LONGLONG WINAPI
MFllMulDiv(LONGLONG val
, LONGLONG num
, LONGLONG denom
, LONGLONG factor
)
9096 #define LLOVERFLOW (sign ? I64_MIN : I64_MAX)
9097 unsigned int sign
, factor_sign
, denom_sign
;
9098 ULARGE_INTEGER c1
, c0
;
9101 TRACE("%s, %s, %s, %s.\n", wine_dbgstr_longlong(val
), wine_dbgstr_longlong(num
),
9102 wine_dbgstr_longlong(denom
), wine_dbgstr_longlong(factor
));
9104 /* compute 128-bit numerator product */
9105 llmult128(&c1
, &c0
, val
, num
);
9107 sign
= (val
< 0) ^ (num
< 0);
9108 factor_sign
= factor
< 0;
9109 denom_sign
= denom
< 0;
9111 factor
= llabs(factor
);
9112 if (sign
== factor_sign
)
9114 if (UI64_MAX
- c0
.QuadPart
< factor
)
9116 if (c1
.QuadPart
== UI64_MAX
) return LLOVERFLOW
;
9119 c0
.QuadPart
+= factor
;
9123 if (c0
.QuadPart
>= factor
)
9124 c0
.QuadPart
-= factor
;
9132 c0
.QuadPart
= factor
- c0
.QuadPart
;
9136 if (c1
.QuadPart
>= denom
) return LLOVERFLOW
;
9138 /* compute quotient, fits in 64 bits */
9139 ret
= lldiv128(c1
, c0
, denom
);
9141 if (ret
>= I64_MAX
) return LLOVERFLOW
;
9142 return sign
? -(LONGLONG
)ret
: ret
;