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"
48 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
50 static HRESULT
heap_strdupW(const WCHAR
*str
, WCHAR
**dest
)
58 size
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
59 *dest
= heap_alloc(size
);
61 memcpy(*dest
, str
, size
);
83 IMFActivate
*activate
;
86 static CRITICAL_SECTION local_handlers_section
= { NULL
, -1, 0, 0, 0, 0 };
88 static struct list local_scheme_handlers
= LIST_INIT(local_scheme_handlers
);
89 static struct list local_bytestream_handlers
= LIST_INIT(local_bytestream_handlers
);
91 struct mft_registration
94 IClassFactory
*factory
;
99 MFT_REGISTER_TYPE_INFO
*input_types
;
100 UINT32 input_types_count
;
101 MFT_REGISTER_TYPE_INFO
*output_types
;
102 UINT32 output_types_count
;
106 static CRITICAL_SECTION local_mfts_section
= { NULL
, -1, 0, 0, 0, 0 };
108 static struct list local_mfts
= LIST_INIT(local_mfts
);
110 struct transform_activate
112 struct attributes attributes
;
113 IMFActivate IMFActivate_iface
;
114 IClassFactory
*factory
;
115 IMFTransform
*transform
;
120 IMFClock IMFClock_iface
;
124 struct system_time_source
126 IMFPresentationTimeSource IMFPresentationTimeSource_iface
;
127 IMFClockStateSink IMFClockStateSink_iface
;
131 LONGLONG start_offset
;
137 static void system_time_source_apply_rate(const struct system_time_source
*source
, LONGLONG
*value
)
140 *value
*= source
->i_rate
;
142 *value
*= source
->rate
;
145 static struct system_time_source
*impl_from_IMFPresentationTimeSource(IMFPresentationTimeSource
*iface
)
147 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFPresentationTimeSource_iface
);
150 static struct system_time_source
*impl_from_IMFClockStateSink(IMFClockStateSink
*iface
)
152 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFClockStateSink_iface
);
155 static struct system_clock
*impl_from_IMFClock(IMFClock
*iface
)
157 return CONTAINING_RECORD(iface
, struct system_clock
, IMFClock_iface
);
160 static struct transform_activate
*impl_from_IMFActivate(IMFActivate
*iface
)
162 return CONTAINING_RECORD(iface
, struct transform_activate
, IMFActivate_iface
);
165 static HRESULT WINAPI
transform_activate_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **out
)
167 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
169 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
170 IsEqualIID(riid
, &IID_IMFAttributes
) ||
171 IsEqualIID(riid
, &IID_IUnknown
))
174 IMFActivate_AddRef(iface
);
178 WARN("Unsupported %s.\n", debugstr_guid(riid
));
180 return E_NOINTERFACE
;
183 static ULONG WINAPI
transform_activate_AddRef(IMFActivate
*iface
)
185 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
186 ULONG refcount
= InterlockedIncrement(&activate
->attributes
.ref
);
188 TRACE("%p, refcount %u.\n", iface
, refcount
);
193 static ULONG WINAPI
transform_activate_Release(IMFActivate
*iface
)
195 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
196 ULONG refcount
= InterlockedDecrement(&activate
->attributes
.ref
);
198 TRACE("%p, refcount %u.\n", iface
, refcount
);
202 clear_attributes_object(&activate
->attributes
);
203 if (activate
->factory
)
204 IClassFactory_Release(activate
->factory
);
205 if (activate
->transform
)
206 IMFTransform_Release(activate
->transform
);
213 static HRESULT WINAPI
transform_activate_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
215 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
217 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
219 return attributes_GetItem(&activate
->attributes
, key
, value
);
222 static HRESULT WINAPI
transform_activate_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
224 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
226 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
228 return attributes_GetItemType(&activate
->attributes
, key
, type
);
231 static HRESULT WINAPI
transform_activate_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
,
234 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
236 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
238 return attributes_CompareItem(&activate
->attributes
, key
, value
, result
);
241 static HRESULT WINAPI
transform_activate_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
,
242 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
244 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
246 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
248 return attributes_Compare(&activate
->attributes
, theirs
, match_type
, ret
);
251 static HRESULT WINAPI
transform_activate_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
253 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
255 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
257 return attributes_GetUINT32(&activate
->attributes
, key
, value
);
260 static HRESULT WINAPI
transform_activate_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
262 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
264 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
266 return attributes_GetUINT64(&activate
->attributes
, key
, value
);
269 static HRESULT WINAPI
transform_activate_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
271 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
273 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
275 return attributes_GetDouble(&activate
->attributes
, key
, value
);
278 static HRESULT WINAPI
transform_activate_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
280 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
282 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
284 return attributes_GetGUID(&activate
->attributes
, key
, value
);
287 static HRESULT WINAPI
transform_activate_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
289 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
291 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
293 return attributes_GetStringLength(&activate
->attributes
, key
, length
);
296 static HRESULT WINAPI
transform_activate_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
297 UINT32 size
, UINT32
*length
)
299 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
301 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
303 return attributes_GetString(&activate
->attributes
, key
, value
, size
, length
);
306 static HRESULT WINAPI
transform_activate_GetAllocatedString(IMFActivate
*iface
, REFGUID key
, WCHAR
**value
,
309 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
311 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
313 return attributes_GetAllocatedString(&activate
->attributes
, key
, value
, length
);
316 static HRESULT WINAPI
transform_activate_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
318 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
320 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
322 return attributes_GetBlobSize(&activate
->attributes
, key
, size
);
325 static HRESULT WINAPI
transform_activate_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
,
328 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
330 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
332 return attributes_GetBlob(&activate
->attributes
, key
, buf
, bufsize
, blobsize
);
335 static HRESULT WINAPI
transform_activate_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
337 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
339 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
341 return attributes_GetAllocatedBlob(&activate
->attributes
, key
, buf
, size
);
344 static HRESULT WINAPI
transform_activate_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **out
)
346 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
348 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
350 return attributes_GetUnknown(&activate
->attributes
, key
, riid
, out
);
353 static HRESULT WINAPI
transform_activate_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
355 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
357 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
359 return attributes_SetItem(&activate
->attributes
, key
, value
);
362 static HRESULT WINAPI
transform_activate_DeleteItem(IMFActivate
*iface
, REFGUID key
)
364 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
366 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
368 return attributes_DeleteItem(&activate
->attributes
, key
);
371 static HRESULT WINAPI
transform_activate_DeleteAllItems(IMFActivate
*iface
)
373 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
375 TRACE("%p.\n", iface
);
377 return attributes_DeleteAllItems(&activate
->attributes
);
380 static HRESULT WINAPI
transform_activate_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
382 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
384 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
386 return attributes_SetUINT32(&activate
->attributes
, key
, value
);
389 static HRESULT WINAPI
transform_activate_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
391 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
393 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
395 return attributes_SetUINT64(&activate
->attributes
, key
, value
);
398 static HRESULT WINAPI
transform_activate_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
400 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
402 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
404 return attributes_SetDouble(&activate
->attributes
, key
, value
);
407 static HRESULT WINAPI
transform_activate_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
409 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
411 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
413 return attributes_SetGUID(&activate
->attributes
, key
, value
);
416 static HRESULT WINAPI
transform_activate_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
418 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
420 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
422 return attributes_SetString(&activate
->attributes
, key
, value
);
425 static HRESULT WINAPI
transform_activate_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
427 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
429 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
431 return attributes_SetBlob(&activate
->attributes
, key
, buf
, size
);
434 static HRESULT WINAPI
transform_activate_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
436 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
438 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
440 return attributes_SetUnknown(&activate
->attributes
, key
, unknown
);
443 static HRESULT WINAPI
transform_activate_LockStore(IMFActivate
*iface
)
445 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
447 TRACE("%p.\n", iface
);
449 return attributes_LockStore(&activate
->attributes
);
452 static HRESULT WINAPI
transform_activate_UnlockStore(IMFActivate
*iface
)
454 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
456 TRACE("%p.\n", iface
);
458 return attributes_UnlockStore(&activate
->attributes
);
461 static HRESULT WINAPI
transform_activate_GetCount(IMFActivate
*iface
, UINT32
*count
)
463 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
465 TRACE("%p, %p.\n", iface
, count
);
467 return attributes_GetCount(&activate
->attributes
, count
);
470 static HRESULT WINAPI
transform_activate_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
,
473 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
475 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
477 return attributes_GetItemByIndex(&activate
->attributes
, index
, key
, value
);
480 static HRESULT WINAPI
transform_activate_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
482 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
484 TRACE("%p, %p.\n", iface
, dest
);
486 return attributes_CopyAllItems(&activate
->attributes
, dest
);
489 static HRESULT WINAPI
transform_activate_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
491 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
495 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
497 EnterCriticalSection(&activate
->attributes
.cs
);
499 if (!activate
->transform
)
501 if (activate
->factory
)
503 if (FAILED(hr
= IClassFactory_CreateInstance(activate
->factory
, NULL
, &IID_IMFTransform
,
504 (void **)&activate
->transform
)))
506 hr
= MF_E_INVALIDREQUEST
;
511 if (SUCCEEDED(hr
= attributes_GetGUID(&activate
->attributes
, &MFT_TRANSFORM_CLSID_Attribute
, &clsid
)))
513 if (FAILED(hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
514 (void **)&activate
->transform
)))
516 hr
= MF_E_INVALIDREQUEST
;
522 if (activate
->transform
)
523 hr
= IMFTransform_QueryInterface(activate
->transform
, riid
, obj
);
525 LeaveCriticalSection(&activate
->attributes
.cs
);
530 static HRESULT WINAPI
transform_activate_ShutdownObject(IMFActivate
*iface
)
532 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
534 TRACE("%p.\n", iface
);
536 EnterCriticalSection(&activate
->attributes
.cs
);
538 if (activate
->transform
)
540 IMFTransform_Release(activate
->transform
);
541 activate
->transform
= NULL
;
544 LeaveCriticalSection(&activate
->attributes
.cs
);
549 static HRESULT WINAPI
transform_activate_DetachObject(IMFActivate
*iface
)
551 TRACE("%p.\n", iface
);
556 static const IMFActivateVtbl transform_activate_vtbl
=
558 transform_activate_QueryInterface
,
559 transform_activate_AddRef
,
560 transform_activate_Release
,
561 transform_activate_GetItem
,
562 transform_activate_GetItemType
,
563 transform_activate_CompareItem
,
564 transform_activate_Compare
,
565 transform_activate_GetUINT32
,
566 transform_activate_GetUINT64
,
567 transform_activate_GetDouble
,
568 transform_activate_GetGUID
,
569 transform_activate_GetStringLength
,
570 transform_activate_GetString
,
571 transform_activate_GetAllocatedString
,
572 transform_activate_GetBlobSize
,
573 transform_activate_GetBlob
,
574 transform_activate_GetAllocatedBlob
,
575 transform_activate_GetUnknown
,
576 transform_activate_SetItem
,
577 transform_activate_DeleteItem
,
578 transform_activate_DeleteAllItems
,
579 transform_activate_SetUINT32
,
580 transform_activate_SetUINT64
,
581 transform_activate_SetDouble
,
582 transform_activate_SetGUID
,
583 transform_activate_SetString
,
584 transform_activate_SetBlob
,
585 transform_activate_SetUnknown
,
586 transform_activate_LockStore
,
587 transform_activate_UnlockStore
,
588 transform_activate_GetCount
,
589 transform_activate_GetItemByIndex
,
590 transform_activate_CopyAllItems
,
591 transform_activate_ActivateObject
,
592 transform_activate_ShutdownObject
,
593 transform_activate_DetachObject
,
596 static HRESULT
create_transform_activate(IClassFactory
*factory
, IMFActivate
**activate
)
598 struct transform_activate
*object
;
601 object
= heap_alloc_zero(sizeof(*object
));
603 return E_OUTOFMEMORY
;
605 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
611 object
->IMFActivate_iface
.lpVtbl
= &transform_activate_vtbl
;
612 object
->factory
= factory
;
614 IClassFactory_AddRef(object
->factory
);
616 *activate
= &object
->IMFActivate_iface
;
621 HRESULT WINAPI
MFCreateTransformActivate(IMFActivate
**activate
)
623 TRACE("%p.\n", activate
);
625 return create_transform_activate(NULL
, activate
);
628 static const WCHAR transform_keyW
[] = L
"MediaFoundation\\Transforms";
629 static const WCHAR categories_keyW
[] = L
"MediaFoundation\\Transforms\\Categories";
631 static const BYTE guid_conv_table
[256] =
633 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
634 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
636 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
637 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
639 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
642 static WCHAR
* GUIDToString(WCHAR
*str
, REFGUID guid
)
644 swprintf(str
, 39, L
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
645 guid
->Data1
, guid
->Data2
, guid
->Data3
, guid
->Data4
[0], guid
->Data4
[1],
646 guid
->Data4
[2], guid
->Data4
[3], guid
->Data4
[4], guid
->Data4
[5],
647 guid
->Data4
[6], guid
->Data4
[7]);
652 static inline BOOL
is_valid_hex(WCHAR c
)
654 if (!(((c
>= '0') && (c
<= '9')) ||
655 ((c
>= 'a') && (c
<= 'f')) ||
656 ((c
>= 'A') && (c
<= 'F'))))
661 static BOOL
GUIDFromString(LPCWSTR s
, GUID
*id
)
665 /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
668 for (i
= 0; i
< 8; i
++)
670 if (!is_valid_hex(s
[i
])) return FALSE
;
671 id
->Data1
= (id
->Data1
<< 4) | guid_conv_table
[s
[i
]];
673 if (s
[8]!='-') return FALSE
;
676 for (i
= 9; i
< 13; i
++)
678 if (!is_valid_hex(s
[i
])) return FALSE
;
679 id
->Data2
= (id
->Data2
<< 4) | guid_conv_table
[s
[i
]];
681 if (s
[13]!='-') return FALSE
;
684 for (i
= 14; i
< 18; i
++)
686 if (!is_valid_hex(s
[i
])) return FALSE
;
687 id
->Data3
= (id
->Data3
<< 4) | guid_conv_table
[s
[i
]];
689 if (s
[18]!='-') return FALSE
;
691 for (i
= 19; i
< 36; i
+=2)
695 if (s
[i
]!='-') return FALSE
;
698 if (!is_valid_hex(s
[i
]) || !is_valid_hex(s
[i
+1])) return FALSE
;
699 id
->Data4
[(i
-19)/2] = guid_conv_table
[s
[i
]] << 4 | guid_conv_table
[s
[i
+1]];
702 if (!s
[36]) return TRUE
;
706 static HRESULT
register_transform(const CLSID
*clsid
, const WCHAR
*name
, UINT32 flags
,
707 UINT32 cinput
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
708 const MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
717 GUIDToString(buffer
, clsid
);
718 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s", transform_keyW
, buffer
);
720 if ((ret
= RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &hclsid
)))
721 hr
= HRESULT_FROM_WIN32(ret
);
725 size
= (lstrlenW(name
) + 1) * sizeof(WCHAR
);
726 if ((ret
= RegSetValueExW(hclsid
, NULL
, 0, REG_SZ
, (BYTE
*)name
, size
)))
727 hr
= HRESULT_FROM_WIN32(ret
);
730 if (SUCCEEDED(hr
) && cinput
&& input_types
)
732 size
= cinput
* sizeof(MFT_REGISTER_TYPE_INFO
);
733 if ((ret
= RegSetValueExW(hclsid
, L
"InputTypes", 0, REG_BINARY
, (BYTE
*)input_types
, size
)))
734 hr
= HRESULT_FROM_WIN32(ret
);
737 if (SUCCEEDED(hr
) && coutput
&& output_types
)
739 size
= coutput
* sizeof(MFT_REGISTER_TYPE_INFO
);
740 if ((ret
= RegSetValueExW(hclsid
, L
"OutputTypes", 0, REG_BINARY
, (BYTE
*)output_types
, size
)))
741 hr
= HRESULT_FROM_WIN32(ret
);
744 if (SUCCEEDED(hr
) && attributes
)
746 if (SUCCEEDED(hr
= MFGetAttributesAsBlobSize(attributes
, &size
)))
748 if ((blob
= heap_alloc(size
)))
750 if (SUCCEEDED(hr
= MFGetAttributesAsBlob(attributes
, blob
, size
)))
752 if ((ret
= RegSetValueExW(hclsid
, L
"Attributes", 0, REG_BINARY
, blob
, size
)))
753 hr
= HRESULT_FROM_WIN32(ret
);
762 if (SUCCEEDED(hr
) && flags
)
764 if ((ret
= RegSetValueExW(hclsid
, L
"MFTFlags", 0, REG_DWORD
, (BYTE
*)&flags
, sizeof(flags
))))
765 hr
= HRESULT_FROM_WIN32(ret
);
772 static HRESULT
register_category(CLSID
*clsid
, GUID
*category
)
775 WCHAR guid1
[64], guid2
[64];
778 GUIDToString(guid1
, category
);
779 GUIDToString(guid2
, clsid
);
781 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s\\%s", categories_keyW
, guid1
, guid2
);
783 if (RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &htmp1
))
790 /***********************************************************************
791 * MFTRegister (mfplat.@)
793 HRESULT WINAPI
MFTRegister(CLSID clsid
, GUID category
, LPWSTR name
, UINT32 flags
, UINT32 cinput
,
794 MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
795 MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
799 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p, %p.\n", debugstr_guid(&clsid
), debugstr_guid(&category
),
800 debugstr_w(name
), flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
802 hr
= register_transform(&clsid
, name
, flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
804 ERR("Failed to write register transform\n");
807 hr
= register_category(&clsid
, &category
);
812 static void release_mft_registration(struct mft_registration
*mft
)
815 IClassFactory_Release(mft
->factory
);
816 heap_free(mft
->name
);
817 heap_free(mft
->input_types
);
818 heap_free(mft
->output_types
);
822 static HRESULT
mft_register_local(IClassFactory
*factory
, REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
823 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
824 const MFT_REGISTER_TYPE_INFO
*output_types
)
826 struct mft_registration
*mft
, *cur
, *unreg_mft
= NULL
;
829 if (!factory
&& !clsid
)
831 WARN("Can't register without factory or CLSID.\n");
835 mft
= heap_alloc_zero(sizeof(*mft
));
837 return E_OUTOFMEMORY
;
839 mft
->factory
= factory
;
841 IClassFactory_AddRef(mft
->factory
);
844 mft
->category
= *category
;
845 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
846 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
849 if (FAILED(hr
= heap_strdupW(name
, &mft
->name
)))
852 if (input_count
&& input_types
)
854 mft
->input_types_count
= input_count
;
855 if (!(mft
->input_types
= heap_calloc(mft
->input_types_count
, sizeof(*input_types
))))
860 memcpy(mft
->input_types
, input_types
, mft
->input_types_count
* sizeof(*input_types
));
863 if (output_count
&& output_types
)
865 mft
->output_types_count
= output_count
;
866 if (!(mft
->output_types
= heap_calloc(mft
->output_types_count
, sizeof(*output_types
))))
871 memcpy(mft
->output_types
, output_types
, mft
->output_types_count
* sizeof(*output_types
));
874 EnterCriticalSection(&local_mfts_section
);
876 LIST_FOR_EACH_ENTRY(cur
, &local_mfts
, struct mft_registration
, entry
)
878 if (cur
->factory
== factory
)
881 list_remove(&cur
->entry
);
885 list_add_tail(&local_mfts
, &mft
->entry
);
887 LeaveCriticalSection(&local_mfts_section
);
890 release_mft_registration(unreg_mft
);
894 release_mft_registration(mft
);
899 HRESULT WINAPI
MFTRegisterLocal(IClassFactory
*factory
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
900 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
901 const MFT_REGISTER_TYPE_INFO
*output_types
)
903 TRACE("%p, %s, %s, %#x, %u, %p, %u, %p.\n", factory
, debugstr_guid(category
), debugstr_w(name
), flags
, input_count
,
904 input_types
, output_count
, output_types
);
906 return mft_register_local(factory
, NULL
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
909 HRESULT WINAPI
MFTRegisterLocalByCLSID(REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
910 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
911 const MFT_REGISTER_TYPE_INFO
*output_types
)
913 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p.\n", debugstr_guid(clsid
), debugstr_guid(category
), debugstr_w(name
), flags
,
914 input_count
, input_types
, output_count
, output_types
);
916 return mft_register_local(NULL
, clsid
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
919 static HRESULT
mft_unregister_local(IClassFactory
*factory
, REFCLSID clsid
)
921 struct mft_registration
*cur
, *cur2
;
922 BOOL unregister_all
= !factory
&& !clsid
;
927 EnterCriticalSection(&local_mfts_section
);
929 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &local_mfts
, struct mft_registration
, entry
)
933 if ((factory
&& cur
->factory
== factory
) || IsEqualCLSID(&cur
->clsid
, clsid
))
935 list_remove(&cur
->entry
);
936 list_add_tail(&unreg
, &cur
->entry
);
942 list_remove(&cur
->entry
);
943 list_add_tail(&unreg
, &cur
->entry
);
947 LeaveCriticalSection(&local_mfts_section
);
949 if (!unregister_all
&& list_empty(&unreg
))
950 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND
);
952 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &unreg
, struct mft_registration
, entry
)
954 list_remove(&cur
->entry
);
955 release_mft_registration(cur
);
961 HRESULT WINAPI
MFTUnregisterLocalByCLSID(CLSID clsid
)
963 TRACE("%s.\n", debugstr_guid(&clsid
));
965 return mft_unregister_local(NULL
, &clsid
);
968 HRESULT WINAPI
MFTUnregisterLocal(IClassFactory
*factory
)
970 TRACE("%p.\n", factory
);
972 return mft_unregister_local(factory
, NULL
);
975 MFTIME WINAPI
MFGetSystemTime(void)
979 GetSystemTimeAsFileTime( (FILETIME
*)&mf
);
984 static BOOL
mft_is_type_info_match(struct mft_registration
*mft
, const GUID
*category
, UINT32 flags
,
985 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
986 const MFT_REGISTER_TYPE_INFO
*output_type
)
988 BOOL matching
= TRUE
;
992 if (!IsEqualGUID(category
, &mft
->category
))
995 /* Default model is synchronous. */
996 model
= mft
->flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
);
998 model
= MFT_ENUM_FLAG_SYNCMFT
;
999 if (!(model
& flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1002 /* These flags should be explicitly enabled. */
1003 if (mft
->flags
& ~flags
& (MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_TRANSCODE_ONLY
))
1006 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
&& !mft
->factory
&& plugin_control
1007 && IMFPluginControl_IsDisabled(plugin_control
, MF_Plugin_Type_MFT
, &mft
->clsid
) == S_OK
)
1014 for (i
= 0, matching
= FALSE
; input_type
&& i
< mft
->input_types_count
; ++i
)
1016 if (!memcmp(&mft
->input_types
[i
], input_type
, sizeof(*input_type
)))
1024 if (output_type
&& matching
)
1026 for (i
= 0, matching
= FALSE
; i
< mft
->output_types_count
; ++i
)
1028 if (!memcmp(&mft
->output_types
[i
], output_type
, sizeof(*output_type
)))
1039 static void mft_get_reg_type_info(const WCHAR
*clsidW
, const WCHAR
*typeW
, MFT_REGISTER_TYPE_INFO
**type
,
1042 HKEY htransform
, hfilter
;
1043 DWORD reg_type
, size
;
1048 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1051 if (RegOpenKeyW(htransform
, clsidW
, &hfilter
))
1053 RegCloseKey(htransform
);
1057 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, NULL
, &size
))
1060 if (reg_type
!= REG_BINARY
)
1063 if (!size
|| size
% sizeof(**type
))
1066 if (!(*type
= heap_alloc(size
)))
1069 *count
= size
/ sizeof(**type
);
1071 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, (BYTE
*)*type
, &size
))
1079 RegCloseKey(hfilter
);
1080 RegCloseKey(htransform
);
1083 static void mft_get_reg_flags(const WCHAR
*clsidW
, const WCHAR
*nameW
, DWORD
*flags
)
1085 DWORD ret
, reg_type
, size
;
1090 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
))
1093 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1099 if (!RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, NULL
, &size
) && reg_type
== REG_DWORD
)
1100 RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, (BYTE
*)flags
, &size
);
1105 static HRESULT
mft_collect_machine_reg(struct list
*mfts
, const GUID
*category
, UINT32 flags
,
1106 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1107 const MFT_REGISTER_TYPE_INFO
*output_type
)
1109 struct mft_registration mft
, *cur
;
1110 HKEY hcategory
, hlist
;
1115 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1118 GUIDToString(clsidW
, category
);
1119 ret
= RegOpenKeyW(hcategory
, clsidW
, &hlist
);
1120 RegCloseKey(hcategory
);
1124 size
= ARRAY_SIZE(clsidW
);
1125 while (!RegEnumKeyExW(hlist
, index
, clsidW
, &size
, NULL
, NULL
, NULL
, NULL
))
1127 memset(&mft
, 0, sizeof(mft
));
1128 mft
.category
= *category
;
1129 if (!GUIDFromString(clsidW
, &mft
.clsid
))
1132 mft_get_reg_flags(clsidW
, L
"MFTFlags", &mft
.flags
);
1135 mft_get_reg_type_info(clsidW
, L
"OutputTypes", &mft
.output_types
, &mft
.output_types_count
);
1138 mft_get_reg_type_info(clsidW
, L
"InputTypes", &mft
.input_types
, &mft
.input_types_count
);
1140 if (!mft_is_type_info_match(&mft
, category
, flags
, plugin_control
, input_type
, output_type
))
1142 heap_free(mft
.input_types
);
1143 heap_free(mft
.output_types
);
1147 cur
= heap_alloc(sizeof(*cur
));
1148 /* Reuse allocated type arrays. */
1150 list_add_tail(mfts
, &cur
->entry
);
1153 size
= ARRAY_SIZE(clsidW
);
1160 static BOOL
mft_is_preferred(IMFPluginControl
*plugin_control
, const CLSID
*clsid
)
1166 while (SUCCEEDED(IMFPluginControl_GetPreferredClsidByIndex(plugin_control
, MF_Plugin_Type_MFT
, index
++, &selector
,
1169 CoTaskMemFree(selector
);
1171 if (IsEqualGUID(&preferred
, clsid
))
1178 static HRESULT
mft_enum(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1179 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1181 IMFPluginControl
*plugin_control
= NULL
;
1182 struct list mfts
, mfts_sorted
, *result
= &mfts
;
1183 struct mft_registration
*mft
, *mft2
;
1184 unsigned int obj_count
;
1191 flags
= MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_SORTANDFILTER
;
1193 /* Synchronous processing is default. */
1194 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1195 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
1197 if (FAILED(hr
= MFGetPluginControl(&plugin_control
)))
1199 WARN("Failed to get plugin control instance, hr %#x.\n", hr
);
1205 /* Collect from registry */
1206 mft_collect_machine_reg(&mfts
, &category
, flags
, plugin_control
, input_type
, output_type
);
1208 /* Collect locally registered ones. */
1209 if (flags
& MFT_ENUM_FLAG_LOCALMFT
)
1211 struct mft_registration
*local
;
1213 EnterCriticalSection(&local_mfts_section
);
1215 LIST_FOR_EACH_ENTRY(local
, &local_mfts
, struct mft_registration
, entry
)
1217 if (mft_is_type_info_match(local
, &category
, flags
, plugin_control
, input_type
, output_type
))
1219 mft
= heap_alloc_zero(sizeof(*mft
));
1221 mft
->clsid
= local
->clsid
;
1222 mft
->factory
= local
->factory
;
1224 IClassFactory_AddRef(mft
->factory
);
1225 mft
->flags
= local
->flags
;
1226 mft
->local
= local
->local
;
1228 list_add_tail(&mfts
, &mft
->entry
);
1232 LeaveCriticalSection(&local_mfts_section
);
1235 list_init(&mfts_sorted
);
1237 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
)
1239 /* Local registrations. */
1240 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1244 list_remove(&mft
->entry
);
1245 list_add_tail(&mfts_sorted
, &mft
->entry
);
1249 /* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */
1251 /* Preferred transforms. */
1252 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1254 if (!mft
->factory
&& mft_is_preferred(plugin_control
, &mft
->clsid
))
1256 list_remove(&mft
->entry
);
1257 list_add_tail(&mfts_sorted
, &mft
->entry
);
1261 /* Append the rest. */
1262 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1264 list_remove(&mft
->entry
);
1265 list_add_tail(&mfts_sorted
, &mft
->entry
);
1268 result
= &mfts_sorted
;
1271 IMFPluginControl_Release(plugin_control
);
1273 /* Create activation objects from CLSID/IClassFactory. */
1275 obj_count
= list_count(result
);
1279 if (!(*activate
= CoTaskMemAlloc(obj_count
* sizeof(**activate
))))
1284 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, result
, struct mft_registration
, entry
)
1286 IMFActivate
*mft_activate
;
1290 if (SUCCEEDED(create_transform_activate(mft
->factory
, &mft_activate
)))
1292 (*activate
)[obj_count
] = mft_activate
;
1296 IMFActivate_SetUINT32(mft_activate
, &MFT_PROCESS_LOCAL_Attribute
, 1);
1301 IMFActivate_SetString(mft_activate
, &MFT_FRIENDLY_NAME_Attribute
, mft
->name
);
1302 if (mft
->input_types
)
1303 IMFActivate_SetBlob(mft_activate
, &MFT_INPUT_TYPES_Attributes
, (const UINT8
*)mft
->input_types
,
1304 sizeof(*mft
->input_types
) * mft
->input_types_count
);
1305 if (mft
->output_types
)
1306 IMFActivate_SetBlob(mft_activate
, &MFT_OUTPUT_TYPES_Attributes
, (const UINT8
*)mft
->output_types
,
1307 sizeof(*mft
->output_types
) * mft
->output_types_count
);
1311 IMFActivate_SetGUID(mft_activate
, &MFT_TRANSFORM_CLSID_Attribute
, &mft
->clsid
);
1313 IMFActivate_SetUINT32(mft_activate
, &MF_TRANSFORM_FLAGS_Attribute
, mft
->flags
);
1314 IMFActivate_SetGUID(mft_activate
, &MF_TRANSFORM_CATEGORY_Attribute
, &mft
->category
);
1320 list_remove(&mft
->entry
);
1321 release_mft_registration(mft
);
1327 CoTaskMemFree(*activate
);
1335 /***********************************************************************
1336 * MFTEnum (mfplat.@)
1338 HRESULT WINAPI
MFTEnum(GUID category
, UINT32 flags
, MFT_REGISTER_TYPE_INFO
*input_type
,
1339 MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, CLSID
**clsids
, UINT32
*count
)
1341 struct mft_registration
*mft
, *mft2
;
1342 unsigned int mft_count
;
1346 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1349 if (!clsids
|| !count
)
1350 return E_INVALIDARG
;
1356 if (FAILED(hr
= mft_collect_machine_reg(&mfts
, &category
, MFT_ENUM_FLAG_SYNCMFT
, NULL
, input_type
, output_type
)))
1359 mft_count
= list_count(&mfts
);
1363 if (!(*clsids
= CoTaskMemAlloc(mft_count
* sizeof(**clsids
))))
1367 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1370 (*clsids
)[mft_count
++] = mft
->clsid
;
1371 list_remove(&mft
->entry
);
1372 release_mft_registration(mft
);
1378 CoTaskMemFree(*clsids
);
1386 /***********************************************************************
1387 * MFTEnumEx (mfplat.@)
1389 HRESULT WINAPI
MFTEnumEx(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1390 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFActivate
***activate
, UINT32
*count
)
1392 TRACE("%s, %#x, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, activate
, count
);
1394 return mft_enum(category
, flags
, input_type
, output_type
, NULL
, activate
, count
);
1397 /***********************************************************************
1398 * MFTEnum2 (mfplat.@)
1400 HRESULT WINAPI
MFTEnum2(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1401 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1403 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1407 FIXME("Ignoring attributes.\n");
1409 return mft_enum(category
, flags
, input_type
, output_type
, attributes
, activate
, count
);
1412 /***********************************************************************
1413 * MFTUnregister (mfplat.@)
1415 HRESULT WINAPI
MFTUnregister(CLSID clsid
)
1417 WCHAR buffer
[64], category
[MAX_PATH
];
1418 HKEY htransform
, hcategory
, htmp
;
1419 DWORD size
= MAX_PATH
;
1422 TRACE("(%s)\n", debugstr_guid(&clsid
));
1424 GUIDToString(buffer
, &clsid
);
1426 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1428 RegDeleteKeyW(htransform
, buffer
);
1429 RegCloseKey(htransform
);
1432 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1434 while (RegEnumKeyExW(hcategory
, index
, category
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1436 if (!RegOpenKeyW(hcategory
, category
, &htmp
))
1438 RegDeleteKeyW(htmp
, buffer
);
1444 RegCloseKey(hcategory
);
1450 /***********************************************************************
1451 * MFStartup (mfplat.@)
1453 HRESULT WINAPI
MFStartup(ULONG version
, DWORD flags
)
1455 #define MF_VERSION_XP MAKELONG( MF_API_VERSION, 1 )
1456 #define MF_VERSION_WIN7 MAKELONG( MF_API_VERSION, 2 )
1458 TRACE("%#x, %#x.\n", version
, flags
);
1460 if (version
!= MF_VERSION_XP
&& version
!= MF_VERSION_WIN7
)
1461 return MF_E_BAD_STARTUP_VERSION
;
1468 /***********************************************************************
1469 * MFShutdown (mfplat.@)
1471 HRESULT WINAPI
MFShutdown(void)
1480 /***********************************************************************
1481 * MFCopyImage (mfplat.@)
1483 HRESULT WINAPI
MFCopyImage(BYTE
*dest
, LONG deststride
, const BYTE
*src
, LONG srcstride
, DWORD width
, DWORD lines
)
1485 TRACE("%p, %d, %p, %d, %u, %u.\n", dest
, deststride
, src
, srcstride
, width
, lines
);
1489 memcpy(dest
, src
, width
);
1503 static int __cdecl
debug_compare_guid(const void *a
, const void *b
)
1505 const GUID
*guid
= a
;
1506 const struct guid_def
*guid_def
= b
;
1507 return memcmp(guid
, guid_def
->guid
, sizeof(*guid
));
1510 const char *debugstr_attr(const GUID
*guid
)
1512 static const struct guid_def guid_defs
[] =
1514 #define X(g) { &(g), #g }
1515 #define MF_READER_WRITER_D3D_MANAGER MF_SOURCE_READER_D3D_MANAGER
1516 X(MF_READWRITE_MMCSS_CLASS
),
1517 X(MF_TOPONODE_MARKIN_HERE
),
1518 X(MF_MT_H264_SUPPORTED_SYNC_FRAME_TYPES
),
1519 X(MF_TOPONODE_MARKOUT_HERE
),
1520 X(EVRConfig_ForceBob
),
1521 X(MF_TOPONODE_DECODER
),
1522 X(EVRConfig_AllowDropToBob
),
1523 X(MF_TOPOLOGY_PROJECTSTART
),
1524 X(EVRConfig_ForceThrottle
),
1525 X(MF_VIDEO_MAX_MB_PER_SEC
),
1526 X(MF_TOPOLOGY_PROJECTSTOP
),
1527 X(MF_SINK_WRITER_ENCODER_CONFIG
),
1528 X(EVRConfig_AllowDropToThrottle
),
1529 X(MF_TOPOLOGY_NO_MARKIN_MARKOUT
),
1530 X(EVRConfig_ForceHalfInterlace
),
1531 X(EVRConfig_AllowDropToHalfInterlace
),
1532 X(EVRConfig_ForceScaling
),
1533 X(MF_MT_H264_CAPABILITIES
),
1534 X(EVRConfig_AllowScaling
),
1535 X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS
),
1536 X(MFT_PREFERRED_ENCODER_PROFILE
),
1537 X(EVRConfig_ForceBatching
),
1538 X(EVRConfig_AllowBatching
),
1539 X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED
),
1540 X(MF_MT_VIDEO_PROFILE
),
1541 X(MF_MT_MPEG2_PROFILE
),
1542 X(MF_MT_DV_AAUX_CTRL_PACK_1
),
1543 X(MF_MT_ALPHA_MODE
),
1544 X(MF_MT_MPEG2_TIMECODE
),
1545 X(MF_PMP_SERVER_CONTEXT
),
1546 X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
),
1547 X(MF_MEDIA_ENGINE_TRACK_ID
),
1548 X(MF_MT_CUSTOM_VIDEO_PRIMARIES
),
1549 X(MF_MT_TIMESTAMP_CAN_BE_DTS
),
1550 X(MFT_CODEC_MERIT_Attribute
),
1551 X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS
),
1553 X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
),
1554 X(MF_MT_MPEG2_FLAGS
),
1555 X(MF_MEDIA_ENGINE_AUDIO_CATEGORY
),
1556 X(MF_MT_PIXEL_ASPECT_RATIO
),
1557 X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK
),
1558 X(MFT_CONNECTED_STREAM_ATTRIBUTE
),
1559 X(MF_MT_REALTIME_CONTENT
),
1560 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
),
1561 X(MF_MT_WRAPPED_TYPE
),
1563 X(MF_MT_AVG_BITRATE
),
1564 X(MF_MT_DECODER_USE_MAX_RESOLUTION
),
1565 X(MF_MT_MAX_LUMINANCE_LEVEL
),
1566 X(MFT_CONNECTED_TO_HW_STREAM
),
1568 X(MF_MT_MAX_KEYFRAME_SPACING
),
1569 X(MFT_TRANSFORM_CLSID_Attribute
),
1570 X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
),
1571 X(MF_MT_AM_FORMAT_TYPE
),
1572 X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME
),
1573 X(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
),
1574 X(MF_MT_H264_MAX_MB_PER_SEC
),
1575 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS
),
1576 X(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
1577 X(MF_PD_PMPHOST_CONTEXT
),
1578 X(MF_PD_APP_CONTEXT
),
1580 X(MF_PD_TOTAL_FILE_SIZE
),
1581 X(MF_PD_AUDIO_ENCODING_BITRATE
),
1582 X(MF_PD_VIDEO_ENCODING_BITRATE
),
1583 X(MFSampleExtension_TargetGlobalLuminance
),
1585 X(MF_MT_H264_SUPPORTED_SLICE_MODES
),
1586 X(MF_PD_LAST_MODIFIED_TIME
),
1587 X(MF_PD_PLAYBACK_ELEMENT_ID
),
1588 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
),
1589 X(MF_MT_ALL_SAMPLES_INDEPENDENT
),
1590 X(MF_PD_PREFERRED_LANGUAGE
),
1591 X(MF_PD_PLAYBACK_BOUNDARY_TIME
),
1592 X(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
),
1593 X(MF_ACTIVATE_MFT_LOCKED
),
1594 X(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
),
1595 X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
),
1596 X(MF_MT_FRAME_SIZE
),
1597 X(MF_MT_H264_SIMULCAST_SUPPORT
),
1598 X(MF_SINK_WRITER_ASYNC_CALLBACK
),
1599 X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH
),
1600 X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
),
1601 X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
),
1602 X(MF_MT_FRAME_RATE_RANGE_MAX
),
1604 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID
),
1605 X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS
),
1606 X(MF_SA_D3D11_USAGE
),
1607 X(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
),
1608 X(MF_MT_GEOMETRIC_APERTURE
),
1609 X(MF_MT_ORIGINAL_WAVE_FORMAT_TAG
),
1610 X(MF_MT_DV_AAUX_SRC_PACK_1
),
1611 X(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
),
1612 X(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
),
1613 X(MF_MEDIA_ENGINE_EXTENSION
),
1614 X(MF_MT_DEFAULT_STRIDE
),
1615 X(MF_MT_ARBITRARY_FORMAT
),
1616 X(MF_TRANSFORM_CATEGORY_Attribute
),
1617 X(MF_MT_MPEG2_HDCP
),
1618 X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
1619 X(MF_MT_SPATIAL_AUDIO_MAX_DYNAMIC_OBJECTS
),
1620 X(MF_MT_DECODER_MAX_DPB_COUNT
),
1621 X(MFSampleExtension_ForwardedDecodeUnits
),
1622 X(MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
1623 X(MF_MT_DV_AAUX_CTRL_PACK_0
),
1624 X(MF_MT_YUV_MATRIX
),
1625 X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED
),
1626 X(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY
),
1627 X(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL
),
1628 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID
),
1629 X(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
),
1630 X(MF_MT_VIDEO_ROTATION
),
1631 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK
),
1632 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
),
1634 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
),
1635 X(MF_MT_MIN_MASTERING_LUMINANCE
),
1636 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
),
1637 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
),
1638 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
),
1639 X(MF_EVENT_STREAM_METADATA_SYSTEMID
),
1640 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
),
1641 X(MF_MT_AUDIO_CHANNEL_MASK
),
1642 X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN
),
1643 X(MF_READWRITE_DISABLE_CONVERTERS
),
1644 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
),
1645 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
),
1646 X(MF_MT_MINIMUM_DISPLAY_APERTURE
),
1647 X(MFSampleExtension_Token
),
1648 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY
),
1649 X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
1650 X(MF_TRANSFORM_ASYNC_UNLOCK
),
1651 X(MF_DISABLE_FRAME_CORRUPTION_INFO
),
1652 X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
),
1653 X(MF_MT_VIDEO_NO_FRAME_ORDERING
),
1654 X(MF_MEDIA_ENGINE_PLAYBACK_VISUAL
),
1655 X(MF_MT_VIDEO_CHROMA_SITING
),
1656 X(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY
),
1657 X(MF_SA_BUFFERS_PER_SAMPLE
),
1658 X(MFSampleExtension_3DVideo_SampleFormat
),
1659 X(MF_MT_H264_RESOLUTION_SCALING
),
1660 X(MF_MT_VIDEO_LEVEL
),
1661 X(MF_MT_MPEG2_LEVEL
),
1662 X(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET
),
1663 X(MF_MT_SAMPLE_SIZE
),
1664 X(MF_MT_AAC_PAYLOAD_TYPE
),
1665 X(MF_TOPOLOGY_PLAYBACK_FRAMERATE
),
1666 X(MF_SOURCE_READER_D3D11_BIND_FLAGS
),
1667 X(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
1668 X(MF_MT_AUDIO_WMADRC_PEAKREF
),
1669 X(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
1670 X(MF_TRANSFORM_FLAGS_Attribute
),
1671 X(MF_MT_H264_SUPPORTED_RATE_CONTROL_MODES
),
1672 X(MF_PD_SAMI_STYLELIST
),
1673 X(MF_MT_AUDIO_WMADRC_AVGREF
),
1674 X(MF_MT_AUDIO_BITS_PER_SAMPLE
),
1676 X(MF_MT_AUDIO_WMADRC_AVGTARGET
),
1678 X(MF_SESSION_TOPOLOADER
),
1679 X(MF_SESSION_GLOBAL_TIME
),
1680 X(MF_SESSION_QUALITY_MANAGER
),
1681 X(MF_SESSION_CONTENT_PROTECTION_MANAGER
),
1682 X(MF_MT_MPEG4_SAMPLE_DESCRIPTION
),
1683 X(MF_MT_MPEG_START_TIME_CODE
),
1684 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1685 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1686 X(MF_READWRITE_MMCSS_PRIORITY_AUDIO
),
1687 X(MF_MT_H264_MAX_CODEC_CONFIG_DELAY
),
1688 X(MF_MT_DV_AAUX_SRC_PACK_0
),
1689 X(MF_BYTESTREAM_ORIGIN_NAME
),
1690 X(MF_BYTESTREAM_CONTENT_TYPE
),
1691 X(MF_MT_DEPTH_MEASUREMENT
),
1692 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
),
1693 X(MF_MT_VIDEO_3D_NUM_VIEWS
),
1694 X(MF_BYTESTREAM_DURATION
),
1695 X(MF_SD_SAMI_LANGUAGE
),
1696 X(MF_EVENT_OUTPUT_NODE
),
1697 X(MF_BYTESTREAM_LAST_MODIFIED_TIME
),
1698 X(MFT_ENUM_ADAPTER_LUID
),
1699 X(MF_MT_FRAME_RATE_RANGE_MIN
),
1700 X(MF_BYTESTREAM_IFO_FILE_URI
),
1701 X(MF_EVENT_TOPOLOGY_STATUS
),
1702 X(MF_BYTESTREAM_DLNA_PROFILE_ID
),
1703 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE
),
1704 X(MF_MT_MAJOR_TYPE
),
1705 X(MF_MT_IN_BAND_PARAMETER_SET
),
1706 X(MF_EVENT_SOURCE_CHARACTERISTICS
),
1707 X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD
),
1708 X(MF_SESSION_SERVER_CONTEXT
),
1709 X(MF_MT_VIDEO_3D_FIRST_IS_LEFT
),
1710 X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT
),
1711 X(MF_PD_ADAPTIVE_STREAMING
),
1712 X(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
),
1713 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
),
1714 X(MF_MT_H264_SUPPORTED_USAGES
),
1715 X(MFT_PREFERRED_OUTPUTTYPE_Attribute
),
1716 X(MFSampleExtension_Timestamp
),
1717 X(MF_TOPONODE_PRIMARYOUTPUT
),
1719 X(MF_TRANSFORM_ASYNC
),
1720 X(MF_TOPONODE_STREAMID
),
1721 X(MF_MEDIA_ENGINE_PLAYBACK_HWND
),
1722 X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
),
1723 X(MF_MT_VIDEO_LIGHTING
),
1724 X(MF_SD_MUTUALLY_EXCLUSIVE
),
1725 X(MF_SD_STREAM_NAME
),
1726 X(MF_MT_DV_VAUX_SRC_PACK
),
1727 X(MF_TOPONODE_RATELESS
),
1728 X(MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS
),
1729 X(MF_TOPONODE_DISABLE_PREROLL
),
1730 X(MF_SA_D3D11_ALLOW_DYNAMIC_YUV_TEXTURE
),
1731 X(MF_MT_VIDEO_3D_FORMAT
),
1732 X(MF_EVENT_STREAM_METADATA_KEYDATA
),
1733 X(MF_READER_WRITER_D3D_MANAGER
),
1734 X(MFSampleExtension_3DVideo
),
1735 X(MF_MT_H264_USAGE
),
1736 X(MF_MEDIA_ENGINE_EME_CALLBACK
),
1737 X(MF_EVENT_SOURCE_FAKE_START
),
1738 X(MF_EVENT_SOURCE_PROJECTSTART
),
1739 X(MF_EVENT_SOURCE_ACTUAL_START
),
1740 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
),
1741 X(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
1742 X(MFT_ENUM_HARDWARE_URL_Attribute
),
1743 X(MF_SOURCE_READER_ASYNC_CALLBACK
),
1744 X(MF_MT_OUTPUT_BUFFER_NUM
),
1745 X(MF_SA_D3D11_BINDFLAGS
),
1746 X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT
),
1747 X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE
),
1748 X(MFT_FRIENDLY_NAME_Attribute
),
1749 X(MF_MT_FIXED_SIZE_SAMPLES
),
1750 X(MFT_SUPPORT_3DVIDEO
),
1751 X(MFT_SUPPORT_3DVIDEO
),
1752 X(MFT_INPUT_TYPES_Attributes
),
1753 X(MF_MT_H264_LAYOUT_PER_STREAM
),
1754 X(MF_EVENT_SCRUBSAMPLE_TIME
),
1755 X(MF_MT_SPATIAL_AUDIO_MAX_METADATA_ITEMS
),
1756 X(MF_MT_MPEG2_ONE_FRAME_PER_PACKET
),
1757 X(MF_MT_INTERLACE_MODE
),
1758 X(MF_MEDIA_ENGINE_CALLBACK
),
1759 X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE
),
1760 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE
),
1761 X(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
1762 X(MF_MT_H264_SVC_CAPABILITIES
),
1763 X(MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
),
1764 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_LENGTH
),
1765 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_FORMAT_ID
),
1766 X(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
),
1767 X(MF_SA_D3D11_SHARED
),
1768 X(MF_MT_PAN_SCAN_ENABLED
),
1769 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
),
1770 X(MF_MT_DV_VAUX_CTRL_PACK
),
1771 X(MFSampleExtension_ForwardedDecodeUnitType
),
1772 X(MF_SA_D3D11_AWARE
),
1773 X(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
1774 X(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS
),
1775 X(MF_MT_SPATIAL_AUDIO_MIN_METADATA_ITEM_OFFSET_SPACING
),
1776 X(MF_TOPONODE_TRANSFORM_OBJECTID
),
1777 X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE
),
1778 X(MF_EVENT_MFT_INPUT_STREAM_ID
),
1779 X(MF_MT_SOURCE_CONTENT_HINT
),
1780 X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute
),
1781 X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE
),
1782 X(MF_READWRITE_MMCSS_PRIORITY
),
1784 X(MF_EVENT_START_PRESENTATION_TIME
),
1785 X(MF_EVENT_SESSIONCAPS
),
1786 X(MF_EVENT_PRESENTATION_TIME_OFFSET
),
1787 X(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
),
1788 X(MF_EVENT_SESSIONCAPS_DELTA
),
1789 X(MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT
),
1790 X(MFSampleExtension_DecodeTimestamp
),
1791 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE
),
1792 X(MF_MT_VIDEO_H264_NO_FMOASO
),
1793 X(MF_MT_AVG_BIT_ERROR_RATE
),
1794 X(MF_MT_VIDEO_PRIMARIES
),
1795 X(MF_SINK_WRITER_DISABLE_THROTTLING
),
1796 X(MF_MT_H264_RATE_CONTROL_MODES
),
1797 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
),
1798 X(MF_READWRITE_D3D_OPTIONAL
),
1799 X(MF_SA_D3D11_HW_PROTECTED
),
1800 X(MF_MEDIA_ENGINE_DXGI_MANAGER
),
1801 X(MF_READWRITE_MMCSS_CLASS_AUDIO
),
1802 X(MF_MEDIA_ENGINE_COREWINDOW
),
1803 X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS
),
1804 X(MF_MT_MPEG4_TRACK_TYPE
),
1805 X(MF_ACTIVATE_VIDEO_WINDOW
),
1806 X(MF_MT_PAN_SCAN_APERTURE
),
1807 X(MF_TOPOLOGY_RESOLUTION_STATUS
),
1808 X(MF_MT_ORIGINAL_4CC
),
1809 X(MF_PD_AUDIO_ISVARIABLEBITRATE
),
1810 X(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS
),
1811 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
),
1812 X(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID
),
1813 X(MF_MT_MPEG2_CONTENT_PACKET
),
1814 X(MFT_PROCESS_LOCAL_Attribute
),
1815 X(MFT_PROCESS_LOCAL_Attribute
),
1816 X(MF_MT_PAD_CONTROL_FLAGS
),
1817 X(MF_MT_VIDEO_NOMINAL_RANGE
),
1818 X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
1819 X(MF_MT_MPEG_SEQUENCE_HEADER
),
1820 X(MF_MEDIA_ENGINE_OPM_HWND
),
1821 X(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
1822 X(MF_MT_SPATIAL_AUDIO_DATA_PRESENT
),
1823 X(MF_MT_FRAME_RATE
),
1824 X(MF_TOPONODE_FLUSH
),
1825 X(MF_MT_MPEG2_STANDARD
),
1826 X(MF_TOPONODE_DRAIN
),
1827 X(MF_MT_TRANSFER_FUNCTION
),
1828 X(MF_TOPONODE_MEDIASTART
),
1829 X(MF_TOPONODE_MEDIASTOP
),
1830 X(MF_SOURCE_READER_MEDIASOURCE_CONFIG
),
1831 X(MF_TOPONODE_SOURCE
),
1832 X(MF_TOPONODE_PRESENTATION_DESCRIPTOR
),
1833 X(MF_TOPONODE_D3DAWARE
),
1834 X(MF_MT_COMPRESSED
),
1835 X(MF_TOPONODE_STREAM_DESCRIPTOR
),
1836 X(MF_TOPONODE_ERRORCODE
),
1837 X(MF_TOPONODE_SEQUENCE_ELEMENTID
),
1838 X(MF_EVENT_MFT_CONTEXT
),
1839 X(MF_MT_FORWARD_CUSTOM_SEI
),
1840 X(MF_TOPONODE_CONNECT_METHOD
),
1841 X(MFT_OUTPUT_TYPES_Attributes
),
1842 X(MF_MT_IMAGE_LOSS_TOLERANT
),
1843 X(MF_SESSION_REMOTE_SOURCE_MODE
),
1844 X(MF_MT_DEPTH_VALUE_UNIT
),
1845 X(MF_MT_AUDIO_NUM_CHANNELS
),
1846 X(MF_MT_ARBITRARY_HEADER
),
1847 X(MF_TOPOLOGY_DXVA_MODE
),
1848 X(MF_TOPONODE_LOCKED
),
1849 X(MF_TOPONODE_WORKQUEUE_ID
),
1850 X(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
),
1851 X(MF_TOPONODE_WORKQUEUE_MMCSS_CLASS
),
1852 X(MF_TOPONODE_DECRYPTOR
),
1853 X(MF_EVENT_DO_THINNING
),
1854 X(MF_TOPONODE_DISCARDABLE
),
1855 X(MF_TOPOLOGY_HARDWARE_MODE
),
1856 X(MF_SOURCE_READER_DISABLE_DXVA
),
1857 X(MF_MT_FORWARD_CUSTOM_NALU
),
1858 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
),
1859 X(MF_TOPONODE_ERROR_MAJORTYPE
),
1861 X(MFT_FIELDOFUSE_UNLOCK_Attribute
),
1862 X(MF_TOPONODE_ERROR_SUBTYPE
),
1863 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
),
1864 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
),
1865 X(MF_MT_VIDEO_3D_LEFT_IS_BASE
),
1866 X(MF_TOPONODE_WORKQUEUE_MMCSS_TASKID
),
1867 #undef MF_READER_WRITER_D3D_MANAGER
1870 struct guid_def
*ret
= NULL
;
1873 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
1875 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
1878 const char *debugstr_mf_guid(const GUID
*guid
)
1880 static const struct guid_def guid_defs
[] =
1882 #define X(g) { &(g), #g }
1883 X(MFAudioFormat_ADTS
),
1884 X(MFAudioFormat_PCM
),
1885 X(MFAudioFormat_PCM_HDCP
),
1886 X(MFAudioFormat_Float
),
1887 X(MFAudioFormat_DTS
),
1888 X(MFAudioFormat_DRM
),
1889 X(MFAudioFormat_MSP1
),
1890 X(MFAudioFormat_Vorbis
),
1891 X(MFAudioFormat_AAC
),
1892 X(MFVideoFormat_RGB24
),
1893 X(MFVideoFormat_ARGB32
),
1894 X(MFVideoFormat_RGB32
),
1895 X(MFVideoFormat_RGB565
),
1896 X(MFVideoFormat_RGB555
),
1897 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
),
1898 X(MFVideoFormat_A2R10G10B10
),
1899 X(MFMediaType_Script
),
1900 X(MFMediaType_Image
),
1901 X(MFMediaType_HTML
),
1902 X(MFMediaType_Binary
),
1903 X(MFVideoFormat_MPEG2
),
1904 X(MFMediaType_FileTransfer
),
1905 X(MFVideoFormat_RGB8
),
1906 X(MFAudioFormat_Dolby_AC3
),
1907 X(MFVideoFormat_L8
),
1908 X(MFAudioFormat_LPCM
),
1909 X(MFVideoFormat_420O
),
1910 X(MFVideoFormat_AI44
),
1911 X(MFVideoFormat_AV1
),
1912 X(MFVideoFormat_AYUV
),
1913 X(MFVideoFormat_H263
),
1914 X(MFVideoFormat_H264
),
1915 X(MFVideoFormat_H265
),
1916 X(MFVideoFormat_HEVC
),
1917 X(MFVideoFormat_HEVC_ES
),
1918 X(MFVideoFormat_I420
),
1919 X(MFVideoFormat_IYUV
),
1920 X(MFVideoFormat_M4S2
),
1921 X(MFVideoFormat_MJPG
),
1922 X(MFVideoFormat_MP43
),
1923 X(MFVideoFormat_MP4S
),
1924 X(MFVideoFormat_MP4V
),
1925 X(MFVideoFormat_MPG1
),
1926 X(MFVideoFormat_MSS1
),
1927 X(MFVideoFormat_MSS2
),
1928 X(MFVideoFormat_NV11
),
1929 X(MFVideoFormat_NV12
),
1930 X(MFVideoFormat_ORAW
),
1931 X(MFAudioFormat_Opus
),
1932 X(MFVideoFormat_D16
),
1933 X(MFAudioFormat_MPEG
),
1934 X(MFVideoFormat_P010
),
1935 X(MFVideoFormat_P016
),
1936 X(MFVideoFormat_P210
),
1937 X(MFVideoFormat_P216
),
1938 X(MFVideoFormat_L16
),
1939 X(MFAudioFormat_MP3
),
1940 X(MFVideoFormat_UYVY
),
1941 X(MFVideoFormat_VP10
),
1942 X(MFVideoFormat_VP80
),
1943 X(MFVideoFormat_VP90
),
1944 X(MFVideoFormat_WMV1
),
1945 X(MFVideoFormat_WMV2
),
1946 X(MFVideoFormat_WMV3
),
1947 X(MFVideoFormat_WVC1
),
1948 X(MFVideoFormat_Y210
),
1949 X(MFVideoFormat_Y216
),
1950 X(MFVideoFormat_Y410
),
1951 X(MFVideoFormat_Y416
),
1952 X(MFVideoFormat_Y41P
),
1953 X(MFVideoFormat_Y41T
),
1954 X(MFVideoFormat_Y42T
),
1955 X(MFVideoFormat_YUY2
),
1956 X(MFVideoFormat_YV12
),
1957 X(MFVideoFormat_YVU9
),
1958 X(MFVideoFormat_YVYU
),
1959 X(MFAudioFormat_WMAudioV8
),
1960 X(MFAudioFormat_ALAC
),
1961 X(MFAudioFormat_AMR_NB
),
1962 X(MFMediaType_Audio
),
1963 X(MFAudioFormat_WMAudioV9
),
1964 X(MFAudioFormat_AMR_WB
),
1965 X(MFAudioFormat_WMAudio_Lossless
),
1966 X(MFAudioFormat_AMR_WP
),
1967 X(MFAudioFormat_WMASPDIF
),
1968 X(MFVideoFormat_DV25
),
1969 X(MFVideoFormat_DV50
),
1970 X(MFVideoFormat_DVC
),
1971 X(MFVideoFormat_DVH1
),
1972 X(MFVideoFormat_DVHD
),
1973 X(MFVideoFormat_DVSD
),
1974 X(MFVideoFormat_DVSL
),
1975 X(MFVideoFormat_A16B16G16R16F
),
1976 X(MFVideoFormat_v210
),
1977 X(MFVideoFormat_v216
),
1978 X(MFVideoFormat_v410
),
1979 X(MFMediaType_Video
),
1980 X(MFAudioFormat_AAC_HDCP
),
1981 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
),
1982 X(MFAudioFormat_Dolby_AC3_HDCP
),
1983 X(MFMediaType_Subtitle
),
1984 X(MFMediaType_Stream
),
1985 X(MFAudioFormat_Dolby_AC3_SPDIF
),
1986 X(MFAudioFormat_Float_SpatialObjects
),
1987 X(MFMediaType_SAMI
),
1988 X(MFAudioFormat_ADTS_HDCP
),
1989 X(MFAudioFormat_FLAC
),
1990 X(MFAudioFormat_Dolby_DDPlus
),
1991 X(MFMediaType_MultiplexedFrames
),
1992 X(MFAudioFormat_Base_HDCP
),
1993 X(MFVideoFormat_Base_HDCP
),
1994 X(MFVideoFormat_H264_HDCP
),
1995 X(MFVideoFormat_HEVC_HDCP
),
1996 X(MFMediaType_Default
),
1997 X(MFMediaType_Protected
),
1998 X(MFVideoFormat_H264_ES
),
1999 X(MFMediaType_Perception
),
2002 struct guid_def
*ret
= NULL
;
2005 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2007 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2016 static int __cdecl
debug_event_id(const void *a
, const void *b
)
2018 const DWORD
*id
= a
;
2019 const struct event_id
*event_id
= b
;
2020 return *id
- event_id
->id
;
2023 static const char *debugstr_eventid(DWORD event
)
2025 static const struct event_id
2032 #define X(e) { e, #e }
2037 X(MESessionUnknown
),
2038 X(MESessionTopologySet
),
2039 X(MESessionTopologiesCleared
),
2040 X(MESessionStarted
),
2042 X(MESessionStopped
),
2045 X(MESessionRateChanged
),
2046 X(MESessionScrubSampleComplete
),
2047 X(MESessionCapabilitiesChanged
),
2048 X(MESessionTopologyStatus
),
2049 X(MESessionNotifyPresentationTime
),
2050 X(MENewPresentation
),
2051 X(MELicenseAcquisitionStart
),
2052 X(MELicenseAcquisitionCompleted
),
2053 X(MEIndividualizationStart
),
2054 X(MEIndividualizationCompleted
),
2055 X(MEEnablerProgress
),
2056 X(MEEnablerCompleted
),
2059 X(MEBufferingStarted
),
2060 X(MEBufferingStopped
),
2063 X(MEReconnectStart
),
2066 X(MESessionStreamSinkFormatChanged
),
2078 X(MEEndOfPresentation
),
2082 X(MEStreamThinMode
),
2083 X(MEStreamFormatChanged
),
2084 X(MESourceRateChanged
),
2085 X(MEEndOfPresentationSegment
),
2086 X(MESourceCharacteristicsChanged
),
2087 X(MESourceRateChangeRequested
),
2088 X(MESourceMetadataChanged
),
2089 X(MESequencerSourceTopologyUpdated
),
2091 X(MEStreamSinkStarted
),
2092 X(MEStreamSinkStopped
),
2093 X(MEStreamSinkPaused
),
2094 X(MEStreamSinkRateChanged
),
2095 X(MEStreamSinkRequestSample
),
2096 X(MEStreamSinkMarker
),
2097 X(MEStreamSinkPrerolled
),
2098 X(MEStreamSinkScrubSampleComplete
),
2099 X(MEStreamSinkFormatChanged
),
2100 X(MEStreamSinkDeviceChanged
),
2102 X(MESinkInvalidated
),
2103 X(MEAudioSessionNameChanged
),
2104 X(MEAudioSessionVolumeChanged
),
2105 X(MEAudioSessionDeviceRemoved
),
2106 X(MEAudioSessionServerShutdown
),
2107 X(MEAudioSessionGroupingParamChanged
),
2108 X(MEAudioSessionIconChanged
),
2109 X(MEAudioSessionFormatChanged
),
2110 X(MEAudioSessionDisconnected
),
2111 X(MEAudioSessionExclusiveModeOverride
),
2114 X(MEContentProtectionMessage
),
2116 X(MEWMDRMLicenseBackupCompleted
),
2117 X(MEWMDRMLicenseBackupProgress
),
2118 X(MEWMDRMLicenseRestoreCompleted
),
2119 X(MEWMDRMLicenseRestoreProgress
),
2120 X(MEWMDRMLicenseAcquisitionCompleted
),
2121 X(MEWMDRMIndividualizationCompleted
),
2122 X(MEWMDRMIndividualizationProgress
),
2123 X(MEWMDRMProximityCompleted
),
2124 X(MEWMDRMLicenseStoreCleaned
),
2125 X(MEWMDRMRevocationDownloadCompleted
),
2126 X(METransformUnknown
),
2127 X(METransformNeedInput
),
2128 X(METransformHaveOutput
),
2129 X(METransformDrainComplete
),
2130 X(METransformMarker
),
2131 X(METransformInputStreamStateChanged
),
2132 X(MEByteStreamCharacteristicsChanged
),
2133 X(MEVideoCaptureDeviceRemoved
),
2134 X(MEVideoCaptureDevicePreempted
),
2135 X(MEStreamSinkFormatInvalidated
),
2136 X(MEEncodingParameters
),
2137 X(MEContentProtectionMetadata
),
2138 X(MEDeviceThermalStateChanged
),
2142 struct event_id
*ret
= bsearch(&event
, event_ids
, ARRAY_SIZE(event_ids
), sizeof(*event_ids
), debug_event_id
);
2143 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbg_sprintf("%u", event
);
2146 static inline struct attributes
*impl_from_IMFAttributes(IMFAttributes
*iface
)
2148 return CONTAINING_RECORD(iface
, struct attributes
, IMFAttributes_iface
);
2151 static HRESULT WINAPI
mfattributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
2153 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2155 if (IsEqualIID(riid
, &IID_IMFAttributes
) ||
2156 IsEqualGUID(riid
, &IID_IUnknown
))
2159 IMFAttributes_AddRef(iface
);
2163 WARN("Unsupported %s.\n", debugstr_guid(riid
));
2165 return E_NOINTERFACE
;
2168 static ULONG WINAPI
mfattributes_AddRef(IMFAttributes
*iface
)
2170 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2171 ULONG refcount
= InterlockedIncrement(&attributes
->ref
);
2173 TRACE("%p, refcount %d.\n", iface
, refcount
);
2178 static ULONG WINAPI
mfattributes_Release(IMFAttributes
*iface
)
2180 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2181 ULONG refcount
= InterlockedDecrement(&attributes
->ref
);
2183 TRACE("%p, refcount %d.\n", iface
, refcount
);
2187 clear_attributes_object(attributes
);
2188 heap_free(attributes
);
2194 static struct attribute
*attributes_find_item(struct attributes
*attributes
, REFGUID key
, size_t *index
)
2198 for (i
= 0; i
< attributes
->count
; ++i
)
2200 if (IsEqualGUID(key
, &attributes
->attributes
[i
].key
))
2204 return &attributes
->attributes
[i
];
2211 static HRESULT
attributes_get_item(struct attributes
*attributes
, const GUID
*key
, PROPVARIANT
*value
)
2213 struct attribute
*attribute
;
2216 EnterCriticalSection(&attributes
->cs
);
2218 attribute
= attributes_find_item(attributes
, key
, NULL
);
2221 if (attribute
->value
.vt
== value
->vt
&& !(value
->vt
== VT_UNKNOWN
&& !attribute
->value
.punkVal
))
2222 hr
= PropVariantCopy(value
, &attribute
->value
);
2224 hr
= MF_E_INVALIDTYPE
;
2227 hr
= MF_E_ATTRIBUTENOTFOUND
;
2229 LeaveCriticalSection(&attributes
->cs
);
2234 HRESULT
attributes_GetItem(struct attributes
*attributes
, REFGUID key
, PROPVARIANT
*value
)
2236 struct attribute
*attribute
;
2239 EnterCriticalSection(&attributes
->cs
);
2241 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2242 hr
= value
? PropVariantCopy(value
, &attribute
->value
) : S_OK
;
2244 hr
= MF_E_ATTRIBUTENOTFOUND
;
2246 LeaveCriticalSection(&attributes
->cs
);
2251 HRESULT
attributes_GetItemType(struct attributes
*attributes
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2253 struct attribute
*attribute
;
2256 EnterCriticalSection(&attributes
->cs
);
2258 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2260 *type
= attribute
->value
.vt
;
2263 hr
= MF_E_ATTRIBUTENOTFOUND
;
2265 LeaveCriticalSection(&attributes
->cs
);
2270 HRESULT
attributes_CompareItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2272 struct attribute
*attribute
;
2276 EnterCriticalSection(&attributes
->cs
);
2278 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2280 *result
= attribute
->value
.vt
== value
->vt
&&
2281 !PropVariantCompareEx(&attribute
->value
, value
, PVCU_DEFAULT
, PVCF_DEFAULT
);
2284 LeaveCriticalSection(&attributes
->cs
);
2289 HRESULT
attributes_Compare(struct attributes
*attributes
, IMFAttributes
*theirs
,
2290 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2292 IMFAttributes
*smaller
, *other
;
2293 MF_ATTRIBUTE_TYPE type
;
2299 if (FAILED(hr
= IMFAttributes_GetCount(theirs
, &count
)))
2302 EnterCriticalSection(&attributes
->cs
);
2308 case MF_ATTRIBUTES_MATCH_OUR_ITEMS
:
2309 for (i
= 0; i
< attributes
->count
; ++i
)
2311 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2312 &attributes
->attributes
[i
].value
, &result
)))
2318 case MF_ATTRIBUTES_MATCH_THEIR_ITEMS
:
2319 hr
= IMFAttributes_Compare(theirs
, &attributes
->IMFAttributes_iface
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2321 case MF_ATTRIBUTES_MATCH_ALL_ITEMS
:
2322 if (count
!= attributes
->count
)
2327 for (i
= 0; i
< count
; ++i
)
2329 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2330 &attributes
->attributes
[i
].value
, &result
)))
2336 case MF_ATTRIBUTES_MATCH_INTERSECTION
:
2337 for (i
= 0; i
< attributes
->count
; ++i
)
2339 if (FAILED(IMFAttributes_GetItemType(theirs
, &attributes
->attributes
[i
].key
, &type
)))
2342 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2343 &attributes
->attributes
[i
].value
, &result
)))
2350 case MF_ATTRIBUTES_MATCH_SMALLER
:
2351 smaller
= attributes
->count
> count
? theirs
: &attributes
->IMFAttributes_iface
;
2352 other
= attributes
->count
> count
? &attributes
->IMFAttributes_iface
: theirs
;
2353 hr
= IMFAttributes_Compare(smaller
, other
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2356 WARN("Unknown match type %d.\n", match_type
);
2360 LeaveCriticalSection(&attributes
->cs
);
2368 HRESULT
attributes_GetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32
*value
)
2370 PROPVARIANT attrval
;
2373 PropVariantInit(&attrval
);
2374 attrval
.vt
= VT_UI4
;
2375 hr
= attributes_get_item(attributes
, key
, &attrval
);
2377 *value
= attrval
.ulVal
;
2382 HRESULT
attributes_GetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64
*value
)
2384 PROPVARIANT attrval
;
2387 PropVariantInit(&attrval
);
2388 attrval
.vt
= VT_UI8
;
2389 hr
= attributes_get_item(attributes
, key
, &attrval
);
2391 *value
= attrval
.uhVal
.QuadPart
;
2396 HRESULT
attributes_GetDouble(struct attributes
*attributes
, REFGUID key
, double *value
)
2398 PROPVARIANT attrval
;
2401 PropVariantInit(&attrval
);
2403 hr
= attributes_get_item(attributes
, key
, &attrval
);
2405 *value
= attrval
.dblVal
;
2410 HRESULT
attributes_GetGUID(struct attributes
*attributes
, REFGUID key
, GUID
*value
)
2412 struct attribute
*attribute
;
2415 EnterCriticalSection(&attributes
->cs
);
2417 attribute
= attributes_find_item(attributes
, key
, NULL
);
2420 if (attribute
->value
.vt
== MF_ATTRIBUTE_GUID
)
2421 *value
= *attribute
->value
.puuid
;
2423 hr
= MF_E_INVALIDTYPE
;
2426 hr
= MF_E_ATTRIBUTENOTFOUND
;
2428 LeaveCriticalSection(&attributes
->cs
);
2433 HRESULT
attributes_GetStringLength(struct attributes
*attributes
, REFGUID key
, UINT32
*length
)
2435 struct attribute
*attribute
;
2438 EnterCriticalSection(&attributes
->cs
);
2440 attribute
= attributes_find_item(attributes
, key
, NULL
);
2443 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2444 *length
= lstrlenW(attribute
->value
.pwszVal
);
2446 hr
= MF_E_INVALIDTYPE
;
2449 hr
= MF_E_ATTRIBUTENOTFOUND
;
2451 LeaveCriticalSection(&attributes
->cs
);
2456 HRESULT
attributes_GetString(struct attributes
*attributes
, REFGUID key
, WCHAR
*value
,
2457 UINT32 size
, UINT32
*length
)
2459 struct attribute
*attribute
;
2462 EnterCriticalSection(&attributes
->cs
);
2464 attribute
= attributes_find_item(attributes
, key
, NULL
);
2467 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2469 int len
= lstrlenW(attribute
->value
.pwszVal
);
2475 hr
= STRSAFE_E_INSUFFICIENT_BUFFER
;
2477 memcpy(value
, attribute
->value
.pwszVal
, (len
+ 1) * sizeof(WCHAR
));
2480 hr
= MF_E_INVALIDTYPE
;
2483 hr
= MF_E_ATTRIBUTENOTFOUND
;
2485 LeaveCriticalSection(&attributes
->cs
);
2490 HRESULT
attributes_GetAllocatedString(struct attributes
*attributes
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2492 PROPVARIANT attrval
;
2495 PropVariantInit(&attrval
);
2496 attrval
.vt
= VT_LPWSTR
;
2497 hr
= attributes_get_item(attributes
, key
, &attrval
);
2500 *value
= attrval
.pwszVal
;
2501 *length
= lstrlenW(*value
);
2507 HRESULT
attributes_GetBlobSize(struct attributes
*attributes
, REFGUID key
, UINT32
*size
)
2509 struct attribute
*attribute
;
2512 EnterCriticalSection(&attributes
->cs
);
2514 attribute
= attributes_find_item(attributes
, key
, NULL
);
2517 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2518 *size
= attribute
->value
.caub
.cElems
;
2520 hr
= MF_E_INVALIDTYPE
;
2523 hr
= MF_E_ATTRIBUTENOTFOUND
;
2525 LeaveCriticalSection(&attributes
->cs
);
2530 HRESULT
attributes_GetBlob(struct attributes
*attributes
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
, UINT32
*blobsize
)
2532 struct attribute
*attribute
;
2535 EnterCriticalSection(&attributes
->cs
);
2537 attribute
= attributes_find_item(attributes
, key
, NULL
);
2540 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2542 UINT32 size
= attribute
->value
.caub
.cElems
;
2544 if (bufsize
>= size
)
2545 hr
= PropVariantToBuffer(&attribute
->value
, buf
, size
);
2547 hr
= E_NOT_SUFFICIENT_BUFFER
;
2553 hr
= MF_E_INVALIDTYPE
;
2556 hr
= MF_E_ATTRIBUTENOTFOUND
;
2558 LeaveCriticalSection(&attributes
->cs
);
2563 HRESULT
attributes_GetAllocatedBlob(struct attributes
*attributes
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2565 PROPVARIANT attrval
;
2568 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2569 hr
= attributes_get_item(attributes
, key
, &attrval
);
2572 *buf
= attrval
.caub
.pElems
;
2573 *size
= attrval
.caub
.cElems
;
2579 HRESULT
attributes_GetUnknown(struct attributes
*attributes
, REFGUID key
, REFIID riid
, void **out
)
2581 PROPVARIANT attrval
;
2584 PropVariantInit(&attrval
);
2585 attrval
.vt
= VT_UNKNOWN
;
2586 hr
= attributes_get_item(attributes
, key
, &attrval
);
2588 hr
= IUnknown_QueryInterface(attrval
.punkVal
, riid
, out
);
2589 PropVariantClear(&attrval
);
2593 static HRESULT
attributes_set_item(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2595 struct attribute
*attribute
;
2597 EnterCriticalSection(&attributes
->cs
);
2599 attribute
= attributes_find_item(attributes
, key
, NULL
);
2602 if (!mf_array_reserve((void **)&attributes
->attributes
, &attributes
->capacity
, attributes
->count
+ 1,
2603 sizeof(*attributes
->attributes
)))
2605 LeaveCriticalSection(&attributes
->cs
);
2606 return E_OUTOFMEMORY
;
2608 attributes
->attributes
[attributes
->count
].key
= *key
;
2609 attribute
= &attributes
->attributes
[attributes
->count
++];
2612 PropVariantClear(&attribute
->value
);
2614 PropVariantCopy(&attribute
->value
, value
);
2616 LeaveCriticalSection(&attributes
->cs
);
2621 HRESULT
attributes_SetItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2627 case MF_ATTRIBUTE_UINT32
:
2628 case MF_ATTRIBUTE_UINT64
:
2629 case MF_ATTRIBUTE_DOUBLE
:
2630 case MF_ATTRIBUTE_GUID
:
2631 case MF_ATTRIBUTE_STRING
:
2632 case MF_ATTRIBUTE_BLOB
:
2633 case MF_ATTRIBUTE_IUNKNOWN
:
2634 return attributes_set_item(attributes
, key
, value
);
2636 PropVariantInit(&empty
);
2637 attributes_set_item(attributes
, key
, &empty
);
2638 return MF_E_INVALIDTYPE
;
2642 HRESULT
attributes_DeleteItem(struct attributes
*attributes
, REFGUID key
)
2644 struct attribute
*attribute
;
2647 EnterCriticalSection(&attributes
->cs
);
2649 if ((attribute
= attributes_find_item(attributes
, key
, &index
)))
2653 PropVariantClear(&attribute
->value
);
2655 attributes
->count
--;
2656 count
= attributes
->count
- index
;
2658 memmove(&attributes
->attributes
[index
], &attributes
->attributes
[index
+ 1], count
* sizeof(*attributes
->attributes
));
2661 LeaveCriticalSection(&attributes
->cs
);
2666 HRESULT
attributes_DeleteAllItems(struct attributes
*attributes
)
2668 EnterCriticalSection(&attributes
->cs
);
2670 while (attributes
->count
)
2672 PropVariantClear(&attributes
->attributes
[--attributes
->count
].value
);
2674 heap_free(attributes
->attributes
);
2675 attributes
->attributes
= NULL
;
2676 attributes
->capacity
= 0;
2678 LeaveCriticalSection(&attributes
->cs
);
2683 HRESULT
attributes_SetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32 value
)
2685 PROPVARIANT attrval
;
2687 attrval
.vt
= VT_UI4
;
2688 attrval
.ulVal
= value
;
2689 return attributes_set_item(attributes
, key
, &attrval
);
2692 HRESULT
attributes_SetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64 value
)
2694 PROPVARIANT attrval
;
2696 attrval
.vt
= VT_UI8
;
2697 attrval
.uhVal
.QuadPart
= value
;
2698 return attributes_set_item(attributes
, key
, &attrval
);
2701 HRESULT
attributes_SetDouble(struct attributes
*attributes
, REFGUID key
, double value
)
2703 PROPVARIANT attrval
;
2706 attrval
.dblVal
= value
;
2707 return attributes_set_item(attributes
, key
, &attrval
);
2710 HRESULT
attributes_SetGUID(struct attributes
*attributes
, REFGUID key
, REFGUID value
)
2712 PROPVARIANT attrval
;
2714 attrval
.vt
= VT_CLSID
;
2715 attrval
.puuid
= (CLSID
*)value
;
2716 return attributes_set_item(attributes
, key
, &attrval
);
2719 HRESULT
attributes_SetString(struct attributes
*attributes
, REFGUID key
, const WCHAR
*value
)
2721 PROPVARIANT attrval
;
2723 attrval
.vt
= VT_LPWSTR
;
2724 attrval
.pwszVal
= (WCHAR
*)value
;
2725 return attributes_set_item(attributes
, key
, &attrval
);
2728 HRESULT
attributes_SetBlob(struct attributes
*attributes
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
2730 PROPVARIANT attrval
;
2732 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2733 attrval
.caub
.cElems
= size
;
2734 attrval
.caub
.pElems
= (UINT8
*)buf
;
2735 return attributes_set_item(attributes
, key
, &attrval
);
2738 HRESULT
attributes_SetUnknown(struct attributes
*attributes
, REFGUID key
, IUnknown
*unknown
)
2740 PROPVARIANT attrval
;
2742 attrval
.vt
= VT_UNKNOWN
;
2743 attrval
.punkVal
= unknown
;
2744 return attributes_set_item(attributes
, key
, &attrval
);
2747 HRESULT
attributes_LockStore(struct attributes
*attributes
)
2749 EnterCriticalSection(&attributes
->cs
);
2754 HRESULT
attributes_UnlockStore(struct attributes
*attributes
)
2756 LeaveCriticalSection(&attributes
->cs
);
2761 HRESULT
attributes_GetCount(struct attributes
*attributes
, UINT32
*count
)
2763 EnterCriticalSection(&attributes
->cs
);
2764 *count
= attributes
->count
;
2765 LeaveCriticalSection(&attributes
->cs
);
2770 HRESULT
attributes_GetItemByIndex(struct attributes
*attributes
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
2774 EnterCriticalSection(&attributes
->cs
);
2776 if (index
< attributes
->count
)
2778 *key
= attributes
->attributes
[index
].key
;
2780 PropVariantCopy(value
, &attributes
->attributes
[index
].value
);
2785 LeaveCriticalSection(&attributes
->cs
);
2790 HRESULT
attributes_CopyAllItems(struct attributes
*attributes
, IMFAttributes
*dest
)
2795 EnterCriticalSection(&attributes
->cs
);
2797 IMFAttributes_LockStore(dest
);
2799 IMFAttributes_DeleteAllItems(dest
);
2801 for (i
= 0; i
< attributes
->count
; ++i
)
2803 hr
= IMFAttributes_SetItem(dest
, &attributes
->attributes
[i
].key
, &attributes
->attributes
[i
].value
);
2808 IMFAttributes_UnlockStore(dest
);
2810 LeaveCriticalSection(&attributes
->cs
);
2815 static HRESULT WINAPI
mfattributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
2817 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2819 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2821 return attributes_GetItem(attributes
, key
, value
);
2824 static HRESULT WINAPI
mfattributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2826 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2828 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
2830 return attributes_GetItemType(attributes
, key
, type
);
2833 static HRESULT WINAPI
mfattributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2835 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2837 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
2839 return attributes_CompareItem(attributes
, key
, value
, result
);
2842 static HRESULT WINAPI
mfattributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
2843 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2845 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2847 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
2849 return attributes_Compare(attributes
, theirs
, match_type
, ret
);
2852 static HRESULT WINAPI
mfattributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
2854 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2856 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2858 return attributes_GetUINT32(attributes
, key
, value
);
2861 static HRESULT WINAPI
mfattributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
2863 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2865 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2867 return attributes_GetUINT64(attributes
, key
, value
);
2870 static HRESULT WINAPI
mfattributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
2872 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2874 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2876 return attributes_GetDouble(attributes
, key
, value
);
2879 static HRESULT WINAPI
mfattributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
2881 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2883 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2885 return attributes_GetGUID(attributes
, key
, value
);
2888 static HRESULT WINAPI
mfattributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
2890 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2892 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
2894 return attributes_GetStringLength(attributes
, key
, length
);
2897 static HRESULT WINAPI
mfattributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
2898 UINT32 size
, UINT32
*length
)
2900 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2902 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
2904 return attributes_GetString(attributes
, key
, value
, size
, length
);
2907 static HRESULT WINAPI
mfattributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2909 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2911 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
2913 return attributes_GetAllocatedString(attributes
, key
, value
, length
);
2916 static HRESULT WINAPI
mfattributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
2918 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2920 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
2922 return attributes_GetBlobSize(attributes
, key
, size
);
2925 static HRESULT WINAPI
mfattributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
2926 UINT32 bufsize
, UINT32
*blobsize
)
2928 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2930 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
2932 return attributes_GetBlob(attributes
, key
, buf
, bufsize
, blobsize
);
2935 static HRESULT WINAPI
mfattributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2937 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2939 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
2941 return attributes_GetAllocatedBlob(attributes
, key
, buf
, size
);
2944 static HRESULT WINAPI
mfattributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
2946 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2948 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
2950 return attributes_GetUnknown(attributes
, key
, riid
, out
);
2953 static HRESULT WINAPI
mfattributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
2955 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2957 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
2959 return attributes_SetItem(attributes
, key
, value
);
2962 static HRESULT WINAPI
mfattributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
2964 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2966 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
2968 return attributes_DeleteItem(attributes
, key
);
2971 static HRESULT WINAPI
mfattributes_DeleteAllItems(IMFAttributes
*iface
)
2973 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2975 TRACE("%p.\n", iface
);
2977 return attributes_DeleteAllItems(attributes
);
2980 static HRESULT WINAPI
mfattributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
2982 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2984 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
2986 return attributes_SetUINT32(attributes
, key
, value
);
2989 static HRESULT WINAPI
mfattributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
2991 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2993 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
2995 return attributes_SetUINT64(attributes
, key
, value
);
2998 static HRESULT WINAPI
mfattributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
3000 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3002 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
3004 return attributes_SetDouble(attributes
, key
, value
);
3007 static HRESULT WINAPI
mfattributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
3009 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3011 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
3013 return attributes_SetGUID(attributes
, key
, value
);
3016 static HRESULT WINAPI
mfattributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
3018 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3020 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
3022 return attributes_SetString(attributes
, key
, value
);
3025 static HRESULT WINAPI
mfattributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
3027 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3029 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
3031 return attributes_SetBlob(attributes
, key
, buf
, size
);
3034 static HRESULT WINAPI
mfattributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
3036 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3038 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
3040 return attributes_SetUnknown(attributes
, key
, unknown
);
3043 static HRESULT WINAPI
mfattributes_LockStore(IMFAttributes
*iface
)
3045 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3047 TRACE("%p.\n", iface
);
3049 return attributes_LockStore(attributes
);
3052 static HRESULT WINAPI
mfattributes_UnlockStore(IMFAttributes
*iface
)
3054 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3056 TRACE("%p.\n", iface
);
3058 return attributes_UnlockStore(attributes
);
3061 static HRESULT WINAPI
mfattributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
3063 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3065 TRACE("%p, %p.\n", iface
, count
);
3067 return attributes_GetCount(attributes
, count
);
3070 static HRESULT WINAPI
mfattributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
3072 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3074 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
3076 return attributes_GetItemByIndex(attributes
, index
, key
, value
);
3079 static HRESULT WINAPI
mfattributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
3081 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3083 TRACE("%p, %p.\n", iface
, dest
);
3085 return attributes_CopyAllItems(attributes
, dest
);
3088 static const IMFAttributesVtbl mfattributes_vtbl
=
3090 mfattributes_QueryInterface
,
3091 mfattributes_AddRef
,
3092 mfattributes_Release
,
3093 mfattributes_GetItem
,
3094 mfattributes_GetItemType
,
3095 mfattributes_CompareItem
,
3096 mfattributes_Compare
,
3097 mfattributes_GetUINT32
,
3098 mfattributes_GetUINT64
,
3099 mfattributes_GetDouble
,
3100 mfattributes_GetGUID
,
3101 mfattributes_GetStringLength
,
3102 mfattributes_GetString
,
3103 mfattributes_GetAllocatedString
,
3104 mfattributes_GetBlobSize
,
3105 mfattributes_GetBlob
,
3106 mfattributes_GetAllocatedBlob
,
3107 mfattributes_GetUnknown
,
3108 mfattributes_SetItem
,
3109 mfattributes_DeleteItem
,
3110 mfattributes_DeleteAllItems
,
3111 mfattributes_SetUINT32
,
3112 mfattributes_SetUINT64
,
3113 mfattributes_SetDouble
,
3114 mfattributes_SetGUID
,
3115 mfattributes_SetString
,
3116 mfattributes_SetBlob
,
3117 mfattributes_SetUnknown
,
3118 mfattributes_LockStore
,
3119 mfattributes_UnlockStore
,
3120 mfattributes_GetCount
,
3121 mfattributes_GetItemByIndex
,
3122 mfattributes_CopyAllItems
3125 HRESULT
init_attributes_object(struct attributes
*object
, UINT32 size
)
3127 object
->IMFAttributes_iface
.lpVtbl
= &mfattributes_vtbl
;
3129 InitializeCriticalSection(&object
->cs
);
3131 object
->attributes
= NULL
;
3133 object
->capacity
= 0;
3134 if (!mf_array_reserve((void **)&object
->attributes
, &object
->capacity
, size
,
3135 sizeof(*object
->attributes
)))
3137 DeleteCriticalSection(&object
->cs
);
3138 return E_OUTOFMEMORY
;
3144 void clear_attributes_object(struct attributes
*object
)
3148 for (i
= 0; i
< object
->count
; i
++)
3149 PropVariantClear(&object
->attributes
[i
].value
);
3150 heap_free(object
->attributes
);
3152 DeleteCriticalSection(&object
->cs
);
3155 /***********************************************************************
3156 * MFCreateAttributes (mfplat.@)
3158 HRESULT WINAPI
MFCreateAttributes(IMFAttributes
**attributes
, UINT32 size
)
3160 struct attributes
*object
;
3163 TRACE("%p, %d\n", attributes
, size
);
3165 object
= heap_alloc_zero(sizeof(*object
));
3167 return E_OUTOFMEMORY
;
3169 if (FAILED(hr
= init_attributes_object(object
, size
)))
3174 *attributes
= &object
->IMFAttributes_iface
;
3179 #define ATTRIBUTES_STORE_MAGIC 0x494d4641 /* IMFA */
3181 struct attributes_store_header
3187 struct attributes_store_item
3204 /***********************************************************************
3205 * MFGetAttributesAsBlobSize (mfplat.@)
3207 HRESULT WINAPI
MFGetAttributesAsBlobSize(IMFAttributes
*attributes
, UINT32
*size
)
3209 unsigned int i
, count
, length
;
3213 TRACE("%p, %p.\n", attributes
, size
);
3215 IMFAttributes_LockStore(attributes
);
3217 hr
= IMFAttributes_GetCount(attributes
, &count
);
3219 *size
= sizeof(struct attributes_store_header
);
3221 for (i
= 0; i
< count
; ++i
)
3223 MF_ATTRIBUTE_TYPE type
;
3225 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &key
, NULL
);
3229 *size
+= sizeof(struct attributes_store_item
);
3231 IMFAttributes_GetItemType(attributes
, &key
, &type
);
3235 case MF_ATTRIBUTE_GUID
:
3236 *size
+= sizeof(GUID
);
3238 case MF_ATTRIBUTE_STRING
:
3239 IMFAttributes_GetStringLength(attributes
, &key
, &length
);
3240 *size
+= (length
+ 1) * sizeof(WCHAR
);
3242 case MF_ATTRIBUTE_BLOB
:
3243 IMFAttributes_GetBlobSize(attributes
, &key
, &length
);
3246 case MF_ATTRIBUTE_UINT32
:
3247 case MF_ATTRIBUTE_UINT64
:
3248 case MF_ATTRIBUTE_DOUBLE
:
3249 case MF_ATTRIBUTE_IUNKNOWN
:
3255 IMFAttributes_UnlockStore(attributes
);
3260 struct attr_serialize_context
3267 static void attributes_serialize_write(struct attr_serialize_context
*context
, const void *value
, unsigned int size
)
3269 memcpy(context
->ptr
, value
, size
);
3270 context
->ptr
+= size
;
3273 static BOOL
attributes_serialize_write_item(struct attr_serialize_context
*context
, struct attributes_store_item
*item
,
3278 case MF_ATTRIBUTE_UINT32
:
3279 case MF_ATTRIBUTE_UINT64
:
3280 case MF_ATTRIBUTE_DOUBLE
:
3281 attributes_serialize_write(context
, item
, sizeof(*item
));
3283 case MF_ATTRIBUTE_GUID
:
3284 case MF_ATTRIBUTE_STRING
:
3285 case MF_ATTRIBUTE_BLOB
:
3286 item
->u
.subheader
.offset
= context
->size
- item
->u
.subheader
.size
;
3287 attributes_serialize_write(context
, item
, sizeof(*item
));
3288 memcpy(context
->buffer
+ item
->u
.subheader
.offset
, value
, item
->u
.subheader
.size
);
3289 context
->size
-= item
->u
.subheader
.size
;
3298 /***********************************************************************
3299 * MFGetAttributesAsBlob (mfplat.@)
3301 HRESULT WINAPI
MFGetAttributesAsBlob(IMFAttributes
*attributes
, UINT8
*buffer
, UINT size
)
3303 struct attributes_store_header header
;
3304 struct attr_serialize_context context
;
3305 unsigned int required_size
, i
;
3310 TRACE("%p, %p, %u.\n", attributes
, buffer
, size
);
3312 if (FAILED(hr
= MFGetAttributesAsBlobSize(attributes
, &required_size
)))
3315 if (required_size
> size
)
3316 return MF_E_BUFFERTOOSMALL
;
3318 context
.buffer
= buffer
;
3319 context
.ptr
= buffer
;
3320 context
.size
= required_size
;
3322 IMFAttributes_LockStore(attributes
);
3324 header
.magic
= ATTRIBUTES_STORE_MAGIC
;
3325 header
.count
= 0; /* Will be updated later */
3326 IMFAttributes_GetCount(attributes
, &count
);
3328 attributes_serialize_write(&context
, &header
, sizeof(header
));
3330 for (i
= 0; i
< count
; ++i
)
3332 struct attributes_store_item item
;
3333 const void *data
= NULL
;
3335 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &item
.key
, &value
);
3339 item
.type
= value
.vt
;
3343 case MF_ATTRIBUTE_UINT32
:
3344 case MF_ATTRIBUTE_UINT64
:
3345 item
.u
.i64
= value
.uhVal
.QuadPart
;
3347 case MF_ATTRIBUTE_DOUBLE
:
3348 item
.u
.f
= value
.dblVal
;
3350 case MF_ATTRIBUTE_GUID
:
3351 item
.u
.subheader
.size
= sizeof(*value
.puuid
);
3354 case MF_ATTRIBUTE_STRING
:
3355 item
.u
.subheader
.size
= (lstrlenW(value
.pwszVal
) + 1) * sizeof(WCHAR
);
3356 data
= value
.pwszVal
;
3358 case MF_ATTRIBUTE_BLOB
:
3359 item
.u
.subheader
.size
= value
.caub
.cElems
;
3360 data
= value
.caub
.pElems
;
3362 case MF_ATTRIBUTE_IUNKNOWN
:
3365 WARN("Unknown attribute type %#x.\n", value
.vt
);
3368 if (attributes_serialize_write_item(&context
, &item
, data
))
3371 PropVariantClear(&value
);
3374 memcpy(context
.buffer
, &header
, sizeof(header
));
3376 IMFAttributes_UnlockStore(attributes
);
3381 static HRESULT
attributes_deserialize_read(struct attr_serialize_context
*context
, void *value
, unsigned int size
)
3383 if (context
->size
< (context
->ptr
- context
->buffer
) + size
)
3384 return E_INVALIDARG
;
3386 memcpy(value
, context
->ptr
, size
);
3387 context
->ptr
+= size
;
3392 /***********************************************************************
3393 * MFInitAttributesFromBlob (mfplat.@)
3395 HRESULT WINAPI
MFInitAttributesFromBlob(IMFAttributes
*dest
, const UINT8
*buffer
, UINT size
)
3397 struct attr_serialize_context context
;
3398 struct attributes_store_header header
;
3399 struct attributes_store_item item
;
3400 IMFAttributes
*attributes
;
3404 TRACE("%p, %p, %u.\n", dest
, buffer
, size
);
3406 context
.buffer
= (UINT8
*)buffer
;
3407 context
.ptr
= (UINT8
*)buffer
;
3408 context
.size
= size
;
3410 /* Validate buffer structure. */
3411 if (FAILED(hr
= attributes_deserialize_read(&context
, &header
, sizeof(header
))))
3414 if (header
.magic
!= ATTRIBUTES_STORE_MAGIC
)
3415 return E_UNEXPECTED
;
3417 if (FAILED(hr
= MFCreateAttributes(&attributes
, header
.count
)))
3420 for (i
= 0; i
< header
.count
; ++i
)
3422 if (FAILED(hr
= attributes_deserialize_read(&context
, &item
, sizeof(item
))))
3429 case MF_ATTRIBUTE_UINT32
:
3430 hr
= IMFAttributes_SetUINT32(attributes
, &item
.key
, item
.u
.i32
);
3432 case MF_ATTRIBUTE_UINT64
:
3433 hr
= IMFAttributes_SetUINT64(attributes
, &item
.key
, item
.u
.i64
);
3435 case MF_ATTRIBUTE_DOUBLE
:
3436 hr
= IMFAttributes_SetDouble(attributes
, &item
.key
, item
.u
.f
);
3438 case MF_ATTRIBUTE_GUID
:
3439 if (item
.u
.subheader
.size
== sizeof(GUID
) &&
3440 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3442 hr
= IMFAttributes_SetGUID(attributes
, &item
.key
,
3443 (const GUID
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3446 case MF_ATTRIBUTE_STRING
:
3447 if (item
.u
.subheader
.size
>= sizeof(WCHAR
) &&
3448 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3450 hr
= IMFAttributes_SetString(attributes
, &item
.key
,
3451 (const WCHAR
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3454 case MF_ATTRIBUTE_BLOB
:
3455 if (item
.u
.subheader
.size
> 0 && item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3457 hr
= IMFAttributes_SetBlob(attributes
, &item
.key
, context
.buffer
+ item
.u
.subheader
.offset
,
3458 item
.u
.subheader
.size
);
3471 IMFAttributes_DeleteAllItems(dest
);
3472 hr
= IMFAttributes_CopyAllItems(attributes
, dest
);
3475 IMFAttributes_Release(attributes
);
3480 typedef struct bytestream
3482 struct attributes attributes
;
3483 IMFByteStream IMFByteStream_iface
;
3484 IMFGetService IMFGetService_iface
;
3485 IRtwqAsyncCallback read_callback
;
3486 IRtwqAsyncCallback write_callback
;
3491 struct list pending
;
3492 CRITICAL_SECTION cs
;
3495 static inline mfbytestream
*impl_from_IMFByteStream(IMFByteStream
*iface
)
3497 return CONTAINING_RECORD(iface
, mfbytestream
, IMFByteStream_iface
);
3500 static struct bytestream
*impl_bytestream_from_IMFGetService(IMFGetService
*iface
)
3502 return CONTAINING_RECORD(iface
, struct bytestream
, IMFGetService_iface
);
3505 static struct bytestream
*impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3507 return CONTAINING_RECORD(iface
, struct bytestream
, read_callback
);
3510 static struct bytestream
*impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3512 return CONTAINING_RECORD(iface
, struct bytestream
, write_callback
);
3515 enum async_stream_op_type
3517 ASYNC_STREAM_OP_READ
,
3518 ASYNC_STREAM_OP_WRITE
,
3521 struct async_stream_op
3523 IUnknown IUnknown_iface
;
3531 ULONG requested_length
;
3532 ULONG actual_length
;
3533 IMFAsyncResult
*caller
;
3535 enum async_stream_op_type type
;
3538 static struct async_stream_op
*impl_async_stream_op_from_IUnknown(IUnknown
*iface
)
3540 return CONTAINING_RECORD(iface
, struct async_stream_op
, IUnknown_iface
);
3543 static HRESULT WINAPI
async_stream_op_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
3545 if (IsEqualIID(riid
, &IID_IUnknown
))
3548 IUnknown_AddRef(iface
);
3552 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3554 return E_NOINTERFACE
;
3557 static ULONG WINAPI
async_stream_op_AddRef(IUnknown
*iface
)
3559 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3560 ULONG refcount
= InterlockedIncrement(&op
->refcount
);
3562 TRACE("%p, refcount %d.\n", iface
, refcount
);
3567 static ULONG WINAPI
async_stream_op_Release(IUnknown
*iface
)
3569 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3570 ULONG refcount
= InterlockedDecrement(&op
->refcount
);
3572 TRACE("%p, refcount %d.\n", iface
, refcount
);
3577 IMFAsyncResult_Release(op
->caller
);
3584 static const IUnknownVtbl async_stream_op_vtbl
=
3586 async_stream_op_QueryInterface
,
3587 async_stream_op_AddRef
,
3588 async_stream_op_Release
,
3591 static HRESULT
bytestream_create_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3592 const BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
, IUnknown
*state
)
3594 struct async_stream_op
*op
;
3595 IRtwqAsyncResult
*request
;
3598 op
= heap_alloc(sizeof(*op
));
3600 return E_OUTOFMEMORY
;
3602 op
->IUnknown_iface
.lpVtbl
= &async_stream_op_vtbl
;
3605 op
->position
= stream
->position
;
3606 op
->requested_length
= size
;
3608 if (FAILED(hr
= RtwqCreateAsyncResult((IUnknown
*)&stream
->IMFByteStream_iface
, (IRtwqAsyncCallback
*)callback
, state
,
3609 (IRtwqAsyncResult
**)&op
->caller
)))
3614 if (FAILED(hr
= RtwqCreateAsyncResult(&op
->IUnknown_iface
, type
== ASYNC_STREAM_OP_READ
? &stream
->read_callback
:
3615 &stream
->write_callback
, NULL
, &request
)))
3618 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, request
);
3619 IRtwqAsyncResult_Release(request
);
3622 IUnknown_Release(&op
->IUnknown_iface
);
3626 static HRESULT
bytestream_complete_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3627 IMFAsyncResult
*result
, ULONG
*actual_length
)
3629 struct async_stream_op
*op
= NULL
, *cur
;
3632 EnterCriticalSection(&stream
->cs
);
3633 LIST_FOR_EACH_ENTRY(cur
, &stream
->pending
, struct async_stream_op
, entry
)
3635 if (cur
->caller
== result
&& cur
->type
== type
)
3638 list_remove(&cur
->entry
);
3642 LeaveCriticalSection(&stream
->cs
);
3645 return E_INVALIDARG
;
3647 if (SUCCEEDED(hr
= IMFAsyncResult_GetStatus(result
)))
3648 *actual_length
= op
->actual_length
;
3650 IUnknown_Release(&op
->IUnknown_iface
);
3655 static HRESULT WINAPI
bytestream_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
3657 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
3658 IsEqualIID(riid
, &IID_IUnknown
))
3661 IRtwqAsyncCallback_AddRef(iface
);
3665 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3667 return E_NOINTERFACE
;
3670 static ULONG WINAPI
bytestream_read_callback_AddRef(IRtwqAsyncCallback
*iface
)
3672 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3673 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3676 static ULONG WINAPI
bytestream_read_callback_Release(IRtwqAsyncCallback
*iface
)
3678 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3679 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3682 static HRESULT WINAPI
bytestream_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
3687 static ULONG WINAPI
bytestream_write_callback_AddRef(IRtwqAsyncCallback
*iface
)
3689 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3690 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3693 static ULONG WINAPI
bytestream_write_callback_Release(IRtwqAsyncCallback
*iface
)
3695 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3696 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3699 static HRESULT WINAPI
bytestream_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
3701 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3703 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
3705 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
3706 IsEqualIID(riid
, &IID_IUnknown
))
3708 *out
= &stream
->IMFByteStream_iface
;
3710 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
3712 *out
= &stream
->attributes
.IMFAttributes_iface
;
3714 else if (stream
->IMFGetService_iface
.lpVtbl
&& IsEqualIID(riid
, &IID_IMFGetService
))
3716 *out
= &stream
->IMFGetService_iface
;
3720 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3722 return E_NOINTERFACE
;
3725 IUnknown_AddRef((IUnknown
*)*out
);
3729 static ULONG WINAPI
bytestream_AddRef(IMFByteStream
*iface
)
3731 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3732 ULONG refcount
= InterlockedIncrement(&stream
->attributes
.ref
);
3734 TRACE("%p, refcount %d.\n", iface
, refcount
);
3739 static ULONG WINAPI
bytestream_Release(IMFByteStream
*iface
)
3741 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3742 ULONG refcount
= InterlockedDecrement(&stream
->attributes
.ref
);
3743 struct async_stream_op
*cur
, *cur2
;
3745 TRACE("%p, refcount %d.\n", iface
, refcount
);
3749 clear_attributes_object(&stream
->attributes
);
3750 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &stream
->pending
, struct async_stream_op
, entry
)
3752 list_remove(&cur
->entry
);
3753 IUnknown_Release(&cur
->IUnknown_iface
);
3755 DeleteCriticalSection(&stream
->cs
);
3757 IStream_Release(stream
->stream
);
3759 CloseHandle(stream
->hfile
);
3766 static HRESULT WINAPI
bytestream_stream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3768 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3772 TRACE("%p, %p.\n", iface
, capabilities
);
3774 if (FAILED(hr
= IStream_Stat(stream
->stream
, &stat
, STATFLAG_NONAME
)))
3777 *capabilities
= MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_SEEKABLE
;
3778 if (stat
.grfMode
& (STGM_WRITE
| STGM_READWRITE
))
3779 *capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
3784 static HRESULT WINAPI
bytestream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3786 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3788 TRACE("%p, %p.\n", iface
, capabilities
);
3790 *capabilities
= stream
->capabilities
;
3795 static HRESULT WINAPI
mfbytestream_SetLength(IMFByteStream
*iface
, QWORD length
)
3797 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3799 FIXME("%p, %s\n", This
, wine_dbgstr_longlong(length
));
3804 static HRESULT WINAPI
bytestream_file_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
3806 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3808 TRACE("%p, %p.\n", iface
, position
);
3811 return E_INVALIDARG
;
3813 *position
= stream
->position
;
3818 static HRESULT WINAPI
bytestream_file_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3820 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3823 TRACE("%p, %p.\n", iface
, length
);
3826 return E_INVALIDARG
;
3828 if (GetFileSizeEx(stream
->hfile
, &li
))
3829 *length
= li
.QuadPart
;
3831 return HRESULT_FROM_WIN32(GetLastError());
3836 static HRESULT WINAPI
bytestream_file_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
3838 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3839 LARGE_INTEGER position
, length
;
3842 TRACE("%p, %p.\n", iface
, ret
);
3844 EnterCriticalSection(&stream
->cs
);
3846 position
.QuadPart
= 0;
3847 if (SetFilePointerEx(stream
->hfile
, position
, &length
, FILE_END
))
3848 *ret
= stream
->position
>= length
.QuadPart
;
3850 hr
= HRESULT_FROM_WIN32(GetLastError());
3852 LeaveCriticalSection(&stream
->cs
);
3857 static HRESULT WINAPI
bytestream_file_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
3859 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3860 LARGE_INTEGER position
;
3864 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
3866 EnterCriticalSection(&stream
->cs
);
3868 position
.QuadPart
= stream
->position
;
3869 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
3871 if ((ret
= ReadFile(stream
->hfile
, buffer
, size
, read_len
, NULL
)))
3872 stream
->position
+= *read_len
;
3876 hr
= HRESULT_FROM_WIN32(GetLastError());
3878 LeaveCriticalSection(&stream
->cs
);
3883 static HRESULT WINAPI
bytestream_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
,
3886 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3888 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3890 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_READ
, data
, size
, callback
, state
);
3893 static HRESULT WINAPI
bytestream_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
3895 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3897 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
3899 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_READ
, result
, byte_read
);
3902 static HRESULT WINAPI
mfbytestream_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
3904 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3906 FIXME("%p, %p, %u, %p\n", This
, data
, count
, written
);
3911 static HRESULT WINAPI
bytestream_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
3912 IMFAsyncCallback
*callback
, IUnknown
*state
)
3914 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3916 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3918 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_WRITE
, data
, size
, callback
, state
);
3921 static HRESULT WINAPI
bytestream_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
3923 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3925 TRACE("%p, %p, %p.\n", iface
, result
, written
);
3927 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_WRITE
, result
, written
);
3930 static HRESULT WINAPI
mfbytestream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
3931 DWORD flags
, QWORD
*current
)
3933 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3935 FIXME("%p, %u, %s, 0x%08x, %p\n", This
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
3940 static HRESULT WINAPI
mfbytestream_Flush(IMFByteStream
*iface
)
3942 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3944 FIXME("%p\n", This
);
3949 static HRESULT WINAPI
mfbytestream_Close(IMFByteStream
*iface
)
3951 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3953 FIXME("%p\n", This
);
3958 static HRESULT WINAPI
bytestream_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
3960 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3962 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
3964 EnterCriticalSection(&stream
->cs
);
3965 stream
->position
= position
;
3966 LeaveCriticalSection(&stream
->cs
);
3971 static const IMFByteStreamVtbl bytestream_file_vtbl
=
3973 bytestream_QueryInterface
,
3976 bytestream_GetCapabilities
,
3977 bytestream_file_GetLength
,
3978 mfbytestream_SetLength
,
3979 bytestream_file_GetCurrentPosition
,
3980 bytestream_SetCurrentPosition
,
3981 bytestream_file_IsEndOfStream
,
3982 bytestream_file_Read
,
3983 bytestream_BeginRead
,
3986 bytestream_BeginWrite
,
3987 bytestream_EndWrite
,
3993 static HRESULT WINAPI
bytestream_stream_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3995 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3999 TRACE("%p, %p.\n", iface
, length
);
4001 if (FAILED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4004 *length
= statstg
.cbSize
.QuadPart
;
4009 static HRESULT WINAPI
bytestream_stream_SetLength(IMFByteStream
*iface
, QWORD length
)
4011 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4012 ULARGE_INTEGER size
;
4015 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4017 EnterCriticalSection(&stream
->cs
);
4019 size
.QuadPart
= length
;
4020 hr
= IStream_SetSize(stream
->stream
, size
);
4022 LeaveCriticalSection(&stream
->cs
);
4027 static HRESULT WINAPI
bytestream_stream_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4029 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4031 TRACE("%p, %p.\n", iface
, position
);
4033 *position
= stream
->position
;
4038 static HRESULT WINAPI
bytestream_stream_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4040 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4044 TRACE("%p, %p.\n", iface
, ret
);
4046 EnterCriticalSection(&stream
->cs
);
4048 if (SUCCEEDED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4049 *ret
= stream
->position
>= statstg
.cbSize
.QuadPart
;
4051 LeaveCriticalSection(&stream
->cs
);
4056 static HRESULT WINAPI
bytestream_stream_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4058 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4059 LARGE_INTEGER position
;
4062 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
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_Read(stream
->stream
, buffer
, size
, read_len
)))
4070 stream
->position
+= *read_len
;
4073 LeaveCriticalSection(&stream
->cs
);
4078 static HRESULT WINAPI
bytestream_stream_Write(IMFByteStream
*iface
, const BYTE
*buffer
, ULONG size
, ULONG
*written
)
4080 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4081 LARGE_INTEGER position
;
4084 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, written
);
4086 EnterCriticalSection(&stream
->cs
);
4088 position
.QuadPart
= stream
->position
;
4089 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4091 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, buffer
, size
, written
)))
4092 stream
->position
+= *written
;
4095 LeaveCriticalSection(&stream
->cs
);
4100 static HRESULT WINAPI
bytestream_stream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN origin
, LONGLONG offset
,
4101 DWORD flags
, QWORD
*current
)
4103 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4106 TRACE("%p, %u, %s, %#x, %p.\n", iface
, origin
, wine_dbgstr_longlong(offset
), flags
, current
);
4108 EnterCriticalSection(&stream
->cs
);
4113 stream
->position
= offset
;
4116 stream
->position
+= offset
;
4119 WARN("Unknown origin mode %d.\n", origin
);
4123 *current
= stream
->position
;
4125 LeaveCriticalSection(&stream
->cs
);
4130 static HRESULT WINAPI
bytestream_stream_Flush(IMFByteStream
*iface
)
4132 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4134 TRACE("%p.\n", iface
);
4136 return IStream_Commit(stream
->stream
, STGC_DEFAULT
);
4139 static HRESULT WINAPI
bytestream_stream_Close(IMFByteStream
*iface
)
4141 TRACE("%p.\n", iface
);
4146 static const IMFByteStreamVtbl bytestream_stream_vtbl
=
4148 bytestream_QueryInterface
,
4151 bytestream_stream_GetCapabilities
,
4152 bytestream_stream_GetLength
,
4153 bytestream_stream_SetLength
,
4154 bytestream_stream_GetCurrentPosition
,
4155 bytestream_SetCurrentPosition
,
4156 bytestream_stream_IsEndOfStream
,
4157 bytestream_stream_Read
,
4158 bytestream_BeginRead
,
4160 bytestream_stream_Write
,
4161 bytestream_BeginWrite
,
4162 bytestream_EndWrite
,
4163 bytestream_stream_Seek
,
4164 bytestream_stream_Flush
,
4165 bytestream_stream_Close
,
4168 static inline mfbytestream
*impl_from_IMFByteStream_IMFAttributes(IMFAttributes
*iface
)
4170 return CONTAINING_RECORD(iface
, mfbytestream
, attributes
.IMFAttributes_iface
);
4173 static HRESULT WINAPI
mfbytestream_attributes_QueryInterface(
4174 IMFAttributes
*iface
, REFIID riid
, void **out
)
4176 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4177 return IMFByteStream_QueryInterface(&This
->IMFByteStream_iface
, riid
, out
);
4180 static ULONG WINAPI
mfbytestream_attributes_AddRef(IMFAttributes
*iface
)
4182 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4183 return IMFByteStream_AddRef(&This
->IMFByteStream_iface
);
4186 static ULONG WINAPI
mfbytestream_attributes_Release(IMFAttributes
*iface
)
4188 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4189 return IMFByteStream_Release(&This
->IMFByteStream_iface
);
4192 static const IMFAttributesVtbl mfbytestream_attributes_vtbl
=
4194 mfbytestream_attributes_QueryInterface
,
4195 mfbytestream_attributes_AddRef
,
4196 mfbytestream_attributes_Release
,
4197 mfattributes_GetItem
,
4198 mfattributes_GetItemType
,
4199 mfattributes_CompareItem
,
4200 mfattributes_Compare
,
4201 mfattributes_GetUINT32
,
4202 mfattributes_GetUINT64
,
4203 mfattributes_GetDouble
,
4204 mfattributes_GetGUID
,
4205 mfattributes_GetStringLength
,
4206 mfattributes_GetString
,
4207 mfattributes_GetAllocatedString
,
4208 mfattributes_GetBlobSize
,
4209 mfattributes_GetBlob
,
4210 mfattributes_GetAllocatedBlob
,
4211 mfattributes_GetUnknown
,
4212 mfattributes_SetItem
,
4213 mfattributes_DeleteItem
,
4214 mfattributes_DeleteAllItems
,
4215 mfattributes_SetUINT32
,
4216 mfattributes_SetUINT64
,
4217 mfattributes_SetDouble
,
4218 mfattributes_SetGUID
,
4219 mfattributes_SetString
,
4220 mfattributes_SetBlob
,
4221 mfattributes_SetUnknown
,
4222 mfattributes_LockStore
,
4223 mfattributes_UnlockStore
,
4224 mfattributes_GetCount
,
4225 mfattributes_GetItemByIndex
,
4226 mfattributes_CopyAllItems
4229 static HRESULT WINAPI
bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4231 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4232 struct async_stream_op
*op
;
4233 LARGE_INTEGER position
;
4237 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4240 op
= impl_async_stream_op_from_IUnknown(object
);
4242 EnterCriticalSection(&stream
->cs
);
4244 position
.QuadPart
= op
->position
;
4245 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4247 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, op
->u
.dest
, op
->requested_length
, &op
->actual_length
)))
4248 stream
->position
+= op
->actual_length
;
4251 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4252 list_add_tail(&stream
->pending
, &op
->entry
);
4254 LeaveCriticalSection(&stream
->cs
);
4256 MFInvokeCallback(op
->caller
);
4261 static HRESULT WINAPI
bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4263 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4264 struct async_stream_op
*op
;
4265 LARGE_INTEGER position
;
4269 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4272 op
= impl_async_stream_op_from_IUnknown(object
);
4274 EnterCriticalSection(&stream
->cs
);
4276 position
.QuadPart
= op
->position
;
4277 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4279 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, op
->u
.src
, op
->requested_length
, &op
->actual_length
)))
4280 stream
->position
+= op
->actual_length
;
4283 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4284 list_add_tail(&stream
->pending
, &op
->entry
);
4286 LeaveCriticalSection(&stream
->cs
);
4288 MFInvokeCallback(op
->caller
);
4293 static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl
=
4295 bytestream_callback_QueryInterface
,
4296 bytestream_read_callback_AddRef
,
4297 bytestream_read_callback_Release
,
4298 bytestream_callback_GetParameters
,
4299 bytestream_stream_read_callback_Invoke
,
4302 static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl
=
4304 bytestream_callback_QueryInterface
,
4305 bytestream_write_callback_AddRef
,
4306 bytestream_write_callback_Release
,
4307 bytestream_callback_GetParameters
,
4308 bytestream_stream_write_callback_Invoke
,
4311 /***********************************************************************
4312 * MFCreateMFByteStreamOnStream (mfplat.@)
4314 HRESULT WINAPI
MFCreateMFByteStreamOnStream(IStream
*stream
, IMFByteStream
**bytestream
)
4316 struct bytestream
*object
;
4317 LARGE_INTEGER position
;
4321 TRACE("%p, %p.\n", stream
, bytestream
);
4323 object
= heap_alloc_zero(sizeof(*object
));
4325 return E_OUTOFMEMORY
;
4327 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
4333 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_stream_vtbl
;
4334 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &mfbytestream_attributes_vtbl
;
4335 object
->read_callback
.lpVtbl
= &bytestream_stream_read_callback_vtbl
;
4336 object
->write_callback
.lpVtbl
= &bytestream_stream_write_callback_vtbl
;
4337 InitializeCriticalSection(&object
->cs
);
4338 list_init(&object
->pending
);
4340 object
->stream
= stream
;
4341 IStream_AddRef(object
->stream
);
4342 position
.QuadPart
= 0;
4343 IStream_Seek(object
->stream
, position
, STREAM_SEEK_SET
, NULL
);
4345 if (SUCCEEDED(IStream_Stat(object
->stream
, &stat
, 0)))
4349 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
,
4351 CoTaskMemFree(stat
.pwcsName
);
4355 *bytestream
= &object
->IMFByteStream_iface
;
4360 static HRESULT WINAPI
bytestream_file_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4362 FIXME("%p, %p.\n", iface
, result
);
4367 static HRESULT WINAPI
bytestream_file_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4369 FIXME("%p, %p.\n", iface
, result
);
4374 static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl
=
4376 bytestream_callback_QueryInterface
,
4377 bytestream_read_callback_AddRef
,
4378 bytestream_read_callback_Release
,
4379 bytestream_callback_GetParameters
,
4380 bytestream_file_read_callback_Invoke
,
4383 static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl
=
4385 bytestream_callback_QueryInterface
,
4386 bytestream_write_callback_AddRef
,
4387 bytestream_write_callback_Release
,
4388 bytestream_callback_GetParameters
,
4389 bytestream_file_write_callback_Invoke
,
4392 static HRESULT WINAPI
bytestream_file_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
4394 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4395 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, obj
);
4398 static ULONG WINAPI
bytestream_file_getservice_AddRef(IMFGetService
*iface
)
4400 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4401 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4404 static ULONG WINAPI
bytestream_file_getservice_Release(IMFGetService
*iface
)
4406 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4407 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4410 static HRESULT WINAPI
bytestream_file_getservice_GetService(IMFGetService
*iface
, REFGUID service
,
4411 REFIID riid
, void **obj
)
4413 FIXME("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
4418 static const IMFGetServiceVtbl bytestream_file_getservice_vtbl
=
4420 bytestream_file_getservice_QueryInterface
,
4421 bytestream_file_getservice_AddRef
,
4422 bytestream_file_getservice_Release
,
4423 bytestream_file_getservice_GetService
,
4426 /***********************************************************************
4427 * MFCreateFile (mfplat.@)
4429 HRESULT WINAPI
MFCreateFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4430 LPCWSTR url
, IMFByteStream
**bytestream
)
4432 DWORD capabilities
= MFBYTESTREAM_IS_SEEKABLE
| MFBYTESTREAM_DOES_NOT_USE_NETWORK
;
4433 DWORD filecreation_disposition
= 0, fileaccessmode
= 0, fileattributes
= 0;
4434 DWORD filesharemode
= FILE_SHARE_READ
;
4435 struct bytestream
*object
;
4440 TRACE("%d, %d, %#x, %s, %p.\n", accessmode
, openmode
, flags
, debugstr_w(url
), bytestream
);
4444 case MF_ACCESSMODE_READ
:
4445 fileaccessmode
= GENERIC_READ
;
4446 capabilities
|= MFBYTESTREAM_IS_READABLE
;
4448 case MF_ACCESSMODE_WRITE
:
4449 fileaccessmode
= GENERIC_WRITE
;
4450 capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
4452 case MF_ACCESSMODE_READWRITE
:
4453 fileaccessmode
= GENERIC_READ
| GENERIC_WRITE
;
4454 capabilities
|= (MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_WRITABLE
);
4460 case MF_OPENMODE_FAIL_IF_NOT_EXIST
:
4461 filecreation_disposition
= OPEN_EXISTING
;
4463 case MF_OPENMODE_FAIL_IF_EXIST
:
4464 filecreation_disposition
= CREATE_NEW
;
4466 case MF_OPENMODE_RESET_IF_EXIST
:
4467 filecreation_disposition
= TRUNCATE_EXISTING
;
4469 case MF_OPENMODE_APPEND_IF_EXIST
:
4470 filecreation_disposition
= OPEN_ALWAYS
;
4471 fileaccessmode
|= FILE_APPEND_DATA
;
4473 case MF_OPENMODE_DELETE_IF_EXIST
:
4474 filecreation_disposition
= CREATE_ALWAYS
;
4478 if (flags
& MF_FILEFLAGS_NOBUFFERING
)
4479 fileattributes
|= FILE_FLAG_NO_BUFFERING
;
4481 /* Open HANDLE to file */
4482 file
= CreateFileW(url
, fileaccessmode
, filesharemode
, NULL
,
4483 filecreation_disposition
, fileattributes
, 0);
4485 if(file
== INVALID_HANDLE_VALUE
)
4486 return HRESULT_FROM_WIN32(GetLastError());
4488 object
= heap_alloc_zero(sizeof(*object
));
4492 return E_OUTOFMEMORY
;
4495 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 2)))
4501 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_file_vtbl
;
4502 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &mfbytestream_attributes_vtbl
;
4503 object
->IMFGetService_iface
.lpVtbl
= &bytestream_file_getservice_vtbl
;
4504 object
->read_callback
.lpVtbl
= &bytestream_file_read_callback_vtbl
;
4505 object
->write_callback
.lpVtbl
= &bytestream_file_write_callback_vtbl
;
4506 InitializeCriticalSection(&object
->cs
);
4507 list_init(&object
->pending
);
4508 object
->capabilities
= capabilities
;
4509 object
->hfile
= file
;
4511 if (GetFileTime(file
, NULL
, NULL
, &writetime
))
4513 IMFAttributes_SetBlob(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_LAST_MODIFIED_TIME
,
4514 (const UINT8
*)&writetime
, sizeof(writetime
));
4517 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
, url
);
4519 *bytestream
= &object
->IMFByteStream_iface
;
4524 struct bytestream_wrapper
4526 IMFByteStreamCacheControl IMFByteStreamCacheControl_iface
;
4527 IMFByteStreamBuffering IMFByteStreamBuffering_iface
;
4528 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
4529 IMFByteStreamTimeSeek IMFByteStreamTimeSeek_iface
;
4530 IMFSampleOutputStream IMFSampleOutputStream_iface
;
4531 IPropertyStore IPropertyStore_iface
;
4532 IMFByteStream IMFByteStream_iface
;
4533 IMFAttributes IMFAttributes_iface
;
4536 IMFByteStreamCacheControl
*cache_control
;
4537 IMFByteStreamBuffering
*stream_buffering
;
4538 IMFMediaEventGenerator
*event_generator
;
4539 IMFByteStreamTimeSeek
*time_seek
;
4540 IMFSampleOutputStream
*sample_output
;
4541 IPropertyStore
*propstore
;
4542 IMFByteStream
*stream
;
4543 IMFAttributes
*attributes
;
4547 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStream(IMFByteStream
*iface
)
4549 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStream_iface
);
4552 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamCacheControl(IMFByteStreamCacheControl
*iface
)
4554 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamCacheControl_iface
);
4557 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamBuffering(IMFByteStreamBuffering
*iface
)
4559 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamBuffering_iface
);
4562 static struct bytestream_wrapper
*impl_wrapper_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
4564 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFMediaEventGenerator_iface
);
4567 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamTimeSeek(IMFByteStreamTimeSeek
*iface
)
4569 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamTimeSeek_iface
);
4572 static struct bytestream_wrapper
*impl_wrapper_from_IMFSampleOutputStream(IMFSampleOutputStream
*iface
)
4574 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFSampleOutputStream_iface
);
4577 static struct bytestream_wrapper
*impl_wrapper_from_IPropertyStore(IPropertyStore
*iface
)
4579 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IPropertyStore_iface
);
4582 static struct bytestream_wrapper
*impl_wrapper_from_IMFAttributes(IMFAttributes
*iface
)
4584 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFAttributes_iface
);
4587 static HRESULT WINAPI
bytestream_wrapper_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
4589 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4591 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
4593 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
4594 IsEqualIID(riid
, &IID_IUnknown
))
4596 *out
= &wrapper
->IMFByteStream_iface
;
4598 else if (wrapper
->cache_control
&& IsEqualIID(riid
, &IID_IMFByteStreamCacheControl
))
4600 *out
= &wrapper
->IMFByteStreamCacheControl_iface
;
4602 else if (wrapper
->stream_buffering
&& IsEqualIID(riid
, &IID_IMFByteStreamBuffering
))
4604 *out
= &wrapper
->IMFByteStreamBuffering_iface
;
4606 else if (wrapper
->event_generator
&& IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
4608 *out
= &wrapper
->IMFMediaEventGenerator_iface
;
4610 else if (wrapper
->time_seek
&& IsEqualIID(riid
, &IID_IMFByteStreamTimeSeek
))
4612 *out
= &wrapper
->IMFByteStreamTimeSeek_iface
;
4614 else if (wrapper
->sample_output
&& IsEqualIID(riid
, &IID_IMFSampleOutputStream
))
4616 *out
= &wrapper
->IMFSampleOutputStream_iface
;
4618 else if (wrapper
->propstore
&& IsEqualIID(riid
, &IID_IPropertyStore
))
4620 *out
= &wrapper
->IPropertyStore_iface
;
4622 else if (wrapper
->attributes
&& IsEqualIID(riid
, &IID_IMFAttributes
))
4624 *out
= &wrapper
->IMFAttributes_iface
;
4628 WARN("Unsupported %s.\n", debugstr_guid(riid
));
4630 return E_NOINTERFACE
;
4633 IUnknown_AddRef((IUnknown
*)*out
);
4637 static ULONG WINAPI
bytestream_wrapper_AddRef(IMFByteStream
*iface
)
4639 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4640 ULONG refcount
= InterlockedIncrement(&wrapper
->refcount
);
4642 TRACE("%p, refcount %d.\n", iface
, refcount
);
4647 static ULONG WINAPI
bytestream_wrapper_Release(IMFByteStream
*iface
)
4649 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4650 ULONG refcount
= InterlockedDecrement(&wrapper
->refcount
);
4652 TRACE("%p, refcount %d.\n", iface
, refcount
);
4656 if (wrapper
->cache_control
)
4657 IMFByteStreamCacheControl_Release(wrapper
->cache_control
);
4658 if (wrapper
->stream_buffering
)
4659 IMFByteStreamBuffering_Release(wrapper
->stream_buffering
);
4660 if (wrapper
->event_generator
)
4661 IMFMediaEventGenerator_Release(wrapper
->event_generator
);
4662 if (wrapper
->time_seek
)
4663 IMFByteStreamTimeSeek_Release(wrapper
->time_seek
);
4664 if (wrapper
->sample_output
)
4665 IMFSampleOutputStream_Release(wrapper
->sample_output
);
4666 if (wrapper
->propstore
)
4667 IPropertyStore_Release(wrapper
->propstore
);
4668 if (wrapper
->attributes
)
4669 IMFAttributes_Release(wrapper
->attributes
);
4670 IMFByteStream_Release(wrapper
->stream
);
4677 static HRESULT WINAPI
bytestream_wrapper_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
4679 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4681 TRACE("%p, %p.\n", iface
, capabilities
);
4683 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4684 IMFByteStream_GetCapabilities(wrapper
->stream
, capabilities
);
4687 static HRESULT WINAPI
bytestream_wrapper_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4689 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4691 TRACE("%p, %p.\n", iface
, length
);
4693 if (wrapper
->is_closed
)
4694 return MF_E_INVALIDREQUEST
;
4696 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4697 IMFByteStream_GetLength(wrapper
->stream
, length
);
4700 static HRESULT WINAPI
bytestream_wrapper_SetLength(IMFByteStream
*iface
, QWORD length
)
4702 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4704 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4706 if (wrapper
->is_closed
)
4707 return MF_E_INVALIDREQUEST
;
4709 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4710 IMFByteStream_SetLength(wrapper
->stream
, length
);
4713 static HRESULT WINAPI
bytestream_wrapper_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4715 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4717 TRACE("%p, %p.\n", iface
, position
);
4719 if (wrapper
->is_closed
)
4720 return MF_E_INVALIDREQUEST
;
4722 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4723 IMFByteStream_GetCurrentPosition(wrapper
->stream
, position
);
4726 static HRESULT WINAPI
bytestream_wrapper_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4728 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4730 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4732 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4733 IMFByteStream_SetCurrentPosition(wrapper
->stream
, position
);
4736 static HRESULT WINAPI
bytestream_wrapper_IsEndOfStream(IMFByteStream
*iface
, BOOL
*eos
)
4738 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4740 TRACE("%p, %p.\n", iface
, eos
);
4742 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4743 IMFByteStream_IsEndOfStream(wrapper
->stream
, eos
);
4746 static HRESULT WINAPI
bytestream_wrapper_Read(IMFByteStream
*iface
, BYTE
*data
, ULONG count
, ULONG
*byte_read
)
4748 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4750 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, byte_read
);
4752 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4753 IMFByteStream_Read(wrapper
->stream
, data
, count
, byte_read
);
4756 static HRESULT WINAPI
bytestream_wrapper_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
,
4757 IMFAsyncCallback
*callback
, IUnknown
*state
)
4759 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4761 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4763 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4764 IMFByteStream_BeginRead(wrapper
->stream
, data
, size
, callback
, state
);
4767 static HRESULT WINAPI
bytestream_wrapper_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4769 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4771 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4773 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4774 IMFByteStream_EndRead(wrapper
->stream
, result
, byte_read
);
4777 static HRESULT WINAPI
bytestream_wrapper_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4779 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4781 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, written
);
4783 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4784 IMFByteStream_Write(wrapper
->stream
, data
, count
, written
);
4787 static HRESULT WINAPI
bytestream_wrapper_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4788 IMFAsyncCallback
*callback
, IUnknown
*state
)
4790 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4792 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4794 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4795 IMFByteStream_BeginWrite(wrapper
->stream
, data
, size
, callback
, state
);
4798 static HRESULT WINAPI
bytestream_wrapper_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4800 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4802 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4804 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4805 IMFByteStream_EndWrite(wrapper
->stream
, result
, written
);
4808 static HRESULT WINAPI
bytestream_wrapper_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
4809 DWORD flags
, QWORD
*current
)
4811 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4813 TRACE("%p, %u, %s, %#x, %p.\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
4815 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4816 IMFByteStream_Seek(wrapper
->stream
, seek
, offset
, flags
, current
);
4819 static HRESULT WINAPI
bytestream_wrapper_Flush(IMFByteStream
*iface
)
4821 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4823 TRACE("%p\n", iface
);
4825 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
: IMFByteStream_Flush(wrapper
->stream
);
4828 static HRESULT WINAPI
bytestream_wrapper_Close(IMFByteStream
*iface
)
4830 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4832 TRACE("%p\n", iface
);
4834 wrapper
->is_closed
= TRUE
;
4839 static const IMFByteStreamVtbl bytestream_wrapper_vtbl
=
4841 bytestream_wrapper_QueryInterface
,
4842 bytestream_wrapper_AddRef
,
4843 bytestream_wrapper_Release
,
4844 bytestream_wrapper_GetCapabilities
,
4845 bytestream_wrapper_GetLength
,
4846 bytestream_wrapper_SetLength
,
4847 bytestream_wrapper_GetCurrentPosition
,
4848 bytestream_wrapper_SetCurrentPosition
,
4849 bytestream_wrapper_IsEndOfStream
,
4850 bytestream_wrapper_Read
,
4851 bytestream_wrapper_BeginRead
,
4852 bytestream_wrapper_EndRead
,
4853 bytestream_wrapper_Write
,
4854 bytestream_wrapper_BeginWrite
,
4855 bytestream_wrapper_EndWrite
,
4856 bytestream_wrapper_Seek
,
4857 bytestream_wrapper_Flush
,
4858 bytestream_wrapper_Close
,
4861 static HRESULT WINAPI
bytestream_wrapper_cache_control_QueryInterface(IMFByteStreamCacheControl
*iface
,
4862 REFIID riid
, void **obj
)
4864 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4865 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4868 static ULONG WINAPI
bytestream_wrapper_cache_control_AddRef(IMFByteStreamCacheControl
*iface
)
4870 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4871 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4874 static ULONG WINAPI
bytestream_wrapper_cache_control_Release(IMFByteStreamCacheControl
*iface
)
4876 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4877 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4880 static HRESULT WINAPI
bytestream_wrapper_cache_control_StopBackgroundTransfer(IMFByteStreamCacheControl
*iface
)
4882 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4884 TRACE("%p.\n", iface
);
4886 return IMFByteStreamCacheControl_StopBackgroundTransfer(wrapper
->cache_control
);
4889 static const IMFByteStreamCacheControlVtbl bytestream_wrapper_cache_control_vtbl
=
4891 bytestream_wrapper_cache_control_QueryInterface
,
4892 bytestream_wrapper_cache_control_AddRef
,
4893 bytestream_wrapper_cache_control_Release
,
4894 bytestream_wrapper_cache_control_StopBackgroundTransfer
,
4897 static HRESULT WINAPI
bytestream_wrapper_buffering_QueryInterface(IMFByteStreamBuffering
*iface
,
4898 REFIID riid
, void **obj
)
4900 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4901 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4904 static ULONG WINAPI
bytestream_wrapper_buffering_AddRef(IMFByteStreamBuffering
*iface
)
4906 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4907 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4910 static ULONG WINAPI
bytestream_wrapper_buffering_Release(IMFByteStreamBuffering
*iface
)
4912 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4913 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4916 static HRESULT WINAPI
bytestream_wrapper_buffering_SetBufferingParams(IMFByteStreamBuffering
*iface
,
4917 MFBYTESTREAM_BUFFERING_PARAMS
*params
)
4919 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4921 TRACE("%p, %p.\n", iface
, params
);
4923 return IMFByteStreamBuffering_SetBufferingParams(wrapper
->stream_buffering
, params
);
4926 static HRESULT WINAPI
bytestream_wrapper_buffering_EnableBuffering(IMFByteStreamBuffering
*iface
,
4929 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4931 TRACE("%p, %d.\n", iface
, enable
);
4933 return IMFByteStreamBuffering_EnableBuffering(wrapper
->stream_buffering
, enable
);
4936 static HRESULT WINAPI
bytestream_wrapper_buffering_StopBuffering(IMFByteStreamBuffering
*iface
)
4938 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4940 TRACE("%p.\n", iface
);
4942 return IMFByteStreamBuffering_StopBuffering(wrapper
->stream_buffering
);
4945 static const IMFByteStreamBufferingVtbl bytestream_wrapper_buffering_vtbl
=
4947 bytestream_wrapper_buffering_QueryInterface
,
4948 bytestream_wrapper_buffering_AddRef
,
4949 bytestream_wrapper_buffering_Release
,
4950 bytestream_wrapper_buffering_SetBufferingParams
,
4951 bytestream_wrapper_buffering_EnableBuffering
,
4952 bytestream_wrapper_buffering_StopBuffering
,
4955 static HRESULT WINAPI
bytestream_wrapper_timeseek_QueryInterface(IMFByteStreamTimeSeek
*iface
,
4956 REFIID riid
, void **obj
)
4958 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4959 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4962 static ULONG WINAPI
bytestream_wrapper_timeseek_AddRef(IMFByteStreamTimeSeek
*iface
)
4964 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4965 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4968 static ULONG WINAPI
bytestream_wrapper_timeseek_Release(IMFByteStreamTimeSeek
*iface
)
4970 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4971 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4974 static HRESULT WINAPI
bytestream_wrapper_timeseek_IsTimeSeekSupported(IMFByteStreamTimeSeek
*iface
, BOOL
*result
)
4976 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4978 TRACE("%p, %p.\n", iface
, result
);
4980 return IMFByteStreamTimeSeek_IsTimeSeekSupported(wrapper
->time_seek
, result
);
4983 static HRESULT WINAPI
bytestream_wrapper_timeseek_TimeSeek(IMFByteStreamTimeSeek
*iface
, QWORD position
)
4985 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4987 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4989 return IMFByteStreamTimeSeek_TimeSeek(wrapper
->time_seek
, position
);
4992 static HRESULT WINAPI
bytestream_wrapper_timeseek_GetTimeSeekResult(IMFByteStreamTimeSeek
*iface
, QWORD
*start_time
,
4993 QWORD
*stop_time
, QWORD
*duration
)
4995 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4997 TRACE("%p, %p, %p, %p.\n", iface
, start_time
, stop_time
, duration
);
4999 return IMFByteStreamTimeSeek_GetTimeSeekResult(wrapper
->time_seek
, start_time
, stop_time
, duration
);
5002 static const IMFByteStreamTimeSeekVtbl bytestream_wrapper_timeseek_vtbl
=
5004 bytestream_wrapper_timeseek_QueryInterface
,
5005 bytestream_wrapper_timeseek_AddRef
,
5006 bytestream_wrapper_timeseek_Release
,
5007 bytestream_wrapper_timeseek_IsTimeSeekSupported
,
5008 bytestream_wrapper_timeseek_TimeSeek
,
5009 bytestream_wrapper_timeseek_GetTimeSeekResult
,
5012 static HRESULT WINAPI
bytestream_wrapper_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
5014 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5015 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5018 static ULONG WINAPI
bytestream_wrapper_events_AddRef(IMFMediaEventGenerator
*iface
)
5020 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5021 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5024 static ULONG WINAPI
bytestream_wrapper_events_Release(IMFMediaEventGenerator
*iface
)
5026 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5027 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5030 static HRESULT WINAPI
bytestream_wrapper_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
5032 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5034 TRACE("%p, %#x, %p.\n", iface
, flags
, event
);
5036 return IMFMediaEventGenerator_GetEvent(wrapper
->event_generator
, flags
, event
);
5039 static HRESULT WINAPI
bytestream_wrapper_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
5041 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5043 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
5045 return IMFMediaEventGenerator_BeginGetEvent(wrapper
->event_generator
, callback
, state
);
5048 static HRESULT WINAPI
bytestream_wrapper_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
5050 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5052 TRACE("%p, %p, %p.\n", iface
, result
, event
);
5054 return IMFMediaEventGenerator_EndGetEvent(wrapper
->event_generator
, result
, event
);
5057 static HRESULT WINAPI
bytestream_wrapper_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType type
,
5058 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
5060 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5062 TRACE("%p, %d, %s, %#x, %s.\n", iface
, type
, debugstr_guid(ext_type
), hr
, debugstr_propvar(value
));
5064 return IMFMediaEventGenerator_QueueEvent(wrapper
->event_generator
, type
, ext_type
, hr
, value
);
5067 static const IMFMediaEventGeneratorVtbl bytestream_wrapper_events_vtbl
=
5069 bytestream_wrapper_events_QueryInterface
,
5070 bytestream_wrapper_events_AddRef
,
5071 bytestream_wrapper_events_Release
,
5072 bytestream_wrapper_events_GetEvent
,
5073 bytestream_wrapper_events_BeginGetEvent
,
5074 bytestream_wrapper_events_EndGetEvent
,
5075 bytestream_wrapper_events_QueueEvent
,
5078 static HRESULT WINAPI
bytestream_wrapper_sample_output_QueryInterface(IMFSampleOutputStream
*iface
, REFIID riid
, void **obj
)
5080 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5081 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5084 static ULONG WINAPI
bytestream_wrapper_sample_output_AddRef(IMFSampleOutputStream
*iface
)
5086 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5087 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5090 static ULONG WINAPI
bytestream_wrapper_sample_output_Release(IMFSampleOutputStream
*iface
)
5092 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5093 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5096 static HRESULT WINAPI
bytestream_wrapper_sample_output_BeginWriteSample(IMFSampleOutputStream
*iface
, IMFSample
*sample
,
5097 IMFAsyncCallback
*callback
, IUnknown
*state
)
5099 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5101 TRACE("%p, %p, %p, %p.\n", iface
, sample
, callback
, state
);
5103 return IMFSampleOutputStream_BeginWriteSample(wrapper
->sample_output
, sample
, callback
, state
);
5106 static HRESULT WINAPI
bytestream_wrapper_sample_output_EndWriteSample(IMFSampleOutputStream
*iface
, IMFAsyncResult
*result
)
5108 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5110 TRACE("%p, %p.\n", iface
, result
);
5112 return IMFSampleOutputStream_EndWriteSample(wrapper
->sample_output
, result
);
5115 static HRESULT WINAPI
bytestream_wrapper_sample_output_Close(IMFSampleOutputStream
*iface
)
5117 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5119 TRACE("%p.\n", iface
);
5121 return IMFSampleOutputStream_Close(wrapper
->sample_output
);
5124 static const IMFSampleOutputStreamVtbl bytestream_wrapper_sample_output_vtbl
=
5126 bytestream_wrapper_sample_output_QueryInterface
,
5127 bytestream_wrapper_sample_output_AddRef
,
5128 bytestream_wrapper_sample_output_Release
,
5129 bytestream_wrapper_sample_output_BeginWriteSample
,
5130 bytestream_wrapper_sample_output_EndWriteSample
,
5131 bytestream_wrapper_sample_output_Close
,
5134 static HRESULT WINAPI
bytestream_wrapper_propstore_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
5136 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5137 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5140 static ULONG WINAPI
bytestream_wrapper_propstore_AddRef(IPropertyStore
*iface
)
5142 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5143 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5146 static ULONG WINAPI
bytestream_wrapper_propstore_Release(IPropertyStore
*iface
)
5148 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5149 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5152 static HRESULT WINAPI
bytestream_wrapper_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
5154 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5156 TRACE("%p, %p.\n", iface
, count
);
5158 return IPropertyStore_GetCount(wrapper
->propstore
, count
);
5161 static HRESULT WINAPI
bytestream_wrapper_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
5163 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5165 TRACE("%p, %u, %p.\n", iface
, prop
, key
);
5167 return IPropertyStore_GetAt(wrapper
->propstore
, prop
, key
);
5170 static HRESULT WINAPI
bytestream_wrapper_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
5172 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5174 TRACE("%p, %p, %p.\n", iface
, key
, value
);
5176 return IPropertyStore_GetValue(wrapper
->propstore
, key
, value
);
5179 static HRESULT WINAPI
bytestream_wrapper_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
,
5180 const PROPVARIANT
*value
)
5182 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5184 TRACE("%p, %p, %s.\n", iface
, key
, debugstr_propvar(value
));
5186 return IPropertyStore_SetValue(wrapper
->propstore
, key
, value
);
5189 static HRESULT WINAPI
bytestream_wrapper_propstore_Commit(IPropertyStore
*iface
)
5191 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5193 TRACE("%p.\n", iface
);
5195 return IPropertyStore_Commit(wrapper
->propstore
);
5198 static const IPropertyStoreVtbl bytestream_wrapper_propstore_vtbl
=
5200 bytestream_wrapper_propstore_QueryInterface
,
5201 bytestream_wrapper_propstore_AddRef
,
5202 bytestream_wrapper_propstore_Release
,
5203 bytestream_wrapper_propstore_GetCount
,
5204 bytestream_wrapper_propstore_GetAt
,
5205 bytestream_wrapper_propstore_GetValue
,
5206 bytestream_wrapper_propstore_SetValue
,
5207 bytestream_wrapper_propstore_Commit
,
5210 static HRESULT WINAPI
bytestream_wrapper_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
5212 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5213 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5216 static ULONG WINAPI
bytestream_wrapper_attributes_AddRef(IMFAttributes
*iface
)
5218 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5219 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5222 static ULONG WINAPI
bytestream_wrapper_attributes_Release(IMFAttributes
*iface
)
5224 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5225 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5228 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
5230 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5232 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5234 return IMFAttributes_GetItem(wrapper
->attributes
, key
, value
);
5237 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
5239 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5241 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
5243 return IMFAttributes_GetItemType(wrapper
->attributes
, key
, type
);
5246 static HRESULT WINAPI
bytestream_wrapper_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
5247 REFPROPVARIANT value
, BOOL
*result
)
5249 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5251 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
5253 return IMFAttributes_CompareItem(wrapper
->attributes
, key
, value
, result
);
5256 static HRESULT WINAPI
bytestream_wrapper_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
5257 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
5259 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5261 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
5263 return IMFAttributes_Compare(wrapper
->attributes
, theirs
, match_type
, ret
);
5266 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
5268 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5270 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5272 return IMFAttributes_GetUINT32(wrapper
->attributes
, key
, value
);
5275 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
5277 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5279 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5281 return IMFAttributes_GetUINT64(wrapper
->attributes
, key
, value
);
5284 static HRESULT WINAPI
bytestream_wrapper_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
5286 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5288 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5290 return IMFAttributes_GetDouble(wrapper
->attributes
, key
, value
);
5293 static HRESULT WINAPI
bytestream_wrapper_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
5295 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5297 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5299 return IMFAttributes_GetGUID(wrapper
->attributes
, key
, value
);
5302 static HRESULT WINAPI
bytestream_wrapper_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
5304 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5306 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
5308 return IMFAttributes_GetStringLength(wrapper
->attributes
, key
, length
);
5311 static HRESULT WINAPI
bytestream_wrapper_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
5312 UINT32 size
, UINT32
*length
)
5314 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5316 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
5318 return IMFAttributes_GetString(wrapper
->attributes
, key
, value
, size
, length
);
5321 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
5323 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5325 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
5327 return IMFAttributes_GetAllocatedString(wrapper
->attributes
, key
, value
, length
);
5330 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
5332 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5334 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
5336 return IMFAttributes_GetBlobSize(wrapper
->attributes
, key
, size
);
5339 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
5340 UINT32 bufsize
, UINT32
*blobsize
)
5342 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5344 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
5346 return IMFAttributes_GetBlob(wrapper
->attributes
, key
, buf
, bufsize
, blobsize
);
5349 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
5351 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5353 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
5355 return IMFAttributes_GetAllocatedBlob(wrapper
->attributes
, key
, buf
, size
);
5358 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **obj
)
5360 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5362 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), obj
);
5364 return IMFAttributes_GetUnknown(wrapper
->attributes
, key
, riid
, obj
);
5367 static HRESULT WINAPI
bytestream_wrapper_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
5369 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5371 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
5373 return IMFAttributes_SetItem(wrapper
->attributes
, key
, value
);
5376 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
5378 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5380 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
5382 return IMFAttributes_DeleteItem(wrapper
->attributes
, key
);
5385 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteAllItems(IMFAttributes
*iface
)
5387 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5389 TRACE("%p.\n", iface
);
5391 return IMFAttributes_DeleteAllItems(wrapper
->attributes
);
5394 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
5396 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5398 TRACE("%p, %s, %d.\n", iface
, debugstr_attr(key
), value
);
5400 return IMFAttributes_SetUINT32(wrapper
->attributes
, key
, value
);
5403 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
5405 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5407 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
5409 return IMFAttributes_SetUINT64(wrapper
->attributes
, key
, value
);
5412 static HRESULT WINAPI
bytestream_wrapper_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
5414 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5416 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
5418 return IMFAttributes_SetDouble(wrapper
->attributes
, key
, value
);
5421 static HRESULT WINAPI
bytestream_wrapper_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
5423 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5425 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
5427 return IMFAttributes_SetGUID(wrapper
->attributes
, key
, value
);
5430 static HRESULT WINAPI
bytestream_wrapper_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
5432 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5434 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
5436 return IMFAttributes_SetString(wrapper
->attributes
, key
, value
);
5439 static HRESULT WINAPI
bytestream_wrapper_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
5441 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5443 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
5445 return IMFAttributes_SetBlob(wrapper
->attributes
, key
, buf
, size
);
5448 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
5450 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5452 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
5454 return IMFAttributes_SetUnknown(wrapper
->attributes
, key
, unknown
);
5457 static HRESULT WINAPI
bytestream_wrapper_attributes_LockStore(IMFAttributes
*iface
)
5459 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5461 TRACE("%p.\n", iface
);
5463 return IMFAttributes_LockStore(wrapper
->attributes
);
5466 static HRESULT WINAPI
bytestream_wrapper_attributes_UnlockStore(IMFAttributes
*iface
)
5468 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5470 TRACE("%p.\n", iface
);
5472 return IMFAttributes_UnlockStore(wrapper
->attributes
);
5475 static HRESULT WINAPI
bytestream_wrapper_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
5477 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5479 TRACE("%p, %p.\n", iface
, count
);
5481 return IMFAttributes_GetCount(wrapper
->attributes
, count
);
5484 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
5486 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5488 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
5490 return IMFAttributes_GetItemByIndex(wrapper
->attributes
, index
, key
, value
);
5493 static HRESULT WINAPI
bytestream_wrapper_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
5495 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5497 TRACE("%p, %p.\n", iface
, dest
);
5499 return IMFAttributes_CopyAllItems(wrapper
->attributes
, dest
);
5502 static const IMFAttributesVtbl bytestream_wrapper_attributes_vtbl
=
5504 bytestream_wrapper_attributes_QueryInterface
,
5505 bytestream_wrapper_attributes_AddRef
,
5506 bytestream_wrapper_attributes_Release
,
5507 bytestream_wrapper_attributes_GetItem
,
5508 bytestream_wrapper_attributes_GetItemType
,
5509 bytestream_wrapper_attributes_CompareItem
,
5510 bytestream_wrapper_attributes_Compare
,
5511 bytestream_wrapper_attributes_GetUINT32
,
5512 bytestream_wrapper_attributes_GetUINT64
,
5513 bytestream_wrapper_attributes_GetDouble
,
5514 bytestream_wrapper_attributes_GetGUID
,
5515 bytestream_wrapper_attributes_GetStringLength
,
5516 bytestream_wrapper_attributes_GetString
,
5517 bytestream_wrapper_attributes_GetAllocatedString
,
5518 bytestream_wrapper_attributes_GetBlobSize
,
5519 bytestream_wrapper_attributes_GetBlob
,
5520 bytestream_wrapper_attributes_GetAllocatedBlob
,
5521 bytestream_wrapper_attributes_GetUnknown
,
5522 bytestream_wrapper_attributes_SetItem
,
5523 bytestream_wrapper_attributes_DeleteItem
,
5524 bytestream_wrapper_attributes_DeleteAllItems
,
5525 bytestream_wrapper_attributes_SetUINT32
,
5526 bytestream_wrapper_attributes_SetUINT64
,
5527 bytestream_wrapper_attributes_SetDouble
,
5528 bytestream_wrapper_attributes_SetGUID
,
5529 bytestream_wrapper_attributes_SetString
,
5530 bytestream_wrapper_attributes_SetBlob
,
5531 bytestream_wrapper_attributes_SetUnknown
,
5532 bytestream_wrapper_attributes_LockStore
,
5533 bytestream_wrapper_attributes_UnlockStore
,
5534 bytestream_wrapper_attributes_GetCount
,
5535 bytestream_wrapper_attributes_GetItemByIndex
,
5536 bytestream_wrapper_attributes_CopyAllItems
5539 /***********************************************************************
5540 * MFCreateMFByteStreamWrapper (mfplat.@)
5542 HRESULT WINAPI
MFCreateMFByteStreamWrapper(IMFByteStream
*stream
, IMFByteStream
**wrapper
)
5544 struct bytestream_wrapper
*object
;
5546 TRACE("%p, %p.\n", stream
, wrapper
);
5548 object
= heap_alloc_zero(sizeof(*object
));
5550 return E_OUTOFMEMORY
;
5552 object
->IMFByteStreamCacheControl_iface
.lpVtbl
= &bytestream_wrapper_cache_control_vtbl
;
5553 object
->IMFByteStreamBuffering_iface
.lpVtbl
= &bytestream_wrapper_buffering_vtbl
;
5554 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &bytestream_wrapper_events_vtbl
;
5555 object
->IMFByteStreamTimeSeek_iface
.lpVtbl
= &bytestream_wrapper_timeseek_vtbl
;
5556 object
->IMFSampleOutputStream_iface
.lpVtbl
= &bytestream_wrapper_sample_output_vtbl
;
5557 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_wrapper_vtbl
;
5558 object
->IPropertyStore_iface
.lpVtbl
= &bytestream_wrapper_propstore_vtbl
;
5559 object
->IMFAttributes_iface
.lpVtbl
= &bytestream_wrapper_attributes_vtbl
;
5561 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamCacheControl
, (void **)&object
->cache_control
);
5562 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamBuffering
, (void **)&object
->stream_buffering
);
5563 IMFByteStream_QueryInterface(stream
, &IID_IMFMediaEventGenerator
, (void **)&object
->event_generator
);
5564 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamTimeSeek
, (void **)&object
->time_seek
);
5565 IMFByteStream_QueryInterface(stream
, &IID_IMFSampleOutputStream
, (void **)&object
->sample_output
);
5566 IMFByteStream_QueryInterface(stream
, &IID_IPropertyStore
, (void **)&object
->propstore
);
5567 IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&object
->attributes
);
5569 object
->stream
= stream
;
5570 IMFByteStream_AddRef(object
->stream
);
5572 object
->refcount
= 1;
5574 *wrapper
= &object
->IMFByteStream_iface
;
5579 static HRESULT WINAPI
MFPluginControl_QueryInterface(IMFPluginControl
*iface
, REFIID riid
, void **ppv
)
5581 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
5582 TRACE("(IID_IUnknown %p)\n", ppv
);
5584 }else if(IsEqualGUID(riid
, &IID_IMFPluginControl
)) {
5585 TRACE("(IID_IMFPluginControl %p)\n", ppv
);
5588 FIXME("(%s %p)\n", debugstr_guid(riid
), ppv
);
5590 return E_NOINTERFACE
;
5593 IUnknown_AddRef((IUnknown
*)*ppv
);
5597 static ULONG WINAPI
MFPluginControl_AddRef(IMFPluginControl
*iface
)
5603 static ULONG WINAPI
MFPluginControl_Release(IMFPluginControl
*iface
)
5609 static HRESULT WINAPI
MFPluginControl_GetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5610 const WCHAR
*selector
, CLSID
*clsid
)
5612 FIXME("(%d %s %p)\n", plugin_type
, debugstr_w(selector
), clsid
);
5616 static HRESULT WINAPI
MFPluginControl_GetPreferredClsidByIndex(IMFPluginControl
*iface
, DWORD plugin_type
,
5617 DWORD index
, WCHAR
**selector
, CLSID
*clsid
)
5619 FIXME("(%d %d %p %p)\n", plugin_type
, index
, selector
, clsid
);
5623 static HRESULT WINAPI
MFPluginControl_SetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5624 const WCHAR
*selector
, const CLSID
*clsid
)
5626 FIXME("(%d %s %s)\n", plugin_type
, debugstr_w(selector
), debugstr_guid(clsid
));
5630 static HRESULT WINAPI
MFPluginControl_IsDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
)
5632 FIXME("(%d %s)\n", plugin_type
, debugstr_guid(clsid
));
5636 static HRESULT WINAPI
MFPluginControl_GetDisabledByIndex(IMFPluginControl
*iface
, DWORD plugin_type
, DWORD index
, CLSID
*clsid
)
5638 FIXME("(%d %d %p)\n", plugin_type
, index
, clsid
);
5642 static HRESULT WINAPI
MFPluginControl_SetDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
, BOOL disabled
)
5644 FIXME("(%d %s %x)\n", plugin_type
, debugstr_guid(clsid
), disabled
);
5648 static const IMFPluginControlVtbl MFPluginControlVtbl
= {
5649 MFPluginControl_QueryInterface
,
5650 MFPluginControl_AddRef
,
5651 MFPluginControl_Release
,
5652 MFPluginControl_GetPreferredClsid
,
5653 MFPluginControl_GetPreferredClsidByIndex
,
5654 MFPluginControl_SetPreferredClsid
,
5655 MFPluginControl_IsDisabled
,
5656 MFPluginControl_GetDisabledByIndex
,
5657 MFPluginControl_SetDisabled
5660 static IMFPluginControl plugin_control
= { &MFPluginControlVtbl
};
5662 /***********************************************************************
5663 * MFGetPluginControl (mfplat.@)
5665 HRESULT WINAPI
MFGetPluginControl(IMFPluginControl
**ret
)
5667 TRACE("(%p)\n", ret
);
5669 *ret
= &plugin_control
;
5673 enum resolved_object_origin
5675 OBJECT_FROM_BYTESTREAM
,
5679 struct resolver_queued_result
5683 MF_OBJECT_TYPE obj_type
;
5685 IRtwqAsyncResult
*inner_result
;
5686 enum resolved_object_origin origin
;
5689 struct resolver_cancel_object
5691 IUnknown IUnknown_iface
;
5696 IMFByteStreamHandler
*stream_handler
;
5697 IMFSchemeHandler
*scheme_handler
;
5699 IUnknown
*cancel_cookie
;
5700 enum resolved_object_origin origin
;
5703 struct source_resolver
5705 IMFSourceResolver IMFSourceResolver_iface
;
5707 IRtwqAsyncCallback stream_callback
;
5708 IRtwqAsyncCallback url_callback
;
5709 CRITICAL_SECTION cs
;
5710 struct list pending
;
5713 static struct source_resolver
*impl_from_IMFSourceResolver(IMFSourceResolver
*iface
)
5715 return CONTAINING_RECORD(iface
, struct source_resolver
, IMFSourceResolver_iface
);
5718 static struct source_resolver
*impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5720 return CONTAINING_RECORD(iface
, struct source_resolver
, stream_callback
);
5723 static struct source_resolver
*impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5725 return CONTAINING_RECORD(iface
, struct source_resolver
, url_callback
);
5728 static HRESULT
resolver_handler_end_create(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
5729 IRtwqAsyncResult
*result
)
5731 IRtwqAsyncResult
*inner_result
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
5732 RTWQASYNCRESULT
*data
= (RTWQASYNCRESULT
*)inner_result
;
5733 struct resolver_queued_result
*queued_result
;
5737 IMFByteStreamHandler
*stream_handler
;
5738 IMFSchemeHandler
*scheme_handler
;
5741 if (!(queued_result
= heap_alloc_zero(sizeof(*queued_result
))))
5742 return E_OUTOFMEMORY
;
5744 queued_result
->origin
= origin
;
5746 IRtwqAsyncResult_GetObject(inner_result
, &handler
.handler
);
5750 case OBJECT_FROM_BYTESTREAM
:
5751 queued_result
->hr
= IMFByteStreamHandler_EndCreateObject(handler
.stream_handler
, (IMFAsyncResult
*)result
,
5752 &queued_result
->obj_type
, &queued_result
->object
);
5754 case OBJECT_FROM_URL
:
5755 queued_result
->hr
= IMFSchemeHandler_EndCreateObject(handler
.scheme_handler
, (IMFAsyncResult
*)result
,
5756 &queued_result
->obj_type
, &queued_result
->object
);
5759 queued_result
->hr
= E_FAIL
;
5762 IUnknown_Release(handler
.handler
);
5766 queued_result
->inner_result
= inner_result
;
5767 IRtwqAsyncResult_AddRef(queued_result
->inner_result
);
5770 /* Push resolved object type and created object, so we don't have to guess on End*() call. */
5771 EnterCriticalSection(&resolver
->cs
);
5772 list_add_tail(&resolver
->pending
, &queued_result
->entry
);
5773 LeaveCriticalSection(&resolver
->cs
);
5776 SetEvent(data
->hEvent
);
5779 IUnknown
*caller_state
= IRtwqAsyncResult_GetStateNoAddRef(inner_result
);
5780 IRtwqAsyncResult
*caller_result
;
5782 if (SUCCEEDED(RtwqCreateAsyncResult(queued_result
->object
, data
->pCallback
, caller_state
, &caller_result
)))
5784 RtwqInvokeCallback(caller_result
);
5785 IRtwqAsyncResult_Release(caller_result
);
5792 static struct resolver_cancel_object
*impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5794 return CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
);
5797 static HRESULT WINAPI
resolver_cancel_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
5799 if (IsEqualIID(riid
, &IID_IUnknown
))
5802 IUnknown_AddRef(iface
);
5807 return E_NOINTERFACE
;
5810 static ULONG WINAPI
resolver_cancel_object_AddRef(IUnknown
*iface
)
5812 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5813 return InterlockedIncrement(&object
->refcount
);
5816 static ULONG WINAPI
resolver_cancel_object_Release(IUnknown
*iface
)
5818 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5819 ULONG refcount
= InterlockedDecrement(&object
->refcount
);
5823 if (object
->cancel_cookie
)
5824 IUnknown_Release(object
->cancel_cookie
);
5825 IUnknown_Release(object
->u
.handler
);
5832 static const IUnknownVtbl resolver_cancel_object_vtbl
=
5834 resolver_cancel_object_QueryInterface
,
5835 resolver_cancel_object_AddRef
,
5836 resolver_cancel_object_Release
,
5839 static struct resolver_cancel_object
*unsafe_impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5844 return (iface
->lpVtbl
== &resolver_cancel_object_vtbl
) ?
5845 CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
) : NULL
;
5848 static HRESULT
resolver_create_cancel_object(IUnknown
*handler
, enum resolved_object_origin origin
,
5849 IUnknown
*cancel_cookie
, IUnknown
**cancel_object
)
5851 struct resolver_cancel_object
*object
;
5853 object
= heap_alloc_zero(sizeof(*object
));
5855 return E_OUTOFMEMORY
;
5857 object
->IUnknown_iface
.lpVtbl
= &resolver_cancel_object_vtbl
;
5858 object
->refcount
= 1;
5859 object
->u
.handler
= handler
;
5860 IUnknown_AddRef(object
->u
.handler
);
5861 object
->cancel_cookie
= cancel_cookie
;
5862 IUnknown_AddRef(object
->cancel_cookie
);
5863 object
->origin
= origin
;
5865 *cancel_object
= &object
->IUnknown_iface
;
5870 static HRESULT WINAPI
source_resolver_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
5872 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
5873 IsEqualIID(riid
, &IID_IUnknown
))
5876 IRtwqAsyncCallback_AddRef(iface
);
5881 return E_NOINTERFACE
;
5884 static ULONG WINAPI
source_resolver_callback_stream_AddRef(IRtwqAsyncCallback
*iface
)
5886 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5887 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5890 static ULONG WINAPI
source_resolver_callback_stream_Release(IRtwqAsyncCallback
*iface
)
5892 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5893 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5896 static HRESULT WINAPI
source_resolver_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
5901 static HRESULT WINAPI
source_resolver_callback_stream_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5903 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5905 return resolver_handler_end_create(resolver
, OBJECT_FROM_BYTESTREAM
, result
);
5908 static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl
=
5910 source_resolver_callback_QueryInterface
,
5911 source_resolver_callback_stream_AddRef
,
5912 source_resolver_callback_stream_Release
,
5913 source_resolver_callback_GetParameters
,
5914 source_resolver_callback_stream_Invoke
,
5917 static ULONG WINAPI
source_resolver_callback_url_AddRef(IRtwqAsyncCallback
*iface
)
5919 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5920 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5923 static ULONG WINAPI
source_resolver_callback_url_Release(IRtwqAsyncCallback
*iface
)
5925 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5926 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5929 static HRESULT WINAPI
source_resolver_callback_url_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5931 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5933 return resolver_handler_end_create(resolver
, OBJECT_FROM_URL
, result
);
5936 static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl
=
5938 source_resolver_callback_QueryInterface
,
5939 source_resolver_callback_url_AddRef
,
5940 source_resolver_callback_url_Release
,
5941 source_resolver_callback_GetParameters
,
5942 source_resolver_callback_url_Invoke
,
5945 static HRESULT
resolver_create_registered_handler(HKEY hkey
, REFIID riid
, void **handler
)
5947 unsigned int j
= 0, name_length
, type
;
5948 HRESULT hr
= E_FAIL
;
5952 name_length
= ARRAY_SIZE(clsidW
);
5953 while (!RegEnumValueW(hkey
, j
++, clsidW
, &name_length
, NULL
, &type
, NULL
, NULL
))
5957 if (SUCCEEDED(CLSIDFromString(clsidW
, &clsid
)))
5959 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, handler
);
5965 name_length
= ARRAY_SIZE(clsidW
);
5971 static HRESULT
resolver_get_bytestream_handler(IMFByteStream
*stream
, const WCHAR
*url
, DWORD flags
,
5972 IMFByteStreamHandler
**handler
)
5974 static const char streamhandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers";
5975 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
5976 IMFAttributes
*attributes
;
5977 const WCHAR
*url_ext
;
5978 WCHAR
*mimeW
= NULL
;
5979 HRESULT hr
= E_FAIL
;
5986 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
5988 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &mimeW
, &length
);
5989 IMFAttributes_Release(attributes
);
5993 url_ext
= url
? wcsrchr(url
, '.') : NULL
;
5995 if (!url_ext
&& !mimeW
)
5997 CoTaskMemFree(mimeW
);
5998 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6001 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6003 struct local_handler
*local_handler
;
6005 EnterCriticalSection(&local_handlers_section
);
6007 LIST_FOR_EACH_ENTRY(local_handler
, &local_bytestream_handlers
, struct local_handler
, entry
)
6009 if ((mimeW
&& !lstrcmpiW(mimeW
, local_handler
->u
.bytestream
.mime
))
6010 || (url_ext
&& !lstrcmpiW(url_ext
, local_handler
->u
.bytestream
.extension
)))
6012 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFByteStreamHandler
,
6018 LeaveCriticalSection(&local_handlers_section
);
6024 for (i
= 0, hr
= E_FAIL
; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6026 const WCHAR
*namesW
[2] = { mimeW
, url_ext
};
6027 HKEY hkey
, hkey_handler
;
6029 if (RegOpenKeyA(hkey_roots
[i
], streamhandlerspath
, &hkey
))
6032 for (j
= 0; j
< ARRAY_SIZE(namesW
); ++j
)
6037 if (!RegOpenKeyW(hkey
, namesW
[j
], &hkey_handler
))
6039 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFByteStreamHandler
, (void **)handler
);
6040 RegCloseKey(hkey_handler
);
6055 static const GUID CLSID_GStreamerByteStreamHandler
= {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
6056 hr
= CoCreateInstance(&CLSID_GStreamerByteStreamHandler
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFByteStreamHandler
, (void **)handler
);
6059 CoTaskMemFree(mimeW
);
6063 static HRESULT
resolver_create_scheme_handler(const WCHAR
*scheme
, DWORD flags
, IMFSchemeHandler
**handler
)
6065 static const char schemehandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers";
6066 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6067 HRESULT hr
= MF_E_UNSUPPORTED_SCHEME
;
6070 TRACE("%s, %#x, %p.\n", debugstr_w(scheme
), flags
, handler
);
6074 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6076 struct local_handler
*local_handler
;
6078 EnterCriticalSection(&local_handlers_section
);
6080 LIST_FOR_EACH_ENTRY(local_handler
, &local_scheme_handlers
, struct local_handler
, entry
)
6082 if (!lstrcmpiW(scheme
, local_handler
->u
.scheme
))
6084 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFSchemeHandler
,
6090 LeaveCriticalSection(&local_handlers_section
);
6096 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6098 HKEY hkey
, hkey_handler
;
6100 hr
= MF_E_UNSUPPORTED_SCHEME
;
6102 if (RegOpenKeyA(hkey_roots
[i
], schemehandlerspath
, &hkey
))
6105 if (!RegOpenKeyW(hkey
, scheme
, &hkey_handler
))
6107 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFSchemeHandler
, (void **)handler
);
6108 RegCloseKey(hkey_handler
);
6120 static HRESULT
resolver_get_scheme_handler(const WCHAR
*url
, DWORD flags
, IMFSchemeHandler
**handler
)
6122 static const WCHAR fileschemeW
[] = L
"file:";
6123 const WCHAR
*ptr
= url
;
6128 /* RFC 3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
6131 WCHAR ch
= towlower(*ptr
);
6133 if (*ptr
== '*' && ptr
== url
)
6138 else if (!(*ptr
>= '0' && *ptr
<= '9') &&
6139 !(ch
>= 'a' && ch
<= 'z') &&
6140 *ptr
!= '+' && *ptr
!= '-' && *ptr
!= '.')
6148 /* Schemes must end with a ':', if not found try "file:" */
6149 if (ptr
== url
|| *ptr
!= ':')
6152 ptr
= fileschemeW
+ ARRAY_SIZE(fileschemeW
) - 1;
6156 scheme
= heap_alloc((len
+ 1) * sizeof(WCHAR
));
6158 return E_OUTOFMEMORY
;
6160 memcpy(scheme
, url
, len
* sizeof(WCHAR
));
6163 hr
= resolver_create_scheme_handler(scheme
, flags
, handler
);
6164 if (FAILED(hr
) && url
!= fileschemeW
)
6165 hr
= resolver_create_scheme_handler(fileschemeW
, flags
, handler
);
6172 static HRESULT
resolver_end_create_object(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
6173 IRtwqAsyncResult
*result
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**out
)
6175 struct resolver_queued_result
*queued_result
= NULL
, *iter
;
6179 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
6182 EnterCriticalSection(&resolver
->cs
);
6184 LIST_FOR_EACH_ENTRY(iter
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6186 if (iter
->inner_result
== result
|| (iter
->object
== object
&& iter
->origin
== origin
))
6188 list_remove(&iter
->entry
);
6189 queued_result
= iter
;
6194 LeaveCriticalSection(&resolver
->cs
);
6196 IUnknown_Release(object
);
6200 *out
= queued_result
->object
;
6201 *obj_type
= queued_result
->obj_type
;
6202 hr
= queued_result
->hr
;
6203 if (queued_result
->inner_result
)
6204 IRtwqAsyncResult_Release(queued_result
->inner_result
);
6205 heap_free(queued_result
);
6213 static HRESULT WINAPI
source_resolver_QueryInterface(IMFSourceResolver
*iface
, REFIID riid
, void **obj
)
6215 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6217 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
6219 if (IsEqualIID(riid
, &IID_IMFSourceResolver
) ||
6220 IsEqualIID(riid
, &IID_IUnknown
))
6222 *obj
= &resolver
->IMFSourceResolver_iface
;
6227 FIXME("unsupported interface %s\n", debugstr_guid(riid
));
6228 return E_NOINTERFACE
;
6231 IUnknown_AddRef((IUnknown
*)*obj
);
6235 static ULONG WINAPI
source_resolver_AddRef(IMFSourceResolver
*iface
)
6237 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6238 ULONG refcount
= InterlockedIncrement(&resolver
->refcount
);
6240 TRACE("%p, refcount %d.\n", iface
, refcount
);
6245 static ULONG WINAPI
source_resolver_Release(IMFSourceResolver
*iface
)
6247 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6248 ULONG refcount
= InterlockedDecrement(&resolver
->refcount
);
6249 struct resolver_queued_result
*result
, *result2
;
6251 TRACE("%p, refcount %d.\n", iface
, refcount
);
6255 LIST_FOR_EACH_ENTRY_SAFE(result
, result2
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6258 IUnknown_Release(result
->object
);
6259 list_remove(&result
->entry
);
6262 DeleteCriticalSection(&resolver
->cs
);
6263 heap_free(resolver
);
6269 static HRESULT WINAPI
source_resolver_CreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6270 DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6272 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6273 IMFSchemeHandler
*handler
;
6274 IRtwqAsyncResult
*result
;
6275 RTWQASYNCRESULT
*data
;
6278 TRACE("%p, %s, %#x, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6280 if (!url
|| !obj_type
|| !object
)
6283 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6286 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6287 IMFSchemeHandler_Release(handler
);
6291 data
= (RTWQASYNCRESULT
*)result
;
6292 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6294 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, NULL
, (IMFAsyncCallback
*)&resolver
->url_callback
,
6295 (IUnknown
*)result
);
6298 IRtwqAsyncResult_Release(result
);
6302 WaitForSingleObject(data
->hEvent
, INFINITE
);
6304 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_URL
, result
, obj_type
, object
);
6305 IRtwqAsyncResult_Release(result
);
6310 static HRESULT WINAPI
source_resolver_CreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6311 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6313 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6314 IMFByteStreamHandler
*handler
;
6315 IRtwqAsyncResult
*result
;
6316 RTWQASYNCRESULT
*data
;
6319 TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6321 if (!stream
|| !obj_type
|| !object
)
6324 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6325 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6327 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6328 IMFByteStreamHandler_Release(handler
);
6332 data
= (RTWQASYNCRESULT
*)result
;
6333 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6335 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
, NULL
,
6336 (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6339 IRtwqAsyncResult_Release(result
);
6343 WaitForSingleObject(data
->hEvent
, INFINITE
);
6345 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, result
, obj_type
, object
);
6346 IRtwqAsyncResult_Release(result
);
6351 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6352 DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
6354 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6355 IMFSchemeHandler
*handler
;
6356 IUnknown
*inner_cookie
= NULL
;
6357 IRtwqAsyncResult
*result
;
6360 TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
6362 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6366 *cancel_cookie
= NULL
;
6368 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6369 IMFSchemeHandler_Release(handler
);
6373 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, cancel_cookie
? &inner_cookie
: NULL
,
6374 (IMFAsyncCallback
*)&resolver
->url_callback
, (IUnknown
*)result
);
6376 if (SUCCEEDED(hr
) && inner_cookie
)
6377 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_URL
, inner_cookie
, cancel_cookie
);
6379 IRtwqAsyncResult_Release(result
);
6384 static HRESULT WINAPI
source_resolver_EndCreateObjectFromURL(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6385 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6387 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6389 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6391 return resolver_end_create_object(resolver
, OBJECT_FROM_URL
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6394 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6395 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
,
6398 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6399 IMFByteStreamHandler
*handler
;
6400 IUnknown
*inner_cookie
= NULL
;
6401 IRtwqAsyncResult
*result
;
6404 TRACE("%p, %p, %s, %#x, %p, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, cancel_cookie
,
6407 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6411 *cancel_cookie
= NULL
;
6413 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6414 IMFByteStreamHandler_Release(handler
);
6418 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
,
6419 cancel_cookie
? &inner_cookie
: NULL
, (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6421 /* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */
6422 if (SUCCEEDED(hr
) && inner_cookie
)
6423 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_BYTESTREAM
, inner_cookie
, cancel_cookie
);
6425 IRtwqAsyncResult_Release(result
);
6430 static HRESULT WINAPI
source_resolver_EndCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6431 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6433 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6435 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6437 return resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6440 static HRESULT WINAPI
source_resolver_CancelObjectCreation(IMFSourceResolver
*iface
, IUnknown
*cancel_cookie
)
6442 struct resolver_cancel_object
*object
;
6445 TRACE("%p, %p.\n", iface
, cancel_cookie
);
6447 if (!(object
= unsafe_impl_cancel_obj_from_IUnknown(cancel_cookie
)))
6448 return E_UNEXPECTED
;
6450 switch (object
->origin
)
6452 case OBJECT_FROM_BYTESTREAM
:
6453 hr
= IMFByteStreamHandler_CancelObjectCreation(object
->u
.stream_handler
, object
->cancel_cookie
);
6455 case OBJECT_FROM_URL
:
6456 hr
= IMFSchemeHandler_CancelObjectCreation(object
->u
.scheme_handler
, object
->cancel_cookie
);
6465 static const IMFSourceResolverVtbl mfsourceresolvervtbl
=
6467 source_resolver_QueryInterface
,
6468 source_resolver_AddRef
,
6469 source_resolver_Release
,
6470 source_resolver_CreateObjectFromURL
,
6471 source_resolver_CreateObjectFromByteStream
,
6472 source_resolver_BeginCreateObjectFromURL
,
6473 source_resolver_EndCreateObjectFromURL
,
6474 source_resolver_BeginCreateObjectFromByteStream
,
6475 source_resolver_EndCreateObjectFromByteStream
,
6476 source_resolver_CancelObjectCreation
,
6479 /***********************************************************************
6480 * MFCreateSourceResolver (mfplat.@)
6482 HRESULT WINAPI
MFCreateSourceResolver(IMFSourceResolver
**resolver
)
6484 struct source_resolver
*object
;
6486 TRACE("%p\n", resolver
);
6491 object
= heap_alloc_zero(sizeof(*object
));
6493 return E_OUTOFMEMORY
;
6495 object
->IMFSourceResolver_iface
.lpVtbl
= &mfsourceresolvervtbl
;
6496 object
->stream_callback
.lpVtbl
= &source_resolver_callback_stream_vtbl
;
6497 object
->url_callback
.lpVtbl
= &source_resolver_callback_url_vtbl
;
6498 object
->refcount
= 1;
6499 list_init(&object
->pending
);
6500 InitializeCriticalSection(&object
->cs
);
6502 *resolver
= &object
->IMFSourceResolver_iface
;
6509 struct attributes attributes
;
6510 IMFMediaEvent IMFMediaEvent_iface
;
6512 MediaEventType type
;
6518 static inline struct media_event
*impl_from_IMFMediaEvent(IMFMediaEvent
*iface
)
6520 return CONTAINING_RECORD(iface
, struct media_event
, IMFMediaEvent_iface
);
6523 static HRESULT WINAPI
mfmediaevent_QueryInterface(IMFMediaEvent
*iface
, REFIID riid
, void **out
)
6525 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6527 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
6529 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
6530 IsEqualGUID(riid
, &IID_IMFAttributes
) ||
6531 IsEqualGUID(riid
, &IID_IMFMediaEvent
))
6533 *out
= &event
->IMFMediaEvent_iface
;
6537 FIXME("%s, %p.\n", debugstr_guid(riid
), out
);
6539 return E_NOINTERFACE
;
6542 IUnknown_AddRef((IUnknown
*)*out
);
6546 static ULONG WINAPI
mfmediaevent_AddRef(IMFMediaEvent
*iface
)
6548 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6549 ULONG refcount
= InterlockedIncrement(&event
->attributes
.ref
);
6551 TRACE("%p, refcount %u.\n", iface
, refcount
);
6556 static ULONG WINAPI
mfmediaevent_Release(IMFMediaEvent
*iface
)
6558 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6559 ULONG refcount
= InterlockedDecrement(&event
->attributes
.ref
);
6561 TRACE("%p, refcount %u.\n", iface
, refcount
);
6565 clear_attributes_object(&event
->attributes
);
6566 PropVariantClear(&event
->value
);
6573 static HRESULT WINAPI
mfmediaevent_GetItem(IMFMediaEvent
*iface
, REFGUID key
, PROPVARIANT
*value
)
6575 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6577 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6579 return attributes_GetItem(&event
->attributes
, key
, value
);
6582 static HRESULT WINAPI
mfmediaevent_GetItemType(IMFMediaEvent
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
6584 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6586 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
6588 return attributes_GetItemType(&event
->attributes
, key
, type
);
6591 static HRESULT WINAPI
mfmediaevent_CompareItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
6593 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6595 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
6597 return attributes_CompareItem(&event
->attributes
, key
, value
, result
);
6600 static HRESULT WINAPI
mfmediaevent_Compare(IMFMediaEvent
*iface
, IMFAttributes
*attrs
, MF_ATTRIBUTES_MATCH_TYPE type
,
6603 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6605 TRACE("%p, %p, %d, %p.\n", iface
, attrs
, type
, result
);
6607 return attributes_Compare(&event
->attributes
, attrs
, type
, result
);
6610 static HRESULT WINAPI
mfmediaevent_GetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*value
)
6612 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6614 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6616 return attributes_GetUINT32(&event
->attributes
, key
, value
);
6619 static HRESULT WINAPI
mfmediaevent_GetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64
*value
)
6621 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6623 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6625 return attributes_GetUINT64(&event
->attributes
, key
, value
);
6628 static HRESULT WINAPI
mfmediaevent_GetDouble(IMFMediaEvent
*iface
, REFGUID key
, double *value
)
6630 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6632 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6634 return attributes_GetDouble(&event
->attributes
, key
, value
);
6637 static HRESULT WINAPI
mfmediaevent_GetGUID(IMFMediaEvent
*iface
, REFGUID key
, GUID
*value
)
6639 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6641 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6643 return attributes_GetGUID(&event
->attributes
, key
, value
);
6646 static HRESULT WINAPI
mfmediaevent_GetStringLength(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*length
)
6648 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6650 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
6652 return attributes_GetStringLength(&event
->attributes
, key
, length
);
6655 static HRESULT WINAPI
mfmediaevent_GetString(IMFMediaEvent
*iface
, REFGUID key
, WCHAR
*value
,
6656 UINT32 size
, UINT32
*length
)
6658 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6660 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
6662 return attributes_GetString(&event
->attributes
, key
, value
, size
, length
);
6665 static HRESULT WINAPI
mfmediaevent_GetAllocatedString(IMFMediaEvent
*iface
, REFGUID key
,
6666 WCHAR
**value
, UINT32
*length
)
6668 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6670 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
6672 return attributes_GetAllocatedString(&event
->attributes
, key
, value
, length
);
6675 static HRESULT WINAPI
mfmediaevent_GetBlobSize(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*size
)
6677 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6679 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
6681 return attributes_GetBlobSize(&event
->attributes
, key
, size
);
6684 static HRESULT WINAPI
mfmediaevent_GetBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
*buf
,
6685 UINT32 bufsize
, UINT32
*blobsize
)
6687 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6689 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
6691 return attributes_GetBlob(&event
->attributes
, key
, buf
, bufsize
, blobsize
);
6694 static HRESULT WINAPI
mfmediaevent_GetAllocatedBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
6696 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6698 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
6700 return attributes_GetAllocatedBlob(&event
->attributes
, key
, buf
, size
);
6703 static HRESULT WINAPI
mfmediaevent_GetUnknown(IMFMediaEvent
*iface
, REFGUID key
, REFIID riid
, void **out
)
6705 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6707 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
6709 return attributes_GetUnknown(&event
->attributes
, key
, riid
, out
);
6712 static HRESULT WINAPI
mfmediaevent_SetItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
)
6714 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6716 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
6718 return attributes_SetItem(&event
->attributes
, key
, value
);
6721 static HRESULT WINAPI
mfmediaevent_DeleteItem(IMFMediaEvent
*iface
, REFGUID key
)
6723 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6725 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
6727 return attributes_DeleteItem(&event
->attributes
, key
);
6730 static HRESULT WINAPI
mfmediaevent_DeleteAllItems(IMFMediaEvent
*iface
)
6732 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6734 TRACE("%p.\n", iface
);
6736 return attributes_DeleteAllItems(&event
->attributes
);
6739 static HRESULT WINAPI
mfmediaevent_SetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32 value
)
6741 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6743 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
6745 return attributes_SetUINT32(&event
->attributes
, key
, value
);
6748 static HRESULT WINAPI
mfmediaevent_SetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64 value
)
6750 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6752 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
6754 return attributes_SetUINT64(&event
->attributes
, key
, value
);
6757 static HRESULT WINAPI
mfmediaevent_SetDouble(IMFMediaEvent
*iface
, REFGUID key
, double value
)
6759 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6761 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
6763 return attributes_SetDouble(&event
->attributes
, key
, value
);
6766 static HRESULT WINAPI
mfmediaevent_SetGUID(IMFMediaEvent
*iface
, REFGUID key
, REFGUID value
)
6768 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6770 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
6772 return attributes_SetGUID(&event
->attributes
, key
, value
);
6775 static HRESULT WINAPI
mfmediaevent_SetString(IMFMediaEvent
*iface
, REFGUID key
, const WCHAR
*value
)
6777 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6779 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
6781 return attributes_SetString(&event
->attributes
, key
, value
);
6784 static HRESULT WINAPI
mfmediaevent_SetBlob(IMFMediaEvent
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
6786 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6788 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
6790 return attributes_SetBlob(&event
->attributes
, key
, buf
, size
);
6793 static HRESULT WINAPI
mfmediaevent_SetUnknown(IMFMediaEvent
*iface
, REFGUID key
, IUnknown
*unknown
)
6795 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6797 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
6799 return attributes_SetUnknown(&event
->attributes
, key
, unknown
);
6802 static HRESULT WINAPI
mfmediaevent_LockStore(IMFMediaEvent
*iface
)
6804 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6806 TRACE("%p.\n", iface
);
6808 return attributes_LockStore(&event
->attributes
);
6811 static HRESULT WINAPI
mfmediaevent_UnlockStore(IMFMediaEvent
*iface
)
6813 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6815 TRACE("%p.\n", iface
);
6817 return attributes_UnlockStore(&event
->attributes
);
6820 static HRESULT WINAPI
mfmediaevent_GetCount(IMFMediaEvent
*iface
, UINT32
*count
)
6822 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6824 TRACE("%p, %p.\n", iface
, count
);
6826 return attributes_GetCount(&event
->attributes
, count
);
6829 static HRESULT WINAPI
mfmediaevent_GetItemByIndex(IMFMediaEvent
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
6831 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6833 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
6835 return attributes_GetItemByIndex(&event
->attributes
, index
, key
, value
);
6838 static HRESULT WINAPI
mfmediaevent_CopyAllItems(IMFMediaEvent
*iface
, IMFAttributes
*dest
)
6840 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6842 TRACE("%p, %p.\n", iface
, dest
);
6844 return attributes_CopyAllItems(&event
->attributes
, dest
);
6847 static HRESULT WINAPI
mfmediaevent_GetType(IMFMediaEvent
*iface
, MediaEventType
*type
)
6849 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6851 TRACE("%p, %p.\n", iface
, type
);
6853 *type
= event
->type
;
6858 static HRESULT WINAPI
mfmediaevent_GetExtendedType(IMFMediaEvent
*iface
, GUID
*extended_type
)
6860 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6862 TRACE("%p, %p.\n", iface
, extended_type
);
6864 *extended_type
= event
->extended_type
;
6869 static HRESULT WINAPI
mfmediaevent_GetStatus(IMFMediaEvent
*iface
, HRESULT
*status
)
6871 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6873 TRACE("%p, %p.\n", iface
, status
);
6875 *status
= event
->status
;
6880 static HRESULT WINAPI
mfmediaevent_GetValue(IMFMediaEvent
*iface
, PROPVARIANT
*value
)
6882 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6884 TRACE("%p, %p.\n", iface
, value
);
6886 PropVariantCopy(value
, &event
->value
);
6891 static const IMFMediaEventVtbl mfmediaevent_vtbl
=
6893 mfmediaevent_QueryInterface
,
6894 mfmediaevent_AddRef
,
6895 mfmediaevent_Release
,
6896 mfmediaevent_GetItem
,
6897 mfmediaevent_GetItemType
,
6898 mfmediaevent_CompareItem
,
6899 mfmediaevent_Compare
,
6900 mfmediaevent_GetUINT32
,
6901 mfmediaevent_GetUINT64
,
6902 mfmediaevent_GetDouble
,
6903 mfmediaevent_GetGUID
,
6904 mfmediaevent_GetStringLength
,
6905 mfmediaevent_GetString
,
6906 mfmediaevent_GetAllocatedString
,
6907 mfmediaevent_GetBlobSize
,
6908 mfmediaevent_GetBlob
,
6909 mfmediaevent_GetAllocatedBlob
,
6910 mfmediaevent_GetUnknown
,
6911 mfmediaevent_SetItem
,
6912 mfmediaevent_DeleteItem
,
6913 mfmediaevent_DeleteAllItems
,
6914 mfmediaevent_SetUINT32
,
6915 mfmediaevent_SetUINT64
,
6916 mfmediaevent_SetDouble
,
6917 mfmediaevent_SetGUID
,
6918 mfmediaevent_SetString
,
6919 mfmediaevent_SetBlob
,
6920 mfmediaevent_SetUnknown
,
6921 mfmediaevent_LockStore
,
6922 mfmediaevent_UnlockStore
,
6923 mfmediaevent_GetCount
,
6924 mfmediaevent_GetItemByIndex
,
6925 mfmediaevent_CopyAllItems
,
6926 mfmediaevent_GetType
,
6927 mfmediaevent_GetExtendedType
,
6928 mfmediaevent_GetStatus
,
6929 mfmediaevent_GetValue
,
6932 /***********************************************************************
6933 * MFCreateMediaEvent (mfplat.@)
6935 HRESULT WINAPI
MFCreateMediaEvent(MediaEventType type
, REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
,
6936 IMFMediaEvent
**event
)
6938 struct media_event
*object
;
6941 TRACE("%s, %s, %#x, %s, %p.\n", debugstr_eventid(type
), debugstr_guid(extended_type
), status
,
6942 debugstr_propvar(value
), event
);
6944 object
= heap_alloc(sizeof(*object
));
6946 return E_OUTOFMEMORY
;
6948 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
6953 object
->IMFMediaEvent_iface
.lpVtbl
= &mfmediaevent_vtbl
;
6955 object
->type
= type
;
6956 object
->extended_type
= *extended_type
;
6957 object
->status
= status
;
6959 PropVariantInit(&object
->value
);
6961 PropVariantCopy(&object
->value
, value
);
6963 *event
= &object
->IMFMediaEvent_iface
;
6965 TRACE("Created event %p.\n", *event
);
6972 IMFMediaEventQueue IMFMediaEventQueue_iface
;
6975 CRITICAL_SECTION cs
;
6976 CONDITION_VARIABLE update_event
;
6980 IRtwqAsyncResult
*subscriber
;
6986 IMFMediaEvent
*event
;
6989 static inline struct event_queue
*impl_from_IMFMediaEventQueue(IMFMediaEventQueue
*iface
)
6991 return CONTAINING_RECORD(iface
, struct event_queue
, IMFMediaEventQueue_iface
);
6994 static IMFMediaEvent
*queue_pop_event(struct event_queue
*queue
)
6996 struct list
*head
= list_head(&queue
->events
);
6997 struct queued_event
*queued_event
;
6998 IMFMediaEvent
*event
;
7003 queued_event
= LIST_ENTRY(head
, struct queued_event
, entry
);
7004 event
= queued_event
->event
;
7005 list_remove(&queued_event
->entry
);
7006 heap_free(queued_event
);
7010 static void event_queue_clear_subscriber(struct event_queue
*queue
)
7012 if (queue
->subscriber
)
7013 IRtwqAsyncResult_Release(queue
->subscriber
);
7014 queue
->subscriber
= NULL
;
7017 static void event_queue_cleanup(struct event_queue
*queue
)
7019 IMFMediaEvent
*event
;
7021 while ((event
= queue_pop_event(queue
)))
7022 IMFMediaEvent_Release(event
);
7023 event_queue_clear_subscriber(queue
);
7026 static HRESULT WINAPI
eventqueue_QueryInterface(IMFMediaEventQueue
*iface
, REFIID riid
, void **out
)
7028 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7030 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7032 if (IsEqualIID(riid
, &IID_IMFMediaEventQueue
) ||
7033 IsEqualIID(riid
, &IID_IUnknown
))
7035 *out
= &queue
->IMFMediaEventQueue_iface
;
7036 IMFMediaEventQueue_AddRef(iface
);
7040 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7042 return E_NOINTERFACE
;
7045 static ULONG WINAPI
eventqueue_AddRef(IMFMediaEventQueue
*iface
)
7047 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7048 ULONG refcount
= InterlockedIncrement(&queue
->refcount
);
7050 TRACE("%p, refcount %u.\n", iface
, refcount
);
7055 static ULONG WINAPI
eventqueue_Release(IMFMediaEventQueue
*iface
)
7057 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7058 ULONG refcount
= InterlockedDecrement(&queue
->refcount
);
7060 TRACE("%p, refcount %u.\n", queue
, refcount
);
7064 event_queue_cleanup(queue
);
7065 DeleteCriticalSection(&queue
->cs
);
7072 static HRESULT WINAPI
eventqueue_GetEvent(IMFMediaEventQueue
*iface
, DWORD flags
, IMFMediaEvent
**event
)
7074 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7077 TRACE("%p, %p.\n", iface
, event
);
7079 EnterCriticalSection(&queue
->cs
);
7081 if (queue
->is_shut_down
)
7083 else if (queue
->subscriber
)
7084 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7087 if (flags
& MF_EVENT_FLAG_NO_WAIT
)
7089 if (!(*event
= queue_pop_event(queue
)))
7090 hr
= MF_E_NO_EVENTS_AVAILABLE
;
7094 while (list_empty(&queue
->events
) && !queue
->is_shut_down
)
7096 SleepConditionVariableCS(&queue
->update_event
, &queue
->cs
, INFINITE
);
7098 *event
= queue_pop_event(queue
);
7099 if (queue
->is_shut_down
)
7104 LeaveCriticalSection(&queue
->cs
);
7109 static void queue_notify_subscriber(struct event_queue
*queue
)
7111 if (list_empty(&queue
->events
) || !queue
->subscriber
|| queue
->notified
)
7114 queue
->notified
= TRUE
;
7115 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, queue
->subscriber
);
7118 static HRESULT WINAPI
eventqueue_BeginGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
7120 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7121 RTWQASYNCRESULT
*result_data
;
7124 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
7127 return E_INVALIDARG
;
7129 EnterCriticalSection(&queue
->cs
);
7131 if (queue
->is_shut_down
)
7133 else if ((result_data
= (RTWQASYNCRESULT
*)queue
->subscriber
))
7135 if (result_data
->pCallback
== (IRtwqAsyncCallback
*)callback
)
7136 hr
= IRtwqAsyncResult_GetStateNoAddRef(queue
->subscriber
) == state
?
7137 MF_S_MULTIPLE_BEGIN
: MF_E_MULTIPLE_BEGIN
;
7139 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7143 hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &queue
->subscriber
);
7145 queue_notify_subscriber(queue
);
7148 LeaveCriticalSection(&queue
->cs
);
7153 static HRESULT WINAPI
eventqueue_EndGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
7155 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7156 HRESULT hr
= E_FAIL
;
7158 TRACE("%p, %p, %p.\n", iface
, result
, event
);
7160 EnterCriticalSection(&queue
->cs
);
7162 if (queue
->is_shut_down
)
7164 else if (queue
->subscriber
== (IRtwqAsyncResult
*)result
)
7166 *event
= queue_pop_event(queue
);
7167 event_queue_clear_subscriber(queue
);
7168 queue
->notified
= FALSE
;
7169 hr
= *event
? S_OK
: E_FAIL
;
7172 LeaveCriticalSection(&queue
->cs
);
7177 static HRESULT
eventqueue_queue_event(struct event_queue
*queue
, IMFMediaEvent
*event
)
7179 struct queued_event
*queued_event
;
7182 queued_event
= heap_alloc(sizeof(*queued_event
));
7184 return E_OUTOFMEMORY
;
7186 queued_event
->event
= event
;
7188 EnterCriticalSection(&queue
->cs
);
7190 if (queue
->is_shut_down
)
7194 IMFMediaEvent_AddRef(queued_event
->event
);
7195 list_add_tail(&queue
->events
, &queued_event
->entry
);
7196 queue_notify_subscriber(queue
);
7199 LeaveCriticalSection(&queue
->cs
);
7202 heap_free(queued_event
);
7204 WakeAllConditionVariable(&queue
->update_event
);
7209 static HRESULT WINAPI
eventqueue_QueueEvent(IMFMediaEventQueue
*iface
, IMFMediaEvent
*event
)
7211 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7213 TRACE("%p, %p.\n", iface
, event
);
7215 return eventqueue_queue_event(queue
, event
);
7218 static HRESULT WINAPI
eventqueue_QueueEventParamVar(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7219 REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
)
7221 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7222 IMFMediaEvent
*event
;
7225 TRACE("%p, %s, %s, %#x, %s\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
,
7226 debugstr_propvar(value
));
7228 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, value
, &event
)))
7231 hr
= eventqueue_queue_event(queue
, event
);
7232 IMFMediaEvent_Release(event
);
7236 static HRESULT WINAPI
eventqueue_QueueEventParamUnk(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7237 REFGUID extended_type
, HRESULT status
, IUnknown
*unk
)
7239 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7240 IMFMediaEvent
*event
;
7244 TRACE("%p, %s, %s, %#x, %p.\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
, unk
);
7246 value
.vt
= VT_UNKNOWN
;
7247 value
.punkVal
= unk
;
7249 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, &value
, &event
)))
7252 hr
= eventqueue_queue_event(queue
, event
);
7253 IMFMediaEvent_Release(event
);
7257 static HRESULT WINAPI
eventqueue_Shutdown(IMFMediaEventQueue
*iface
)
7259 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7261 TRACE("%p\n", queue
);
7263 EnterCriticalSection(&queue
->cs
);
7265 if (!queue
->is_shut_down
)
7267 event_queue_cleanup(queue
);
7268 queue
->is_shut_down
= TRUE
;
7271 LeaveCriticalSection(&queue
->cs
);
7273 WakeAllConditionVariable(&queue
->update_event
);
7278 static const IMFMediaEventQueueVtbl eventqueuevtbl
=
7280 eventqueue_QueryInterface
,
7283 eventqueue_GetEvent
,
7284 eventqueue_BeginGetEvent
,
7285 eventqueue_EndGetEvent
,
7286 eventqueue_QueueEvent
,
7287 eventqueue_QueueEventParamVar
,
7288 eventqueue_QueueEventParamUnk
,
7292 /***********************************************************************
7293 * MFCreateEventQueue (mfplat.@)
7295 HRESULT WINAPI
MFCreateEventQueue(IMFMediaEventQueue
**queue
)
7297 struct event_queue
*object
;
7299 TRACE("%p\n", queue
);
7301 object
= heap_alloc_zero(sizeof(*object
));
7303 return E_OUTOFMEMORY
;
7305 object
->IMFMediaEventQueue_iface
.lpVtbl
= &eventqueuevtbl
;
7306 object
->refcount
= 1;
7307 list_init(&object
->events
);
7308 InitializeCriticalSection(&object
->cs
);
7309 InitializeConditionVariable(&object
->update_event
);
7311 *queue
= &object
->IMFMediaEventQueue_iface
;
7318 IMFCollection IMFCollection_iface
;
7320 IUnknown
**elements
;
7325 static struct collection
*impl_from_IMFCollection(IMFCollection
*iface
)
7327 return CONTAINING_RECORD(iface
, struct collection
, IMFCollection_iface
);
7330 static void collection_clear(struct collection
*collection
)
7334 for (i
= 0; i
< collection
->count
; ++i
)
7336 if (collection
->elements
[i
])
7337 IUnknown_Release(collection
->elements
[i
]);
7340 heap_free(collection
->elements
);
7341 collection
->elements
= NULL
;
7342 collection
->count
= 0;
7343 collection
->capacity
= 0;
7346 static HRESULT WINAPI
collection_QueryInterface(IMFCollection
*iface
, REFIID riid
, void **out
)
7348 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7350 if (IsEqualIID(riid
, &IID_IMFCollection
) ||
7351 IsEqualIID(riid
, &IID_IUnknown
))
7354 IMFCollection_AddRef(iface
);
7358 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
7360 return E_NOINTERFACE
;
7363 static ULONG WINAPI
collection_AddRef(IMFCollection
*iface
)
7365 struct collection
*collection
= impl_from_IMFCollection(iface
);
7366 ULONG refcount
= InterlockedIncrement(&collection
->refcount
);
7368 TRACE("%p, %d.\n", collection
, refcount
);
7373 static ULONG WINAPI
collection_Release(IMFCollection
*iface
)
7375 struct collection
*collection
= impl_from_IMFCollection(iface
);
7376 ULONG refcount
= InterlockedDecrement(&collection
->refcount
);
7378 TRACE("%p, %d.\n", collection
, refcount
);
7382 collection_clear(collection
);
7383 heap_free(collection
->elements
);
7384 heap_free(collection
);
7390 static HRESULT WINAPI
collection_GetElementCount(IMFCollection
*iface
, DWORD
*count
)
7392 struct collection
*collection
= impl_from_IMFCollection(iface
);
7394 TRACE("%p, %p.\n", iface
, count
);
7399 *count
= collection
->count
;
7404 static HRESULT WINAPI
collection_GetElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7406 struct collection
*collection
= impl_from_IMFCollection(iface
);
7408 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7413 if (idx
>= collection
->count
)
7414 return E_INVALIDARG
;
7416 *element
= collection
->elements
[idx
];
7418 IUnknown_AddRef(*element
);
7420 return *element
? S_OK
: E_UNEXPECTED
;
7423 static HRESULT WINAPI
collection_AddElement(IMFCollection
*iface
, IUnknown
*element
)
7425 struct collection
*collection
= impl_from_IMFCollection(iface
);
7427 TRACE("%p, %p.\n", iface
, element
);
7429 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, collection
->count
+ 1,
7430 sizeof(*collection
->elements
)))
7431 return E_OUTOFMEMORY
;
7433 collection
->elements
[collection
->count
++] = element
;
7435 IUnknown_AddRef(element
);
7440 static HRESULT WINAPI
collection_RemoveElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7442 struct collection
*collection
= impl_from_IMFCollection(iface
);
7445 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7450 if (idx
>= collection
->count
)
7451 return E_INVALIDARG
;
7453 *element
= collection
->elements
[idx
];
7455 count
= collection
->count
- idx
- 1;
7457 memmove(&collection
->elements
[idx
], &collection
->elements
[idx
+ 1], count
* sizeof(*collection
->elements
));
7458 collection
->count
--;
7463 static HRESULT WINAPI
collection_InsertElementAt(IMFCollection
*iface
, DWORD idx
, IUnknown
*element
)
7465 struct collection
*collection
= impl_from_IMFCollection(iface
);
7468 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7470 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, idx
+ 1,
7471 sizeof(*collection
->elements
)))
7472 return E_OUTOFMEMORY
;
7474 if (idx
< collection
->count
)
7476 memmove(&collection
->elements
[idx
+ 1], &collection
->elements
[idx
],
7477 (collection
->count
- idx
) * sizeof(*collection
->elements
));
7478 collection
->count
++;
7482 for (i
= collection
->count
; i
< idx
; ++i
)
7483 collection
->elements
[i
] = NULL
;
7484 collection
->count
= idx
+ 1;
7487 collection
->elements
[idx
] = element
;
7488 if (collection
->elements
[idx
])
7489 IUnknown_AddRef(collection
->elements
[idx
]);
7494 static HRESULT WINAPI
collection_RemoveAllElements(IMFCollection
*iface
)
7496 struct collection
*collection
= impl_from_IMFCollection(iface
);
7498 TRACE("%p.\n", iface
);
7500 collection_clear(collection
);
7505 static const IMFCollectionVtbl mfcollectionvtbl
=
7507 collection_QueryInterface
,
7510 collection_GetElementCount
,
7511 collection_GetElement
,
7512 collection_AddElement
,
7513 collection_RemoveElement
,
7514 collection_InsertElementAt
,
7515 collection_RemoveAllElements
,
7518 /***********************************************************************
7519 * MFCreateCollection (mfplat.@)
7521 HRESULT WINAPI
MFCreateCollection(IMFCollection
**collection
)
7523 struct collection
*object
;
7525 TRACE("%p\n", collection
);
7530 object
= heap_alloc_zero(sizeof(*object
));
7532 return E_OUTOFMEMORY
;
7534 object
->IMFCollection_iface
.lpVtbl
= &mfcollectionvtbl
;
7535 object
->refcount
= 1;
7537 *collection
= &object
->IMFCollection_iface
;
7542 /***********************************************************************
7543 * MFHeapAlloc (mfplat.@)
7545 void *WINAPI
MFHeapAlloc(SIZE_T size
, ULONG flags
, char *file
, int line
, EAllocationType type
)
7547 TRACE("%lu, %#x, %s, %d, %#x.\n", size
, flags
, debugstr_a(file
), line
, type
);
7548 return HeapAlloc(GetProcessHeap(), flags
, size
);
7551 /***********************************************************************
7552 * MFHeapFree (mfplat.@)
7554 void WINAPI
MFHeapFree(void *p
)
7557 HeapFree(GetProcessHeap(), 0, p
);
7560 /***********************************************************************
7561 * MFCreateMFByteStreamOnStreamEx (mfplat.@)
7563 HRESULT WINAPI
MFCreateMFByteStreamOnStreamEx(IUnknown
*stream
, IMFByteStream
**bytestream
)
7565 FIXME("(%p, %p): stub\n", stream
, bytestream
);
7570 static HRESULT WINAPI
system_clock_QueryInterface(IMFClock
*iface
, REFIID riid
, void **obj
)
7572 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7574 if (IsEqualIID(riid
, &IID_IMFClock
) ||
7575 IsEqualIID(riid
, &IID_IUnknown
))
7578 IMFClock_AddRef(iface
);
7582 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7584 return E_NOINTERFACE
;
7587 static ULONG WINAPI
system_clock_AddRef(IMFClock
*iface
)
7589 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7590 ULONG refcount
= InterlockedIncrement(&clock
->refcount
);
7592 TRACE("%p, refcount %u.\n", iface
, refcount
);
7597 static ULONG WINAPI
system_clock_Release(IMFClock
*iface
)
7599 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7600 ULONG refcount
= InterlockedDecrement(&clock
->refcount
);
7602 TRACE("%p, refcount %u.\n", iface
, refcount
);
7610 static HRESULT WINAPI
system_clock_GetClockCharacteristics(IMFClock
*iface
, DWORD
*flags
)
7612 TRACE("%p, %p.\n", iface
, flags
);
7614 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING
|
7615 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7620 static HRESULT WINAPI
system_clock_GetCorrelatedTime(IMFClock
*iface
, DWORD reserved
, LONGLONG
*clock_time
,
7621 MFTIME
*system_time
)
7623 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7625 *clock_time
= *system_time
= MFGetSystemTime();
7630 static HRESULT WINAPI
system_clock_GetContinuityKey(IMFClock
*iface
, DWORD
*key
)
7632 TRACE("%p, %p.\n", iface
, key
);
7639 static HRESULT WINAPI
system_clock_GetState(IMFClock
*iface
, DWORD reserved
, MFCLOCK_STATE
*state
)
7641 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7643 *state
= MFCLOCK_STATE_RUNNING
;
7648 static HRESULT WINAPI
system_clock_GetProperties(IMFClock
*iface
, MFCLOCK_PROPERTIES
*props
)
7650 TRACE("%p, %p.\n", iface
, props
);
7655 memset(props
, 0, sizeof(*props
));
7656 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7657 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7658 props
->dwClockJitter
= 1;
7663 static const IMFClockVtbl system_clock_vtbl
=
7665 system_clock_QueryInterface
,
7666 system_clock_AddRef
,
7667 system_clock_Release
,
7668 system_clock_GetClockCharacteristics
,
7669 system_clock_GetCorrelatedTime
,
7670 system_clock_GetContinuityKey
,
7671 system_clock_GetState
,
7672 system_clock_GetProperties
,
7675 static HRESULT
create_system_clock(IMFClock
**clock
)
7677 struct system_clock
*object
;
7679 if (!(object
= heap_alloc(sizeof(*object
))))
7680 return E_OUTOFMEMORY
;
7682 object
->IMFClock_iface
.lpVtbl
= &system_clock_vtbl
;
7683 object
->refcount
= 1;
7685 *clock
= &object
->IMFClock_iface
;
7690 static HRESULT WINAPI
system_time_source_QueryInterface(IMFPresentationTimeSource
*iface
, REFIID riid
, void **obj
)
7692 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7694 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7696 if (IsEqualIID(riid
, &IID_IMFPresentationTimeSource
) ||
7697 IsEqualIID(riid
, &IID_IUnknown
))
7699 *obj
= &source
->IMFPresentationTimeSource_iface
;
7701 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
7703 *obj
= &source
->IMFClockStateSink_iface
;
7707 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7709 return E_NOINTERFACE
;
7712 IUnknown_AddRef((IUnknown
*)*obj
);
7716 static ULONG WINAPI
system_time_source_AddRef(IMFPresentationTimeSource
*iface
)
7718 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7719 ULONG refcount
= InterlockedIncrement(&source
->refcount
);
7721 TRACE("%p, refcount %u.\n", iface
, refcount
);
7726 static ULONG WINAPI
system_time_source_Release(IMFPresentationTimeSource
*iface
)
7728 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7729 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
7731 TRACE("%p, refcount %u.\n", iface
, refcount
);
7736 IMFClock_Release(source
->clock
);
7737 DeleteCriticalSection(&source
->cs
);
7744 static HRESULT WINAPI
system_time_source_GetClockCharacteristics(IMFPresentationTimeSource
*iface
, DWORD
*flags
)
7746 TRACE("%p, %p.\n", iface
, flags
);
7748 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7753 static HRESULT WINAPI
system_time_source_GetCorrelatedTime(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7754 LONGLONG
*clock_time
, MFTIME
*system_time
)
7756 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7759 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7761 EnterCriticalSection(&source
->cs
);
7762 if (SUCCEEDED(hr
= IMFClock_GetCorrelatedTime(source
->clock
, 0, clock_time
, system_time
)))
7764 if (source
->state
== MFCLOCK_STATE_RUNNING
)
7766 system_time_source_apply_rate(source
, clock_time
);
7767 *clock_time
+= source
->start_offset
;
7770 *clock_time
= source
->start_offset
;
7772 LeaveCriticalSection(&source
->cs
);
7777 static HRESULT WINAPI
system_time_source_GetContinuityKey(IMFPresentationTimeSource
*iface
, DWORD
*key
)
7779 TRACE("%p, %p.\n", iface
, key
);
7786 static HRESULT WINAPI
system_time_source_GetState(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7787 MFCLOCK_STATE
*state
)
7789 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7791 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7793 EnterCriticalSection(&source
->cs
);
7794 *state
= source
->state
;
7795 LeaveCriticalSection(&source
->cs
);
7800 static HRESULT WINAPI
system_time_source_GetProperties(IMFPresentationTimeSource
*iface
, MFCLOCK_PROPERTIES
*props
)
7802 TRACE("%p, %p.\n", iface
, props
);
7807 memset(props
, 0, sizeof(*props
));
7808 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7809 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7810 props
->dwClockJitter
= 1;
7815 static HRESULT WINAPI
system_time_source_GetUnderlyingClock(IMFPresentationTimeSource
*iface
, IMFClock
**clock
)
7817 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7819 TRACE("%p, %p.\n", iface
, clock
);
7821 *clock
= source
->clock
;
7822 IMFClock_AddRef(*clock
);
7827 static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl
=
7829 system_time_source_QueryInterface
,
7830 system_time_source_AddRef
,
7831 system_time_source_Release
,
7832 system_time_source_GetClockCharacteristics
,
7833 system_time_source_GetCorrelatedTime
,
7834 system_time_source_GetContinuityKey
,
7835 system_time_source_GetState
,
7836 system_time_source_GetProperties
,
7837 system_time_source_GetUnderlyingClock
,
7840 static HRESULT WINAPI
system_time_source_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **out
)
7842 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7843 return IMFPresentationTimeSource_QueryInterface(&source
->IMFPresentationTimeSource_iface
, riid
, out
);
7846 static ULONG WINAPI
system_time_source_sink_AddRef(IMFClockStateSink
*iface
)
7848 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7849 return IMFPresentationTimeSource_AddRef(&source
->IMFPresentationTimeSource_iface
);
7852 static ULONG WINAPI
system_time_source_sink_Release(IMFClockStateSink
*iface
)
7854 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7855 return IMFPresentationTimeSource_Release(&source
->IMFPresentationTimeSource_iface
);
7860 CLOCK_CMD_START
= 0,
7867 static HRESULT
system_time_source_change_state(struct system_time_source
*source
, enum clock_command command
)
7869 static const BYTE state_change_is_allowed
[MFCLOCK_STATE_PAUSED
+1][CLOCK_CMD_MAX
] =
7871 /* INVALID */ { 1, 0, 1, 0 },
7872 /* RUNNING */ { 1, 1, 1, 0 },
7873 /* STOPPED */ { 1, 1, 0, 0 },
7874 /* PAUSED */ { 1, 1, 0, 1 },
7876 static const MFCLOCK_STATE states
[CLOCK_CMD_MAX
] =
7878 /* CLOCK_CMD_START */ MFCLOCK_STATE_RUNNING
,
7879 /* CLOCK_CMD_STOP */ MFCLOCK_STATE_STOPPED
,
7880 /* CLOCK_CMD_PAUSE */ MFCLOCK_STATE_PAUSED
,
7881 /* CLOCK_CMD_RESTART */ MFCLOCK_STATE_RUNNING
,
7884 /* Special case that go against usual state change vs return value behavior. */
7885 if (source
->state
== MFCLOCK_STATE_INVALID
&& command
== CLOCK_CMD_STOP
)
7888 if (!state_change_is_allowed
[source
->state
][command
])
7889 return MF_E_INVALIDREQUEST
;
7891 source
->state
= states
[command
];
7896 static HRESULT WINAPI
system_time_source_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
,
7897 LONGLONG start_offset
)
7899 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7900 MFCLOCK_STATE state
;
7903 TRACE("%p, %s, %s.\n", iface
, debugstr_time(system_time
), debugstr_time(start_offset
));
7905 EnterCriticalSection(&source
->cs
);
7906 state
= source
->state
;
7907 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_START
)))
7909 system_time_source_apply_rate(source
, &system_time
);
7910 if (start_offset
== PRESENTATION_CURRENT_POSITION
)
7914 case MFCLOCK_STATE_RUNNING
:
7916 case MFCLOCK_STATE_PAUSED
:
7917 source
->start_offset
-= system_time
;
7920 source
->start_offset
= -system_time
;
7927 source
->start_offset
= -system_time
+ start_offset
;
7930 LeaveCriticalSection(&source
->cs
);
7935 static HRESULT WINAPI
system_time_source_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
7937 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7940 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7942 EnterCriticalSection(&source
->cs
);
7943 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_STOP
)))
7944 source
->start_offset
= 0;
7945 LeaveCriticalSection(&source
->cs
);
7950 static HRESULT WINAPI
system_time_source_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
7952 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7955 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7957 EnterCriticalSection(&source
->cs
);
7958 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_PAUSE
)))
7960 system_time_source_apply_rate(source
, &system_time
);
7961 source
->start_offset
+= system_time
;
7963 LeaveCriticalSection(&source
->cs
);
7968 static HRESULT WINAPI
system_time_source_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
7970 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7973 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7975 EnterCriticalSection(&source
->cs
);
7976 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_RESTART
)))
7978 system_time_source_apply_rate(source
, &system_time
);
7979 source
->start_offset
-= system_time
;
7981 LeaveCriticalSection(&source
->cs
);
7986 static HRESULT WINAPI
system_time_source_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
7988 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7991 TRACE("%p, %s, %f.\n", iface
, debugstr_time(system_time
), rate
);
7994 return MF_E_UNSUPPORTED_RATE
;
7996 modf(rate
, &intpart
);
7998 EnterCriticalSection(&source
->cs
);
7999 source
->rate
= rate
;
8000 source
->i_rate
= rate
== intpart
? rate
: 0;
8001 LeaveCriticalSection(&source
->cs
);
8006 static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl
=
8008 system_time_source_sink_QueryInterface
,
8009 system_time_source_sink_AddRef
,
8010 system_time_source_sink_Release
,
8011 system_time_source_sink_OnClockStart
,
8012 system_time_source_sink_OnClockStop
,
8013 system_time_source_sink_OnClockPause
,
8014 system_time_source_sink_OnClockRestart
,
8015 system_time_source_sink_OnClockSetRate
,
8018 /***********************************************************************
8019 * MFCreateSystemTimeSource (mfplat.@)
8021 HRESULT WINAPI
MFCreateSystemTimeSource(IMFPresentationTimeSource
**time_source
)
8023 struct system_time_source
*object
;
8026 TRACE("%p.\n", time_source
);
8028 object
= heap_alloc_zero(sizeof(*object
));
8030 return E_OUTOFMEMORY
;
8032 object
->IMFPresentationTimeSource_iface
.lpVtbl
= &systemtimesourcevtbl
;
8033 object
->IMFClockStateSink_iface
.lpVtbl
= &systemtimesourcesinkvtbl
;
8034 object
->refcount
= 1;
8035 object
->rate
= 1.0f
;
8037 InitializeCriticalSection(&object
->cs
);
8039 if (FAILED(hr
= create_system_clock(&object
->clock
)))
8041 IMFPresentationTimeSource_Release(&object
->IMFPresentationTimeSource_iface
);
8045 *time_source
= &object
->IMFPresentationTimeSource_iface
;
8050 struct async_create_file
8052 IRtwqAsyncCallback IRtwqAsyncCallback_iface
;
8054 MF_FILE_ACCESSMODE access_mode
;
8055 MF_FILE_OPENMODE open_mode
;
8056 MF_FILE_FLAGS flags
;
8060 struct async_create_file_result
8063 IRtwqAsyncResult
*result
;
8064 IMFByteStream
*stream
;
8067 static struct list async_create_file_results
= LIST_INIT(async_create_file_results
);
8068 static CRITICAL_SECTION async_create_file_cs
= { NULL
, -1, 0, 0, 0, 0 };
8070 static struct async_create_file
*impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
8072 return CONTAINING_RECORD(iface
, struct async_create_file
, IRtwqAsyncCallback_iface
);
8075 static HRESULT WINAPI
async_create_file_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
8077 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
8078 IsEqualIID(riid
, &IID_IUnknown
))
8081 IRtwqAsyncCallback_AddRef(iface
);
8086 return E_NOINTERFACE
;
8089 static ULONG WINAPI
async_create_file_callback_AddRef(IRtwqAsyncCallback
*iface
)
8091 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8092 ULONG refcount
= InterlockedIncrement(&async
->refcount
);
8094 TRACE("%p, refcount %u.\n", iface
, refcount
);
8099 static ULONG WINAPI
async_create_file_callback_Release(IRtwqAsyncCallback
*iface
)
8101 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8102 ULONG refcount
= InterlockedDecrement(&async
->refcount
);
8104 TRACE("%p, refcount %u.\n", iface
, refcount
);
8108 heap_free(async
->path
);
8115 static HRESULT WINAPI
async_create_file_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
8120 static HRESULT WINAPI
async_create_file_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
8122 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8123 IRtwqAsyncResult
*caller
;
8124 IMFByteStream
*stream
;
8127 caller
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
8129 hr
= MFCreateFile(async
->access_mode
, async
->open_mode
, async
->flags
, async
->path
, &stream
);
8132 struct async_create_file_result
*result_item
;
8134 result_item
= heap_alloc(sizeof(*result_item
));
8137 result_item
->result
= caller
;
8138 IRtwqAsyncResult_AddRef(caller
);
8139 result_item
->stream
= stream
;
8140 IMFByteStream_AddRef(stream
);
8142 EnterCriticalSection(&async_create_file_cs
);
8143 list_add_tail(&async_create_file_results
, &result_item
->entry
);
8144 LeaveCriticalSection(&async_create_file_cs
);
8147 IMFByteStream_Release(stream
);
8150 IRtwqAsyncResult_SetStatus(caller
, hr
);
8152 RtwqInvokeCallback(caller
);
8157 static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl
=
8159 async_create_file_callback_QueryInterface
,
8160 async_create_file_callback_AddRef
,
8161 async_create_file_callback_Release
,
8162 async_create_file_callback_GetParameters
,
8163 async_create_file_callback_Invoke
,
8166 /***********************************************************************
8167 * MFBeginCreateFile (mfplat.@)
8169 HRESULT WINAPI
MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode
, MF_FILE_OPENMODE open_mode
, MF_FILE_FLAGS flags
,
8170 const WCHAR
*path
, IMFAsyncCallback
*callback
, IUnknown
*state
, IUnknown
**cancel_cookie
)
8172 struct async_create_file
*async
= NULL
;
8173 IRtwqAsyncResult
*caller
, *item
= NULL
;
8176 TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode
, open_mode
, flags
, debugstr_w(path
), callback
, state
,
8180 *cancel_cookie
= NULL
;
8182 if (FAILED(hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &caller
)))
8185 async
= heap_alloc(sizeof(*async
));
8192 async
->IRtwqAsyncCallback_iface
.lpVtbl
= &async_create_file_callback_vtbl
;
8193 async
->refcount
= 1;
8194 async
->access_mode
= access_mode
;
8195 async
->open_mode
= open_mode
;
8196 async
->flags
= flags
;
8197 if (FAILED(hr
= heap_strdupW(path
, &async
->path
)))
8200 hr
= RtwqCreateAsyncResult(NULL
, &async
->IRtwqAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
8206 *cancel_cookie
= (IUnknown
*)caller
;
8207 IUnknown_AddRef(*cancel_cookie
);
8210 hr
= RtwqInvokeCallback(item
);
8214 IRtwqAsyncCallback_Release(&async
->IRtwqAsyncCallback_iface
);
8216 IRtwqAsyncResult_Release(item
);
8218 IRtwqAsyncResult_Release(caller
);
8223 static HRESULT
async_create_file_pull_result(IUnknown
*unk
, IMFByteStream
**stream
)
8225 struct async_create_file_result
*item
;
8226 HRESULT hr
= MF_E_UNEXPECTED
;
8227 IRtwqAsyncResult
*result
;
8231 if (FAILED(IUnknown_QueryInterface(unk
, &IID_IRtwqAsyncResult
, (void **)&result
)))
8234 EnterCriticalSection(&async_create_file_cs
);
8236 LIST_FOR_EACH_ENTRY(item
, &async_create_file_results
, struct async_create_file_result
, entry
)
8238 if (result
== item
->result
)
8240 *stream
= item
->stream
;
8241 IRtwqAsyncResult_Release(item
->result
);
8242 list_remove(&item
->entry
);
8248 LeaveCriticalSection(&async_create_file_cs
);
8251 hr
= IRtwqAsyncResult_GetStatus(result
);
8253 IRtwqAsyncResult_Release(result
);
8258 /***********************************************************************
8259 * MFEndCreateFile (mfplat.@)
8261 HRESULT WINAPI
MFEndCreateFile(IMFAsyncResult
*result
, IMFByteStream
**stream
)
8263 TRACE("%p, %p.\n", result
, stream
);
8265 return async_create_file_pull_result((IUnknown
*)result
, stream
);
8268 /***********************************************************************
8269 * MFCancelCreateFile (mfplat.@)
8271 HRESULT WINAPI
MFCancelCreateFile(IUnknown
*cancel_cookie
)
8273 IMFByteStream
*stream
= NULL
;
8276 TRACE("%p.\n", cancel_cookie
);
8278 hr
= async_create_file_pull_result(cancel_cookie
, &stream
);
8281 IMFByteStream_Release(stream
);
8286 /***********************************************************************
8287 * MFRegisterLocalSchemeHandler (mfplat.@)
8289 HRESULT WINAPI
MFRegisterLocalSchemeHandler(const WCHAR
*scheme
, IMFActivate
*activate
)
8291 struct local_handler
*handler
;
8294 TRACE("%s, %p.\n", debugstr_w(scheme
), activate
);
8296 if (!scheme
|| !activate
)
8297 return E_INVALIDARG
;
8299 if (!(handler
= heap_alloc(sizeof(*handler
))))
8300 return E_OUTOFMEMORY
;
8302 if (FAILED(hr
= heap_strdupW(scheme
, &handler
->u
.scheme
)))
8307 handler
->activate
= activate
;
8308 IMFActivate_AddRef(handler
->activate
);
8310 EnterCriticalSection(&local_handlers_section
);
8311 list_add_head(&local_scheme_handlers
, &handler
->entry
);
8312 LeaveCriticalSection(&local_handlers_section
);
8317 /***********************************************************************
8318 * MFRegisterLocalByteStreamHandler (mfplat.@)
8320 HRESULT WINAPI
MFRegisterLocalByteStreamHandler(const WCHAR
*extension
, const WCHAR
*mime
, IMFActivate
*activate
)
8322 struct local_handler
*handler
;
8325 TRACE("%s, %s, %p.\n", debugstr_w(extension
), debugstr_w(mime
), activate
);
8327 if ((!extension
&& !mime
) || !activate
)
8328 return E_INVALIDARG
;
8330 if (!(handler
= heap_alloc_zero(sizeof(*handler
))))
8331 return E_OUTOFMEMORY
;
8333 hr
= heap_strdupW(extension
, &handler
->u
.bytestream
.extension
);
8335 hr
= heap_strdupW(mime
, &handler
->u
.bytestream
.mime
);
8340 EnterCriticalSection(&local_handlers_section
);
8341 list_add_head(&local_bytestream_handlers
, &handler
->entry
);
8342 LeaveCriticalSection(&local_handlers_section
);
8347 heap_free(handler
->u
.bytestream
.extension
);
8348 heap_free(handler
->u
.bytestream
.mime
);
8354 struct property_store
8356 IPropertyStore IPropertyStore_iface
;
8358 CRITICAL_SECTION cs
;
8359 size_t count
, capacity
;
8367 static struct property_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
8369 return CONTAINING_RECORD(iface
, struct property_store
, IPropertyStore_iface
);
8372 static HRESULT WINAPI
property_store_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
8374 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8376 if (IsEqualIID(riid
, &IID_IPropertyStore
) || IsEqualIID(riid
, &IID_IUnknown
))
8379 IPropertyStore_AddRef(iface
);
8384 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
8385 return E_NOINTERFACE
;
8388 static ULONG WINAPI
property_store_AddRef(IPropertyStore
*iface
)
8390 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8391 ULONG refcount
= InterlockedIncrement(&store
->refcount
);
8393 TRACE("%p, refcount %d.\n", iface
, refcount
);
8398 static ULONG WINAPI
property_store_Release(IPropertyStore
*iface
)
8400 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8401 ULONG refcount
= InterlockedDecrement(&store
->refcount
);
8403 TRACE("%p, refcount %d.\n", iface
, refcount
);
8407 DeleteCriticalSection(&store
->cs
);
8408 heap_free(store
->values
);
8415 static HRESULT WINAPI
property_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
8417 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8419 TRACE("%p, %p.\n", iface
, count
);
8422 return E_INVALIDARG
;
8424 EnterCriticalSection(&store
->cs
);
8425 *count
= store
->count
;
8426 LeaveCriticalSection(&store
->cs
);
8430 static HRESULT WINAPI
property_store_GetAt(IPropertyStore
*iface
, DWORD index
, PROPERTYKEY
*key
)
8432 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8434 TRACE("%p, %u, %p.\n", iface
, index
, key
);
8436 EnterCriticalSection(&store
->cs
);
8438 if (index
>= store
->count
)
8440 LeaveCriticalSection(&store
->cs
);
8441 return E_INVALIDARG
;
8444 *key
= store
->values
[index
].key
;
8446 LeaveCriticalSection(&store
->cs
);
8450 static HRESULT WINAPI
property_store_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
8452 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8455 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8458 return E_INVALIDARG
;
8463 EnterCriticalSection(&store
->cs
);
8465 for (i
= 0; i
< store
->count
; ++i
)
8467 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8469 PropVariantCopy(value
, &store
->values
[i
].value
);
8470 LeaveCriticalSection(&store
->cs
);
8475 LeaveCriticalSection(&store
->cs
);
8479 static HRESULT WINAPI
property_store_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
8481 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8484 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8486 EnterCriticalSection(&store
->cs
);
8488 for (i
= 0; i
< store
->count
; ++i
)
8490 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8492 PropVariantCopy(&store
->values
[i
].value
, value
);
8493 LeaveCriticalSection(&store
->cs
);
8498 if (!mf_array_reserve((void **)&store
->values
, &store
->capacity
, store
->count
+ 1, sizeof(*store
->values
)))
8500 LeaveCriticalSection(&store
->cs
);
8501 return E_OUTOFMEMORY
;
8504 store
->values
[store
->count
].key
= *key
;
8505 PropVariantCopy(&store
->values
[store
->count
].value
, value
);
8508 LeaveCriticalSection(&store
->cs
);
8512 static HRESULT WINAPI
property_store_Commit(IPropertyStore
*iface
)
8514 TRACE("%p.\n", iface
);
8519 static const IPropertyStoreVtbl property_store_vtbl
=
8521 property_store_QueryInterface
,
8522 property_store_AddRef
,
8523 property_store_Release
,
8524 property_store_GetCount
,
8525 property_store_GetAt
,
8526 property_store_GetValue
,
8527 property_store_SetValue
,
8528 property_store_Commit
,
8531 /***********************************************************************
8532 * CreatePropertyStore (mfplat.@)
8534 HRESULT WINAPI
CreatePropertyStore(IPropertyStore
**store
)
8536 struct property_store
*object
;
8538 TRACE("%p.\n", store
);
8541 return E_INVALIDARG
;
8543 if (!(object
= heap_alloc_zero(sizeof(*object
))))
8544 return E_OUTOFMEMORY
;
8546 object
->IPropertyStore_iface
.lpVtbl
= &property_store_vtbl
;
8547 object
->refcount
= 1;
8548 InitializeCriticalSection(&object
->cs
);
8550 TRACE("Created store %p.\n", object
);
8551 *store
= &object
->IPropertyStore_iface
;
8556 struct shared_dxgi_manager
8558 IMFDXGIDeviceManager
*manager
;
8563 static struct shared_dxgi_manager shared_dm
;
8564 static CRITICAL_SECTION shared_dm_cs
= { NULL
, -1, 0, 0, 0, 0 };
8566 enum dxgi_device_handle_flags
8568 DXGI_DEVICE_HANDLE_FLAG_OPEN
= 0x1,
8569 DXGI_DEVICE_HANDLE_FLAG_INVALID
= 0x2,
8570 DXGI_DEVICE_HANDLE_FLAG_LOCKED
= 0x4,
8573 struct dxgi_device_manager
8575 IMFDXGIDeviceManager IMFDXGIDeviceManager_iface
;
8578 IDXGIDevice
*device
;
8580 unsigned int *handles
;
8585 unsigned int locking_tid
;
8587 CRITICAL_SECTION cs
;
8588 CONDITION_VARIABLE lock
;
8591 static struct dxgi_device_manager
*impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager
*iface
)
8593 return CONTAINING_RECORD(iface
, struct dxgi_device_manager
, IMFDXGIDeviceManager_iface
);
8596 static HRESULT
dxgi_device_manager_get_handle_index(struct dxgi_device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
8598 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
8600 *idx
= (ULONG_PTR
)hdevice
- 1;
8604 static HRESULT WINAPI
dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager
*iface
, REFIID riid
, void **obj
)
8606 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8608 if (IsEqualIID(riid
, &IID_IMFDXGIDeviceManager
) ||
8609 IsEqualGUID(riid
, &IID_IUnknown
))
8612 IMFDXGIDeviceManager_AddRef(iface
);
8616 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8618 return E_NOINTERFACE
;
8621 static ULONG WINAPI
dxgi_device_manager_AddRef(IMFDXGIDeviceManager
*iface
)
8623 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8624 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
8626 TRACE("%p, refcount %u.\n", iface
, refcount
);
8631 static ULONG WINAPI
dxgi_device_manager_Release(IMFDXGIDeviceManager
*iface
)
8633 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8634 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
8636 TRACE("%p, refcount %u.\n", iface
, refcount
);
8640 if (manager
->device
)
8641 IDXGIDevice_Release(manager
->device
);
8642 DeleteCriticalSection(&manager
->cs
);
8643 heap_free(manager
->handles
);
8650 static void dxgi_device_manager_lock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8652 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
)
8655 manager
->handles
[idx
] |= DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8659 static void dxgi_device_manager_unlock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8661 if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
))
8664 manager
->handles
[idx
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8665 if (!--manager
->locks
)
8666 manager
->locking_tid
= 0;
8669 static HRESULT WINAPI
dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8671 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8675 TRACE("%p, %p.\n", iface
, hdevice
);
8677 EnterCriticalSection(&manager
->cs
);
8679 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8681 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8683 dxgi_device_manager_unlock_handle(manager
, idx
);
8684 manager
->handles
[idx
] = 0;
8685 if (idx
== manager
->count
- 1)
8692 LeaveCriticalSection(&manager
->cs
);
8694 WakeAllConditionVariable(&manager
->lock
);
8699 static HRESULT WINAPI
dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8700 REFIID riid
, void **service
)
8702 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8706 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), service
);
8708 EnterCriticalSection(&manager
->cs
);
8710 if (!manager
->device
)
8711 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8712 else if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8714 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8715 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8716 else if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8717 hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, service
);
8722 LeaveCriticalSection(&manager
->cs
);
8727 static HRESULT WINAPI
dxgi_device_manager_LockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8728 REFIID riid
, void **obj
, BOOL block
)
8730 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8734 TRACE("%p, %p, %s, %p, %d.\n", iface
, hdevice
, wine_dbgstr_guid(riid
), obj
, block
);
8736 EnterCriticalSection(&manager
->cs
);
8738 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8740 if (!manager
->device
)
8742 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8744 else if (manager
->locking_tid
== GetCurrentThreadId())
8746 if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8747 dxgi_device_manager_lock_handle(manager
, idx
);
8749 else if (manager
->locking_tid
&& !block
)
8751 hr
= MF_E_DXGI_VIDEO_DEVICE_LOCKED
;
8755 while (manager
->locking_tid
)
8757 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
8760 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8762 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8763 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8764 else if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8766 manager
->locking_tid
= GetCurrentThreadId();
8767 dxgi_device_manager_lock_handle(manager
, idx
);
8773 LeaveCriticalSection(&manager
->cs
);
8778 static HRESULT WINAPI
dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE
*hdevice
)
8780 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8784 TRACE("%p, %p.\n", iface
, hdevice
);
8788 EnterCriticalSection(&manager
->cs
);
8790 if (!manager
->device
)
8791 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8794 for (i
= 0; i
< manager
->count
; ++i
)
8796 if (!(manager
->handles
[i
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8798 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8799 *hdevice
= ULongToHandle(i
+ 1);
8804 if (mf_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
8805 sizeof(*manager
->handles
)))
8807 *hdevice
= ULongToHandle(manager
->count
+ 1);
8808 manager
->handles
[manager
->count
++] = DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8814 LeaveCriticalSection(&manager
->cs
);
8819 static HRESULT WINAPI
dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager
*iface
, IUnknown
*device
, UINT token
)
8821 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8822 IDXGIDevice
*dxgi_device
;
8825 TRACE("%p, %p, %u.\n", iface
, device
, token
);
8827 if (!device
|| token
!= manager
->token
)
8828 return E_INVALIDARG
;
8830 if (FAILED(IUnknown_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
)))
8831 return E_INVALIDARG
;
8833 EnterCriticalSection(&manager
->cs
);
8835 if (manager
->device
)
8837 for (i
= 0; i
< manager
->count
; ++i
)
8839 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_INVALID
;
8840 manager
->handles
[i
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8842 manager
->locking_tid
= 0;
8844 IDXGIDevice_Release(manager
->device
);
8846 manager
->device
= dxgi_device
;
8848 LeaveCriticalSection(&manager
->cs
);
8850 WakeAllConditionVariable(&manager
->lock
);
8855 static HRESULT WINAPI
dxgi_device_manager_TestDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8857 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8861 TRACE("%p, %p.\n", iface
, hdevice
);
8863 EnterCriticalSection(&manager
->cs
);
8865 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8867 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8868 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8869 else if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8873 LeaveCriticalSection(&manager
->cs
);
8878 static HRESULT WINAPI
dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8881 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8882 HRESULT hr
= E_FAIL
;
8885 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
8887 EnterCriticalSection(&manager
->cs
);
8889 if (SUCCEEDED(dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8891 hr
= manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
? S_OK
: E_INVALIDARG
;
8893 dxgi_device_manager_unlock_handle(manager
, idx
);
8896 LeaveCriticalSection(&manager
->cs
);
8898 WakeAllConditionVariable(&manager
->lock
);
8903 static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl
=
8905 dxgi_device_manager_QueryInterface
,
8906 dxgi_device_manager_AddRef
,
8907 dxgi_device_manager_Release
,
8908 dxgi_device_manager_CloseDeviceHandle
,
8909 dxgi_device_manager_GetVideoService
,
8910 dxgi_device_manager_LockDevice
,
8911 dxgi_device_manager_OpenDeviceHandle
,
8912 dxgi_device_manager_ResetDevice
,
8913 dxgi_device_manager_TestDevice
,
8914 dxgi_device_manager_UnlockDevice
,
8917 /***********************************************************************
8918 * MFCreateDXGIDeviceManager (mfplat.@)
8920 HRESULT WINAPI
MFCreateDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
8922 struct dxgi_device_manager
*object
;
8924 TRACE("%p, %p.\n", token
, manager
);
8926 if (!token
|| !manager
)
8929 if (!(object
= heap_alloc_zero(sizeof(*object
))))
8930 return E_OUTOFMEMORY
;
8932 object
->IMFDXGIDeviceManager_iface
.lpVtbl
= &dxgi_device_manager_vtbl
;
8933 object
->refcount
= 1;
8934 object
->token
= GetTickCount();
8935 InitializeCriticalSection(&object
->cs
);
8936 InitializeConditionVariable(&object
->lock
);
8938 TRACE("Created device manager: %p, token: %u.\n", object
, object
->token
);
8940 *token
= object
->token
;
8941 *manager
= &object
->IMFDXGIDeviceManager_iface
;
8946 /***********************************************************************
8947 * MFLockDXGIDeviceManager (mfplat.@)
8949 HRESULT WINAPI
MFLockDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
8953 TRACE("%p, %p.\n", token
, manager
);
8955 EnterCriticalSection(&shared_dm_cs
);
8957 if (!shared_dm
.manager
)
8958 hr
= MFCreateDXGIDeviceManager(&shared_dm
.token
, &shared_dm
.manager
);
8962 *manager
= shared_dm
.manager
;
8963 IMFDXGIDeviceManager_AddRef(*manager
);
8966 if (token
) *token
= shared_dm
.token
;
8969 LeaveCriticalSection(&shared_dm_cs
);
8974 /***********************************************************************
8975 * MFUnlockDXGIDeviceManager (mfplat.@)
8977 HRESULT WINAPI
MFUnlockDXGIDeviceManager(void)
8981 EnterCriticalSection(&shared_dm_cs
);
8983 if (shared_dm
.manager
)
8985 IMFDXGIDeviceManager_Release(shared_dm
.manager
);
8986 if (!--shared_dm
.locks
)
8988 shared_dm
.manager
= NULL
;
8989 shared_dm
.token
= 0;
8993 LeaveCriticalSection(&shared_dm_cs
);
9000 * MFllMulDiv implementation is derived from gstreamer utility functions code (gstutils.c),
9001 * released under LGPL2. Full authors list follows.
9002 * ===================================================================================
9003 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
9004 * 2000 Wim Taymans <wtay@chello.be>
9005 * 2002 Thomas Vander Stichele <thomas@apestaart.org>
9006 * 2004 Wim Taymans <wim@fluendo.com>
9007 * 2015 Jan Schmidt <jan@centricular.com>
9008 * ===================================================================================
9011 static void llmult128(ULARGE_INTEGER
*c1
, ULARGE_INTEGER
*c0
, LONGLONG val
, LONGLONG num
)
9013 ULARGE_INTEGER a1
, b0
, v
, n
;
9015 v
.QuadPart
= llabs(val
);
9016 n
.QuadPart
= llabs(num
);
9018 /* do 128 bits multiply
9026 * -------------------
9029 * "a0" is optimized away, result is stored directly in c0. "b1" is
9030 * optimized away, result is stored directly in c1.
9032 c0
->QuadPart
= (ULONGLONG
)v
.LowPart
* n
.LowPart
;
9033 a1
.QuadPart
= (ULONGLONG
)v
.LowPart
* n
.HighPart
;
9034 b0
.QuadPart
= (ULONGLONG
)v
.HighPart
* n
.LowPart
;
9036 /* add the high word of a0 to the low words of a1 and b0 using c1 as
9037 * scrach space to capture the carry. the low word of the result becomes
9038 * the final high word of c0 */
9039 c1
->QuadPart
= (ULONGLONG
)c0
->HighPart
+ a1
.LowPart
+ b0
.LowPart
;
9040 c0
->HighPart
= c1
->LowPart
;
9042 /* add the carry from the result above (found in the high word of c1) and
9043 * the high words of a1 and b0 to b1, the result is c1. */
9044 c1
->QuadPart
= (ULONGLONG
)v
.HighPart
* n
.HighPart
+ c1
->HighPart
+ a1
.HighPart
+ b0
.HighPart
;
9047 static ULONGLONG
lldiv128(ULARGE_INTEGER c1
, ULARGE_INTEGER c0
, LONGLONG denom
)
9049 ULARGE_INTEGER q1
, q0
, rhat
;
9050 ULARGE_INTEGER v
, cmp1
, cmp2
;
9053 v
.QuadPart
= llabs(denom
);
9055 /* 64bit numerator */
9056 if (c1
.QuadPart
== 0)
9057 return c0
.QuadPart
/ v
.QuadPart
;
9059 /* 96bit numerator, 32bit denominator */
9060 if (v
.HighPart
== 0 && c1
.HighPart
== 0)
9062 ULONGLONG low
= c0
.LowPart
, high
= c0
.HighPart
+ ((ULONGLONG
)c1
.LowPart
<< 32);
9063 low
+= (high
% v
.LowPart
) << 32;
9064 return ((high
/ v
.LowPart
) << 32) + (low
/ v
.LowPart
);
9067 /* 128bit numerator, 32bit denominator */
9068 if (v
.HighPart
== 0)
9071 /* count number of leading zeroes */
9072 BitScanReverse(&s
, v
.HighPart
);
9077 /* normalize divisor and dividend */
9079 c1
.QuadPart
= (c1
.QuadPart
<< s
) | (c0
.HighPart
>> (32 - s
));
9083 q1
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9084 rhat
.QuadPart
= c1
.QuadPart
- q1
.QuadPart
* v
.HighPart
;
9086 cmp1
.HighPart
= rhat
.LowPart
;
9087 cmp1
.LowPart
= c0
.HighPart
;
9088 cmp2
.QuadPart
= q1
.QuadPart
* v
.LowPart
;
9090 while (q1
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9093 rhat
.QuadPart
+= v
.HighPart
;
9096 cmp1
.HighPart
= rhat
.LowPart
;
9097 cmp2
.QuadPart
-= v
.LowPart
;
9099 c1
.HighPart
= c1
.LowPart
;
9100 c1
.LowPart
= c0
.HighPart
;
9101 c1
.QuadPart
-= q1
.QuadPart
* v
.QuadPart
;
9102 q0
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9103 rhat
.QuadPart
= c1
.QuadPart
- q0
.QuadPart
* v
.HighPart
;
9105 cmp1
.HighPart
= rhat
.LowPart
;
9106 cmp1
.LowPart
= c0
.LowPart
;
9107 cmp2
.QuadPart
= q0
.QuadPart
* v
.LowPart
;
9109 while (q0
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9112 rhat
.QuadPart
+= v
.HighPart
;
9115 cmp1
.HighPart
= rhat
.LowPart
;
9116 cmp2
.QuadPart
-= v
.LowPart
;
9118 q0
.HighPart
+= q1
.LowPart
;
9123 /***********************************************************************
9124 * MFllMulDiv (mfplat.@)
9126 LONGLONG WINAPI
MFllMulDiv(LONGLONG val
, LONGLONG num
, LONGLONG denom
, LONGLONG factor
)
9128 #define LLOVERFLOW (sign ? I64_MIN : I64_MAX)
9129 unsigned int sign
, factor_sign
, denom_sign
;
9130 ULARGE_INTEGER c1
, c0
;
9133 TRACE("%s, %s, %s, %s.\n", wine_dbgstr_longlong(val
), wine_dbgstr_longlong(num
),
9134 wine_dbgstr_longlong(denom
), wine_dbgstr_longlong(factor
));
9136 /* compute 128-bit numerator product */
9137 llmult128(&c1
, &c0
, val
, num
);
9139 sign
= (val
< 0) ^ (num
< 0);
9140 factor_sign
= factor
< 0;
9141 denom_sign
= denom
< 0;
9143 factor
= llabs(factor
);
9144 if (sign
== factor_sign
)
9146 if (UI64_MAX
- c0
.QuadPart
< factor
)
9148 if (c1
.QuadPart
== UI64_MAX
) return LLOVERFLOW
;
9151 c0
.QuadPart
+= factor
;
9155 if (c0
.QuadPart
>= factor
)
9156 c0
.QuadPart
-= factor
;
9164 c0
.QuadPart
= factor
- c0
.QuadPart
;
9168 if (c1
.QuadPart
>= denom
) return LLOVERFLOW
;
9170 /* compute quotient, fits in 64 bits */
9171 ret
= lldiv128(c1
, c0
, denom
);
9173 if (ret
>= I64_MAX
) return LLOVERFLOW
;
9174 return sign
? -(LONGLONG
)ret
: ret
;