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
24 #define NONAMELESSUNION
38 #include "wine/debug.h"
39 #include "wine/list.h"
41 #include "mfplat_private.h"
42 #include "mfreadwrite.h"
43 #include "mfmediaengine.h"
44 #include "propvarutil.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
49 static HRESULT
heap_strdupW(const WCHAR
*str
, WCHAR
**dest
)
57 size
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
58 *dest
= heap_alloc(size
);
60 memcpy(*dest
, str
, size
);
82 IMFActivate
*activate
;
85 static CRITICAL_SECTION local_handlers_section
= { NULL
, -1, 0, 0, 0, 0 };
87 static struct list local_scheme_handlers
= LIST_INIT(local_scheme_handlers
);
88 static struct list local_bytestream_handlers
= LIST_INIT(local_bytestream_handlers
);
90 struct mft_registration
93 IClassFactory
*factory
;
98 MFT_REGISTER_TYPE_INFO
*input_types
;
99 UINT32 input_types_count
;
100 MFT_REGISTER_TYPE_INFO
*output_types
;
101 UINT32 output_types_count
;
105 static CRITICAL_SECTION local_mfts_section
= { NULL
, -1, 0, 0, 0, 0 };
107 static struct list local_mfts
= LIST_INIT(local_mfts
);
109 struct transform_activate
111 struct attributes attributes
;
112 IMFActivate IMFActivate_iface
;
113 IClassFactory
*factory
;
114 IMFTransform
*transform
;
119 IMFClock IMFClock_iface
;
123 struct system_time_source
125 IMFPresentationTimeSource IMFPresentationTimeSource_iface
;
126 IMFClockStateSink IMFClockStateSink_iface
;
130 LONGLONG start_offset
;
136 static void system_time_source_apply_rate(const struct system_time_source
*source
, LONGLONG
*value
)
139 *value
*= source
->i_rate
;
141 *value
*= source
->rate
;
144 static struct system_time_source
*impl_from_IMFPresentationTimeSource(IMFPresentationTimeSource
*iface
)
146 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFPresentationTimeSource_iface
);
149 static struct system_time_source
*impl_from_IMFClockStateSink(IMFClockStateSink
*iface
)
151 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFClockStateSink_iface
);
154 static struct system_clock
*impl_from_IMFClock(IMFClock
*iface
)
156 return CONTAINING_RECORD(iface
, struct system_clock
, IMFClock_iface
);
159 static struct transform_activate
*impl_from_IMFActivate(IMFActivate
*iface
)
161 return CONTAINING_RECORD(iface
, struct transform_activate
, IMFActivate_iface
);
164 static HRESULT WINAPI
transform_activate_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **out
)
166 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
168 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
169 IsEqualIID(riid
, &IID_IMFAttributes
) ||
170 IsEqualIID(riid
, &IID_IUnknown
))
173 IMFActivate_AddRef(iface
);
177 WARN("Unsupported %s.\n", debugstr_guid(riid
));
179 return E_NOINTERFACE
;
182 static ULONG WINAPI
transform_activate_AddRef(IMFActivate
*iface
)
184 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
185 ULONG refcount
= InterlockedIncrement(&activate
->attributes
.ref
);
187 TRACE("%p, refcount %u.\n", iface
, refcount
);
192 static ULONG WINAPI
transform_activate_Release(IMFActivate
*iface
)
194 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
195 ULONG refcount
= InterlockedDecrement(&activate
->attributes
.ref
);
197 TRACE("%p, refcount %u.\n", iface
, refcount
);
201 clear_attributes_object(&activate
->attributes
);
202 if (activate
->factory
)
203 IClassFactory_Release(activate
->factory
);
204 if (activate
->transform
)
205 IMFTransform_Release(activate
->transform
);
212 static HRESULT WINAPI
transform_activate_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
214 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
216 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
218 return attributes_GetItem(&activate
->attributes
, key
, value
);
221 static HRESULT WINAPI
transform_activate_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
223 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
225 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
227 return attributes_GetItemType(&activate
->attributes
, key
, type
);
230 static HRESULT WINAPI
transform_activate_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
,
233 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
235 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
237 return attributes_CompareItem(&activate
->attributes
, key
, value
, result
);
240 static HRESULT WINAPI
transform_activate_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
,
241 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
243 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
245 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
247 return attributes_Compare(&activate
->attributes
, theirs
, match_type
, ret
);
250 static HRESULT WINAPI
transform_activate_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
252 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
254 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
256 return attributes_GetUINT32(&activate
->attributes
, key
, value
);
259 static HRESULT WINAPI
transform_activate_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
261 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
263 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
265 return attributes_GetUINT64(&activate
->attributes
, key
, value
);
268 static HRESULT WINAPI
transform_activate_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
270 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
272 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
274 return attributes_GetDouble(&activate
->attributes
, key
, value
);
277 static HRESULT WINAPI
transform_activate_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
279 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
281 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
283 return attributes_GetGUID(&activate
->attributes
, key
, value
);
286 static HRESULT WINAPI
transform_activate_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
288 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
290 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
292 return attributes_GetStringLength(&activate
->attributes
, key
, length
);
295 static HRESULT WINAPI
transform_activate_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
296 UINT32 size
, UINT32
*length
)
298 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
300 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
302 return attributes_GetString(&activate
->attributes
, key
, value
, size
, length
);
305 static HRESULT WINAPI
transform_activate_GetAllocatedString(IMFActivate
*iface
, REFGUID key
, WCHAR
**value
,
308 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
310 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
312 return attributes_GetAllocatedString(&activate
->attributes
, key
, value
, length
);
315 static HRESULT WINAPI
transform_activate_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
317 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
319 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
321 return attributes_GetBlobSize(&activate
->attributes
, key
, size
);
324 static HRESULT WINAPI
transform_activate_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
,
327 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
329 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
331 return attributes_GetBlob(&activate
->attributes
, key
, buf
, bufsize
, blobsize
);
334 static HRESULT WINAPI
transform_activate_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
336 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
338 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
340 return attributes_GetAllocatedBlob(&activate
->attributes
, key
, buf
, size
);
343 static HRESULT WINAPI
transform_activate_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **out
)
345 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
347 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
349 return attributes_GetUnknown(&activate
->attributes
, key
, riid
, out
);
352 static HRESULT WINAPI
transform_activate_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
354 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
356 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
358 return attributes_SetItem(&activate
->attributes
, key
, value
);
361 static HRESULT WINAPI
transform_activate_DeleteItem(IMFActivate
*iface
, REFGUID key
)
363 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
365 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
367 return attributes_DeleteItem(&activate
->attributes
, key
);
370 static HRESULT WINAPI
transform_activate_DeleteAllItems(IMFActivate
*iface
)
372 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
374 TRACE("%p.\n", iface
);
376 return attributes_DeleteAllItems(&activate
->attributes
);
379 static HRESULT WINAPI
transform_activate_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
381 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
383 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
385 return attributes_SetUINT32(&activate
->attributes
, key
, value
);
388 static HRESULT WINAPI
transform_activate_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
390 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
392 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
394 return attributes_SetUINT64(&activate
->attributes
, key
, value
);
397 static HRESULT WINAPI
transform_activate_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
399 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
401 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
403 return attributes_SetDouble(&activate
->attributes
, key
, value
);
406 static HRESULT WINAPI
transform_activate_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
408 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
410 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
412 return attributes_SetGUID(&activate
->attributes
, key
, value
);
415 static HRESULT WINAPI
transform_activate_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
417 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
419 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
421 return attributes_SetString(&activate
->attributes
, key
, value
);
424 static HRESULT WINAPI
transform_activate_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
426 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
428 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
430 return attributes_SetBlob(&activate
->attributes
, key
, buf
, size
);
433 static HRESULT WINAPI
transform_activate_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
435 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
437 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
439 return attributes_SetUnknown(&activate
->attributes
, key
, unknown
);
442 static HRESULT WINAPI
transform_activate_LockStore(IMFActivate
*iface
)
444 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
446 TRACE("%p.\n", iface
);
448 return attributes_LockStore(&activate
->attributes
);
451 static HRESULT WINAPI
transform_activate_UnlockStore(IMFActivate
*iface
)
453 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
455 TRACE("%p.\n", iface
);
457 return attributes_UnlockStore(&activate
->attributes
);
460 static HRESULT WINAPI
transform_activate_GetCount(IMFActivate
*iface
, UINT32
*count
)
462 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
464 TRACE("%p, %p.\n", iface
, count
);
466 return attributes_GetCount(&activate
->attributes
, count
);
469 static HRESULT WINAPI
transform_activate_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
,
472 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
474 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
476 return attributes_GetItemByIndex(&activate
->attributes
, index
, key
, value
);
479 static HRESULT WINAPI
transform_activate_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
481 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
483 TRACE("%p, %p.\n", iface
, dest
);
485 return attributes_CopyAllItems(&activate
->attributes
, dest
);
488 static HRESULT WINAPI
transform_activate_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
490 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
494 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
496 EnterCriticalSection(&activate
->attributes
.cs
);
498 if (!activate
->transform
)
500 if (activate
->factory
)
502 if (FAILED(hr
= IClassFactory_CreateInstance(activate
->factory
, NULL
, &IID_IMFTransform
,
503 (void **)&activate
->transform
)))
505 hr
= MF_E_INVALIDREQUEST
;
510 if (SUCCEEDED(hr
= attributes_GetGUID(&activate
->attributes
, &MFT_TRANSFORM_CLSID_Attribute
, &clsid
)))
512 if (FAILED(hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
513 (void **)&activate
->transform
)))
515 hr
= MF_E_INVALIDREQUEST
;
521 if (activate
->transform
)
522 hr
= IMFTransform_QueryInterface(activate
->transform
, riid
, obj
);
524 LeaveCriticalSection(&activate
->attributes
.cs
);
529 static HRESULT WINAPI
transform_activate_ShutdownObject(IMFActivate
*iface
)
531 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
533 TRACE("%p.\n", iface
);
535 EnterCriticalSection(&activate
->attributes
.cs
);
537 if (activate
->transform
)
539 IMFTransform_Release(activate
->transform
);
540 activate
->transform
= NULL
;
543 LeaveCriticalSection(&activate
->attributes
.cs
);
548 static HRESULT WINAPI
transform_activate_DetachObject(IMFActivate
*iface
)
550 TRACE("%p.\n", iface
);
555 static const IMFActivateVtbl transform_activate_vtbl
=
557 transform_activate_QueryInterface
,
558 transform_activate_AddRef
,
559 transform_activate_Release
,
560 transform_activate_GetItem
,
561 transform_activate_GetItemType
,
562 transform_activate_CompareItem
,
563 transform_activate_Compare
,
564 transform_activate_GetUINT32
,
565 transform_activate_GetUINT64
,
566 transform_activate_GetDouble
,
567 transform_activate_GetGUID
,
568 transform_activate_GetStringLength
,
569 transform_activate_GetString
,
570 transform_activate_GetAllocatedString
,
571 transform_activate_GetBlobSize
,
572 transform_activate_GetBlob
,
573 transform_activate_GetAllocatedBlob
,
574 transform_activate_GetUnknown
,
575 transform_activate_SetItem
,
576 transform_activate_DeleteItem
,
577 transform_activate_DeleteAllItems
,
578 transform_activate_SetUINT32
,
579 transform_activate_SetUINT64
,
580 transform_activate_SetDouble
,
581 transform_activate_SetGUID
,
582 transform_activate_SetString
,
583 transform_activate_SetBlob
,
584 transform_activate_SetUnknown
,
585 transform_activate_LockStore
,
586 transform_activate_UnlockStore
,
587 transform_activate_GetCount
,
588 transform_activate_GetItemByIndex
,
589 transform_activate_CopyAllItems
,
590 transform_activate_ActivateObject
,
591 transform_activate_ShutdownObject
,
592 transform_activate_DetachObject
,
595 static HRESULT
create_transform_activate(IClassFactory
*factory
, IMFActivate
**activate
)
597 struct transform_activate
*object
;
600 object
= heap_alloc_zero(sizeof(*object
));
602 return E_OUTOFMEMORY
;
604 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
610 object
->IMFActivate_iface
.lpVtbl
= &transform_activate_vtbl
;
611 object
->factory
= factory
;
613 IClassFactory_AddRef(object
->factory
);
615 *activate
= &object
->IMFActivate_iface
;
620 HRESULT WINAPI
MFCreateTransformActivate(IMFActivate
**activate
)
622 TRACE("%p.\n", activate
);
624 return create_transform_activate(NULL
, activate
);
627 static const WCHAR transform_keyW
[] = L
"MediaFoundation\\Transforms";
628 static const WCHAR categories_keyW
[] = L
"MediaFoundation\\Transforms\\Categories";
630 static const BYTE guid_conv_table
[256] =
632 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
633 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
634 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
635 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
636 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
637 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
638 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
641 static WCHAR
* GUIDToString(WCHAR
*str
, REFGUID guid
)
643 swprintf(str
, 39, L
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
644 guid
->Data1
, guid
->Data2
, guid
->Data3
, guid
->Data4
[0], guid
->Data4
[1],
645 guid
->Data4
[2], guid
->Data4
[3], guid
->Data4
[4], guid
->Data4
[5],
646 guid
->Data4
[6], guid
->Data4
[7]);
651 static inline BOOL
is_valid_hex(WCHAR c
)
653 if (!(((c
>= '0') && (c
<= '9')) ||
654 ((c
>= 'a') && (c
<= 'f')) ||
655 ((c
>= 'A') && (c
<= 'F'))))
660 static BOOL
GUIDFromString(LPCWSTR s
, GUID
*id
)
664 /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
667 for (i
= 0; i
< 8; i
++)
669 if (!is_valid_hex(s
[i
])) return FALSE
;
670 id
->Data1
= (id
->Data1
<< 4) | guid_conv_table
[s
[i
]];
672 if (s
[8]!='-') return FALSE
;
675 for (i
= 9; i
< 13; i
++)
677 if (!is_valid_hex(s
[i
])) return FALSE
;
678 id
->Data2
= (id
->Data2
<< 4) | guid_conv_table
[s
[i
]];
680 if (s
[13]!='-') return FALSE
;
683 for (i
= 14; i
< 18; i
++)
685 if (!is_valid_hex(s
[i
])) return FALSE
;
686 id
->Data3
= (id
->Data3
<< 4) | guid_conv_table
[s
[i
]];
688 if (s
[18]!='-') return FALSE
;
690 for (i
= 19; i
< 36; i
+=2)
694 if (s
[i
]!='-') return FALSE
;
697 if (!is_valid_hex(s
[i
]) || !is_valid_hex(s
[i
+1])) return FALSE
;
698 id
->Data4
[(i
-19)/2] = guid_conv_table
[s
[i
]] << 4 | guid_conv_table
[s
[i
+1]];
701 if (!s
[36]) return TRUE
;
705 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, LPVOID reserved
)
709 case DLL_WINE_PREATTACH
:
710 return FALSE
; /* prefer native version */
711 case DLL_PROCESS_ATTACH
:
712 DisableThreadLibraryCalls(instance
);
719 static HRESULT
register_transform(const CLSID
*clsid
, const WCHAR
*name
, UINT32 flags
,
720 UINT32 cinput
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
721 const MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
730 GUIDToString(buffer
, clsid
);
731 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s", transform_keyW
, buffer
);
733 if ((ret
= RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &hclsid
)))
734 hr
= HRESULT_FROM_WIN32(ret
);
738 size
= (lstrlenW(name
) + 1) * sizeof(WCHAR
);
739 if ((ret
= RegSetValueExW(hclsid
, NULL
, 0, REG_SZ
, (BYTE
*)name
, size
)))
740 hr
= HRESULT_FROM_WIN32(ret
);
743 if (SUCCEEDED(hr
) && cinput
&& input_types
)
745 size
= cinput
* sizeof(MFT_REGISTER_TYPE_INFO
);
746 if ((ret
= RegSetValueExW(hclsid
, L
"InputTypes", 0, REG_BINARY
, (BYTE
*)input_types
, size
)))
747 hr
= HRESULT_FROM_WIN32(ret
);
750 if (SUCCEEDED(hr
) && coutput
&& output_types
)
752 size
= coutput
* sizeof(MFT_REGISTER_TYPE_INFO
);
753 if ((ret
= RegSetValueExW(hclsid
, L
"OutputTypes", 0, REG_BINARY
, (BYTE
*)output_types
, size
)))
754 hr
= HRESULT_FROM_WIN32(ret
);
757 if (SUCCEEDED(hr
) && attributes
)
759 if (SUCCEEDED(hr
= MFGetAttributesAsBlobSize(attributes
, &size
)))
761 if ((blob
= heap_alloc(size
)))
763 if (SUCCEEDED(hr
= MFGetAttributesAsBlob(attributes
, blob
, size
)))
765 if ((ret
= RegSetValueExW(hclsid
, L
"Attributes", 0, REG_BINARY
, blob
, size
)))
766 hr
= HRESULT_FROM_WIN32(ret
);
775 if (SUCCEEDED(hr
) && flags
)
777 if ((ret
= RegSetValueExW(hclsid
, L
"MFTFlags", 0, REG_DWORD
, (BYTE
*)&flags
, sizeof(flags
))))
778 hr
= HRESULT_FROM_WIN32(ret
);
785 static HRESULT
register_category(CLSID
*clsid
, GUID
*category
)
788 WCHAR guid1
[64], guid2
[64];
791 GUIDToString(guid1
, category
);
792 GUIDToString(guid2
, clsid
);
794 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s\\%s", categories_keyW
, guid1
, guid2
);
796 if (RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &htmp1
))
803 /***********************************************************************
804 * MFTRegister (mfplat.@)
806 HRESULT WINAPI
MFTRegister(CLSID clsid
, GUID category
, LPWSTR name
, UINT32 flags
, UINT32 cinput
,
807 MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
808 MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
812 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p, %p.\n", debugstr_guid(&clsid
), debugstr_guid(&category
),
813 debugstr_w(name
), flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
815 hr
= register_transform(&clsid
, name
, flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
817 ERR("Failed to write register transform\n");
820 hr
= register_category(&clsid
, &category
);
825 static void release_mft_registration(struct mft_registration
*mft
)
828 IClassFactory_Release(mft
->factory
);
829 heap_free(mft
->name
);
830 heap_free(mft
->input_types
);
831 heap_free(mft
->output_types
);
835 static HRESULT
mft_register_local(IClassFactory
*factory
, REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
836 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
837 const MFT_REGISTER_TYPE_INFO
*output_types
)
839 struct mft_registration
*mft
, *cur
, *unreg_mft
= NULL
;
842 if (!factory
&& !clsid
)
844 WARN("Can't register without factory or CLSID.\n");
848 mft
= heap_alloc_zero(sizeof(*mft
));
850 return E_OUTOFMEMORY
;
852 mft
->factory
= factory
;
854 IClassFactory_AddRef(mft
->factory
);
857 mft
->category
= *category
;
858 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
859 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
862 if (FAILED(hr
= heap_strdupW(name
, &mft
->name
)))
865 if (input_count
&& input_types
)
867 mft
->input_types_count
= input_count
;
868 if (!(mft
->input_types
= heap_calloc(mft
->input_types_count
, sizeof(*input_types
))))
873 memcpy(mft
->input_types
, input_types
, mft
->input_types_count
* sizeof(*input_types
));
876 if (output_count
&& output_types
)
878 mft
->output_types_count
= output_count
;
879 if (!(mft
->output_types
= heap_calloc(mft
->output_types_count
, sizeof(*output_types
))))
884 memcpy(mft
->output_types
, output_types
, mft
->output_types_count
* sizeof(*output_types
));
887 EnterCriticalSection(&local_mfts_section
);
889 LIST_FOR_EACH_ENTRY(cur
, &local_mfts
, struct mft_registration
, entry
)
891 if (cur
->factory
== factory
)
894 list_remove(&cur
->entry
);
898 list_add_tail(&local_mfts
, &mft
->entry
);
900 LeaveCriticalSection(&local_mfts_section
);
903 release_mft_registration(unreg_mft
);
907 release_mft_registration(mft
);
912 HRESULT WINAPI
MFTRegisterLocal(IClassFactory
*factory
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
913 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
914 const MFT_REGISTER_TYPE_INFO
*output_types
)
916 TRACE("%p, %s, %s, %#x, %u, %p, %u, %p.\n", factory
, debugstr_guid(category
), debugstr_w(name
), flags
, input_count
,
917 input_types
, output_count
, output_types
);
919 return mft_register_local(factory
, NULL
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
922 HRESULT WINAPI
MFTRegisterLocalByCLSID(REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
923 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
924 const MFT_REGISTER_TYPE_INFO
*output_types
)
926 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p.\n", debugstr_guid(clsid
), debugstr_guid(category
), debugstr_w(name
), flags
,
927 input_count
, input_types
, output_count
, output_types
);
929 return mft_register_local(NULL
, clsid
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
932 static HRESULT
mft_unregister_local(IClassFactory
*factory
, REFCLSID clsid
)
934 struct mft_registration
*cur
, *cur2
;
935 BOOL unregister_all
= !factory
&& !clsid
;
940 EnterCriticalSection(&local_mfts_section
);
942 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &local_mfts
, struct mft_registration
, entry
)
946 if ((factory
&& cur
->factory
== factory
) || IsEqualCLSID(&cur
->clsid
, clsid
))
948 list_remove(&cur
->entry
);
949 list_add_tail(&unreg
, &cur
->entry
);
955 list_remove(&cur
->entry
);
956 list_add_tail(&unreg
, &cur
->entry
);
960 LeaveCriticalSection(&local_mfts_section
);
962 if (!unregister_all
&& list_empty(&unreg
))
963 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND
);
965 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &unreg
, struct mft_registration
, entry
)
967 list_remove(&cur
->entry
);
968 release_mft_registration(cur
);
974 HRESULT WINAPI
MFTUnregisterLocalByCLSID(CLSID clsid
)
976 TRACE("%s.\n", debugstr_guid(&clsid
));
978 return mft_unregister_local(NULL
, &clsid
);
981 HRESULT WINAPI
MFTUnregisterLocal(IClassFactory
*factory
)
983 TRACE("%p.\n", factory
);
985 return mft_unregister_local(factory
, NULL
);
988 MFTIME WINAPI
MFGetSystemTime(void)
992 GetSystemTimeAsFileTime( (FILETIME
*)&mf
);
997 static BOOL
mft_is_type_info_match(struct mft_registration
*mft
, const GUID
*category
, UINT32 flags
,
998 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
999 const MFT_REGISTER_TYPE_INFO
*output_type
)
1001 BOOL matching
= TRUE
;
1005 if (!IsEqualGUID(category
, &mft
->category
))
1008 /* Default model is synchronous. */
1009 model
= mft
->flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
);
1011 model
= MFT_ENUM_FLAG_SYNCMFT
;
1012 if (!(model
& flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1015 /* These flags should be explicitly enabled. */
1016 if (mft
->flags
& ~flags
& (MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_TRANSCODE_ONLY
))
1019 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
&& !mft
->factory
&& plugin_control
1020 && IMFPluginControl_IsDisabled(plugin_control
, MF_Plugin_Type_MFT
, &mft
->clsid
) == S_OK
)
1027 for (i
= 0, matching
= FALSE
; input_type
&& i
< mft
->input_types_count
; ++i
)
1029 if (!memcmp(&mft
->input_types
[i
], input_type
, sizeof(*input_type
)))
1037 if (output_type
&& matching
)
1039 for (i
= 0, matching
= FALSE
; i
< mft
->output_types_count
; ++i
)
1041 if (!memcmp(&mft
->output_types
[i
], output_type
, sizeof(*output_type
)))
1052 static void mft_get_reg_type_info(const WCHAR
*clsidW
, const WCHAR
*typeW
, MFT_REGISTER_TYPE_INFO
**type
,
1055 HKEY htransform
, hfilter
;
1056 DWORD reg_type
, size
;
1061 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1064 if (RegOpenKeyW(htransform
, clsidW
, &hfilter
))
1066 RegCloseKey(htransform
);
1070 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, NULL
, &size
))
1073 if (reg_type
!= REG_BINARY
)
1076 if (!size
|| size
% sizeof(**type
))
1079 if (!(*type
= heap_alloc(size
)))
1082 *count
= size
/ sizeof(**type
);
1084 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, (BYTE
*)*type
, &size
))
1092 RegCloseKey(hfilter
);
1093 RegCloseKey(htransform
);
1096 static void mft_get_reg_flags(const WCHAR
*clsidW
, const WCHAR
*nameW
, DWORD
*flags
)
1098 DWORD ret
, reg_type
, size
;
1103 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
))
1106 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1112 if (!RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, NULL
, &size
) && reg_type
== REG_DWORD
)
1113 RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, (BYTE
*)flags
, &size
);
1118 static HRESULT
mft_collect_machine_reg(struct list
*mfts
, const GUID
*category
, UINT32 flags
,
1119 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1120 const MFT_REGISTER_TYPE_INFO
*output_type
)
1122 struct mft_registration mft
, *cur
;
1123 HKEY hcategory
, hlist
;
1128 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1131 GUIDToString(clsidW
, category
);
1132 ret
= RegOpenKeyW(hcategory
, clsidW
, &hlist
);
1133 RegCloseKey(hcategory
);
1137 size
= ARRAY_SIZE(clsidW
);
1138 while (!RegEnumKeyExW(hlist
, index
, clsidW
, &size
, NULL
, NULL
, NULL
, NULL
))
1140 memset(&mft
, 0, sizeof(mft
));
1141 mft
.category
= *category
;
1142 if (!GUIDFromString(clsidW
, &mft
.clsid
))
1145 mft_get_reg_flags(clsidW
, L
"MFTFlags", &mft
.flags
);
1148 mft_get_reg_type_info(clsidW
, L
"OutputTypes", &mft
.output_types
, &mft
.output_types_count
);
1151 mft_get_reg_type_info(clsidW
, L
"InputTypes", &mft
.input_types
, &mft
.input_types_count
);
1153 if (!mft_is_type_info_match(&mft
, category
, flags
, plugin_control
, input_type
, output_type
))
1155 heap_free(mft
.input_types
);
1156 heap_free(mft
.output_types
);
1160 cur
= heap_alloc(sizeof(*cur
));
1161 /* Reuse allocated type arrays. */
1163 list_add_tail(mfts
, &cur
->entry
);
1166 size
= ARRAY_SIZE(clsidW
);
1173 static BOOL
mft_is_preferred(IMFPluginControl
*plugin_control
, const CLSID
*clsid
)
1179 while (SUCCEEDED(IMFPluginControl_GetPreferredClsidByIndex(plugin_control
, MF_Plugin_Type_MFT
, index
++, &selector
,
1182 CoTaskMemFree(selector
);
1184 if (IsEqualGUID(&preferred
, clsid
))
1191 static HRESULT
mft_enum(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1192 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1194 IMFPluginControl
*plugin_control
= NULL
;
1195 struct list mfts
, mfts_sorted
, *result
= &mfts
;
1196 struct mft_registration
*mft
, *mft2
;
1197 unsigned int obj_count
;
1204 flags
= MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_SORTANDFILTER
;
1206 /* Synchronous processing is default. */
1207 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1208 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
1210 if (FAILED(hr
= MFGetPluginControl(&plugin_control
)))
1212 WARN("Failed to get plugin control instance, hr %#x.\n", hr
);
1218 /* Collect from registry */
1219 mft_collect_machine_reg(&mfts
, &category
, flags
, plugin_control
, input_type
, output_type
);
1221 /* Collect locally registered ones. */
1222 if (flags
& MFT_ENUM_FLAG_LOCALMFT
)
1224 struct mft_registration
*local
;
1226 EnterCriticalSection(&local_mfts_section
);
1228 LIST_FOR_EACH_ENTRY(local
, &local_mfts
, struct mft_registration
, entry
)
1230 if (mft_is_type_info_match(local
, &category
, flags
, plugin_control
, input_type
, output_type
))
1232 mft
= heap_alloc_zero(sizeof(*mft
));
1234 mft
->clsid
= local
->clsid
;
1235 mft
->factory
= local
->factory
;
1237 IClassFactory_AddRef(mft
->factory
);
1238 mft
->flags
= local
->flags
;
1239 mft
->local
= local
->local
;
1241 list_add_tail(&mfts
, &mft
->entry
);
1245 LeaveCriticalSection(&local_mfts_section
);
1248 list_init(&mfts_sorted
);
1250 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
)
1252 /* Local registrations. */
1253 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1257 list_remove(&mft
->entry
);
1258 list_add_tail(&mfts_sorted
, &mft
->entry
);
1262 /* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */
1264 /* Preferred transforms. */
1265 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1267 if (!mft
->factory
&& mft_is_preferred(plugin_control
, &mft
->clsid
))
1269 list_remove(&mft
->entry
);
1270 list_add_tail(&mfts_sorted
, &mft
->entry
);
1274 /* Append the rest. */
1275 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1277 list_remove(&mft
->entry
);
1278 list_add_tail(&mfts_sorted
, &mft
->entry
);
1281 result
= &mfts_sorted
;
1284 IMFPluginControl_Release(plugin_control
);
1286 /* Create activation objects from CLSID/IClassFactory. */
1288 obj_count
= list_count(result
);
1292 if (!(*activate
= CoTaskMemAlloc(obj_count
* sizeof(**activate
))))
1297 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, result
, struct mft_registration
, entry
)
1299 IMFActivate
*mft_activate
;
1303 if (SUCCEEDED(create_transform_activate(mft
->factory
, &mft_activate
)))
1305 (*activate
)[obj_count
] = mft_activate
;
1309 IMFActivate_SetUINT32(mft_activate
, &MFT_PROCESS_LOCAL_Attribute
, 1);
1314 IMFActivate_SetString(mft_activate
, &MFT_FRIENDLY_NAME_Attribute
, mft
->name
);
1315 if (mft
->input_types
)
1316 IMFActivate_SetBlob(mft_activate
, &MFT_INPUT_TYPES_Attributes
, (const UINT8
*)mft
->input_types
,
1317 sizeof(*mft
->input_types
) * mft
->input_types_count
);
1318 if (mft
->output_types
)
1319 IMFActivate_SetBlob(mft_activate
, &MFT_OUTPUT_TYPES_Attributes
, (const UINT8
*)mft
->output_types
,
1320 sizeof(*mft
->output_types
) * mft
->output_types_count
);
1324 IMFActivate_SetGUID(mft_activate
, &MFT_TRANSFORM_CLSID_Attribute
, &mft
->clsid
);
1326 IMFActivate_SetUINT32(mft_activate
, &MF_TRANSFORM_FLAGS_Attribute
, mft
->flags
);
1327 IMFActivate_SetGUID(mft_activate
, &MF_TRANSFORM_CATEGORY_Attribute
, &mft
->category
);
1333 list_remove(&mft
->entry
);
1334 release_mft_registration(mft
);
1340 CoTaskMemFree(*activate
);
1348 /***********************************************************************
1349 * MFTEnum (mfplat.@)
1351 HRESULT WINAPI
MFTEnum(GUID category
, UINT32 flags
, MFT_REGISTER_TYPE_INFO
*input_type
,
1352 MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, CLSID
**clsids
, UINT32
*count
)
1354 struct mft_registration
*mft
, *mft2
;
1355 unsigned int mft_count
;
1359 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1362 if (!clsids
|| !count
)
1363 return E_INVALIDARG
;
1369 if (FAILED(hr
= mft_collect_machine_reg(&mfts
, &category
, MFT_ENUM_FLAG_SYNCMFT
, NULL
, input_type
, output_type
)))
1372 mft_count
= list_count(&mfts
);
1376 if (!(*clsids
= CoTaskMemAlloc(mft_count
* sizeof(**clsids
))))
1380 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1383 (*clsids
)[mft_count
++] = mft
->clsid
;
1384 list_remove(&mft
->entry
);
1385 release_mft_registration(mft
);
1391 CoTaskMemFree(*clsids
);
1399 /***********************************************************************
1400 * MFTEnumEx (mfplat.@)
1402 HRESULT WINAPI
MFTEnumEx(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1403 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFActivate
***activate
, UINT32
*count
)
1405 TRACE("%s, %#x, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, activate
, count
);
1407 return mft_enum(category
, flags
, input_type
, output_type
, NULL
, activate
, count
);
1410 /***********************************************************************
1411 * MFTEnum2 (mfplat.@)
1413 HRESULT WINAPI
MFTEnum2(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1414 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1416 TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category
), flags
, input_type
, output_type
, attributes
,
1420 FIXME("Ignoring attributes.\n");
1422 return mft_enum(category
, flags
, input_type
, output_type
, attributes
, activate
, count
);
1425 /***********************************************************************
1426 * MFTUnregister (mfplat.@)
1428 HRESULT WINAPI
MFTUnregister(CLSID clsid
)
1430 WCHAR buffer
[64], category
[MAX_PATH
];
1431 HKEY htransform
, hcategory
, htmp
;
1432 DWORD size
= MAX_PATH
;
1435 TRACE("(%s)\n", debugstr_guid(&clsid
));
1437 GUIDToString(buffer
, &clsid
);
1439 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1441 RegDeleteKeyW(htransform
, buffer
);
1442 RegCloseKey(htransform
);
1445 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1447 while (RegEnumKeyExW(hcategory
, index
, category
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1449 if (!RegOpenKeyW(hcategory
, category
, &htmp
))
1451 RegDeleteKeyW(htmp
, buffer
);
1457 RegCloseKey(hcategory
);
1463 /***********************************************************************
1464 * MFStartup (mfplat.@)
1466 HRESULT WINAPI
MFStartup(ULONG version
, DWORD flags
)
1468 #define MF_VERSION_XP MAKELONG( MF_API_VERSION, 1 )
1469 #define MF_VERSION_WIN7 MAKELONG( MF_API_VERSION, 2 )
1471 TRACE("%#x, %#x.\n", version
, flags
);
1473 if (version
!= MF_VERSION_XP
&& version
!= MF_VERSION_WIN7
)
1474 return MF_E_BAD_STARTUP_VERSION
;
1481 /***********************************************************************
1482 * MFShutdown (mfplat.@)
1484 HRESULT WINAPI
MFShutdown(void)
1493 /***********************************************************************
1494 * MFCopyImage (mfplat.@)
1496 HRESULT WINAPI
MFCopyImage(BYTE
*dest
, LONG deststride
, const BYTE
*src
, LONG srcstride
, DWORD width
, DWORD lines
)
1498 TRACE("%p, %d, %p, %d, %u, %u.\n", dest
, deststride
, src
, srcstride
, width
, lines
);
1502 memcpy(dest
, src
, width
);
1516 static int __cdecl
debug_compare_guid(const void *a
, const void *b
)
1518 const GUID
*guid
= a
;
1519 const struct guid_def
*guid_def
= b
;
1520 return memcmp(guid
, guid_def
->guid
, sizeof(*guid
));
1523 const char *debugstr_attr(const GUID
*guid
)
1525 static const struct guid_def guid_defs
[] =
1527 #define X(g) { &(g), #g }
1528 X(MF_READWRITE_MMCSS_CLASS
),
1529 X(MF_TOPONODE_MARKIN_HERE
),
1530 X(MF_MT_H264_SUPPORTED_SYNC_FRAME_TYPES
),
1531 X(MF_TOPONODE_MARKOUT_HERE
),
1532 X(EVRConfig_ForceBob
),
1533 X(MF_TOPONODE_DECODER
),
1534 X(EVRConfig_AllowDropToBob
),
1535 X(MF_TOPOLOGY_PROJECTSTART
),
1536 X(EVRConfig_ForceThrottle
),
1537 X(MF_VIDEO_MAX_MB_PER_SEC
),
1538 X(MF_TOPOLOGY_PROJECTSTOP
),
1539 X(MF_SINK_WRITER_ENCODER_CONFIG
),
1540 X(EVRConfig_AllowDropToThrottle
),
1541 X(MF_TOPOLOGY_NO_MARKIN_MARKOUT
),
1542 X(EVRConfig_ForceHalfInterlace
),
1543 X(EVRConfig_AllowDropToHalfInterlace
),
1544 X(EVRConfig_ForceScaling
),
1545 X(MF_MT_H264_CAPABILITIES
),
1546 X(EVRConfig_AllowScaling
),
1547 X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS
),
1548 X(MFT_PREFERRED_ENCODER_PROFILE
),
1549 X(EVRConfig_ForceBatching
),
1550 X(EVRConfig_AllowBatching
),
1551 X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED
),
1552 X(MF_MT_VIDEO_PROFILE
),
1553 X(MF_MT_MPEG2_PROFILE
),
1554 X(MF_MT_DV_AAUX_CTRL_PACK_1
),
1555 X(MF_MT_ALPHA_MODE
),
1556 X(MF_MT_MPEG2_TIMECODE
),
1557 X(MF_PMP_SERVER_CONTEXT
),
1558 X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
),
1559 X(MF_MEDIA_ENGINE_TRACK_ID
),
1560 X(MF_MT_CUSTOM_VIDEO_PRIMARIES
),
1561 X(MF_MT_TIMESTAMP_CAN_BE_DTS
),
1562 X(MFT_CODEC_MERIT_Attribute
),
1563 X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS
),
1565 X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
),
1566 X(MF_MT_MPEG2_FLAGS
),
1567 X(MF_MEDIA_ENGINE_AUDIO_CATEGORY
),
1568 X(MF_MT_PIXEL_ASPECT_RATIO
),
1569 X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK
),
1570 X(MFT_CONNECTED_STREAM_ATTRIBUTE
),
1571 X(MF_MT_REALTIME_CONTENT
),
1572 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
),
1573 X(MF_MT_WRAPPED_TYPE
),
1575 X(MF_MT_AVG_BITRATE
),
1576 X(MF_MT_DECODER_USE_MAX_RESOLUTION
),
1577 X(MF_MT_MAX_LUMINANCE_LEVEL
),
1578 X(MFT_CONNECTED_TO_HW_STREAM
),
1580 X(MF_MT_MAX_KEYFRAME_SPACING
),
1581 X(MFT_TRANSFORM_CLSID_Attribute
),
1582 X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
),
1583 X(MF_MT_AM_FORMAT_TYPE
),
1584 X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME
),
1585 X(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
),
1586 X(MF_MT_H264_MAX_MB_PER_SEC
),
1587 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS
),
1588 X(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
1589 X(MF_PD_PMPHOST_CONTEXT
),
1590 X(MF_PD_APP_CONTEXT
),
1592 X(MF_PD_TOTAL_FILE_SIZE
),
1593 X(MF_PD_AUDIO_ENCODING_BITRATE
),
1594 X(MF_PD_VIDEO_ENCODING_BITRATE
),
1595 X(MFSampleExtension_TargetGlobalLuminance
),
1597 X(MF_MT_H264_SUPPORTED_SLICE_MODES
),
1598 X(MF_PD_LAST_MODIFIED_TIME
),
1599 X(MF_PD_PLAYBACK_ELEMENT_ID
),
1600 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
),
1601 X(MF_MT_ALL_SAMPLES_INDEPENDENT
),
1602 X(MF_PD_PREFERRED_LANGUAGE
),
1603 X(MF_PD_PLAYBACK_BOUNDARY_TIME
),
1604 X(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
),
1605 X(MF_ACTIVATE_MFT_LOCKED
),
1606 X(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
),
1607 X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
),
1608 X(MF_MT_FRAME_SIZE
),
1609 X(MF_MT_H264_SIMULCAST_SUPPORT
),
1610 X(MF_SINK_WRITER_ASYNC_CALLBACK
),
1611 X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH
),
1612 X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
),
1613 X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
),
1614 X(MF_MT_FRAME_RATE_RANGE_MAX
),
1616 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID
),
1617 X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS
),
1618 X(MF_SA_D3D11_USAGE
),
1619 X(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
),
1620 X(MF_MT_GEOMETRIC_APERTURE
),
1621 X(MF_MT_ORIGINAL_WAVE_FORMAT_TAG
),
1622 X(MF_MT_DV_AAUX_SRC_PACK_1
),
1623 X(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
),
1624 X(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
),
1625 X(MF_MEDIA_ENGINE_EXTENSION
),
1626 X(MF_MT_DEFAULT_STRIDE
),
1627 X(MF_MT_ARBITRARY_FORMAT
),
1628 X(MF_TRANSFORM_CATEGORY_Attribute
),
1629 X(MF_MT_MPEG2_HDCP
),
1630 X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
1631 X(MF_MT_SPATIAL_AUDIO_MAX_DYNAMIC_OBJECTS
),
1632 X(MF_MT_DECODER_MAX_DPB_COUNT
),
1633 X(MFSampleExtension_ForwardedDecodeUnits
),
1634 X(MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
1635 X(MF_MT_DV_AAUX_CTRL_PACK_0
),
1636 X(MF_MT_YUV_MATRIX
),
1637 X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED
),
1638 X(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY
),
1639 X(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL
),
1640 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID
),
1641 X(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
),
1642 X(MF_MT_VIDEO_ROTATION
),
1643 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK
),
1644 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
),
1646 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
),
1647 X(MF_MT_MIN_MASTERING_LUMINANCE
),
1648 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
),
1649 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
),
1650 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
),
1651 X(MF_EVENT_STREAM_METADATA_SYSTEMID
),
1652 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
),
1653 X(MF_MT_AUDIO_CHANNEL_MASK
),
1654 X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN
),
1655 X(MF_READWRITE_DISABLE_CONVERTERS
),
1656 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
),
1657 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
),
1658 X(MF_MT_MINIMUM_DISPLAY_APERTURE
),
1659 X(MFSampleExtension_Token
),
1660 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY
),
1661 X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
1662 X(MF_TRANSFORM_ASYNC_UNLOCK
),
1663 X(MF_DISABLE_FRAME_CORRUPTION_INFO
),
1664 X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
),
1665 X(MF_MT_VIDEO_NO_FRAME_ORDERING
),
1666 X(MF_MEDIA_ENGINE_PLAYBACK_VISUAL
),
1667 X(MF_MT_VIDEO_CHROMA_SITING
),
1668 X(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY
),
1669 X(MF_SA_BUFFERS_PER_SAMPLE
),
1670 X(MFSampleExtension_3DVideo_SampleFormat
),
1671 X(MF_MT_H264_RESOLUTION_SCALING
),
1672 X(MF_MT_VIDEO_LEVEL
),
1673 X(MF_MT_MPEG2_LEVEL
),
1674 X(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET
),
1675 X(MF_MT_SAMPLE_SIZE
),
1676 X(MF_MT_AAC_PAYLOAD_TYPE
),
1677 X(MF_TOPOLOGY_PLAYBACK_FRAMERATE
),
1678 X(MF_SOURCE_READER_D3D11_BIND_FLAGS
),
1679 X(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
1680 X(MF_MT_AUDIO_WMADRC_PEAKREF
),
1681 X(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
1682 X(MF_TRANSFORM_FLAGS_Attribute
),
1683 X(MF_MT_H264_SUPPORTED_RATE_CONTROL_MODES
),
1684 X(MF_PD_SAMI_STYLELIST
),
1685 X(MF_MT_AUDIO_WMADRC_AVGREF
),
1686 X(MF_MT_AUDIO_BITS_PER_SAMPLE
),
1688 X(MF_MT_AUDIO_WMADRC_AVGTARGET
),
1690 X(MF_SESSION_TOPOLOADER
),
1691 X(MF_SESSION_GLOBAL_TIME
),
1692 X(MF_SESSION_QUALITY_MANAGER
),
1693 X(MF_SESSION_CONTENT_PROTECTION_MANAGER
),
1694 X(MF_MT_MPEG4_SAMPLE_DESCRIPTION
),
1695 X(MF_MT_MPEG_START_TIME_CODE
),
1696 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1697 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1698 X(MF_READWRITE_MMCSS_PRIORITY_AUDIO
),
1699 X(MF_MT_H264_MAX_CODEC_CONFIG_DELAY
),
1700 X(MF_MT_DV_AAUX_SRC_PACK_0
),
1701 X(MF_BYTESTREAM_ORIGIN_NAME
),
1702 X(MF_BYTESTREAM_CONTENT_TYPE
),
1703 X(MF_MT_DEPTH_MEASUREMENT
),
1704 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
),
1705 X(MF_MT_VIDEO_3D_NUM_VIEWS
),
1706 X(MF_BYTESTREAM_DURATION
),
1707 X(MF_SD_SAMI_LANGUAGE
),
1708 X(MF_EVENT_OUTPUT_NODE
),
1709 X(MF_BYTESTREAM_LAST_MODIFIED_TIME
),
1710 X(MFT_ENUM_ADAPTER_LUID
),
1711 X(MF_MT_FRAME_RATE_RANGE_MIN
),
1712 X(MF_BYTESTREAM_IFO_FILE_URI
),
1713 X(MF_EVENT_TOPOLOGY_STATUS
),
1714 X(MF_BYTESTREAM_DLNA_PROFILE_ID
),
1715 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE
),
1716 X(MF_MT_MAJOR_TYPE
),
1717 X(MF_MT_IN_BAND_PARAMETER_SET
),
1718 X(MF_EVENT_SOURCE_CHARACTERISTICS
),
1719 X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD
),
1720 X(MF_SESSION_SERVER_CONTEXT
),
1721 X(MF_MT_VIDEO_3D_FIRST_IS_LEFT
),
1722 X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT
),
1723 X(MF_PD_ADAPTIVE_STREAMING
),
1724 X(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
),
1725 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
),
1726 X(MF_MT_H264_SUPPORTED_USAGES
),
1727 X(MFT_PREFERRED_OUTPUTTYPE_Attribute
),
1728 X(MFSampleExtension_Timestamp
),
1729 X(MF_TOPONODE_PRIMARYOUTPUT
),
1731 X(MF_TRANSFORM_ASYNC
),
1732 X(MF_TOPONODE_STREAMID
),
1733 X(MF_MEDIA_ENGINE_PLAYBACK_HWND
),
1734 X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
),
1735 X(MF_MT_VIDEO_LIGHTING
),
1736 X(MF_SD_MUTUALLY_EXCLUSIVE
),
1737 X(MF_SD_STREAM_NAME
),
1738 X(MF_MT_DV_VAUX_SRC_PACK
),
1739 X(MF_TOPONODE_RATELESS
),
1740 X(MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS
),
1741 X(MF_TOPONODE_DISABLE_PREROLL
),
1742 X(MF_SA_D3D11_ALLOW_DYNAMIC_YUV_TEXTURE
),
1743 X(MF_MT_VIDEO_3D_FORMAT
),
1744 X(MF_EVENT_STREAM_METADATA_KEYDATA
),
1745 X(MF_SINK_WRITER_D3D_MANAGER
),
1746 X(MF_SOURCE_READER_D3D_MANAGER
),
1747 X(MFSampleExtension_3DVideo
),
1748 X(MF_MT_H264_USAGE
),
1749 X(MF_MEDIA_ENGINE_EME_CALLBACK
),
1750 X(MF_EVENT_SOURCE_FAKE_START
),
1751 X(MF_EVENT_SOURCE_PROJECTSTART
),
1752 X(MF_EVENT_SOURCE_ACTUAL_START
),
1753 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
),
1754 X(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
1755 X(MFT_ENUM_HARDWARE_URL_Attribute
),
1756 X(MF_SOURCE_READER_ASYNC_CALLBACK
),
1757 X(MF_MT_OUTPUT_BUFFER_NUM
),
1758 X(MF_SA_D3D11_BINDFLAGS
),
1759 X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT
),
1760 X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE
),
1761 X(MFT_FRIENDLY_NAME_Attribute
),
1762 X(MF_MT_FIXED_SIZE_SAMPLES
),
1763 X(MFT_SUPPORT_3DVIDEO
),
1764 X(MFT_SUPPORT_3DVIDEO
),
1765 X(MFT_INPUT_TYPES_Attributes
),
1766 X(MF_MT_H264_LAYOUT_PER_STREAM
),
1767 X(MF_EVENT_SCRUBSAMPLE_TIME
),
1768 X(MF_MT_SPATIAL_AUDIO_MAX_METADATA_ITEMS
),
1769 X(MF_MT_MPEG2_ONE_FRAME_PER_PACKET
),
1770 X(MF_MT_INTERLACE_MODE
),
1771 X(MF_MEDIA_ENGINE_CALLBACK
),
1772 X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE
),
1773 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE
),
1774 X(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
1775 X(MF_MT_H264_SVC_CAPABILITIES
),
1776 X(MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
),
1777 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_LENGTH
),
1778 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_FORMAT_ID
),
1779 X(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
),
1780 X(MF_SA_D3D11_SHARED
),
1781 X(MF_MT_PAN_SCAN_ENABLED
),
1782 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
),
1783 X(MF_MT_DV_VAUX_CTRL_PACK
),
1784 X(MFSampleExtension_ForwardedDecodeUnitType
),
1785 X(MF_SA_D3D11_AWARE
),
1786 X(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
1787 X(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS
),
1788 X(MF_MT_SPATIAL_AUDIO_MIN_METADATA_ITEM_OFFSET_SPACING
),
1789 X(MF_TOPONODE_TRANSFORM_OBJECTID
),
1790 X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE
),
1791 X(MF_EVENT_MFT_INPUT_STREAM_ID
),
1792 X(MF_MT_SOURCE_CONTENT_HINT
),
1793 X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute
),
1794 X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE
),
1795 X(MF_READWRITE_MMCSS_PRIORITY
),
1797 X(MF_EVENT_START_PRESENTATION_TIME
),
1798 X(MF_EVENT_SESSIONCAPS
),
1799 X(MF_EVENT_PRESENTATION_TIME_OFFSET
),
1800 X(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
),
1801 X(MF_EVENT_SESSIONCAPS_DELTA
),
1802 X(MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT
),
1803 X(MFSampleExtension_DecodeTimestamp
),
1804 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE
),
1805 X(MF_MT_VIDEO_H264_NO_FMOASO
),
1806 X(MF_MT_AVG_BIT_ERROR_RATE
),
1807 X(MF_MT_VIDEO_PRIMARIES
),
1808 X(MF_SINK_WRITER_DISABLE_THROTTLING
),
1809 X(MF_MT_H264_RATE_CONTROL_MODES
),
1810 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
),
1811 X(MF_READWRITE_D3D_OPTIONAL
),
1812 X(MF_SA_D3D11_HW_PROTECTED
),
1813 X(MF_MEDIA_ENGINE_DXGI_MANAGER
),
1814 X(MF_READWRITE_MMCSS_CLASS_AUDIO
),
1815 X(MF_MEDIA_ENGINE_COREWINDOW
),
1816 X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS
),
1817 X(MF_MT_MPEG4_TRACK_TYPE
),
1818 X(MF_ACTIVATE_VIDEO_WINDOW
),
1819 X(MF_MT_PAN_SCAN_APERTURE
),
1820 X(MF_TOPOLOGY_RESOLUTION_STATUS
),
1821 X(MF_MT_ORIGINAL_4CC
),
1822 X(MF_PD_AUDIO_ISVARIABLEBITRATE
),
1823 X(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS
),
1824 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
),
1825 X(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID
),
1826 X(MF_MT_MPEG2_CONTENT_PACKET
),
1827 X(MFT_PROCESS_LOCAL_Attribute
),
1828 X(MFT_PROCESS_LOCAL_Attribute
),
1829 X(MF_MT_PAD_CONTROL_FLAGS
),
1830 X(MF_MT_VIDEO_NOMINAL_RANGE
),
1831 X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
1832 X(MF_MT_MPEG_SEQUENCE_HEADER
),
1833 X(MF_MEDIA_ENGINE_OPM_HWND
),
1834 X(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
1835 X(MF_MT_SPATIAL_AUDIO_DATA_PRESENT
),
1836 X(MF_MT_FRAME_RATE
),
1837 X(MF_TOPONODE_FLUSH
),
1838 X(MF_MT_MPEG2_STANDARD
),
1839 X(MF_TOPONODE_DRAIN
),
1840 X(MF_MT_TRANSFER_FUNCTION
),
1841 X(MF_TOPONODE_MEDIASTART
),
1842 X(MF_TOPONODE_MEDIASTOP
),
1843 X(MF_SOURCE_READER_MEDIASOURCE_CONFIG
),
1844 X(MF_TOPONODE_SOURCE
),
1845 X(MF_TOPONODE_PRESENTATION_DESCRIPTOR
),
1846 X(MF_TOPONODE_D3DAWARE
),
1847 X(MF_MT_COMPRESSED
),
1848 X(MF_TOPONODE_STREAM_DESCRIPTOR
),
1849 X(MF_TOPONODE_ERRORCODE
),
1850 X(MF_TOPONODE_SEQUENCE_ELEMENTID
),
1851 X(MF_EVENT_MFT_CONTEXT
),
1852 X(MF_MT_FORWARD_CUSTOM_SEI
),
1853 X(MF_TOPONODE_CONNECT_METHOD
),
1854 X(MFT_OUTPUT_TYPES_Attributes
),
1855 X(MF_MT_IMAGE_LOSS_TOLERANT
),
1856 X(MF_SESSION_REMOTE_SOURCE_MODE
),
1857 X(MF_MT_DEPTH_VALUE_UNIT
),
1858 X(MF_MT_AUDIO_NUM_CHANNELS
),
1859 X(MF_MT_ARBITRARY_HEADER
),
1860 X(MF_TOPOLOGY_DXVA_MODE
),
1861 X(MF_TOPONODE_LOCKED
),
1862 X(MF_TOPONODE_WORKQUEUE_ID
),
1863 X(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
),
1864 X(MF_TOPONODE_WORKQUEUE_MMCSS_CLASS
),
1865 X(MF_TOPONODE_DECRYPTOR
),
1866 X(MF_EVENT_DO_THINNING
),
1867 X(MF_TOPONODE_DISCARDABLE
),
1868 X(MF_TOPOLOGY_HARDWARE_MODE
),
1869 X(MF_SOURCE_READER_DISABLE_DXVA
),
1870 X(MF_MT_FORWARD_CUSTOM_NALU
),
1871 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
),
1872 X(MF_TOPONODE_ERROR_MAJORTYPE
),
1874 X(MFT_FIELDOFUSE_UNLOCK_Attribute
),
1875 X(MF_TOPONODE_ERROR_SUBTYPE
),
1876 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
),
1877 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
),
1878 X(MF_MT_VIDEO_3D_LEFT_IS_BASE
),
1879 X(MF_TOPONODE_WORKQUEUE_MMCSS_TASKID
),
1882 struct guid_def
*ret
= NULL
;
1885 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
1887 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
1890 const char *debugstr_mf_guid(const GUID
*guid
)
1892 static const struct guid_def guid_defs
[] =
1894 #define X(g) { &(g), #g }
1895 X(MFAudioFormat_ADTS
),
1896 X(MFAudioFormat_PCM
),
1897 X(MFAudioFormat_PCM_HDCP
),
1898 X(MFAudioFormat_Float
),
1899 X(MFAudioFormat_DTS
),
1900 X(MFAudioFormat_DRM
),
1901 X(MFAudioFormat_MSP1
),
1902 X(MFAudioFormat_Vorbis
),
1903 X(MFAudioFormat_AAC
),
1904 X(MFVideoFormat_RGB24
),
1905 X(MFVideoFormat_ARGB32
),
1906 X(MFVideoFormat_RGB32
),
1907 X(MFVideoFormat_RGB565
),
1908 X(MFVideoFormat_RGB555
),
1909 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
),
1910 X(MFVideoFormat_A2R10G10B10
),
1911 X(MFMediaType_Script
),
1912 X(MFMediaType_Image
),
1913 X(MFMediaType_HTML
),
1914 X(MFMediaType_Binary
),
1915 X(MFVideoFormat_MPEG2
),
1916 X(MFMediaType_FileTransfer
),
1917 X(MFVideoFormat_RGB8
),
1918 X(MFAudioFormat_Dolby_AC3
),
1919 X(MFVideoFormat_L8
),
1920 X(MFAudioFormat_LPCM
),
1921 X(MFVideoFormat_420O
),
1922 X(MFVideoFormat_AI44
),
1923 X(MFVideoFormat_AV1
),
1924 X(MFVideoFormat_AYUV
),
1925 X(MFVideoFormat_H263
),
1926 X(MFVideoFormat_H264
),
1927 X(MFVideoFormat_H265
),
1928 X(MFVideoFormat_HEVC
),
1929 X(MFVideoFormat_HEVC_ES
),
1930 X(MFVideoFormat_I420
),
1931 X(MFVideoFormat_IYUV
),
1932 X(MFVideoFormat_M4S2
),
1933 X(MFVideoFormat_MJPG
),
1934 X(MFVideoFormat_MP43
),
1935 X(MFVideoFormat_MP4S
),
1936 X(MFVideoFormat_MP4V
),
1937 X(MFVideoFormat_MPG1
),
1938 X(MFVideoFormat_MSS1
),
1939 X(MFVideoFormat_MSS2
),
1940 X(MFVideoFormat_NV11
),
1941 X(MFVideoFormat_NV12
),
1942 X(MFVideoFormat_ORAW
),
1943 X(MFAudioFormat_Opus
),
1944 X(MFVideoFormat_D16
),
1945 X(MFAudioFormat_MPEG
),
1946 X(MFVideoFormat_P010
),
1947 X(MFVideoFormat_P016
),
1948 X(MFVideoFormat_P210
),
1949 X(MFVideoFormat_P216
),
1950 X(MFVideoFormat_L16
),
1951 X(MFAudioFormat_MP3
),
1952 X(MFVideoFormat_UYVY
),
1953 X(MFVideoFormat_VP10
),
1954 X(MFVideoFormat_VP80
),
1955 X(MFVideoFormat_VP90
),
1956 X(MFVideoFormat_WMV1
),
1957 X(MFVideoFormat_WMV2
),
1958 X(MFVideoFormat_WMV3
),
1959 X(MFVideoFormat_WVC1
),
1960 X(MFVideoFormat_Y210
),
1961 X(MFVideoFormat_Y216
),
1962 X(MFVideoFormat_Y410
),
1963 X(MFVideoFormat_Y416
),
1964 X(MFVideoFormat_Y41P
),
1965 X(MFVideoFormat_Y41T
),
1966 X(MFVideoFormat_Y42T
),
1967 X(MFVideoFormat_YUY2
),
1968 X(MFVideoFormat_YV12
),
1969 X(MFVideoFormat_YVU9
),
1970 X(MFVideoFormat_YVYU
),
1971 X(MFAudioFormat_WMAudioV8
),
1972 X(MFAudioFormat_ALAC
),
1973 X(MFAudioFormat_AMR_NB
),
1974 X(MFMediaType_Audio
),
1975 X(MFAudioFormat_WMAudioV9
),
1976 X(MFAudioFormat_AMR_WB
),
1977 X(MFAudioFormat_WMAudio_Lossless
),
1978 X(MFAudioFormat_AMR_WP
),
1979 X(MFAudioFormat_WMASPDIF
),
1980 X(MFVideoFormat_DV25
),
1981 X(MFVideoFormat_DV50
),
1982 X(MFVideoFormat_DVC
),
1983 X(MFVideoFormat_DVH1
),
1984 X(MFVideoFormat_DVHD
),
1985 X(MFVideoFormat_DVSD
),
1986 X(MFVideoFormat_DVSL
),
1987 X(MFVideoFormat_A16B16G16R16F
),
1988 X(MFVideoFormat_v210
),
1989 X(MFVideoFormat_v216
),
1990 X(MFVideoFormat_v410
),
1991 X(MFMediaType_Video
),
1992 X(MFAudioFormat_AAC_HDCP
),
1993 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
),
1994 X(MFAudioFormat_Dolby_AC3_HDCP
),
1995 X(MFMediaType_Subtitle
),
1996 X(MFMediaType_Stream
),
1997 X(MFAudioFormat_Dolby_AC3_SPDIF
),
1998 X(MFAudioFormat_Float_SpatialObjects
),
1999 X(MFMediaType_SAMI
),
2000 X(MFAudioFormat_ADTS_HDCP
),
2001 X(MFAudioFormat_FLAC
),
2002 X(MFAudioFormat_Dolby_DDPlus
),
2003 X(MFMediaType_MultiplexedFrames
),
2004 X(MFAudioFormat_Base_HDCP
),
2005 X(MFVideoFormat_Base_HDCP
),
2006 X(MFVideoFormat_H264_HDCP
),
2007 X(MFVideoFormat_HEVC_HDCP
),
2008 X(MFMediaType_Default
),
2009 X(MFMediaType_Protected
),
2010 X(MFVideoFormat_H264_ES
),
2011 X(MFMediaType_Perception
),
2014 struct guid_def
*ret
= NULL
;
2017 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2019 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2028 static int __cdecl
debug_event_id(const void *a
, const void *b
)
2030 const DWORD
*id
= a
;
2031 const struct event_id
*event_id
= b
;
2032 return *id
- event_id
->id
;
2035 static const char *debugstr_eventid(DWORD event
)
2037 static const struct event_id
2044 #define X(e) { e, #e }
2049 X(MESessionUnknown
),
2050 X(MESessionTopologySet
),
2051 X(MESessionTopologiesCleared
),
2052 X(MESessionStarted
),
2054 X(MESessionStopped
),
2057 X(MESessionRateChanged
),
2058 X(MESessionScrubSampleComplete
),
2059 X(MESessionCapabilitiesChanged
),
2060 X(MESessionTopologyStatus
),
2061 X(MESessionNotifyPresentationTime
),
2062 X(MENewPresentation
),
2063 X(MELicenseAcquisitionStart
),
2064 X(MELicenseAcquisitionCompleted
),
2065 X(MEIndividualizationStart
),
2066 X(MEIndividualizationCompleted
),
2067 X(MEEnablerProgress
),
2068 X(MEEnablerCompleted
),
2071 X(MEBufferingStarted
),
2072 X(MEBufferingStopped
),
2075 X(MEReconnectStart
),
2078 X(MESessionStreamSinkFormatChanged
),
2090 X(MEEndOfPresentation
),
2094 X(MEStreamThinMode
),
2095 X(MEStreamFormatChanged
),
2096 X(MESourceRateChanged
),
2097 X(MEEndOfPresentationSegment
),
2098 X(MESourceCharacteristicsChanged
),
2099 X(MESourceRateChangeRequested
),
2100 X(MESourceMetadataChanged
),
2101 X(MESequencerSourceTopologyUpdated
),
2103 X(MEStreamSinkStarted
),
2104 X(MEStreamSinkStopped
),
2105 X(MEStreamSinkPaused
),
2106 X(MEStreamSinkRateChanged
),
2107 X(MEStreamSinkRequestSample
),
2108 X(MEStreamSinkMarker
),
2109 X(MEStreamSinkPrerolled
),
2110 X(MEStreamSinkScrubSampleComplete
),
2111 X(MEStreamSinkFormatChanged
),
2112 X(MEStreamSinkDeviceChanged
),
2114 X(MESinkInvalidated
),
2115 X(MEAudioSessionNameChanged
),
2116 X(MEAudioSessionVolumeChanged
),
2117 X(MEAudioSessionDeviceRemoved
),
2118 X(MEAudioSessionServerShutdown
),
2119 X(MEAudioSessionGroupingParamChanged
),
2120 X(MEAudioSessionIconChanged
),
2121 X(MEAudioSessionFormatChanged
),
2122 X(MEAudioSessionDisconnected
),
2123 X(MEAudioSessionExclusiveModeOverride
),
2126 X(MEContentProtectionMessage
),
2128 X(MEWMDRMLicenseBackupCompleted
),
2129 X(MEWMDRMLicenseBackupProgress
),
2130 X(MEWMDRMLicenseRestoreCompleted
),
2131 X(MEWMDRMLicenseRestoreProgress
),
2132 X(MEWMDRMLicenseAcquisitionCompleted
),
2133 X(MEWMDRMIndividualizationCompleted
),
2134 X(MEWMDRMIndividualizationProgress
),
2135 X(MEWMDRMProximityCompleted
),
2136 X(MEWMDRMLicenseStoreCleaned
),
2137 X(MEWMDRMRevocationDownloadCompleted
),
2138 X(METransformUnknown
),
2139 X(METransformNeedInput
),
2140 X(METransformHaveOutput
),
2141 X(METransformDrainComplete
),
2142 X(METransformMarker
),
2143 X(METransformInputStreamStateChanged
),
2144 X(MEByteStreamCharacteristicsChanged
),
2145 X(MEVideoCaptureDeviceRemoved
),
2146 X(MEVideoCaptureDevicePreempted
),
2147 X(MEStreamSinkFormatInvalidated
),
2148 X(MEEncodingParameters
),
2149 X(MEContentProtectionMetadata
),
2150 X(MEDeviceThermalStateChanged
),
2154 struct event_id
*ret
= bsearch(&event
, event_ids
, ARRAY_SIZE(event_ids
), sizeof(*event_ids
), debug_event_id
);
2155 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbg_sprintf("%u", event
);
2158 static inline struct attributes
*impl_from_IMFAttributes(IMFAttributes
*iface
)
2160 return CONTAINING_RECORD(iface
, struct attributes
, IMFAttributes_iface
);
2163 static HRESULT WINAPI
mfattributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
2165 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2167 if (IsEqualIID(riid
, &IID_IMFAttributes
) ||
2168 IsEqualGUID(riid
, &IID_IUnknown
))
2171 IMFAttributes_AddRef(iface
);
2175 WARN("Unsupported %s.\n", debugstr_guid(riid
));
2177 return E_NOINTERFACE
;
2180 static ULONG WINAPI
mfattributes_AddRef(IMFAttributes
*iface
)
2182 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2183 ULONG refcount
= InterlockedIncrement(&attributes
->ref
);
2185 TRACE("%p, refcount %d.\n", iface
, refcount
);
2190 static ULONG WINAPI
mfattributes_Release(IMFAttributes
*iface
)
2192 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2193 ULONG refcount
= InterlockedDecrement(&attributes
->ref
);
2195 TRACE("%p, refcount %d.\n", iface
, refcount
);
2199 clear_attributes_object(attributes
);
2200 heap_free(attributes
);
2206 static struct attribute
*attributes_find_item(struct attributes
*attributes
, REFGUID key
, size_t *index
)
2210 for (i
= 0; i
< attributes
->count
; ++i
)
2212 if (IsEqualGUID(key
, &attributes
->attributes
[i
].key
))
2216 return &attributes
->attributes
[i
];
2223 static HRESULT
attributes_get_item(struct attributes
*attributes
, const GUID
*key
, PROPVARIANT
*value
)
2225 struct attribute
*attribute
;
2228 EnterCriticalSection(&attributes
->cs
);
2230 attribute
= attributes_find_item(attributes
, key
, NULL
);
2233 if (attribute
->value
.vt
== value
->vt
&& !(value
->vt
== VT_UNKNOWN
&& !attribute
->value
.u
.punkVal
))
2234 hr
= PropVariantCopy(value
, &attribute
->value
);
2236 hr
= MF_E_INVALIDTYPE
;
2239 hr
= MF_E_ATTRIBUTENOTFOUND
;
2241 LeaveCriticalSection(&attributes
->cs
);
2246 HRESULT
attributes_GetItem(struct attributes
*attributes
, REFGUID key
, PROPVARIANT
*value
)
2248 struct attribute
*attribute
;
2251 EnterCriticalSection(&attributes
->cs
);
2253 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2254 hr
= value
? PropVariantCopy(value
, &attribute
->value
) : S_OK
;
2256 hr
= MF_E_ATTRIBUTENOTFOUND
;
2258 LeaveCriticalSection(&attributes
->cs
);
2263 HRESULT
attributes_GetItemType(struct attributes
*attributes
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2265 struct attribute
*attribute
;
2268 EnterCriticalSection(&attributes
->cs
);
2270 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2272 *type
= attribute
->value
.vt
;
2275 hr
= MF_E_ATTRIBUTENOTFOUND
;
2277 LeaveCriticalSection(&attributes
->cs
);
2282 HRESULT
attributes_CompareItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2284 struct attribute
*attribute
;
2288 EnterCriticalSection(&attributes
->cs
);
2290 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2292 *result
= attribute
->value
.vt
== value
->vt
&&
2293 !PropVariantCompareEx(&attribute
->value
, value
, PVCU_DEFAULT
, PVCF_DEFAULT
);
2296 LeaveCriticalSection(&attributes
->cs
);
2301 HRESULT
attributes_Compare(struct attributes
*attributes
, IMFAttributes
*theirs
,
2302 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2304 IMFAttributes
*smaller
, *other
;
2305 MF_ATTRIBUTE_TYPE type
;
2311 if (FAILED(hr
= IMFAttributes_GetCount(theirs
, &count
)))
2314 EnterCriticalSection(&attributes
->cs
);
2320 case MF_ATTRIBUTES_MATCH_OUR_ITEMS
:
2321 for (i
= 0; i
< attributes
->count
; ++i
)
2323 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2324 &attributes
->attributes
[i
].value
, &result
)))
2330 case MF_ATTRIBUTES_MATCH_THEIR_ITEMS
:
2331 hr
= IMFAttributes_Compare(theirs
, &attributes
->IMFAttributes_iface
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2333 case MF_ATTRIBUTES_MATCH_ALL_ITEMS
:
2334 if (count
!= attributes
->count
)
2339 for (i
= 0; i
< count
; ++i
)
2341 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2342 &attributes
->attributes
[i
].value
, &result
)))
2348 case MF_ATTRIBUTES_MATCH_INTERSECTION
:
2349 for (i
= 0; i
< attributes
->count
; ++i
)
2351 if (FAILED(IMFAttributes_GetItemType(theirs
, &attributes
->attributes
[i
].key
, &type
)))
2354 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2355 &attributes
->attributes
[i
].value
, &result
)))
2362 case MF_ATTRIBUTES_MATCH_SMALLER
:
2363 smaller
= attributes
->count
> count
? theirs
: &attributes
->IMFAttributes_iface
;
2364 other
= attributes
->count
> count
? &attributes
->IMFAttributes_iface
: theirs
;
2365 hr
= IMFAttributes_Compare(smaller
, other
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2368 WARN("Unknown match type %d.\n", match_type
);
2372 LeaveCriticalSection(&attributes
->cs
);
2380 HRESULT
attributes_GetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32
*value
)
2382 PROPVARIANT attrval
;
2385 PropVariantInit(&attrval
);
2386 attrval
.vt
= VT_UI4
;
2387 hr
= attributes_get_item(attributes
, key
, &attrval
);
2389 *value
= attrval
.u
.ulVal
;
2394 HRESULT
attributes_GetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64
*value
)
2396 PROPVARIANT attrval
;
2399 PropVariantInit(&attrval
);
2400 attrval
.vt
= VT_UI8
;
2401 hr
= attributes_get_item(attributes
, key
, &attrval
);
2403 *value
= attrval
.u
.uhVal
.QuadPart
;
2408 HRESULT
attributes_GetDouble(struct attributes
*attributes
, REFGUID key
, double *value
)
2410 PROPVARIANT attrval
;
2413 PropVariantInit(&attrval
);
2415 hr
= attributes_get_item(attributes
, key
, &attrval
);
2417 *value
= attrval
.u
.dblVal
;
2422 HRESULT
attributes_GetGUID(struct attributes
*attributes
, REFGUID key
, GUID
*value
)
2424 struct attribute
*attribute
;
2427 EnterCriticalSection(&attributes
->cs
);
2429 attribute
= attributes_find_item(attributes
, key
, NULL
);
2432 if (attribute
->value
.vt
== MF_ATTRIBUTE_GUID
)
2433 *value
= *attribute
->value
.u
.puuid
;
2435 hr
= MF_E_INVALIDTYPE
;
2438 hr
= MF_E_ATTRIBUTENOTFOUND
;
2440 LeaveCriticalSection(&attributes
->cs
);
2445 HRESULT
attributes_GetStringLength(struct attributes
*attributes
, REFGUID key
, UINT32
*length
)
2447 struct attribute
*attribute
;
2450 EnterCriticalSection(&attributes
->cs
);
2452 attribute
= attributes_find_item(attributes
, key
, NULL
);
2455 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2456 *length
= lstrlenW(attribute
->value
.u
.pwszVal
);
2458 hr
= MF_E_INVALIDTYPE
;
2461 hr
= MF_E_ATTRIBUTENOTFOUND
;
2463 LeaveCriticalSection(&attributes
->cs
);
2468 HRESULT
attributes_GetString(struct attributes
*attributes
, REFGUID key
, WCHAR
*value
,
2469 UINT32 size
, UINT32
*length
)
2471 struct attribute
*attribute
;
2474 EnterCriticalSection(&attributes
->cs
);
2476 attribute
= attributes_find_item(attributes
, key
, NULL
);
2479 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2481 int len
= lstrlenW(attribute
->value
.u
.pwszVal
);
2487 hr
= STRSAFE_E_INSUFFICIENT_BUFFER
;
2489 memcpy(value
, attribute
->value
.u
.pwszVal
, (len
+ 1) * sizeof(WCHAR
));
2492 hr
= MF_E_INVALIDTYPE
;
2495 hr
= MF_E_ATTRIBUTENOTFOUND
;
2497 LeaveCriticalSection(&attributes
->cs
);
2502 HRESULT
attributes_GetAllocatedString(struct attributes
*attributes
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2504 PROPVARIANT attrval
;
2507 PropVariantInit(&attrval
);
2508 attrval
.vt
= VT_LPWSTR
;
2509 hr
= attributes_get_item(attributes
, key
, &attrval
);
2512 *value
= attrval
.u
.pwszVal
;
2513 *length
= lstrlenW(*value
);
2519 HRESULT
attributes_GetBlobSize(struct attributes
*attributes
, REFGUID key
, UINT32
*size
)
2521 struct attribute
*attribute
;
2524 EnterCriticalSection(&attributes
->cs
);
2526 attribute
= attributes_find_item(attributes
, key
, NULL
);
2529 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2530 *size
= attribute
->value
.u
.caub
.cElems
;
2532 hr
= MF_E_INVALIDTYPE
;
2535 hr
= MF_E_ATTRIBUTENOTFOUND
;
2537 LeaveCriticalSection(&attributes
->cs
);
2542 HRESULT
attributes_GetBlob(struct attributes
*attributes
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
, UINT32
*blobsize
)
2544 struct attribute
*attribute
;
2547 EnterCriticalSection(&attributes
->cs
);
2549 attribute
= attributes_find_item(attributes
, key
, NULL
);
2552 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2554 UINT32 size
= attribute
->value
.u
.caub
.cElems
;
2556 if (bufsize
>= size
)
2557 hr
= PropVariantToBuffer(&attribute
->value
, buf
, size
);
2559 hr
= E_NOT_SUFFICIENT_BUFFER
;
2565 hr
= MF_E_INVALIDTYPE
;
2568 hr
= MF_E_ATTRIBUTENOTFOUND
;
2570 LeaveCriticalSection(&attributes
->cs
);
2575 HRESULT
attributes_GetAllocatedBlob(struct attributes
*attributes
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2577 PROPVARIANT attrval
;
2580 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2581 hr
= attributes_get_item(attributes
, key
, &attrval
);
2584 *buf
= attrval
.u
.caub
.pElems
;
2585 *size
= attrval
.u
.caub
.cElems
;
2591 HRESULT
attributes_GetUnknown(struct attributes
*attributes
, REFGUID key
, REFIID riid
, void **out
)
2593 PROPVARIANT attrval
;
2596 PropVariantInit(&attrval
);
2597 attrval
.vt
= VT_UNKNOWN
;
2598 hr
= attributes_get_item(attributes
, key
, &attrval
);
2600 hr
= IUnknown_QueryInterface(attrval
.u
.punkVal
, riid
, out
);
2601 PropVariantClear(&attrval
);
2605 static HRESULT
attributes_set_item(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2607 struct attribute
*attribute
;
2609 EnterCriticalSection(&attributes
->cs
);
2611 attribute
= attributes_find_item(attributes
, key
, NULL
);
2614 if (!mf_array_reserve((void **)&attributes
->attributes
, &attributes
->capacity
, attributes
->count
+ 1,
2615 sizeof(*attributes
->attributes
)))
2617 LeaveCriticalSection(&attributes
->cs
);
2618 return E_OUTOFMEMORY
;
2620 attributes
->attributes
[attributes
->count
].key
= *key
;
2621 attribute
= &attributes
->attributes
[attributes
->count
++];
2624 PropVariantClear(&attribute
->value
);
2626 PropVariantCopy(&attribute
->value
, value
);
2628 LeaveCriticalSection(&attributes
->cs
);
2633 HRESULT
attributes_SetItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2639 case MF_ATTRIBUTE_UINT32
:
2640 case MF_ATTRIBUTE_UINT64
:
2641 case MF_ATTRIBUTE_DOUBLE
:
2642 case MF_ATTRIBUTE_GUID
:
2643 case MF_ATTRIBUTE_STRING
:
2644 case MF_ATTRIBUTE_BLOB
:
2645 case MF_ATTRIBUTE_IUNKNOWN
:
2646 return attributes_set_item(attributes
, key
, value
);
2648 PropVariantInit(&empty
);
2649 attributes_set_item(attributes
, key
, &empty
);
2650 return MF_E_INVALIDTYPE
;
2654 HRESULT
attributes_DeleteItem(struct attributes
*attributes
, REFGUID key
)
2656 struct attribute
*attribute
;
2659 EnterCriticalSection(&attributes
->cs
);
2661 if ((attribute
= attributes_find_item(attributes
, key
, &index
)))
2665 PropVariantClear(&attribute
->value
);
2667 attributes
->count
--;
2668 count
= attributes
->count
- index
;
2670 memmove(&attributes
->attributes
[index
], &attributes
->attributes
[index
+ 1], count
* sizeof(*attributes
->attributes
));
2673 LeaveCriticalSection(&attributes
->cs
);
2678 HRESULT
attributes_DeleteAllItems(struct attributes
*attributes
)
2680 EnterCriticalSection(&attributes
->cs
);
2682 while (attributes
->count
)
2684 PropVariantClear(&attributes
->attributes
[--attributes
->count
].value
);
2686 heap_free(attributes
->attributes
);
2687 attributes
->attributes
= NULL
;
2688 attributes
->capacity
= 0;
2690 LeaveCriticalSection(&attributes
->cs
);
2695 HRESULT
attributes_SetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32 value
)
2697 PROPVARIANT attrval
;
2699 attrval
.vt
= VT_UI4
;
2700 attrval
.u
.ulVal
= value
;
2701 return attributes_set_item(attributes
, key
, &attrval
);
2704 HRESULT
attributes_SetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64 value
)
2706 PROPVARIANT attrval
;
2708 attrval
.vt
= VT_UI8
;
2709 attrval
.u
.uhVal
.QuadPart
= value
;
2710 return attributes_set_item(attributes
, key
, &attrval
);
2713 HRESULT
attributes_SetDouble(struct attributes
*attributes
, REFGUID key
, double value
)
2715 PROPVARIANT attrval
;
2718 attrval
.u
.dblVal
= value
;
2719 return attributes_set_item(attributes
, key
, &attrval
);
2722 HRESULT
attributes_SetGUID(struct attributes
*attributes
, REFGUID key
, REFGUID value
)
2724 PROPVARIANT attrval
;
2726 attrval
.vt
= VT_CLSID
;
2727 attrval
.u
.puuid
= (CLSID
*)value
;
2728 return attributes_set_item(attributes
, key
, &attrval
);
2731 HRESULT
attributes_SetString(struct attributes
*attributes
, REFGUID key
, const WCHAR
*value
)
2733 PROPVARIANT attrval
;
2735 attrval
.vt
= VT_LPWSTR
;
2736 attrval
.u
.pwszVal
= (WCHAR
*)value
;
2737 return attributes_set_item(attributes
, key
, &attrval
);
2740 HRESULT
attributes_SetBlob(struct attributes
*attributes
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
2742 PROPVARIANT attrval
;
2744 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2745 attrval
.u
.caub
.cElems
= size
;
2746 attrval
.u
.caub
.pElems
= (UINT8
*)buf
;
2747 return attributes_set_item(attributes
, key
, &attrval
);
2750 HRESULT
attributes_SetUnknown(struct attributes
*attributes
, REFGUID key
, IUnknown
*unknown
)
2752 PROPVARIANT attrval
;
2754 attrval
.vt
= VT_UNKNOWN
;
2755 attrval
.u
.punkVal
= unknown
;
2756 return attributes_set_item(attributes
, key
, &attrval
);
2759 HRESULT
attributes_LockStore(struct attributes
*attributes
)
2761 EnterCriticalSection(&attributes
->cs
);
2766 HRESULT
attributes_UnlockStore(struct attributes
*attributes
)
2768 LeaveCriticalSection(&attributes
->cs
);
2773 HRESULT
attributes_GetCount(struct attributes
*attributes
, UINT32
*count
)
2775 EnterCriticalSection(&attributes
->cs
);
2776 *count
= attributes
->count
;
2777 LeaveCriticalSection(&attributes
->cs
);
2782 HRESULT
attributes_GetItemByIndex(struct attributes
*attributes
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
2786 EnterCriticalSection(&attributes
->cs
);
2788 if (index
< attributes
->count
)
2790 *key
= attributes
->attributes
[index
].key
;
2792 PropVariantCopy(value
, &attributes
->attributes
[index
].value
);
2797 LeaveCriticalSection(&attributes
->cs
);
2802 HRESULT
attributes_CopyAllItems(struct attributes
*attributes
, IMFAttributes
*dest
)
2807 EnterCriticalSection(&attributes
->cs
);
2809 IMFAttributes_LockStore(dest
);
2811 IMFAttributes_DeleteAllItems(dest
);
2813 for (i
= 0; i
< attributes
->count
; ++i
)
2815 hr
= IMFAttributes_SetItem(dest
, &attributes
->attributes
[i
].key
, &attributes
->attributes
[i
].value
);
2820 IMFAttributes_UnlockStore(dest
);
2822 LeaveCriticalSection(&attributes
->cs
);
2827 static HRESULT WINAPI
mfattributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
2829 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2831 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2833 return attributes_GetItem(attributes
, key
, value
);
2836 static HRESULT WINAPI
mfattributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2838 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2840 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
2842 return attributes_GetItemType(attributes
, key
, type
);
2845 static HRESULT WINAPI
mfattributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2847 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2849 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
2851 return attributes_CompareItem(attributes
, key
, value
, result
);
2854 static HRESULT WINAPI
mfattributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
2855 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2857 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2859 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
2861 return attributes_Compare(attributes
, theirs
, match_type
, ret
);
2864 static HRESULT WINAPI
mfattributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
2866 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2868 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2870 return attributes_GetUINT32(attributes
, key
, value
);
2873 static HRESULT WINAPI
mfattributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
2875 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2877 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2879 return attributes_GetUINT64(attributes
, key
, value
);
2882 static HRESULT WINAPI
mfattributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
2884 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2886 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2888 return attributes_GetDouble(attributes
, key
, value
);
2891 static HRESULT WINAPI
mfattributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
2893 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2895 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2897 return attributes_GetGUID(attributes
, key
, value
);
2900 static HRESULT WINAPI
mfattributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
2902 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2904 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
2906 return attributes_GetStringLength(attributes
, key
, length
);
2909 static HRESULT WINAPI
mfattributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
2910 UINT32 size
, UINT32
*length
)
2912 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2914 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
2916 return attributes_GetString(attributes
, key
, value
, size
, length
);
2919 static HRESULT WINAPI
mfattributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2921 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2923 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
2925 return attributes_GetAllocatedString(attributes
, key
, value
, length
);
2928 static HRESULT WINAPI
mfattributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
2930 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2932 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
2934 return attributes_GetBlobSize(attributes
, key
, size
);
2937 static HRESULT WINAPI
mfattributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
2938 UINT32 bufsize
, UINT32
*blobsize
)
2940 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2942 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
2944 return attributes_GetBlob(attributes
, key
, buf
, bufsize
, blobsize
);
2947 static HRESULT WINAPI
mfattributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2949 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2951 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
2953 return attributes_GetAllocatedBlob(attributes
, key
, buf
, size
);
2956 static HRESULT WINAPI
mfattributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
2958 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2960 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
2962 return attributes_GetUnknown(attributes
, key
, riid
, out
);
2965 static HRESULT WINAPI
mfattributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
2967 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2969 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
2971 return attributes_SetItem(attributes
, key
, value
);
2974 static HRESULT WINAPI
mfattributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
2976 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2978 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
2980 return attributes_DeleteItem(attributes
, key
);
2983 static HRESULT WINAPI
mfattributes_DeleteAllItems(IMFAttributes
*iface
)
2985 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2987 TRACE("%p.\n", iface
);
2989 return attributes_DeleteAllItems(attributes
);
2992 static HRESULT WINAPI
mfattributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
2994 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2996 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
2998 return attributes_SetUINT32(attributes
, key
, value
);
3001 static HRESULT WINAPI
mfattributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
3003 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3005 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
3007 return attributes_SetUINT64(attributes
, key
, value
);
3010 static HRESULT WINAPI
mfattributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
3012 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3014 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
3016 return attributes_SetDouble(attributes
, key
, value
);
3019 static HRESULT WINAPI
mfattributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
3021 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3023 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
3025 return attributes_SetGUID(attributes
, key
, value
);
3028 static HRESULT WINAPI
mfattributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
3030 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3032 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
3034 return attributes_SetString(attributes
, key
, value
);
3037 static HRESULT WINAPI
mfattributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
3039 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3041 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
3043 return attributes_SetBlob(attributes
, key
, buf
, size
);
3046 static HRESULT WINAPI
mfattributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
3048 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3050 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
3052 return attributes_SetUnknown(attributes
, key
, unknown
);
3055 static HRESULT WINAPI
mfattributes_LockStore(IMFAttributes
*iface
)
3057 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3059 TRACE("%p.\n", iface
);
3061 return attributes_LockStore(attributes
);
3064 static HRESULT WINAPI
mfattributes_UnlockStore(IMFAttributes
*iface
)
3066 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3068 TRACE("%p.\n", iface
);
3070 return attributes_UnlockStore(attributes
);
3073 static HRESULT WINAPI
mfattributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
3075 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3077 TRACE("%p, %p.\n", iface
, count
);
3079 return attributes_GetCount(attributes
, count
);
3082 static HRESULT WINAPI
mfattributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
3084 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3086 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
3088 return attributes_GetItemByIndex(attributes
, index
, key
, value
);
3091 static HRESULT WINAPI
mfattributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
3093 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3095 TRACE("%p, %p.\n", iface
, dest
);
3097 return attributes_CopyAllItems(attributes
, dest
);
3100 static const IMFAttributesVtbl mfattributes_vtbl
=
3102 mfattributes_QueryInterface
,
3103 mfattributes_AddRef
,
3104 mfattributes_Release
,
3105 mfattributes_GetItem
,
3106 mfattributes_GetItemType
,
3107 mfattributes_CompareItem
,
3108 mfattributes_Compare
,
3109 mfattributes_GetUINT32
,
3110 mfattributes_GetUINT64
,
3111 mfattributes_GetDouble
,
3112 mfattributes_GetGUID
,
3113 mfattributes_GetStringLength
,
3114 mfattributes_GetString
,
3115 mfattributes_GetAllocatedString
,
3116 mfattributes_GetBlobSize
,
3117 mfattributes_GetBlob
,
3118 mfattributes_GetAllocatedBlob
,
3119 mfattributes_GetUnknown
,
3120 mfattributes_SetItem
,
3121 mfattributes_DeleteItem
,
3122 mfattributes_DeleteAllItems
,
3123 mfattributes_SetUINT32
,
3124 mfattributes_SetUINT64
,
3125 mfattributes_SetDouble
,
3126 mfattributes_SetGUID
,
3127 mfattributes_SetString
,
3128 mfattributes_SetBlob
,
3129 mfattributes_SetUnknown
,
3130 mfattributes_LockStore
,
3131 mfattributes_UnlockStore
,
3132 mfattributes_GetCount
,
3133 mfattributes_GetItemByIndex
,
3134 mfattributes_CopyAllItems
3137 HRESULT
init_attributes_object(struct attributes
*object
, UINT32 size
)
3139 object
->IMFAttributes_iface
.lpVtbl
= &mfattributes_vtbl
;
3141 InitializeCriticalSection(&object
->cs
);
3143 object
->attributes
= NULL
;
3145 object
->capacity
= 0;
3146 if (!mf_array_reserve((void **)&object
->attributes
, &object
->capacity
, size
,
3147 sizeof(*object
->attributes
)))
3149 DeleteCriticalSection(&object
->cs
);
3150 return E_OUTOFMEMORY
;
3156 void clear_attributes_object(struct attributes
*object
)
3160 for (i
= 0; i
< object
->count
; i
++)
3161 PropVariantClear(&object
->attributes
[i
].value
);
3162 heap_free(object
->attributes
);
3164 DeleteCriticalSection(&object
->cs
);
3167 /***********************************************************************
3168 * MFCreateAttributes (mfplat.@)
3170 HRESULT WINAPI
MFCreateAttributes(IMFAttributes
**attributes
, UINT32 size
)
3172 struct attributes
*object
;
3175 TRACE("%p, %d\n", attributes
, size
);
3177 object
= heap_alloc_zero(sizeof(*object
));
3179 return E_OUTOFMEMORY
;
3181 if (FAILED(hr
= init_attributes_object(object
, size
)))
3186 *attributes
= &object
->IMFAttributes_iface
;
3191 #define ATTRIBUTES_STORE_MAGIC 0x494d4641 /* IMFA */
3193 struct attributes_store_header
3199 struct attributes_store_item
3216 /***********************************************************************
3217 * MFGetAttributesAsBlobSize (mfplat.@)
3219 HRESULT WINAPI
MFGetAttributesAsBlobSize(IMFAttributes
*attributes
, UINT32
*size
)
3221 unsigned int i
, count
, length
;
3225 TRACE("%p, %p.\n", attributes
, size
);
3227 IMFAttributes_LockStore(attributes
);
3229 hr
= IMFAttributes_GetCount(attributes
, &count
);
3231 *size
= sizeof(struct attributes_store_header
);
3233 for (i
= 0; i
< count
; ++i
)
3235 MF_ATTRIBUTE_TYPE type
;
3237 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &key
, NULL
);
3241 *size
+= sizeof(struct attributes_store_item
);
3243 IMFAttributes_GetItemType(attributes
, &key
, &type
);
3247 case MF_ATTRIBUTE_GUID
:
3248 *size
+= sizeof(GUID
);
3250 case MF_ATTRIBUTE_STRING
:
3251 IMFAttributes_GetStringLength(attributes
, &key
, &length
);
3252 *size
+= (length
+ 1) * sizeof(WCHAR
);
3254 case MF_ATTRIBUTE_BLOB
:
3255 IMFAttributes_GetBlobSize(attributes
, &key
, &length
);
3258 case MF_ATTRIBUTE_UINT32
:
3259 case MF_ATTRIBUTE_UINT64
:
3260 case MF_ATTRIBUTE_DOUBLE
:
3261 case MF_ATTRIBUTE_IUNKNOWN
:
3267 IMFAttributes_UnlockStore(attributes
);
3272 struct attr_serialize_context
3279 static void attributes_serialize_write(struct attr_serialize_context
*context
, const void *value
, unsigned int size
)
3281 memcpy(context
->ptr
, value
, size
);
3282 context
->ptr
+= size
;
3285 static BOOL
attributes_serialize_write_item(struct attr_serialize_context
*context
, struct attributes_store_item
*item
,
3290 case MF_ATTRIBUTE_UINT32
:
3291 case MF_ATTRIBUTE_UINT64
:
3292 case MF_ATTRIBUTE_DOUBLE
:
3293 attributes_serialize_write(context
, item
, sizeof(*item
));
3295 case MF_ATTRIBUTE_GUID
:
3296 case MF_ATTRIBUTE_STRING
:
3297 case MF_ATTRIBUTE_BLOB
:
3298 item
->u
.subheader
.offset
= context
->size
- item
->u
.subheader
.size
;
3299 attributes_serialize_write(context
, item
, sizeof(*item
));
3300 memcpy(context
->buffer
+ item
->u
.subheader
.offset
, value
, item
->u
.subheader
.size
);
3301 context
->size
-= item
->u
.subheader
.size
;
3310 /***********************************************************************
3311 * MFGetAttributesAsBlob (mfplat.@)
3313 HRESULT WINAPI
MFGetAttributesAsBlob(IMFAttributes
*attributes
, UINT8
*buffer
, UINT size
)
3315 struct attributes_store_header header
;
3316 struct attr_serialize_context context
;
3317 unsigned int required_size
, i
;
3322 TRACE("%p, %p, %u.\n", attributes
, buffer
, size
);
3324 if (FAILED(hr
= MFGetAttributesAsBlobSize(attributes
, &required_size
)))
3327 if (required_size
> size
)
3328 return MF_E_BUFFERTOOSMALL
;
3330 context
.buffer
= buffer
;
3331 context
.ptr
= buffer
;
3332 context
.size
= required_size
;
3334 IMFAttributes_LockStore(attributes
);
3336 header
.magic
= ATTRIBUTES_STORE_MAGIC
;
3337 header
.count
= 0; /* Will be updated later */
3338 IMFAttributes_GetCount(attributes
, &count
);
3340 attributes_serialize_write(&context
, &header
, sizeof(header
));
3342 for (i
= 0; i
< count
; ++i
)
3344 struct attributes_store_item item
;
3345 const void *data
= NULL
;
3347 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &item
.key
, &value
);
3351 item
.type
= value
.vt
;
3355 case MF_ATTRIBUTE_UINT32
:
3356 case MF_ATTRIBUTE_UINT64
:
3357 item
.u
.i64
= value
.u
.uhVal
.QuadPart
;
3359 case MF_ATTRIBUTE_DOUBLE
:
3360 item
.u
.f
= value
.u
.dblVal
;
3362 case MF_ATTRIBUTE_GUID
:
3363 item
.u
.subheader
.size
= sizeof(*value
.u
.puuid
);
3364 data
= value
.u
.puuid
;
3366 case MF_ATTRIBUTE_STRING
:
3367 item
.u
.subheader
.size
= (lstrlenW(value
.u
.pwszVal
) + 1) * sizeof(WCHAR
);
3368 data
= value
.u
.pwszVal
;
3370 case MF_ATTRIBUTE_BLOB
:
3371 item
.u
.subheader
.size
= value
.u
.caub
.cElems
;
3372 data
= value
.u
.caub
.pElems
;
3374 case MF_ATTRIBUTE_IUNKNOWN
:
3377 WARN("Unknown attribute type %#x.\n", value
.vt
);
3380 if (attributes_serialize_write_item(&context
, &item
, data
))
3383 PropVariantClear(&value
);
3386 memcpy(context
.buffer
, &header
, sizeof(header
));
3388 IMFAttributes_UnlockStore(attributes
);
3393 static HRESULT
attributes_deserialize_read(struct attr_serialize_context
*context
, void *value
, unsigned int size
)
3395 if (context
->size
< (context
->ptr
- context
->buffer
) + size
)
3396 return E_INVALIDARG
;
3398 memcpy(value
, context
->ptr
, size
);
3399 context
->ptr
+= size
;
3404 /***********************************************************************
3405 * MFInitAttributesFromBlob (mfplat.@)
3407 HRESULT WINAPI
MFInitAttributesFromBlob(IMFAttributes
*dest
, const UINT8
*buffer
, UINT size
)
3409 struct attr_serialize_context context
;
3410 struct attributes_store_header header
;
3411 struct attributes_store_item item
;
3412 IMFAttributes
*attributes
;
3416 TRACE("%p, %p, %u.\n", dest
, buffer
, size
);
3418 context
.buffer
= (UINT8
*)buffer
;
3419 context
.ptr
= (UINT8
*)buffer
;
3420 context
.size
= size
;
3422 /* Validate buffer structure. */
3423 if (FAILED(hr
= attributes_deserialize_read(&context
, &header
, sizeof(header
))))
3426 if (header
.magic
!= ATTRIBUTES_STORE_MAGIC
)
3427 return E_UNEXPECTED
;
3429 if (FAILED(hr
= MFCreateAttributes(&attributes
, header
.count
)))
3432 for (i
= 0; i
< header
.count
; ++i
)
3434 if (FAILED(hr
= attributes_deserialize_read(&context
, &item
, sizeof(item
))))
3441 case MF_ATTRIBUTE_UINT32
:
3442 hr
= IMFAttributes_SetUINT32(attributes
, &item
.key
, item
.u
.i32
);
3444 case MF_ATTRIBUTE_UINT64
:
3445 hr
= IMFAttributes_SetUINT64(attributes
, &item
.key
, item
.u
.i64
);
3447 case MF_ATTRIBUTE_DOUBLE
:
3448 hr
= IMFAttributes_SetDouble(attributes
, &item
.key
, item
.u
.f
);
3450 case MF_ATTRIBUTE_GUID
:
3451 if (item
.u
.subheader
.size
== sizeof(GUID
) &&
3452 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3454 hr
= IMFAttributes_SetGUID(attributes
, &item
.key
,
3455 (const GUID
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3458 case MF_ATTRIBUTE_STRING
:
3459 if (item
.u
.subheader
.size
>= sizeof(WCHAR
) &&
3460 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3462 hr
= IMFAttributes_SetString(attributes
, &item
.key
,
3463 (const WCHAR
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3466 case MF_ATTRIBUTE_BLOB
:
3467 if (item
.u
.subheader
.size
> 0 && item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3469 hr
= IMFAttributes_SetBlob(attributes
, &item
.key
, context
.buffer
+ item
.u
.subheader
.offset
,
3470 item
.u
.subheader
.size
);
3483 IMFAttributes_DeleteAllItems(dest
);
3484 hr
= IMFAttributes_CopyAllItems(attributes
, dest
);
3487 IMFAttributes_Release(attributes
);
3492 typedef struct bytestream
3494 struct attributes attributes
;
3495 IMFByteStream IMFByteStream_iface
;
3496 IMFGetService IMFGetService_iface
;
3497 IRtwqAsyncCallback read_callback
;
3498 IRtwqAsyncCallback write_callback
;
3503 struct list pending
;
3504 CRITICAL_SECTION cs
;
3507 static inline mfbytestream
*impl_from_IMFByteStream(IMFByteStream
*iface
)
3509 return CONTAINING_RECORD(iface
, mfbytestream
, IMFByteStream_iface
);
3512 static struct bytestream
*impl_bytestream_from_IMFGetService(IMFGetService
*iface
)
3514 return CONTAINING_RECORD(iface
, struct bytestream
, IMFGetService_iface
);
3517 static struct bytestream
*impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3519 return CONTAINING_RECORD(iface
, struct bytestream
, read_callback
);
3522 static struct bytestream
*impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3524 return CONTAINING_RECORD(iface
, struct bytestream
, write_callback
);
3527 enum async_stream_op_type
3529 ASYNC_STREAM_OP_READ
,
3530 ASYNC_STREAM_OP_WRITE
,
3533 struct async_stream_op
3535 IUnknown IUnknown_iface
;
3543 ULONG requested_length
;
3544 ULONG actual_length
;
3545 IMFAsyncResult
*caller
;
3547 enum async_stream_op_type type
;
3550 static struct async_stream_op
*impl_async_stream_op_from_IUnknown(IUnknown
*iface
)
3552 return CONTAINING_RECORD(iface
, struct async_stream_op
, IUnknown_iface
);
3555 static HRESULT WINAPI
async_stream_op_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
3557 if (IsEqualIID(riid
, &IID_IUnknown
))
3560 IUnknown_AddRef(iface
);
3564 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3566 return E_NOINTERFACE
;
3569 static ULONG WINAPI
async_stream_op_AddRef(IUnknown
*iface
)
3571 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3572 ULONG refcount
= InterlockedIncrement(&op
->refcount
);
3574 TRACE("%p, refcount %d.\n", iface
, refcount
);
3579 static ULONG WINAPI
async_stream_op_Release(IUnknown
*iface
)
3581 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3582 ULONG refcount
= InterlockedDecrement(&op
->refcount
);
3584 TRACE("%p, refcount %d.\n", iface
, refcount
);
3589 IMFAsyncResult_Release(op
->caller
);
3596 static const IUnknownVtbl async_stream_op_vtbl
=
3598 async_stream_op_QueryInterface
,
3599 async_stream_op_AddRef
,
3600 async_stream_op_Release
,
3603 static HRESULT
bytestream_create_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3604 const BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
, IUnknown
*state
)
3606 struct async_stream_op
*op
;
3607 IRtwqAsyncResult
*request
;
3610 op
= heap_alloc(sizeof(*op
));
3612 return E_OUTOFMEMORY
;
3614 op
->IUnknown_iface
.lpVtbl
= &async_stream_op_vtbl
;
3617 op
->position
= stream
->position
;
3618 op
->requested_length
= size
;
3620 if (FAILED(hr
= RtwqCreateAsyncResult((IUnknown
*)&stream
->IMFByteStream_iface
, (IRtwqAsyncCallback
*)callback
, state
,
3621 (IRtwqAsyncResult
**)&op
->caller
)))
3626 if (FAILED(hr
= RtwqCreateAsyncResult(&op
->IUnknown_iface
, type
== ASYNC_STREAM_OP_READ
? &stream
->read_callback
:
3627 &stream
->write_callback
, NULL
, &request
)))
3630 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, request
);
3631 IRtwqAsyncResult_Release(request
);
3634 IUnknown_Release(&op
->IUnknown_iface
);
3638 static HRESULT
bytestream_complete_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3639 IMFAsyncResult
*result
, ULONG
*actual_length
)
3641 struct async_stream_op
*op
= NULL
, *cur
;
3644 EnterCriticalSection(&stream
->cs
);
3645 LIST_FOR_EACH_ENTRY(cur
, &stream
->pending
, struct async_stream_op
, entry
)
3647 if (cur
->caller
== result
&& cur
->type
== type
)
3650 list_remove(&cur
->entry
);
3654 LeaveCriticalSection(&stream
->cs
);
3657 return E_INVALIDARG
;
3659 if (SUCCEEDED(hr
= IMFAsyncResult_GetStatus(result
)))
3660 *actual_length
= op
->actual_length
;
3662 IUnknown_Release(&op
->IUnknown_iface
);
3667 static HRESULT WINAPI
bytestream_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
3669 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
3670 IsEqualIID(riid
, &IID_IUnknown
))
3673 IRtwqAsyncCallback_AddRef(iface
);
3677 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3679 return E_NOINTERFACE
;
3682 static ULONG WINAPI
bytestream_read_callback_AddRef(IRtwqAsyncCallback
*iface
)
3684 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3685 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3688 static ULONG WINAPI
bytestream_read_callback_Release(IRtwqAsyncCallback
*iface
)
3690 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3691 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3694 static HRESULT WINAPI
bytestream_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
3699 static ULONG WINAPI
bytestream_write_callback_AddRef(IRtwqAsyncCallback
*iface
)
3701 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3702 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3705 static ULONG WINAPI
bytestream_write_callback_Release(IRtwqAsyncCallback
*iface
)
3707 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3708 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3711 static HRESULT WINAPI
bytestream_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
3713 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3715 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
3717 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
3718 IsEqualIID(riid
, &IID_IUnknown
))
3720 *out
= &stream
->IMFByteStream_iface
;
3722 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
3724 *out
= &stream
->attributes
.IMFAttributes_iface
;
3726 else if (stream
->IMFGetService_iface
.lpVtbl
&& IsEqualIID(riid
, &IID_IMFGetService
))
3728 *out
= &stream
->IMFGetService_iface
;
3732 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3734 return E_NOINTERFACE
;
3737 IUnknown_AddRef((IUnknown
*)*out
);
3741 static ULONG WINAPI
bytestream_AddRef(IMFByteStream
*iface
)
3743 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3744 ULONG refcount
= InterlockedIncrement(&stream
->attributes
.ref
);
3746 TRACE("%p, refcount %d.\n", iface
, refcount
);
3751 static ULONG WINAPI
bytestream_Release(IMFByteStream
*iface
)
3753 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3754 ULONG refcount
= InterlockedDecrement(&stream
->attributes
.ref
);
3755 struct async_stream_op
*cur
, *cur2
;
3757 TRACE("%p, refcount %d.\n", iface
, refcount
);
3761 clear_attributes_object(&stream
->attributes
);
3762 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &stream
->pending
, struct async_stream_op
, entry
)
3764 list_remove(&cur
->entry
);
3765 IUnknown_Release(&cur
->IUnknown_iface
);
3767 DeleteCriticalSection(&stream
->cs
);
3769 IStream_Release(stream
->stream
);
3771 CloseHandle(stream
->hfile
);
3778 static HRESULT WINAPI
bytestream_stream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3780 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3784 TRACE("%p, %p.\n", iface
, capabilities
);
3786 if (FAILED(hr
= IStream_Stat(stream
->stream
, &stat
, STATFLAG_NONAME
)))
3789 *capabilities
= MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_SEEKABLE
;
3790 if (stat
.grfMode
& (STGM_WRITE
| STGM_READWRITE
))
3791 *capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
3796 static HRESULT WINAPI
bytestream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3798 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3800 TRACE("%p, %p.\n", iface
, capabilities
);
3802 *capabilities
= stream
->capabilities
;
3807 static HRESULT WINAPI
mfbytestream_SetLength(IMFByteStream
*iface
, QWORD length
)
3809 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3811 FIXME("%p, %s\n", This
, wine_dbgstr_longlong(length
));
3816 static HRESULT WINAPI
bytestream_file_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
3818 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3820 TRACE("%p, %p.\n", iface
, position
);
3823 return E_INVALIDARG
;
3825 *position
= stream
->position
;
3830 static HRESULT WINAPI
bytestream_file_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3832 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3835 TRACE("%p, %p.\n", iface
, length
);
3838 return E_INVALIDARG
;
3840 if (GetFileSizeEx(stream
->hfile
, &li
))
3841 *length
= li
.QuadPart
;
3843 return HRESULT_FROM_WIN32(GetLastError());
3848 static HRESULT WINAPI
bytestream_file_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
3850 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3851 LARGE_INTEGER position
, length
;
3854 TRACE("%p, %p.\n", iface
, ret
);
3856 EnterCriticalSection(&stream
->cs
);
3858 position
.QuadPart
= 0;
3859 if (SetFilePointerEx(stream
->hfile
, position
, &length
, FILE_END
))
3860 *ret
= stream
->position
>= length
.QuadPart
;
3862 hr
= HRESULT_FROM_WIN32(GetLastError());
3864 LeaveCriticalSection(&stream
->cs
);
3869 static HRESULT WINAPI
bytestream_file_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
3871 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3872 LARGE_INTEGER position
;
3876 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
3878 EnterCriticalSection(&stream
->cs
);
3880 position
.QuadPart
= stream
->position
;
3881 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
3883 if ((ret
= ReadFile(stream
->hfile
, buffer
, size
, read_len
, NULL
)))
3884 stream
->position
+= *read_len
;
3888 hr
= HRESULT_FROM_WIN32(GetLastError());
3890 LeaveCriticalSection(&stream
->cs
);
3895 static HRESULT WINAPI
bytestream_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
,
3898 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3900 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3902 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_READ
, data
, size
, callback
, state
);
3905 static HRESULT WINAPI
bytestream_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
3907 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3909 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
3911 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_READ
, result
, byte_read
);
3914 static HRESULT WINAPI
mfbytestream_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
3916 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3918 FIXME("%p, %p, %u, %p\n", This
, data
, count
, written
);
3923 static HRESULT WINAPI
bytestream_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
3924 IMFAsyncCallback
*callback
, IUnknown
*state
)
3926 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3928 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
3930 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_WRITE
, data
, size
, callback
, state
);
3933 static HRESULT WINAPI
bytestream_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
3935 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3937 TRACE("%p, %p, %p.\n", iface
, result
, written
);
3939 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_WRITE
, result
, written
);
3942 static HRESULT WINAPI
mfbytestream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
3943 DWORD flags
, QWORD
*current
)
3945 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3947 FIXME("%p, %u, %s, 0x%08x, %p\n", This
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
3952 static HRESULT WINAPI
mfbytestream_Flush(IMFByteStream
*iface
)
3954 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3956 FIXME("%p\n", This
);
3961 static HRESULT WINAPI
mfbytestream_Close(IMFByteStream
*iface
)
3963 mfbytestream
*This
= impl_from_IMFByteStream(iface
);
3965 FIXME("%p\n", This
);
3970 static HRESULT WINAPI
bytestream_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
3972 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3974 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
3976 EnterCriticalSection(&stream
->cs
);
3977 stream
->position
= position
;
3978 LeaveCriticalSection(&stream
->cs
);
3983 static const IMFByteStreamVtbl bytestream_file_vtbl
=
3985 bytestream_QueryInterface
,
3988 bytestream_GetCapabilities
,
3989 bytestream_file_GetLength
,
3990 mfbytestream_SetLength
,
3991 bytestream_file_GetCurrentPosition
,
3992 bytestream_SetCurrentPosition
,
3993 bytestream_file_IsEndOfStream
,
3994 bytestream_file_Read
,
3995 bytestream_BeginRead
,
3998 bytestream_BeginWrite
,
3999 bytestream_EndWrite
,
4005 static HRESULT WINAPI
bytestream_stream_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4007 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4011 TRACE("%p, %p.\n", iface
, length
);
4013 if (FAILED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4016 *length
= statstg
.cbSize
.QuadPart
;
4021 static HRESULT WINAPI
bytestream_stream_SetLength(IMFByteStream
*iface
, QWORD length
)
4023 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4024 ULARGE_INTEGER size
;
4027 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4029 EnterCriticalSection(&stream
->cs
);
4031 size
.QuadPart
= length
;
4032 hr
= IStream_SetSize(stream
->stream
, size
);
4034 LeaveCriticalSection(&stream
->cs
);
4039 static HRESULT WINAPI
bytestream_stream_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4041 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4043 TRACE("%p, %p.\n", iface
, position
);
4045 *position
= stream
->position
;
4050 static HRESULT WINAPI
bytestream_stream_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4052 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4056 TRACE("%p, %p.\n", iface
, ret
);
4058 EnterCriticalSection(&stream
->cs
);
4060 if (SUCCEEDED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4061 *ret
= stream
->position
>= statstg
.cbSize
.QuadPart
;
4063 LeaveCriticalSection(&stream
->cs
);
4068 static HRESULT WINAPI
bytestream_stream_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4070 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4071 LARGE_INTEGER position
;
4074 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, read_len
);
4076 EnterCriticalSection(&stream
->cs
);
4078 position
.QuadPart
= stream
->position
;
4079 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4081 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, buffer
, size
, read_len
)))
4082 stream
->position
+= *read_len
;
4085 LeaveCriticalSection(&stream
->cs
);
4090 static HRESULT WINAPI
bytestream_stream_Write(IMFByteStream
*iface
, const BYTE
*buffer
, ULONG size
, ULONG
*written
)
4092 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4093 LARGE_INTEGER position
;
4096 TRACE("%p, %p, %u, %p.\n", iface
, buffer
, size
, written
);
4098 EnterCriticalSection(&stream
->cs
);
4100 position
.QuadPart
= stream
->position
;
4101 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4103 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, buffer
, size
, written
)))
4104 stream
->position
+= *written
;
4107 LeaveCriticalSection(&stream
->cs
);
4112 static HRESULT WINAPI
bytestream_stream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN origin
, LONGLONG offset
,
4113 DWORD flags
, QWORD
*current
)
4115 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4118 TRACE("%p, %u, %s, %#x, %p.\n", iface
, origin
, wine_dbgstr_longlong(offset
), flags
, current
);
4120 EnterCriticalSection(&stream
->cs
);
4125 stream
->position
= offset
;
4128 stream
->position
+= offset
;
4131 WARN("Unknown origin mode %d.\n", origin
);
4135 *current
= stream
->position
;
4137 LeaveCriticalSection(&stream
->cs
);
4142 static HRESULT WINAPI
bytestream_stream_Flush(IMFByteStream
*iface
)
4144 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4146 TRACE("%p.\n", iface
);
4148 return IStream_Commit(stream
->stream
, STGC_DEFAULT
);
4151 static HRESULT WINAPI
bytestream_stream_Close(IMFByteStream
*iface
)
4153 TRACE("%p.\n", iface
);
4158 static const IMFByteStreamVtbl bytestream_stream_vtbl
=
4160 bytestream_QueryInterface
,
4163 bytestream_stream_GetCapabilities
,
4164 bytestream_stream_GetLength
,
4165 bytestream_stream_SetLength
,
4166 bytestream_stream_GetCurrentPosition
,
4167 bytestream_SetCurrentPosition
,
4168 bytestream_stream_IsEndOfStream
,
4169 bytestream_stream_Read
,
4170 bytestream_BeginRead
,
4172 bytestream_stream_Write
,
4173 bytestream_BeginWrite
,
4174 bytestream_EndWrite
,
4175 bytestream_stream_Seek
,
4176 bytestream_stream_Flush
,
4177 bytestream_stream_Close
,
4180 static inline mfbytestream
*impl_from_IMFByteStream_IMFAttributes(IMFAttributes
*iface
)
4182 return CONTAINING_RECORD(iface
, mfbytestream
, attributes
.IMFAttributes_iface
);
4185 static HRESULT WINAPI
mfbytestream_attributes_QueryInterface(
4186 IMFAttributes
*iface
, REFIID riid
, void **out
)
4188 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4189 return IMFByteStream_QueryInterface(&This
->IMFByteStream_iface
, riid
, out
);
4192 static ULONG WINAPI
mfbytestream_attributes_AddRef(IMFAttributes
*iface
)
4194 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4195 return IMFByteStream_AddRef(&This
->IMFByteStream_iface
);
4198 static ULONG WINAPI
mfbytestream_attributes_Release(IMFAttributes
*iface
)
4200 mfbytestream
*This
= impl_from_IMFByteStream_IMFAttributes(iface
);
4201 return IMFByteStream_Release(&This
->IMFByteStream_iface
);
4204 static const IMFAttributesVtbl mfbytestream_attributes_vtbl
=
4206 mfbytestream_attributes_QueryInterface
,
4207 mfbytestream_attributes_AddRef
,
4208 mfbytestream_attributes_Release
,
4209 mfattributes_GetItem
,
4210 mfattributes_GetItemType
,
4211 mfattributes_CompareItem
,
4212 mfattributes_Compare
,
4213 mfattributes_GetUINT32
,
4214 mfattributes_GetUINT64
,
4215 mfattributes_GetDouble
,
4216 mfattributes_GetGUID
,
4217 mfattributes_GetStringLength
,
4218 mfattributes_GetString
,
4219 mfattributes_GetAllocatedString
,
4220 mfattributes_GetBlobSize
,
4221 mfattributes_GetBlob
,
4222 mfattributes_GetAllocatedBlob
,
4223 mfattributes_GetUnknown
,
4224 mfattributes_SetItem
,
4225 mfattributes_DeleteItem
,
4226 mfattributes_DeleteAllItems
,
4227 mfattributes_SetUINT32
,
4228 mfattributes_SetUINT64
,
4229 mfattributes_SetDouble
,
4230 mfattributes_SetGUID
,
4231 mfattributes_SetString
,
4232 mfattributes_SetBlob
,
4233 mfattributes_SetUnknown
,
4234 mfattributes_LockStore
,
4235 mfattributes_UnlockStore
,
4236 mfattributes_GetCount
,
4237 mfattributes_GetItemByIndex
,
4238 mfattributes_CopyAllItems
4241 static HRESULT WINAPI
bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4243 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4244 struct async_stream_op
*op
;
4245 LARGE_INTEGER position
;
4249 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4252 op
= impl_async_stream_op_from_IUnknown(object
);
4254 EnterCriticalSection(&stream
->cs
);
4256 position
.QuadPart
= op
->position
;
4257 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4259 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, op
->u
.dest
, op
->requested_length
, &op
->actual_length
)))
4260 stream
->position
+= op
->actual_length
;
4263 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4264 list_add_tail(&stream
->pending
, &op
->entry
);
4266 LeaveCriticalSection(&stream
->cs
);
4268 MFInvokeCallback(op
->caller
);
4273 static HRESULT WINAPI
bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4275 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4276 struct async_stream_op
*op
;
4277 LARGE_INTEGER position
;
4281 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4284 op
= impl_async_stream_op_from_IUnknown(object
);
4286 EnterCriticalSection(&stream
->cs
);
4288 position
.QuadPart
= op
->position
;
4289 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4291 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, op
->u
.src
, op
->requested_length
, &op
->actual_length
)))
4292 stream
->position
+= op
->actual_length
;
4295 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4296 list_add_tail(&stream
->pending
, &op
->entry
);
4298 LeaveCriticalSection(&stream
->cs
);
4300 MFInvokeCallback(op
->caller
);
4305 static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl
=
4307 bytestream_callback_QueryInterface
,
4308 bytestream_read_callback_AddRef
,
4309 bytestream_read_callback_Release
,
4310 bytestream_callback_GetParameters
,
4311 bytestream_stream_read_callback_Invoke
,
4314 static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl
=
4316 bytestream_callback_QueryInterface
,
4317 bytestream_write_callback_AddRef
,
4318 bytestream_write_callback_Release
,
4319 bytestream_callback_GetParameters
,
4320 bytestream_stream_write_callback_Invoke
,
4323 /***********************************************************************
4324 * MFCreateMFByteStreamOnStream (mfplat.@)
4326 HRESULT WINAPI
MFCreateMFByteStreamOnStream(IStream
*stream
, IMFByteStream
**bytestream
)
4328 struct bytestream
*object
;
4329 LARGE_INTEGER position
;
4333 TRACE("%p, %p.\n", stream
, bytestream
);
4335 object
= heap_alloc_zero(sizeof(*object
));
4337 return E_OUTOFMEMORY
;
4339 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
4345 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_stream_vtbl
;
4346 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &mfbytestream_attributes_vtbl
;
4347 object
->read_callback
.lpVtbl
= &bytestream_stream_read_callback_vtbl
;
4348 object
->write_callback
.lpVtbl
= &bytestream_stream_write_callback_vtbl
;
4349 InitializeCriticalSection(&object
->cs
);
4350 list_init(&object
->pending
);
4352 object
->stream
= stream
;
4353 IStream_AddRef(object
->stream
);
4354 position
.QuadPart
= 0;
4355 IStream_Seek(object
->stream
, position
, STREAM_SEEK_SET
, NULL
);
4357 if (SUCCEEDED(IStream_Stat(object
->stream
, &stat
, 0)))
4361 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
,
4363 CoTaskMemFree(stat
.pwcsName
);
4367 *bytestream
= &object
->IMFByteStream_iface
;
4372 static HRESULT WINAPI
bytestream_file_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4374 FIXME("%p, %p.\n", iface
, result
);
4379 static HRESULT WINAPI
bytestream_file_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4381 FIXME("%p, %p.\n", iface
, result
);
4386 static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl
=
4388 bytestream_callback_QueryInterface
,
4389 bytestream_read_callback_AddRef
,
4390 bytestream_read_callback_Release
,
4391 bytestream_callback_GetParameters
,
4392 bytestream_file_read_callback_Invoke
,
4395 static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl
=
4397 bytestream_callback_QueryInterface
,
4398 bytestream_write_callback_AddRef
,
4399 bytestream_write_callback_Release
,
4400 bytestream_callback_GetParameters
,
4401 bytestream_file_write_callback_Invoke
,
4404 static HRESULT WINAPI
bytestream_file_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
4406 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4407 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, obj
);
4410 static ULONG WINAPI
bytestream_file_getservice_AddRef(IMFGetService
*iface
)
4412 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4413 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4416 static ULONG WINAPI
bytestream_file_getservice_Release(IMFGetService
*iface
)
4418 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4419 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4422 static HRESULT WINAPI
bytestream_file_getservice_GetService(IMFGetService
*iface
, REFGUID service
,
4423 REFIID riid
, void **obj
)
4425 FIXME("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
4430 static const IMFGetServiceVtbl bytestream_file_getservice_vtbl
=
4432 bytestream_file_getservice_QueryInterface
,
4433 bytestream_file_getservice_AddRef
,
4434 bytestream_file_getservice_Release
,
4435 bytestream_file_getservice_GetService
,
4438 /***********************************************************************
4439 * MFCreateFile (mfplat.@)
4441 HRESULT WINAPI
MFCreateFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4442 LPCWSTR url
, IMFByteStream
**bytestream
)
4444 DWORD capabilities
= MFBYTESTREAM_IS_SEEKABLE
| MFBYTESTREAM_DOES_NOT_USE_NETWORK
;
4445 DWORD filecreation_disposition
= 0, fileaccessmode
= 0, fileattributes
= 0;
4446 DWORD filesharemode
= FILE_SHARE_READ
;
4447 struct bytestream
*object
;
4452 TRACE("%d, %d, %#x, %s, %p.\n", accessmode
, openmode
, flags
, debugstr_w(url
), bytestream
);
4456 case MF_ACCESSMODE_READ
:
4457 fileaccessmode
= GENERIC_READ
;
4458 capabilities
|= MFBYTESTREAM_IS_READABLE
;
4460 case MF_ACCESSMODE_WRITE
:
4461 fileaccessmode
= GENERIC_WRITE
;
4462 capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
4464 case MF_ACCESSMODE_READWRITE
:
4465 fileaccessmode
= GENERIC_READ
| GENERIC_WRITE
;
4466 capabilities
|= (MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_WRITABLE
);
4472 case MF_OPENMODE_FAIL_IF_NOT_EXIST
:
4473 filecreation_disposition
= OPEN_EXISTING
;
4475 case MF_OPENMODE_FAIL_IF_EXIST
:
4476 filecreation_disposition
= CREATE_NEW
;
4478 case MF_OPENMODE_RESET_IF_EXIST
:
4479 filecreation_disposition
= TRUNCATE_EXISTING
;
4481 case MF_OPENMODE_APPEND_IF_EXIST
:
4482 filecreation_disposition
= OPEN_ALWAYS
;
4483 fileaccessmode
|= FILE_APPEND_DATA
;
4485 case MF_OPENMODE_DELETE_IF_EXIST
:
4486 filecreation_disposition
= CREATE_ALWAYS
;
4490 if (flags
& MF_FILEFLAGS_NOBUFFERING
)
4491 fileattributes
|= FILE_FLAG_NO_BUFFERING
;
4493 /* Open HANDLE to file */
4494 file
= CreateFileW(url
, fileaccessmode
, filesharemode
, NULL
,
4495 filecreation_disposition
, fileattributes
, 0);
4497 if(file
== INVALID_HANDLE_VALUE
)
4498 return HRESULT_FROM_WIN32(GetLastError());
4500 object
= heap_alloc_zero(sizeof(*object
));
4504 return E_OUTOFMEMORY
;
4507 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 2)))
4513 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_file_vtbl
;
4514 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &mfbytestream_attributes_vtbl
;
4515 object
->IMFGetService_iface
.lpVtbl
= &bytestream_file_getservice_vtbl
;
4516 object
->read_callback
.lpVtbl
= &bytestream_file_read_callback_vtbl
;
4517 object
->write_callback
.lpVtbl
= &bytestream_file_write_callback_vtbl
;
4518 InitializeCriticalSection(&object
->cs
);
4519 list_init(&object
->pending
);
4520 object
->capabilities
= capabilities
;
4521 object
->hfile
= file
;
4523 if (GetFileTime(file
, NULL
, NULL
, &writetime
))
4525 IMFAttributes_SetBlob(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_LAST_MODIFIED_TIME
,
4526 (const UINT8
*)&writetime
, sizeof(writetime
));
4529 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
, url
);
4531 *bytestream
= &object
->IMFByteStream_iface
;
4536 struct bytestream_wrapper
4538 IMFByteStreamCacheControl IMFByteStreamCacheControl_iface
;
4539 IMFByteStreamBuffering IMFByteStreamBuffering_iface
;
4540 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
4541 IMFByteStreamTimeSeek IMFByteStreamTimeSeek_iface
;
4542 IMFSampleOutputStream IMFSampleOutputStream_iface
;
4543 IPropertyStore IPropertyStore_iface
;
4544 IMFByteStream IMFByteStream_iface
;
4545 IMFAttributes IMFAttributes_iface
;
4548 IMFByteStreamCacheControl
*cache_control
;
4549 IMFByteStreamBuffering
*stream_buffering
;
4550 IMFMediaEventGenerator
*event_generator
;
4551 IMFByteStreamTimeSeek
*time_seek
;
4552 IMFSampleOutputStream
*sample_output
;
4553 IPropertyStore
*propstore
;
4554 IMFByteStream
*stream
;
4555 IMFAttributes
*attributes
;
4559 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStream(IMFByteStream
*iface
)
4561 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStream_iface
);
4564 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamCacheControl(IMFByteStreamCacheControl
*iface
)
4566 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamCacheControl_iface
);
4569 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamBuffering(IMFByteStreamBuffering
*iface
)
4571 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamBuffering_iface
);
4574 static struct bytestream_wrapper
*impl_wrapper_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
4576 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFMediaEventGenerator_iface
);
4579 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamTimeSeek(IMFByteStreamTimeSeek
*iface
)
4581 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamTimeSeek_iface
);
4584 static struct bytestream_wrapper
*impl_wrapper_from_IMFSampleOutputStream(IMFSampleOutputStream
*iface
)
4586 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFSampleOutputStream_iface
);
4589 static struct bytestream_wrapper
*impl_wrapper_from_IPropertyStore(IPropertyStore
*iface
)
4591 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IPropertyStore_iface
);
4594 static struct bytestream_wrapper
*impl_wrapper_from_IMFAttributes(IMFAttributes
*iface
)
4596 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFAttributes_iface
);
4599 static HRESULT WINAPI
bytestream_wrapper_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
4601 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4603 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
4605 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
4606 IsEqualIID(riid
, &IID_IUnknown
))
4608 *out
= &wrapper
->IMFByteStream_iface
;
4610 else if (wrapper
->cache_control
&& IsEqualIID(riid
, &IID_IMFByteStreamCacheControl
))
4612 *out
= &wrapper
->IMFByteStreamCacheControl_iface
;
4614 else if (wrapper
->stream_buffering
&& IsEqualIID(riid
, &IID_IMFByteStreamBuffering
))
4616 *out
= &wrapper
->IMFByteStreamBuffering_iface
;
4618 else if (wrapper
->event_generator
&& IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
4620 *out
= &wrapper
->IMFMediaEventGenerator_iface
;
4622 else if (wrapper
->time_seek
&& IsEqualIID(riid
, &IID_IMFByteStreamTimeSeek
))
4624 *out
= &wrapper
->IMFByteStreamTimeSeek_iface
;
4626 else if (wrapper
->sample_output
&& IsEqualIID(riid
, &IID_IMFSampleOutputStream
))
4628 *out
= &wrapper
->IMFSampleOutputStream_iface
;
4630 else if (wrapper
->propstore
&& IsEqualIID(riid
, &IID_IPropertyStore
))
4632 *out
= &wrapper
->IPropertyStore_iface
;
4634 else if (wrapper
->attributes
&& IsEqualIID(riid
, &IID_IMFAttributes
))
4636 *out
= &wrapper
->IMFAttributes_iface
;
4640 WARN("Unsupported %s.\n", debugstr_guid(riid
));
4642 return E_NOINTERFACE
;
4645 IUnknown_AddRef((IUnknown
*)*out
);
4649 static ULONG WINAPI
bytestream_wrapper_AddRef(IMFByteStream
*iface
)
4651 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4652 ULONG refcount
= InterlockedIncrement(&wrapper
->refcount
);
4654 TRACE("%p, refcount %d.\n", iface
, refcount
);
4659 static ULONG WINAPI
bytestream_wrapper_Release(IMFByteStream
*iface
)
4661 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4662 ULONG refcount
= InterlockedDecrement(&wrapper
->refcount
);
4664 TRACE("%p, refcount %d.\n", iface
, refcount
);
4668 if (wrapper
->cache_control
)
4669 IMFByteStreamCacheControl_Release(wrapper
->cache_control
);
4670 if (wrapper
->stream_buffering
)
4671 IMFByteStreamBuffering_Release(wrapper
->stream_buffering
);
4672 if (wrapper
->event_generator
)
4673 IMFMediaEventGenerator_Release(wrapper
->event_generator
);
4674 if (wrapper
->time_seek
)
4675 IMFByteStreamTimeSeek_Release(wrapper
->time_seek
);
4676 if (wrapper
->sample_output
)
4677 IMFSampleOutputStream_Release(wrapper
->sample_output
);
4678 if (wrapper
->propstore
)
4679 IPropertyStore_Release(wrapper
->propstore
);
4680 if (wrapper
->attributes
)
4681 IMFAttributes_Release(wrapper
->attributes
);
4682 IMFByteStream_Release(wrapper
->stream
);
4689 static HRESULT WINAPI
bytestream_wrapper_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
4691 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4693 TRACE("%p, %p.\n", iface
, capabilities
);
4695 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4696 IMFByteStream_GetCapabilities(wrapper
->stream
, capabilities
);
4699 static HRESULT WINAPI
bytestream_wrapper_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4701 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4703 TRACE("%p, %p.\n", iface
, length
);
4705 if (wrapper
->is_closed
)
4706 return MF_E_INVALIDREQUEST
;
4708 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4709 IMFByteStream_GetLength(wrapper
->stream
, length
);
4712 static HRESULT WINAPI
bytestream_wrapper_SetLength(IMFByteStream
*iface
, QWORD length
)
4714 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4716 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4718 if (wrapper
->is_closed
)
4719 return MF_E_INVALIDREQUEST
;
4721 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4722 IMFByteStream_SetLength(wrapper
->stream
, length
);
4725 static HRESULT WINAPI
bytestream_wrapper_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4727 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4729 TRACE("%p, %p.\n", iface
, position
);
4731 if (wrapper
->is_closed
)
4732 return MF_E_INVALIDREQUEST
;
4734 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4735 IMFByteStream_GetCurrentPosition(wrapper
->stream
, position
);
4738 static HRESULT WINAPI
bytestream_wrapper_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4740 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4742 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4744 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4745 IMFByteStream_SetCurrentPosition(wrapper
->stream
, position
);
4748 static HRESULT WINAPI
bytestream_wrapper_IsEndOfStream(IMFByteStream
*iface
, BOOL
*eos
)
4750 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4752 TRACE("%p, %p.\n", iface
, eos
);
4754 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4755 IMFByteStream_IsEndOfStream(wrapper
->stream
, eos
);
4758 static HRESULT WINAPI
bytestream_wrapper_Read(IMFByteStream
*iface
, BYTE
*data
, ULONG count
, ULONG
*byte_read
)
4760 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4762 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, byte_read
);
4764 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4765 IMFByteStream_Read(wrapper
->stream
, data
, count
, byte_read
);
4768 static HRESULT WINAPI
bytestream_wrapper_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
,
4769 IMFAsyncCallback
*callback
, IUnknown
*state
)
4771 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4773 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4775 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4776 IMFByteStream_BeginRead(wrapper
->stream
, data
, size
, callback
, state
);
4779 static HRESULT WINAPI
bytestream_wrapper_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4781 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4783 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4785 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4786 IMFByteStream_EndRead(wrapper
->stream
, result
, byte_read
);
4789 static HRESULT WINAPI
bytestream_wrapper_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4791 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4793 TRACE("%p, %p, %u, %p.\n", iface
, data
, count
, written
);
4795 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4796 IMFByteStream_Write(wrapper
->stream
, data
, count
, written
);
4799 static HRESULT WINAPI
bytestream_wrapper_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4800 IMFAsyncCallback
*callback
, IUnknown
*state
)
4802 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4804 TRACE("%p, %p, %u, %p, %p.\n", iface
, data
, size
, callback
, state
);
4806 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4807 IMFByteStream_BeginWrite(wrapper
->stream
, data
, size
, callback
, state
);
4810 static HRESULT WINAPI
bytestream_wrapper_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4812 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4814 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4816 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4817 IMFByteStream_EndWrite(wrapper
->stream
, result
, written
);
4820 static HRESULT WINAPI
bytestream_wrapper_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
4821 DWORD flags
, QWORD
*current
)
4823 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4825 TRACE("%p, %u, %s, %#x, %p.\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
4827 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4828 IMFByteStream_Seek(wrapper
->stream
, seek
, offset
, flags
, current
);
4831 static HRESULT WINAPI
bytestream_wrapper_Flush(IMFByteStream
*iface
)
4833 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4835 TRACE("%p\n", iface
);
4837 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
: IMFByteStream_Flush(wrapper
->stream
);
4840 static HRESULT WINAPI
bytestream_wrapper_Close(IMFByteStream
*iface
)
4842 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4844 TRACE("%p\n", iface
);
4846 wrapper
->is_closed
= TRUE
;
4851 static const IMFByteStreamVtbl bytestream_wrapper_vtbl
=
4853 bytestream_wrapper_QueryInterface
,
4854 bytestream_wrapper_AddRef
,
4855 bytestream_wrapper_Release
,
4856 bytestream_wrapper_GetCapabilities
,
4857 bytestream_wrapper_GetLength
,
4858 bytestream_wrapper_SetLength
,
4859 bytestream_wrapper_GetCurrentPosition
,
4860 bytestream_wrapper_SetCurrentPosition
,
4861 bytestream_wrapper_IsEndOfStream
,
4862 bytestream_wrapper_Read
,
4863 bytestream_wrapper_BeginRead
,
4864 bytestream_wrapper_EndRead
,
4865 bytestream_wrapper_Write
,
4866 bytestream_wrapper_BeginWrite
,
4867 bytestream_wrapper_EndWrite
,
4868 bytestream_wrapper_Seek
,
4869 bytestream_wrapper_Flush
,
4870 bytestream_wrapper_Close
,
4873 static HRESULT WINAPI
bytestream_wrapper_cache_control_QueryInterface(IMFByteStreamCacheControl
*iface
,
4874 REFIID riid
, void **obj
)
4876 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4877 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4880 static ULONG WINAPI
bytestream_wrapper_cache_control_AddRef(IMFByteStreamCacheControl
*iface
)
4882 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4883 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4886 static ULONG WINAPI
bytestream_wrapper_cache_control_Release(IMFByteStreamCacheControl
*iface
)
4888 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4889 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4892 static HRESULT WINAPI
bytestream_wrapper_cache_control_StopBackgroundTransfer(IMFByteStreamCacheControl
*iface
)
4894 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
4896 TRACE("%p.\n", iface
);
4898 return IMFByteStreamCacheControl_StopBackgroundTransfer(wrapper
->cache_control
);
4901 static const IMFByteStreamCacheControlVtbl bytestream_wrapper_cache_control_vtbl
=
4903 bytestream_wrapper_cache_control_QueryInterface
,
4904 bytestream_wrapper_cache_control_AddRef
,
4905 bytestream_wrapper_cache_control_Release
,
4906 bytestream_wrapper_cache_control_StopBackgroundTransfer
,
4909 static HRESULT WINAPI
bytestream_wrapper_buffering_QueryInterface(IMFByteStreamBuffering
*iface
,
4910 REFIID riid
, void **obj
)
4912 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4913 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4916 static ULONG WINAPI
bytestream_wrapper_buffering_AddRef(IMFByteStreamBuffering
*iface
)
4918 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4919 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4922 static ULONG WINAPI
bytestream_wrapper_buffering_Release(IMFByteStreamBuffering
*iface
)
4924 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4925 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4928 static HRESULT WINAPI
bytestream_wrapper_buffering_SetBufferingParams(IMFByteStreamBuffering
*iface
,
4929 MFBYTESTREAM_BUFFERING_PARAMS
*params
)
4931 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4933 TRACE("%p, %p.\n", iface
, params
);
4935 return IMFByteStreamBuffering_SetBufferingParams(wrapper
->stream_buffering
, params
);
4938 static HRESULT WINAPI
bytestream_wrapper_buffering_EnableBuffering(IMFByteStreamBuffering
*iface
,
4941 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4943 TRACE("%p, %d.\n", iface
, enable
);
4945 return IMFByteStreamBuffering_EnableBuffering(wrapper
->stream_buffering
, enable
);
4948 static HRESULT WINAPI
bytestream_wrapper_buffering_StopBuffering(IMFByteStreamBuffering
*iface
)
4950 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
4952 TRACE("%p.\n", iface
);
4954 return IMFByteStreamBuffering_StopBuffering(wrapper
->stream_buffering
);
4957 static const IMFByteStreamBufferingVtbl bytestream_wrapper_buffering_vtbl
=
4959 bytestream_wrapper_buffering_QueryInterface
,
4960 bytestream_wrapper_buffering_AddRef
,
4961 bytestream_wrapper_buffering_Release
,
4962 bytestream_wrapper_buffering_SetBufferingParams
,
4963 bytestream_wrapper_buffering_EnableBuffering
,
4964 bytestream_wrapper_buffering_StopBuffering
,
4967 static HRESULT WINAPI
bytestream_wrapper_timeseek_QueryInterface(IMFByteStreamTimeSeek
*iface
,
4968 REFIID riid
, void **obj
)
4970 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4971 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
4974 static ULONG WINAPI
bytestream_wrapper_timeseek_AddRef(IMFByteStreamTimeSeek
*iface
)
4976 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4977 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
4980 static ULONG WINAPI
bytestream_wrapper_timeseek_Release(IMFByteStreamTimeSeek
*iface
)
4982 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4983 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
4986 static HRESULT WINAPI
bytestream_wrapper_timeseek_IsTimeSeekSupported(IMFByteStreamTimeSeek
*iface
, BOOL
*result
)
4988 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4990 TRACE("%p, %p.\n", iface
, result
);
4992 return IMFByteStreamTimeSeek_IsTimeSeekSupported(wrapper
->time_seek
, result
);
4995 static HRESULT WINAPI
bytestream_wrapper_timeseek_TimeSeek(IMFByteStreamTimeSeek
*iface
, QWORD position
)
4997 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
4999 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
5001 return IMFByteStreamTimeSeek_TimeSeek(wrapper
->time_seek
, position
);
5004 static HRESULT WINAPI
bytestream_wrapper_timeseek_GetTimeSeekResult(IMFByteStreamTimeSeek
*iface
, QWORD
*start_time
,
5005 QWORD
*stop_time
, QWORD
*duration
)
5007 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5009 TRACE("%p, %p, %p, %p.\n", iface
, start_time
, stop_time
, duration
);
5011 return IMFByteStreamTimeSeek_GetTimeSeekResult(wrapper
->time_seek
, start_time
, stop_time
, duration
);
5014 static const IMFByteStreamTimeSeekVtbl bytestream_wrapper_timeseek_vtbl
=
5016 bytestream_wrapper_timeseek_QueryInterface
,
5017 bytestream_wrapper_timeseek_AddRef
,
5018 bytestream_wrapper_timeseek_Release
,
5019 bytestream_wrapper_timeseek_IsTimeSeekSupported
,
5020 bytestream_wrapper_timeseek_TimeSeek
,
5021 bytestream_wrapper_timeseek_GetTimeSeekResult
,
5024 static HRESULT WINAPI
bytestream_wrapper_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
5026 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5027 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5030 static ULONG WINAPI
bytestream_wrapper_events_AddRef(IMFMediaEventGenerator
*iface
)
5032 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5033 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5036 static ULONG WINAPI
bytestream_wrapper_events_Release(IMFMediaEventGenerator
*iface
)
5038 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5039 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5042 static HRESULT WINAPI
bytestream_wrapper_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
5044 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5046 TRACE("%p, %#x, %p.\n", iface
, flags
, event
);
5048 return IMFMediaEventGenerator_GetEvent(wrapper
->event_generator
, flags
, event
);
5051 static HRESULT WINAPI
bytestream_wrapper_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
5053 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5055 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
5057 return IMFMediaEventGenerator_BeginGetEvent(wrapper
->event_generator
, callback
, state
);
5060 static HRESULT WINAPI
bytestream_wrapper_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
5062 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5064 TRACE("%p, %p, %p.\n", iface
, result
, event
);
5066 return IMFMediaEventGenerator_EndGetEvent(wrapper
->event_generator
, result
, event
);
5069 static HRESULT WINAPI
bytestream_wrapper_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType type
,
5070 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
5072 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5074 TRACE("%p, %d, %s, %#x, %s.\n", iface
, type
, debugstr_guid(ext_type
), hr
, debugstr_propvar(value
));
5076 return IMFMediaEventGenerator_QueueEvent(wrapper
->event_generator
, type
, ext_type
, hr
, value
);
5079 static const IMFMediaEventGeneratorVtbl bytestream_wrapper_events_vtbl
=
5081 bytestream_wrapper_events_QueryInterface
,
5082 bytestream_wrapper_events_AddRef
,
5083 bytestream_wrapper_events_Release
,
5084 bytestream_wrapper_events_GetEvent
,
5085 bytestream_wrapper_events_BeginGetEvent
,
5086 bytestream_wrapper_events_EndGetEvent
,
5087 bytestream_wrapper_events_QueueEvent
,
5090 static HRESULT WINAPI
bytestream_wrapper_sample_output_QueryInterface(IMFSampleOutputStream
*iface
, REFIID riid
, void **obj
)
5092 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5093 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5096 static ULONG WINAPI
bytestream_wrapper_sample_output_AddRef(IMFSampleOutputStream
*iface
)
5098 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5099 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5102 static ULONG WINAPI
bytestream_wrapper_sample_output_Release(IMFSampleOutputStream
*iface
)
5104 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5105 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5108 static HRESULT WINAPI
bytestream_wrapper_sample_output_BeginWriteSample(IMFSampleOutputStream
*iface
, IMFSample
*sample
,
5109 IMFAsyncCallback
*callback
, IUnknown
*state
)
5111 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5113 TRACE("%p, %p, %p, %p.\n", iface
, sample
, callback
, state
);
5115 return IMFSampleOutputStream_BeginWriteSample(wrapper
->sample_output
, sample
, callback
, state
);
5118 static HRESULT WINAPI
bytestream_wrapper_sample_output_EndWriteSample(IMFSampleOutputStream
*iface
, IMFAsyncResult
*result
)
5120 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5122 TRACE("%p, %p.\n", iface
, result
);
5124 return IMFSampleOutputStream_EndWriteSample(wrapper
->sample_output
, result
);
5127 static HRESULT WINAPI
bytestream_wrapper_sample_output_Close(IMFSampleOutputStream
*iface
)
5129 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5131 TRACE("%p.\n", iface
);
5133 return IMFSampleOutputStream_Close(wrapper
->sample_output
);
5136 static const IMFSampleOutputStreamVtbl bytestream_wrapper_sample_output_vtbl
=
5138 bytestream_wrapper_sample_output_QueryInterface
,
5139 bytestream_wrapper_sample_output_AddRef
,
5140 bytestream_wrapper_sample_output_Release
,
5141 bytestream_wrapper_sample_output_BeginWriteSample
,
5142 bytestream_wrapper_sample_output_EndWriteSample
,
5143 bytestream_wrapper_sample_output_Close
,
5146 static HRESULT WINAPI
bytestream_wrapper_propstore_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
5148 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5149 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5152 static ULONG WINAPI
bytestream_wrapper_propstore_AddRef(IPropertyStore
*iface
)
5154 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5155 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5158 static ULONG WINAPI
bytestream_wrapper_propstore_Release(IPropertyStore
*iface
)
5160 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5161 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5164 static HRESULT WINAPI
bytestream_wrapper_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
5166 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5168 TRACE("%p, %p.\n", iface
, count
);
5170 return IPropertyStore_GetCount(wrapper
->propstore
, count
);
5173 static HRESULT WINAPI
bytestream_wrapper_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
5175 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5177 TRACE("%p, %u, %p.\n", iface
, prop
, key
);
5179 return IPropertyStore_GetAt(wrapper
->propstore
, prop
, key
);
5182 static HRESULT WINAPI
bytestream_wrapper_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
5184 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5186 TRACE("%p, %p, %p.\n", iface
, key
, value
);
5188 return IPropertyStore_GetValue(wrapper
->propstore
, key
, value
);
5191 static HRESULT WINAPI
bytestream_wrapper_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
,
5192 const PROPVARIANT
*value
)
5194 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5196 TRACE("%p, %p, %s.\n", iface
, key
, debugstr_propvar(value
));
5198 return IPropertyStore_SetValue(wrapper
->propstore
, key
, value
);
5201 static HRESULT WINAPI
bytestream_wrapper_propstore_Commit(IPropertyStore
*iface
)
5203 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5205 TRACE("%p.\n", iface
);
5207 return IPropertyStore_Commit(wrapper
->propstore
);
5210 static const IPropertyStoreVtbl bytestream_wrapper_propstore_vtbl
=
5212 bytestream_wrapper_propstore_QueryInterface
,
5213 bytestream_wrapper_propstore_AddRef
,
5214 bytestream_wrapper_propstore_Release
,
5215 bytestream_wrapper_propstore_GetCount
,
5216 bytestream_wrapper_propstore_GetAt
,
5217 bytestream_wrapper_propstore_GetValue
,
5218 bytestream_wrapper_propstore_SetValue
,
5219 bytestream_wrapper_propstore_Commit
,
5222 static HRESULT WINAPI
bytestream_wrapper_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
5224 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5225 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5228 static ULONG WINAPI
bytestream_wrapper_attributes_AddRef(IMFAttributes
*iface
)
5230 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5231 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5234 static ULONG WINAPI
bytestream_wrapper_attributes_Release(IMFAttributes
*iface
)
5236 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5237 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5240 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
5242 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5244 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5246 return IMFAttributes_GetItem(wrapper
->attributes
, key
, value
);
5249 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
5251 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5253 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
5255 return IMFAttributes_GetItemType(wrapper
->attributes
, key
, type
);
5258 static HRESULT WINAPI
bytestream_wrapper_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
5259 REFPROPVARIANT value
, BOOL
*result
)
5261 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5263 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
5265 return IMFAttributes_CompareItem(wrapper
->attributes
, key
, value
, result
);
5268 static HRESULT WINAPI
bytestream_wrapper_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
5269 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
5271 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5273 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
5275 return IMFAttributes_Compare(wrapper
->attributes
, theirs
, match_type
, ret
);
5278 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
5280 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5282 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5284 return IMFAttributes_GetUINT32(wrapper
->attributes
, key
, value
);
5287 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
5289 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5291 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5293 return IMFAttributes_GetUINT64(wrapper
->attributes
, key
, value
);
5296 static HRESULT WINAPI
bytestream_wrapper_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
5298 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5300 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5302 return IMFAttributes_GetDouble(wrapper
->attributes
, key
, value
);
5305 static HRESULT WINAPI
bytestream_wrapper_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
5307 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5309 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5311 return IMFAttributes_GetGUID(wrapper
->attributes
, key
, value
);
5314 static HRESULT WINAPI
bytestream_wrapper_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
5316 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5318 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
5320 return IMFAttributes_GetStringLength(wrapper
->attributes
, key
, length
);
5323 static HRESULT WINAPI
bytestream_wrapper_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
5324 UINT32 size
, UINT32
*length
)
5326 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5328 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
5330 return IMFAttributes_GetString(wrapper
->attributes
, key
, value
, size
, length
);
5333 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
5335 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5337 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
5339 return IMFAttributes_GetAllocatedString(wrapper
->attributes
, key
, value
, length
);
5342 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
5344 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5346 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
5348 return IMFAttributes_GetBlobSize(wrapper
->attributes
, key
, size
);
5351 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
5352 UINT32 bufsize
, UINT32
*blobsize
)
5354 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5356 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
5358 return IMFAttributes_GetBlob(wrapper
->attributes
, key
, buf
, bufsize
, blobsize
);
5361 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
5363 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5365 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
5367 return IMFAttributes_GetAllocatedBlob(wrapper
->attributes
, key
, buf
, size
);
5370 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **obj
)
5372 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5374 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), obj
);
5376 return IMFAttributes_GetUnknown(wrapper
->attributes
, key
, riid
, obj
);
5379 static HRESULT WINAPI
bytestream_wrapper_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
5381 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5383 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
5385 return IMFAttributes_SetItem(wrapper
->attributes
, key
, value
);
5388 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
5390 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5392 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
5394 return IMFAttributes_DeleteItem(wrapper
->attributes
, key
);
5397 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteAllItems(IMFAttributes
*iface
)
5399 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5401 TRACE("%p.\n", iface
);
5403 return IMFAttributes_DeleteAllItems(wrapper
->attributes
);
5406 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
5408 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5410 TRACE("%p, %s, %d.\n", iface
, debugstr_attr(key
), value
);
5412 return IMFAttributes_SetUINT32(wrapper
->attributes
, key
, value
);
5415 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
5417 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5419 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
5421 return IMFAttributes_SetUINT64(wrapper
->attributes
, key
, value
);
5424 static HRESULT WINAPI
bytestream_wrapper_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
5426 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5428 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
5430 return IMFAttributes_SetDouble(wrapper
->attributes
, key
, value
);
5433 static HRESULT WINAPI
bytestream_wrapper_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
5435 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5437 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
5439 return IMFAttributes_SetGUID(wrapper
->attributes
, key
, value
);
5442 static HRESULT WINAPI
bytestream_wrapper_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
5444 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5446 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
5448 return IMFAttributes_SetString(wrapper
->attributes
, key
, value
);
5451 static HRESULT WINAPI
bytestream_wrapper_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
5453 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5455 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
5457 return IMFAttributes_SetBlob(wrapper
->attributes
, key
, buf
, size
);
5460 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
5462 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5464 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
5466 return IMFAttributes_SetUnknown(wrapper
->attributes
, key
, unknown
);
5469 static HRESULT WINAPI
bytestream_wrapper_attributes_LockStore(IMFAttributes
*iface
)
5471 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5473 TRACE("%p.\n", iface
);
5475 return IMFAttributes_LockStore(wrapper
->attributes
);
5478 static HRESULT WINAPI
bytestream_wrapper_attributes_UnlockStore(IMFAttributes
*iface
)
5480 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5482 TRACE("%p.\n", iface
);
5484 return IMFAttributes_UnlockStore(wrapper
->attributes
);
5487 static HRESULT WINAPI
bytestream_wrapper_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
5489 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5491 TRACE("%p, %p.\n", iface
, count
);
5493 return IMFAttributes_GetCount(wrapper
->attributes
, count
);
5496 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
5498 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5500 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
5502 return IMFAttributes_GetItemByIndex(wrapper
->attributes
, index
, key
, value
);
5505 static HRESULT WINAPI
bytestream_wrapper_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
5507 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5509 TRACE("%p, %p.\n", iface
, dest
);
5511 return IMFAttributes_CopyAllItems(wrapper
->attributes
, dest
);
5514 static const IMFAttributesVtbl bytestream_wrapper_attributes_vtbl
=
5516 bytestream_wrapper_attributes_QueryInterface
,
5517 bytestream_wrapper_attributes_AddRef
,
5518 bytestream_wrapper_attributes_Release
,
5519 bytestream_wrapper_attributes_GetItem
,
5520 bytestream_wrapper_attributes_GetItemType
,
5521 bytestream_wrapper_attributes_CompareItem
,
5522 bytestream_wrapper_attributes_Compare
,
5523 bytestream_wrapper_attributes_GetUINT32
,
5524 bytestream_wrapper_attributes_GetUINT64
,
5525 bytestream_wrapper_attributes_GetDouble
,
5526 bytestream_wrapper_attributes_GetGUID
,
5527 bytestream_wrapper_attributes_GetStringLength
,
5528 bytestream_wrapper_attributes_GetString
,
5529 bytestream_wrapper_attributes_GetAllocatedString
,
5530 bytestream_wrapper_attributes_GetBlobSize
,
5531 bytestream_wrapper_attributes_GetBlob
,
5532 bytestream_wrapper_attributes_GetAllocatedBlob
,
5533 bytestream_wrapper_attributes_GetUnknown
,
5534 bytestream_wrapper_attributes_SetItem
,
5535 bytestream_wrapper_attributes_DeleteItem
,
5536 bytestream_wrapper_attributes_DeleteAllItems
,
5537 bytestream_wrapper_attributes_SetUINT32
,
5538 bytestream_wrapper_attributes_SetUINT64
,
5539 bytestream_wrapper_attributes_SetDouble
,
5540 bytestream_wrapper_attributes_SetGUID
,
5541 bytestream_wrapper_attributes_SetString
,
5542 bytestream_wrapper_attributes_SetBlob
,
5543 bytestream_wrapper_attributes_SetUnknown
,
5544 bytestream_wrapper_attributes_LockStore
,
5545 bytestream_wrapper_attributes_UnlockStore
,
5546 bytestream_wrapper_attributes_GetCount
,
5547 bytestream_wrapper_attributes_GetItemByIndex
,
5548 bytestream_wrapper_attributes_CopyAllItems
5551 /***********************************************************************
5552 * MFCreateMFByteStreamWrapper (mfplat.@)
5554 HRESULT WINAPI
MFCreateMFByteStreamWrapper(IMFByteStream
*stream
, IMFByteStream
**wrapper
)
5556 struct bytestream_wrapper
*object
;
5558 TRACE("%p, %p.\n", stream
, wrapper
);
5560 object
= heap_alloc_zero(sizeof(*object
));
5562 return E_OUTOFMEMORY
;
5564 object
->IMFByteStreamCacheControl_iface
.lpVtbl
= &bytestream_wrapper_cache_control_vtbl
;
5565 object
->IMFByteStreamBuffering_iface
.lpVtbl
= &bytestream_wrapper_buffering_vtbl
;
5566 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &bytestream_wrapper_events_vtbl
;
5567 object
->IMFByteStreamTimeSeek_iface
.lpVtbl
= &bytestream_wrapper_timeseek_vtbl
;
5568 object
->IMFSampleOutputStream_iface
.lpVtbl
= &bytestream_wrapper_sample_output_vtbl
;
5569 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_wrapper_vtbl
;
5570 object
->IPropertyStore_iface
.lpVtbl
= &bytestream_wrapper_propstore_vtbl
;
5571 object
->IMFAttributes_iface
.lpVtbl
= &bytestream_wrapper_attributes_vtbl
;
5573 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamCacheControl
, (void **)&object
->cache_control
);
5574 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamBuffering
, (void **)&object
->stream_buffering
);
5575 IMFByteStream_QueryInterface(stream
, &IID_IMFMediaEventGenerator
, (void **)&object
->event_generator
);
5576 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamTimeSeek
, (void **)&object
->time_seek
);
5577 IMFByteStream_QueryInterface(stream
, &IID_IMFSampleOutputStream
, (void **)&object
->sample_output
);
5578 IMFByteStream_QueryInterface(stream
, &IID_IPropertyStore
, (void **)&object
->propstore
);
5579 IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&object
->attributes
);
5581 object
->stream
= stream
;
5582 IMFByteStream_AddRef(object
->stream
);
5584 object
->refcount
= 1;
5586 *wrapper
= &object
->IMFByteStream_iface
;
5591 static HRESULT WINAPI
MFPluginControl_QueryInterface(IMFPluginControl
*iface
, REFIID riid
, void **ppv
)
5593 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
5594 TRACE("(IID_IUnknown %p)\n", ppv
);
5596 }else if(IsEqualGUID(riid
, &IID_IMFPluginControl
)) {
5597 TRACE("(IID_IMFPluginControl %p)\n", ppv
);
5600 FIXME("(%s %p)\n", debugstr_guid(riid
), ppv
);
5602 return E_NOINTERFACE
;
5605 IUnknown_AddRef((IUnknown
*)*ppv
);
5609 static ULONG WINAPI
MFPluginControl_AddRef(IMFPluginControl
*iface
)
5615 static ULONG WINAPI
MFPluginControl_Release(IMFPluginControl
*iface
)
5621 static HRESULT WINAPI
MFPluginControl_GetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5622 const WCHAR
*selector
, CLSID
*clsid
)
5624 FIXME("(%d %s %p)\n", plugin_type
, debugstr_w(selector
), clsid
);
5628 static HRESULT WINAPI
MFPluginControl_GetPreferredClsidByIndex(IMFPluginControl
*iface
, DWORD plugin_type
,
5629 DWORD index
, WCHAR
**selector
, CLSID
*clsid
)
5631 FIXME("(%d %d %p %p)\n", plugin_type
, index
, selector
, clsid
);
5635 static HRESULT WINAPI
MFPluginControl_SetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5636 const WCHAR
*selector
, const CLSID
*clsid
)
5638 FIXME("(%d %s %s)\n", plugin_type
, debugstr_w(selector
), debugstr_guid(clsid
));
5642 static HRESULT WINAPI
MFPluginControl_IsDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
)
5644 FIXME("(%d %s)\n", plugin_type
, debugstr_guid(clsid
));
5648 static HRESULT WINAPI
MFPluginControl_GetDisabledByIndex(IMFPluginControl
*iface
, DWORD plugin_type
, DWORD index
, CLSID
*clsid
)
5650 FIXME("(%d %d %p)\n", plugin_type
, index
, clsid
);
5654 static HRESULT WINAPI
MFPluginControl_SetDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
, BOOL disabled
)
5656 FIXME("(%d %s %x)\n", plugin_type
, debugstr_guid(clsid
), disabled
);
5660 static const IMFPluginControlVtbl MFPluginControlVtbl
= {
5661 MFPluginControl_QueryInterface
,
5662 MFPluginControl_AddRef
,
5663 MFPluginControl_Release
,
5664 MFPluginControl_GetPreferredClsid
,
5665 MFPluginControl_GetPreferredClsidByIndex
,
5666 MFPluginControl_SetPreferredClsid
,
5667 MFPluginControl_IsDisabled
,
5668 MFPluginControl_GetDisabledByIndex
,
5669 MFPluginControl_SetDisabled
5672 static IMFPluginControl plugin_control
= { &MFPluginControlVtbl
};
5674 /***********************************************************************
5675 * MFGetPluginControl (mfplat.@)
5677 HRESULT WINAPI
MFGetPluginControl(IMFPluginControl
**ret
)
5679 TRACE("(%p)\n", ret
);
5681 *ret
= &plugin_control
;
5685 enum resolved_object_origin
5687 OBJECT_FROM_BYTESTREAM
,
5691 struct resolver_queued_result
5695 MF_OBJECT_TYPE obj_type
;
5697 IRtwqAsyncResult
*inner_result
;
5698 enum resolved_object_origin origin
;
5701 struct resolver_cancel_object
5703 IUnknown IUnknown_iface
;
5708 IMFByteStreamHandler
*stream_handler
;
5709 IMFSchemeHandler
*scheme_handler
;
5711 IUnknown
*cancel_cookie
;
5712 enum resolved_object_origin origin
;
5715 struct source_resolver
5717 IMFSourceResolver IMFSourceResolver_iface
;
5719 IRtwqAsyncCallback stream_callback
;
5720 IRtwqAsyncCallback url_callback
;
5721 CRITICAL_SECTION cs
;
5722 struct list pending
;
5725 static struct source_resolver
*impl_from_IMFSourceResolver(IMFSourceResolver
*iface
)
5727 return CONTAINING_RECORD(iface
, struct source_resolver
, IMFSourceResolver_iface
);
5730 static struct source_resolver
*impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5732 return CONTAINING_RECORD(iface
, struct source_resolver
, stream_callback
);
5735 static struct source_resolver
*impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5737 return CONTAINING_RECORD(iface
, struct source_resolver
, url_callback
);
5740 static HRESULT
resolver_handler_end_create(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
5741 IRtwqAsyncResult
*result
)
5743 IRtwqAsyncResult
*inner_result
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
5744 RTWQASYNCRESULT
*data
= (RTWQASYNCRESULT
*)inner_result
;
5745 struct resolver_queued_result
*queued_result
;
5749 IMFByteStreamHandler
*stream_handler
;
5750 IMFSchemeHandler
*scheme_handler
;
5753 if (!(queued_result
= heap_alloc_zero(sizeof(*queued_result
))))
5754 return E_OUTOFMEMORY
;
5756 queued_result
->origin
= origin
;
5758 IRtwqAsyncResult_GetObject(inner_result
, &handler
.handler
);
5762 case OBJECT_FROM_BYTESTREAM
:
5763 queued_result
->hr
= IMFByteStreamHandler_EndCreateObject(handler
.stream_handler
, (IMFAsyncResult
*)result
,
5764 &queued_result
->obj_type
, &queued_result
->object
);
5766 case OBJECT_FROM_URL
:
5767 queued_result
->hr
= IMFSchemeHandler_EndCreateObject(handler
.scheme_handler
, (IMFAsyncResult
*)result
,
5768 &queued_result
->obj_type
, &queued_result
->object
);
5771 queued_result
->hr
= E_FAIL
;
5774 IUnknown_Release(handler
.handler
);
5778 queued_result
->inner_result
= inner_result
;
5779 IRtwqAsyncResult_AddRef(queued_result
->inner_result
);
5782 /* Push resolved object type and created object, so we don't have to guess on End*() call. */
5783 EnterCriticalSection(&resolver
->cs
);
5784 list_add_tail(&resolver
->pending
, &queued_result
->entry
);
5785 LeaveCriticalSection(&resolver
->cs
);
5788 SetEvent(data
->hEvent
);
5791 IUnknown
*caller_state
= IRtwqAsyncResult_GetStateNoAddRef(inner_result
);
5792 IRtwqAsyncResult
*caller_result
;
5794 if (SUCCEEDED(RtwqCreateAsyncResult(queued_result
->object
, data
->pCallback
, caller_state
, &caller_result
)))
5796 RtwqInvokeCallback(caller_result
);
5797 IRtwqAsyncResult_Release(caller_result
);
5804 static struct resolver_cancel_object
*impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5806 return CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
);
5809 static HRESULT WINAPI
resolver_cancel_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
5811 if (IsEqualIID(riid
, &IID_IUnknown
))
5814 IUnknown_AddRef(iface
);
5819 return E_NOINTERFACE
;
5822 static ULONG WINAPI
resolver_cancel_object_AddRef(IUnknown
*iface
)
5824 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5825 return InterlockedIncrement(&object
->refcount
);
5828 static ULONG WINAPI
resolver_cancel_object_Release(IUnknown
*iface
)
5830 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5831 ULONG refcount
= InterlockedDecrement(&object
->refcount
);
5835 if (object
->cancel_cookie
)
5836 IUnknown_Release(object
->cancel_cookie
);
5837 IUnknown_Release(object
->u
.handler
);
5844 static const IUnknownVtbl resolver_cancel_object_vtbl
=
5846 resolver_cancel_object_QueryInterface
,
5847 resolver_cancel_object_AddRef
,
5848 resolver_cancel_object_Release
,
5851 static struct resolver_cancel_object
*unsafe_impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5856 return (iface
->lpVtbl
== &resolver_cancel_object_vtbl
) ?
5857 CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
) : NULL
;
5860 static HRESULT
resolver_create_cancel_object(IUnknown
*handler
, enum resolved_object_origin origin
,
5861 IUnknown
*cancel_cookie
, IUnknown
**cancel_object
)
5863 struct resolver_cancel_object
*object
;
5865 object
= heap_alloc_zero(sizeof(*object
));
5867 return E_OUTOFMEMORY
;
5869 object
->IUnknown_iface
.lpVtbl
= &resolver_cancel_object_vtbl
;
5870 object
->refcount
= 1;
5871 object
->u
.handler
= handler
;
5872 IUnknown_AddRef(object
->u
.handler
);
5873 object
->cancel_cookie
= cancel_cookie
;
5874 IUnknown_AddRef(object
->cancel_cookie
);
5875 object
->origin
= origin
;
5877 *cancel_object
= &object
->IUnknown_iface
;
5882 static HRESULT WINAPI
source_resolver_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
5884 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
5885 IsEqualIID(riid
, &IID_IUnknown
))
5888 IRtwqAsyncCallback_AddRef(iface
);
5893 return E_NOINTERFACE
;
5896 static ULONG WINAPI
source_resolver_callback_stream_AddRef(IRtwqAsyncCallback
*iface
)
5898 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5899 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5902 static ULONG WINAPI
source_resolver_callback_stream_Release(IRtwqAsyncCallback
*iface
)
5904 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5905 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5908 static HRESULT WINAPI
source_resolver_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
5913 static HRESULT WINAPI
source_resolver_callback_stream_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5915 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
5917 return resolver_handler_end_create(resolver
, OBJECT_FROM_BYTESTREAM
, result
);
5920 static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl
=
5922 source_resolver_callback_QueryInterface
,
5923 source_resolver_callback_stream_AddRef
,
5924 source_resolver_callback_stream_Release
,
5925 source_resolver_callback_GetParameters
,
5926 source_resolver_callback_stream_Invoke
,
5929 static ULONG WINAPI
source_resolver_callback_url_AddRef(IRtwqAsyncCallback
*iface
)
5931 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5932 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
5935 static ULONG WINAPI
source_resolver_callback_url_Release(IRtwqAsyncCallback
*iface
)
5937 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5938 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
5941 static HRESULT WINAPI
source_resolver_callback_url_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
5943 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
5945 return resolver_handler_end_create(resolver
, OBJECT_FROM_URL
, result
);
5948 static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl
=
5950 source_resolver_callback_QueryInterface
,
5951 source_resolver_callback_url_AddRef
,
5952 source_resolver_callback_url_Release
,
5953 source_resolver_callback_GetParameters
,
5954 source_resolver_callback_url_Invoke
,
5957 static HRESULT
resolver_create_registered_handler(HKEY hkey
, REFIID riid
, void **handler
)
5959 unsigned int j
= 0, name_length
, type
;
5960 HRESULT hr
= E_FAIL
;
5964 name_length
= ARRAY_SIZE(clsidW
);
5965 while (!RegEnumValueW(hkey
, j
++, clsidW
, &name_length
, NULL
, &type
, NULL
, NULL
))
5969 if (SUCCEEDED(CLSIDFromString(clsidW
, &clsid
)))
5971 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, handler
);
5977 name_length
= ARRAY_SIZE(clsidW
);
5983 static HRESULT
resolver_get_bytestream_handler(IMFByteStream
*stream
, const WCHAR
*url
, DWORD flags
,
5984 IMFByteStreamHandler
**handler
)
5986 static const char streamhandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers";
5987 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
5988 IMFAttributes
*attributes
;
5989 const WCHAR
*url_ext
;
5990 WCHAR
*mimeW
= NULL
;
5991 HRESULT hr
= E_FAIL
;
5998 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
6000 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &mimeW
, &length
);
6001 IMFAttributes_Release(attributes
);
6005 url_ext
= url
? wcsrchr(url
, '.') : NULL
;
6007 if (!url_ext
&& !mimeW
)
6009 CoTaskMemFree(mimeW
);
6010 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6013 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6015 struct local_handler
*local_handler
;
6017 EnterCriticalSection(&local_handlers_section
);
6019 LIST_FOR_EACH_ENTRY(local_handler
, &local_bytestream_handlers
, struct local_handler
, entry
)
6021 if ((mimeW
&& !lstrcmpiW(mimeW
, local_handler
->u
.bytestream
.mime
))
6022 || (url_ext
&& !lstrcmpiW(url_ext
, local_handler
->u
.bytestream
.extension
)))
6024 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFByteStreamHandler
,
6030 LeaveCriticalSection(&local_handlers_section
);
6036 for (i
= 0, hr
= E_FAIL
; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6038 const WCHAR
*namesW
[2] = { mimeW
, url_ext
};
6039 HKEY hkey
, hkey_handler
;
6041 if (RegOpenKeyA(hkey_roots
[i
], streamhandlerspath
, &hkey
))
6044 for (j
= 0; j
< ARRAY_SIZE(namesW
); ++j
)
6049 if (!RegOpenKeyW(hkey
, namesW
[j
], &hkey_handler
))
6051 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFByteStreamHandler
, (void **)handler
);
6052 RegCloseKey(hkey_handler
);
6067 static const GUID CLSID_GStreamerByteStreamHandler
= {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
6068 hr
= CoCreateInstance(&CLSID_GStreamerByteStreamHandler
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFByteStreamHandler
, (void **)handler
);
6071 CoTaskMemFree(mimeW
);
6075 static HRESULT
resolver_create_scheme_handler(const WCHAR
*scheme
, DWORD flags
, IMFSchemeHandler
**handler
)
6077 static const char schemehandlerspath
[] = "Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers";
6078 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6079 HRESULT hr
= MF_E_UNSUPPORTED_SCHEME
;
6082 TRACE("%s, %#x, %p.\n", debugstr_w(scheme
), flags
, handler
);
6086 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6088 struct local_handler
*local_handler
;
6090 EnterCriticalSection(&local_handlers_section
);
6092 LIST_FOR_EACH_ENTRY(local_handler
, &local_scheme_handlers
, struct local_handler
, entry
)
6094 if (!lstrcmpiW(scheme
, local_handler
->u
.scheme
))
6096 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFSchemeHandler
,
6102 LeaveCriticalSection(&local_handlers_section
);
6108 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6110 HKEY hkey
, hkey_handler
;
6112 hr
= MF_E_UNSUPPORTED_SCHEME
;
6114 if (RegOpenKeyA(hkey_roots
[i
], schemehandlerspath
, &hkey
))
6117 if (!RegOpenKeyW(hkey
, scheme
, &hkey_handler
))
6119 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFSchemeHandler
, (void **)handler
);
6120 RegCloseKey(hkey_handler
);
6132 static HRESULT
resolver_get_scheme_handler(const WCHAR
*url
, DWORD flags
, IMFSchemeHandler
**handler
)
6134 static const WCHAR fileschemeW
[] = L
"file:";
6135 const WCHAR
*ptr
= url
;
6140 /* RFC 3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
6143 WCHAR ch
= towlower(*ptr
);
6145 if (*ptr
== '*' && ptr
== url
)
6150 else if (!(*ptr
>= '0' && *ptr
<= '9') &&
6151 !(ch
>= 'a' && ch
<= 'z') &&
6152 *ptr
!= '+' && *ptr
!= '-' && *ptr
!= '.')
6160 /* Schemes must end with a ':', if not found try "file:" */
6161 if (ptr
== url
|| *ptr
!= ':')
6164 ptr
= fileschemeW
+ ARRAY_SIZE(fileschemeW
) - 1;
6168 scheme
= heap_alloc((len
+ 1) * sizeof(WCHAR
));
6170 return E_OUTOFMEMORY
;
6172 memcpy(scheme
, url
, len
* sizeof(WCHAR
));
6175 hr
= resolver_create_scheme_handler(scheme
, flags
, handler
);
6176 if (FAILED(hr
) && url
!= fileschemeW
)
6177 hr
= resolver_create_scheme_handler(fileschemeW
, flags
, handler
);
6184 static HRESULT
resolver_end_create_object(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
6185 IRtwqAsyncResult
*result
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**out
)
6187 struct resolver_queued_result
*queued_result
= NULL
, *iter
;
6191 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
6194 EnterCriticalSection(&resolver
->cs
);
6196 LIST_FOR_EACH_ENTRY(iter
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6198 if (iter
->inner_result
== result
|| (iter
->object
== object
&& iter
->origin
== origin
))
6200 list_remove(&iter
->entry
);
6201 queued_result
= iter
;
6206 LeaveCriticalSection(&resolver
->cs
);
6208 IUnknown_Release(object
);
6212 *out
= queued_result
->object
;
6213 *obj_type
= queued_result
->obj_type
;
6214 hr
= queued_result
->hr
;
6215 if (queued_result
->inner_result
)
6216 IRtwqAsyncResult_Release(queued_result
->inner_result
);
6217 heap_free(queued_result
);
6225 static HRESULT WINAPI
source_resolver_QueryInterface(IMFSourceResolver
*iface
, REFIID riid
, void **obj
)
6227 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6229 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
6231 if (IsEqualIID(riid
, &IID_IMFSourceResolver
) ||
6232 IsEqualIID(riid
, &IID_IUnknown
))
6234 *obj
= &resolver
->IMFSourceResolver_iface
;
6239 FIXME("unsupported interface %s\n", debugstr_guid(riid
));
6240 return E_NOINTERFACE
;
6243 IUnknown_AddRef((IUnknown
*)*obj
);
6247 static ULONG WINAPI
source_resolver_AddRef(IMFSourceResolver
*iface
)
6249 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6250 ULONG refcount
= InterlockedIncrement(&resolver
->refcount
);
6252 TRACE("%p, refcount %d.\n", iface
, refcount
);
6257 static ULONG WINAPI
source_resolver_Release(IMFSourceResolver
*iface
)
6259 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6260 ULONG refcount
= InterlockedDecrement(&resolver
->refcount
);
6261 struct resolver_queued_result
*result
, *result2
;
6263 TRACE("%p, refcount %d.\n", iface
, refcount
);
6267 LIST_FOR_EACH_ENTRY_SAFE(result
, result2
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6270 IUnknown_Release(result
->object
);
6271 list_remove(&result
->entry
);
6274 DeleteCriticalSection(&resolver
->cs
);
6275 heap_free(resolver
);
6281 static HRESULT WINAPI
source_resolver_CreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6282 DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6284 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6285 IMFSchemeHandler
*handler
;
6286 IRtwqAsyncResult
*result
;
6287 RTWQASYNCRESULT
*data
;
6290 TRACE("%p, %s, %#x, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6292 if (!url
|| !obj_type
|| !object
)
6295 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6298 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6299 IMFSchemeHandler_Release(handler
);
6303 data
= (RTWQASYNCRESULT
*)result
;
6304 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6306 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, NULL
, (IMFAsyncCallback
*)&resolver
->url_callback
,
6307 (IUnknown
*)result
);
6310 IRtwqAsyncResult_Release(result
);
6314 WaitForSingleObject(data
->hEvent
, INFINITE
);
6316 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_URL
, result
, obj_type
, object
);
6317 IRtwqAsyncResult_Release(result
);
6322 static HRESULT WINAPI
source_resolver_CreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6323 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6325 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6326 IMFByteStreamHandler
*handler
;
6327 IRtwqAsyncResult
*result
;
6328 RTWQASYNCRESULT
*data
;
6331 TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6333 if (!stream
|| !obj_type
|| !object
)
6336 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6337 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6339 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6340 IMFByteStreamHandler_Release(handler
);
6344 data
= (RTWQASYNCRESULT
*)result
;
6345 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6347 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
, NULL
,
6348 (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6351 IRtwqAsyncResult_Release(result
);
6355 WaitForSingleObject(data
->hEvent
, INFINITE
);
6357 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, result
, obj_type
, object
);
6358 IRtwqAsyncResult_Release(result
);
6363 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6364 DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
6366 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6367 IMFSchemeHandler
*handler
;
6368 IUnknown
*inner_cookie
= NULL
;
6369 IRtwqAsyncResult
*result
;
6372 TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
6374 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6378 *cancel_cookie
= NULL
;
6380 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6381 IMFSchemeHandler_Release(handler
);
6385 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, cancel_cookie
? &inner_cookie
: NULL
,
6386 (IMFAsyncCallback
*)&resolver
->url_callback
, (IUnknown
*)result
);
6388 if (SUCCEEDED(hr
) && inner_cookie
)
6389 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_URL
, inner_cookie
, cancel_cookie
);
6391 IRtwqAsyncResult_Release(result
);
6396 static HRESULT WINAPI
source_resolver_EndCreateObjectFromURL(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6397 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6399 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6401 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6403 return resolver_end_create_object(resolver
, OBJECT_FROM_URL
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6406 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6407 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
,
6410 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6411 IMFByteStreamHandler
*handler
;
6412 IUnknown
*inner_cookie
= NULL
;
6413 IRtwqAsyncResult
*result
;
6416 TRACE("%p, %p, %s, %#x, %p, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, cancel_cookie
,
6419 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6423 *cancel_cookie
= NULL
;
6425 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6426 IMFByteStreamHandler_Release(handler
);
6430 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
,
6431 cancel_cookie
? &inner_cookie
: NULL
, (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6433 /* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */
6434 if (SUCCEEDED(hr
) && inner_cookie
)
6435 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_BYTESTREAM
, inner_cookie
, cancel_cookie
);
6437 IRtwqAsyncResult_Release(result
);
6442 static HRESULT WINAPI
source_resolver_EndCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6443 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6445 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6447 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6449 return resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6452 static HRESULT WINAPI
source_resolver_CancelObjectCreation(IMFSourceResolver
*iface
, IUnknown
*cancel_cookie
)
6454 struct resolver_cancel_object
*object
;
6457 TRACE("%p, %p.\n", iface
, cancel_cookie
);
6459 if (!(object
= unsafe_impl_cancel_obj_from_IUnknown(cancel_cookie
)))
6460 return E_UNEXPECTED
;
6462 switch (object
->origin
)
6464 case OBJECT_FROM_BYTESTREAM
:
6465 hr
= IMFByteStreamHandler_CancelObjectCreation(object
->u
.stream_handler
, object
->cancel_cookie
);
6467 case OBJECT_FROM_URL
:
6468 hr
= IMFSchemeHandler_CancelObjectCreation(object
->u
.scheme_handler
, object
->cancel_cookie
);
6477 static const IMFSourceResolverVtbl mfsourceresolvervtbl
=
6479 source_resolver_QueryInterface
,
6480 source_resolver_AddRef
,
6481 source_resolver_Release
,
6482 source_resolver_CreateObjectFromURL
,
6483 source_resolver_CreateObjectFromByteStream
,
6484 source_resolver_BeginCreateObjectFromURL
,
6485 source_resolver_EndCreateObjectFromURL
,
6486 source_resolver_BeginCreateObjectFromByteStream
,
6487 source_resolver_EndCreateObjectFromByteStream
,
6488 source_resolver_CancelObjectCreation
,
6491 /***********************************************************************
6492 * MFCreateSourceResolver (mfplat.@)
6494 HRESULT WINAPI
MFCreateSourceResolver(IMFSourceResolver
**resolver
)
6496 struct source_resolver
*object
;
6498 TRACE("%p\n", resolver
);
6503 object
= heap_alloc_zero(sizeof(*object
));
6505 return E_OUTOFMEMORY
;
6507 object
->IMFSourceResolver_iface
.lpVtbl
= &mfsourceresolvervtbl
;
6508 object
->stream_callback
.lpVtbl
= &source_resolver_callback_stream_vtbl
;
6509 object
->url_callback
.lpVtbl
= &source_resolver_callback_url_vtbl
;
6510 object
->refcount
= 1;
6511 list_init(&object
->pending
);
6512 InitializeCriticalSection(&object
->cs
);
6514 *resolver
= &object
->IMFSourceResolver_iface
;
6521 struct attributes attributes
;
6522 IMFMediaEvent IMFMediaEvent_iface
;
6524 MediaEventType type
;
6530 static inline struct media_event
*impl_from_IMFMediaEvent(IMFMediaEvent
*iface
)
6532 return CONTAINING_RECORD(iface
, struct media_event
, IMFMediaEvent_iface
);
6535 static HRESULT WINAPI
mfmediaevent_QueryInterface(IMFMediaEvent
*iface
, REFIID riid
, void **out
)
6537 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6539 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
6541 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
6542 IsEqualGUID(riid
, &IID_IMFAttributes
) ||
6543 IsEqualGUID(riid
, &IID_IMFMediaEvent
))
6545 *out
= &event
->IMFMediaEvent_iface
;
6549 FIXME("%s, %p.\n", debugstr_guid(riid
), out
);
6551 return E_NOINTERFACE
;
6554 IUnknown_AddRef((IUnknown
*)*out
);
6558 static ULONG WINAPI
mfmediaevent_AddRef(IMFMediaEvent
*iface
)
6560 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6561 ULONG refcount
= InterlockedIncrement(&event
->attributes
.ref
);
6563 TRACE("%p, refcount %u.\n", iface
, refcount
);
6568 static ULONG WINAPI
mfmediaevent_Release(IMFMediaEvent
*iface
)
6570 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6571 ULONG refcount
= InterlockedDecrement(&event
->attributes
.ref
);
6573 TRACE("%p, refcount %u.\n", iface
, refcount
);
6577 clear_attributes_object(&event
->attributes
);
6578 PropVariantClear(&event
->value
);
6585 static HRESULT WINAPI
mfmediaevent_GetItem(IMFMediaEvent
*iface
, REFGUID key
, PROPVARIANT
*value
)
6587 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6589 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6591 return attributes_GetItem(&event
->attributes
, key
, value
);
6594 static HRESULT WINAPI
mfmediaevent_GetItemType(IMFMediaEvent
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
6596 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6598 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
6600 return attributes_GetItemType(&event
->attributes
, key
, type
);
6603 static HRESULT WINAPI
mfmediaevent_CompareItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
6605 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6607 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
6609 return attributes_CompareItem(&event
->attributes
, key
, value
, result
);
6612 static HRESULT WINAPI
mfmediaevent_Compare(IMFMediaEvent
*iface
, IMFAttributes
*attrs
, MF_ATTRIBUTES_MATCH_TYPE type
,
6615 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6617 TRACE("%p, %p, %d, %p.\n", iface
, attrs
, type
, result
);
6619 return attributes_Compare(&event
->attributes
, attrs
, type
, result
);
6622 static HRESULT WINAPI
mfmediaevent_GetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*value
)
6624 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6626 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6628 return attributes_GetUINT32(&event
->attributes
, key
, value
);
6631 static HRESULT WINAPI
mfmediaevent_GetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64
*value
)
6633 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6635 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6637 return attributes_GetUINT64(&event
->attributes
, key
, value
);
6640 static HRESULT WINAPI
mfmediaevent_GetDouble(IMFMediaEvent
*iface
, REFGUID key
, double *value
)
6642 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6644 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6646 return attributes_GetDouble(&event
->attributes
, key
, value
);
6649 static HRESULT WINAPI
mfmediaevent_GetGUID(IMFMediaEvent
*iface
, REFGUID key
, GUID
*value
)
6651 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6653 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6655 return attributes_GetGUID(&event
->attributes
, key
, value
);
6658 static HRESULT WINAPI
mfmediaevent_GetStringLength(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*length
)
6660 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6662 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
6664 return attributes_GetStringLength(&event
->attributes
, key
, length
);
6667 static HRESULT WINAPI
mfmediaevent_GetString(IMFMediaEvent
*iface
, REFGUID key
, WCHAR
*value
,
6668 UINT32 size
, UINT32
*length
)
6670 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6672 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
6674 return attributes_GetString(&event
->attributes
, key
, value
, size
, length
);
6677 static HRESULT WINAPI
mfmediaevent_GetAllocatedString(IMFMediaEvent
*iface
, REFGUID key
,
6678 WCHAR
**value
, UINT32
*length
)
6680 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6682 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
6684 return attributes_GetAllocatedString(&event
->attributes
, key
, value
, length
);
6687 static HRESULT WINAPI
mfmediaevent_GetBlobSize(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*size
)
6689 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6691 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
6693 return attributes_GetBlobSize(&event
->attributes
, key
, size
);
6696 static HRESULT WINAPI
mfmediaevent_GetBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
*buf
,
6697 UINT32 bufsize
, UINT32
*blobsize
)
6699 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6701 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
6703 return attributes_GetBlob(&event
->attributes
, key
, buf
, bufsize
, blobsize
);
6706 static HRESULT WINAPI
mfmediaevent_GetAllocatedBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
6708 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6710 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
6712 return attributes_GetAllocatedBlob(&event
->attributes
, key
, buf
, size
);
6715 static HRESULT WINAPI
mfmediaevent_GetUnknown(IMFMediaEvent
*iface
, REFGUID key
, REFIID riid
, void **out
)
6717 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6719 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
6721 return attributes_GetUnknown(&event
->attributes
, key
, riid
, out
);
6724 static HRESULT WINAPI
mfmediaevent_SetItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
)
6726 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6728 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
6730 return attributes_SetItem(&event
->attributes
, key
, value
);
6733 static HRESULT WINAPI
mfmediaevent_DeleteItem(IMFMediaEvent
*iface
, REFGUID key
)
6735 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6737 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
6739 return attributes_DeleteItem(&event
->attributes
, key
);
6742 static HRESULT WINAPI
mfmediaevent_DeleteAllItems(IMFMediaEvent
*iface
)
6744 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6746 TRACE("%p.\n", iface
);
6748 return attributes_DeleteAllItems(&event
->attributes
);
6751 static HRESULT WINAPI
mfmediaevent_SetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32 value
)
6753 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6755 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
6757 return attributes_SetUINT32(&event
->attributes
, key
, value
);
6760 static HRESULT WINAPI
mfmediaevent_SetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64 value
)
6762 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6764 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
6766 return attributes_SetUINT64(&event
->attributes
, key
, value
);
6769 static HRESULT WINAPI
mfmediaevent_SetDouble(IMFMediaEvent
*iface
, REFGUID key
, double value
)
6771 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6773 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
6775 return attributes_SetDouble(&event
->attributes
, key
, value
);
6778 static HRESULT WINAPI
mfmediaevent_SetGUID(IMFMediaEvent
*iface
, REFGUID key
, REFGUID value
)
6780 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6782 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
6784 return attributes_SetGUID(&event
->attributes
, key
, value
);
6787 static HRESULT WINAPI
mfmediaevent_SetString(IMFMediaEvent
*iface
, REFGUID key
, const WCHAR
*value
)
6789 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6791 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
6793 return attributes_SetString(&event
->attributes
, key
, value
);
6796 static HRESULT WINAPI
mfmediaevent_SetBlob(IMFMediaEvent
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
6798 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6800 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
6802 return attributes_SetBlob(&event
->attributes
, key
, buf
, size
);
6805 static HRESULT WINAPI
mfmediaevent_SetUnknown(IMFMediaEvent
*iface
, REFGUID key
, IUnknown
*unknown
)
6807 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6809 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
6811 return attributes_SetUnknown(&event
->attributes
, key
, unknown
);
6814 static HRESULT WINAPI
mfmediaevent_LockStore(IMFMediaEvent
*iface
)
6816 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6818 TRACE("%p.\n", iface
);
6820 return attributes_LockStore(&event
->attributes
);
6823 static HRESULT WINAPI
mfmediaevent_UnlockStore(IMFMediaEvent
*iface
)
6825 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6827 TRACE("%p.\n", iface
);
6829 return attributes_UnlockStore(&event
->attributes
);
6832 static HRESULT WINAPI
mfmediaevent_GetCount(IMFMediaEvent
*iface
, UINT32
*count
)
6834 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6836 TRACE("%p, %p.\n", iface
, count
);
6838 return attributes_GetCount(&event
->attributes
, count
);
6841 static HRESULT WINAPI
mfmediaevent_GetItemByIndex(IMFMediaEvent
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
6843 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6845 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
6847 return attributes_GetItemByIndex(&event
->attributes
, index
, key
, value
);
6850 static HRESULT WINAPI
mfmediaevent_CopyAllItems(IMFMediaEvent
*iface
, IMFAttributes
*dest
)
6852 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6854 TRACE("%p, %p.\n", iface
, dest
);
6856 return attributes_CopyAllItems(&event
->attributes
, dest
);
6859 static HRESULT WINAPI
mfmediaevent_GetType(IMFMediaEvent
*iface
, MediaEventType
*type
)
6861 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6863 TRACE("%p, %p.\n", iface
, type
);
6865 *type
= event
->type
;
6870 static HRESULT WINAPI
mfmediaevent_GetExtendedType(IMFMediaEvent
*iface
, GUID
*extended_type
)
6872 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6874 TRACE("%p, %p.\n", iface
, extended_type
);
6876 *extended_type
= event
->extended_type
;
6881 static HRESULT WINAPI
mfmediaevent_GetStatus(IMFMediaEvent
*iface
, HRESULT
*status
)
6883 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6885 TRACE("%p, %p.\n", iface
, status
);
6887 *status
= event
->status
;
6892 static HRESULT WINAPI
mfmediaevent_GetValue(IMFMediaEvent
*iface
, PROPVARIANT
*value
)
6894 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6896 TRACE("%p, %p.\n", iface
, value
);
6898 PropVariantCopy(value
, &event
->value
);
6903 static const IMFMediaEventVtbl mfmediaevent_vtbl
=
6905 mfmediaevent_QueryInterface
,
6906 mfmediaevent_AddRef
,
6907 mfmediaevent_Release
,
6908 mfmediaevent_GetItem
,
6909 mfmediaevent_GetItemType
,
6910 mfmediaevent_CompareItem
,
6911 mfmediaevent_Compare
,
6912 mfmediaevent_GetUINT32
,
6913 mfmediaevent_GetUINT64
,
6914 mfmediaevent_GetDouble
,
6915 mfmediaevent_GetGUID
,
6916 mfmediaevent_GetStringLength
,
6917 mfmediaevent_GetString
,
6918 mfmediaevent_GetAllocatedString
,
6919 mfmediaevent_GetBlobSize
,
6920 mfmediaevent_GetBlob
,
6921 mfmediaevent_GetAllocatedBlob
,
6922 mfmediaevent_GetUnknown
,
6923 mfmediaevent_SetItem
,
6924 mfmediaevent_DeleteItem
,
6925 mfmediaevent_DeleteAllItems
,
6926 mfmediaevent_SetUINT32
,
6927 mfmediaevent_SetUINT64
,
6928 mfmediaevent_SetDouble
,
6929 mfmediaevent_SetGUID
,
6930 mfmediaevent_SetString
,
6931 mfmediaevent_SetBlob
,
6932 mfmediaevent_SetUnknown
,
6933 mfmediaevent_LockStore
,
6934 mfmediaevent_UnlockStore
,
6935 mfmediaevent_GetCount
,
6936 mfmediaevent_GetItemByIndex
,
6937 mfmediaevent_CopyAllItems
,
6938 mfmediaevent_GetType
,
6939 mfmediaevent_GetExtendedType
,
6940 mfmediaevent_GetStatus
,
6941 mfmediaevent_GetValue
,
6944 /***********************************************************************
6945 * MFCreateMediaEvent (mfplat.@)
6947 HRESULT WINAPI
MFCreateMediaEvent(MediaEventType type
, REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
,
6948 IMFMediaEvent
**event
)
6950 struct media_event
*object
;
6953 TRACE("%s, %s, %#x, %s, %p.\n", debugstr_eventid(type
), debugstr_guid(extended_type
), status
,
6954 debugstr_propvar(value
), event
);
6956 object
= heap_alloc(sizeof(*object
));
6958 return E_OUTOFMEMORY
;
6960 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
6965 object
->IMFMediaEvent_iface
.lpVtbl
= &mfmediaevent_vtbl
;
6967 object
->type
= type
;
6968 object
->extended_type
= *extended_type
;
6969 object
->status
= status
;
6971 PropVariantInit(&object
->value
);
6973 PropVariantCopy(&object
->value
, value
);
6975 *event
= &object
->IMFMediaEvent_iface
;
6977 TRACE("Created event %p.\n", *event
);
6984 IMFMediaEventQueue IMFMediaEventQueue_iface
;
6987 CRITICAL_SECTION cs
;
6988 CONDITION_VARIABLE update_event
;
6992 IRtwqAsyncResult
*subscriber
;
6998 IMFMediaEvent
*event
;
7001 static inline struct event_queue
*impl_from_IMFMediaEventQueue(IMFMediaEventQueue
*iface
)
7003 return CONTAINING_RECORD(iface
, struct event_queue
, IMFMediaEventQueue_iface
);
7006 static IMFMediaEvent
*queue_pop_event(struct event_queue
*queue
)
7008 struct list
*head
= list_head(&queue
->events
);
7009 struct queued_event
*queued_event
;
7010 IMFMediaEvent
*event
;
7015 queued_event
= LIST_ENTRY(head
, struct queued_event
, entry
);
7016 event
= queued_event
->event
;
7017 list_remove(&queued_event
->entry
);
7018 heap_free(queued_event
);
7022 static void event_queue_cleanup(struct event_queue
*queue
)
7024 IMFMediaEvent
*event
;
7026 while ((event
= queue_pop_event(queue
)))
7027 IMFMediaEvent_Release(event
);
7030 static HRESULT WINAPI
eventqueue_QueryInterface(IMFMediaEventQueue
*iface
, REFIID riid
, void **out
)
7032 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7034 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7036 if (IsEqualIID(riid
, &IID_IMFMediaEventQueue
) ||
7037 IsEqualIID(riid
, &IID_IUnknown
))
7039 *out
= &queue
->IMFMediaEventQueue_iface
;
7040 IMFMediaEventQueue_AddRef(iface
);
7044 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7046 return E_NOINTERFACE
;
7049 static ULONG WINAPI
eventqueue_AddRef(IMFMediaEventQueue
*iface
)
7051 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7052 ULONG refcount
= InterlockedIncrement(&queue
->refcount
);
7054 TRACE("%p, refcount %u.\n", iface
, refcount
);
7059 static ULONG WINAPI
eventqueue_Release(IMFMediaEventQueue
*iface
)
7061 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7062 ULONG refcount
= InterlockedDecrement(&queue
->refcount
);
7064 TRACE("%p, refcount %u.\n", queue
, refcount
);
7068 event_queue_cleanup(queue
);
7069 DeleteCriticalSection(&queue
->cs
);
7076 static HRESULT WINAPI
eventqueue_GetEvent(IMFMediaEventQueue
*iface
, DWORD flags
, IMFMediaEvent
**event
)
7078 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7081 TRACE("%p, %p.\n", iface
, event
);
7083 EnterCriticalSection(&queue
->cs
);
7085 if (queue
->is_shut_down
)
7087 else if (queue
->subscriber
)
7088 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7091 if (flags
& MF_EVENT_FLAG_NO_WAIT
)
7093 if (!(*event
= queue_pop_event(queue
)))
7094 hr
= MF_E_NO_EVENTS_AVAILABLE
;
7098 while (list_empty(&queue
->events
) && !queue
->is_shut_down
)
7100 SleepConditionVariableCS(&queue
->update_event
, &queue
->cs
, INFINITE
);
7102 *event
= queue_pop_event(queue
);
7103 if (queue
->is_shut_down
)
7108 LeaveCriticalSection(&queue
->cs
);
7113 static void queue_notify_subscriber(struct event_queue
*queue
)
7115 if (list_empty(&queue
->events
) || !queue
->subscriber
|| queue
->notified
)
7118 queue
->notified
= TRUE
;
7119 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, queue
->subscriber
);
7122 static HRESULT WINAPI
eventqueue_BeginGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
7124 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7125 MFASYNCRESULT
*result_data
= (MFASYNCRESULT
*)queue
->subscriber
;
7128 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
7131 return E_INVALIDARG
;
7133 EnterCriticalSection(&queue
->cs
);
7135 if (queue
->is_shut_down
)
7137 else if (result_data
)
7139 if (result_data
->pCallback
== callback
)
7140 hr
= IRtwqAsyncResult_GetStateNoAddRef(queue
->subscriber
) == state
?
7141 MF_S_MULTIPLE_BEGIN
: MF_E_MULTIPLE_BEGIN
;
7143 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7147 hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &queue
->subscriber
);
7149 queue_notify_subscriber(queue
);
7152 LeaveCriticalSection(&queue
->cs
);
7157 static HRESULT WINAPI
eventqueue_EndGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
7159 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7160 HRESULT hr
= E_FAIL
;
7162 TRACE("%p, %p, %p.\n", iface
, result
, event
);
7164 EnterCriticalSection(&queue
->cs
);
7166 if (queue
->is_shut_down
)
7168 else if (queue
->subscriber
== (IRtwqAsyncResult
*)result
)
7170 *event
= queue_pop_event(queue
);
7171 if (queue
->subscriber
)
7172 IRtwqAsyncResult_Release(queue
->subscriber
);
7173 queue
->subscriber
= NULL
;
7174 queue
->notified
= FALSE
;
7175 hr
= *event
? S_OK
: E_FAIL
;
7178 LeaveCriticalSection(&queue
->cs
);
7183 static HRESULT
eventqueue_queue_event(struct event_queue
*queue
, IMFMediaEvent
*event
)
7185 struct queued_event
*queued_event
;
7188 queued_event
= heap_alloc(sizeof(*queued_event
));
7190 return E_OUTOFMEMORY
;
7192 queued_event
->event
= event
;
7194 EnterCriticalSection(&queue
->cs
);
7196 if (queue
->is_shut_down
)
7200 IMFMediaEvent_AddRef(queued_event
->event
);
7201 list_add_tail(&queue
->events
, &queued_event
->entry
);
7202 queue_notify_subscriber(queue
);
7205 LeaveCriticalSection(&queue
->cs
);
7208 heap_free(queued_event
);
7210 WakeAllConditionVariable(&queue
->update_event
);
7215 static HRESULT WINAPI
eventqueue_QueueEvent(IMFMediaEventQueue
*iface
, IMFMediaEvent
*event
)
7217 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7219 TRACE("%p, %p.\n", iface
, event
);
7221 return eventqueue_queue_event(queue
, event
);
7224 static HRESULT WINAPI
eventqueue_QueueEventParamVar(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7225 REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
)
7227 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7228 IMFMediaEvent
*event
;
7231 TRACE("%p, %s, %s, %#x, %s\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
,
7232 debugstr_propvar(value
));
7234 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, value
, &event
)))
7237 hr
= eventqueue_queue_event(queue
, event
);
7238 IMFMediaEvent_Release(event
);
7242 static HRESULT WINAPI
eventqueue_QueueEventParamUnk(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7243 REFGUID extended_type
, HRESULT status
, IUnknown
*unk
)
7245 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7246 IMFMediaEvent
*event
;
7250 TRACE("%p, %s, %s, %#x, %p.\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
, unk
);
7252 value
.vt
= VT_UNKNOWN
;
7253 value
.u
.punkVal
= unk
;
7255 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, &value
, &event
)))
7258 hr
= eventqueue_queue_event(queue
, event
);
7259 IMFMediaEvent_Release(event
);
7263 static HRESULT WINAPI
eventqueue_Shutdown(IMFMediaEventQueue
*iface
)
7265 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7267 TRACE("%p\n", queue
);
7269 EnterCriticalSection(&queue
->cs
);
7271 if (!queue
->is_shut_down
)
7273 event_queue_cleanup(queue
);
7274 queue
->is_shut_down
= TRUE
;
7277 LeaveCriticalSection(&queue
->cs
);
7279 WakeAllConditionVariable(&queue
->update_event
);
7284 static const IMFMediaEventQueueVtbl eventqueuevtbl
=
7286 eventqueue_QueryInterface
,
7289 eventqueue_GetEvent
,
7290 eventqueue_BeginGetEvent
,
7291 eventqueue_EndGetEvent
,
7292 eventqueue_QueueEvent
,
7293 eventqueue_QueueEventParamVar
,
7294 eventqueue_QueueEventParamUnk
,
7298 /***********************************************************************
7299 * MFCreateEventQueue (mfplat.@)
7301 HRESULT WINAPI
MFCreateEventQueue(IMFMediaEventQueue
**queue
)
7303 struct event_queue
*object
;
7305 TRACE("%p\n", queue
);
7307 object
= heap_alloc_zero(sizeof(*object
));
7309 return E_OUTOFMEMORY
;
7311 object
->IMFMediaEventQueue_iface
.lpVtbl
= &eventqueuevtbl
;
7312 object
->refcount
= 1;
7313 list_init(&object
->events
);
7314 InitializeCriticalSection(&object
->cs
);
7315 InitializeConditionVariable(&object
->update_event
);
7317 *queue
= &object
->IMFMediaEventQueue_iface
;
7324 IMFCollection IMFCollection_iface
;
7326 IUnknown
**elements
;
7331 static struct collection
*impl_from_IMFCollection(IMFCollection
*iface
)
7333 return CONTAINING_RECORD(iface
, struct collection
, IMFCollection_iface
);
7336 static void collection_clear(struct collection
*collection
)
7340 for (i
= 0; i
< collection
->count
; ++i
)
7342 if (collection
->elements
[i
])
7343 IUnknown_Release(collection
->elements
[i
]);
7346 heap_free(collection
->elements
);
7347 collection
->elements
= NULL
;
7348 collection
->count
= 0;
7349 collection
->capacity
= 0;
7352 static HRESULT WINAPI
collection_QueryInterface(IMFCollection
*iface
, REFIID riid
, void **out
)
7354 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7356 if (IsEqualIID(riid
, &IID_IMFCollection
) ||
7357 IsEqualIID(riid
, &IID_IUnknown
))
7360 IMFCollection_AddRef(iface
);
7364 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
7366 return E_NOINTERFACE
;
7369 static ULONG WINAPI
collection_AddRef(IMFCollection
*iface
)
7371 struct collection
*collection
= impl_from_IMFCollection(iface
);
7372 ULONG refcount
= InterlockedIncrement(&collection
->refcount
);
7374 TRACE("%p, %d.\n", collection
, refcount
);
7379 static ULONG WINAPI
collection_Release(IMFCollection
*iface
)
7381 struct collection
*collection
= impl_from_IMFCollection(iface
);
7382 ULONG refcount
= InterlockedDecrement(&collection
->refcount
);
7384 TRACE("%p, %d.\n", collection
, refcount
);
7388 collection_clear(collection
);
7389 heap_free(collection
->elements
);
7390 heap_free(collection
);
7396 static HRESULT WINAPI
collection_GetElementCount(IMFCollection
*iface
, DWORD
*count
)
7398 struct collection
*collection
= impl_from_IMFCollection(iface
);
7400 TRACE("%p, %p.\n", iface
, count
);
7405 *count
= collection
->count
;
7410 static HRESULT WINAPI
collection_GetElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7412 struct collection
*collection
= impl_from_IMFCollection(iface
);
7414 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7419 if (idx
>= collection
->count
)
7420 return E_INVALIDARG
;
7422 *element
= collection
->elements
[idx
];
7424 IUnknown_AddRef(*element
);
7426 return *element
? S_OK
: E_UNEXPECTED
;
7429 static HRESULT WINAPI
collection_AddElement(IMFCollection
*iface
, IUnknown
*element
)
7431 struct collection
*collection
= impl_from_IMFCollection(iface
);
7433 TRACE("%p, %p.\n", iface
, element
);
7435 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, collection
->count
+ 1,
7436 sizeof(*collection
->elements
)))
7437 return E_OUTOFMEMORY
;
7439 collection
->elements
[collection
->count
++] = element
;
7441 IUnknown_AddRef(element
);
7446 static HRESULT WINAPI
collection_RemoveElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7448 struct collection
*collection
= impl_from_IMFCollection(iface
);
7451 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7456 if (idx
>= collection
->count
)
7457 return E_INVALIDARG
;
7459 *element
= collection
->elements
[idx
];
7461 count
= collection
->count
- idx
- 1;
7463 memmove(&collection
->elements
[idx
], &collection
->elements
[idx
+ 1], count
* sizeof(*collection
->elements
));
7464 collection
->count
--;
7469 static HRESULT WINAPI
collection_InsertElementAt(IMFCollection
*iface
, DWORD idx
, IUnknown
*element
)
7471 struct collection
*collection
= impl_from_IMFCollection(iface
);
7474 TRACE("%p, %u, %p.\n", iface
, idx
, element
);
7476 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, idx
+ 1,
7477 sizeof(*collection
->elements
)))
7478 return E_OUTOFMEMORY
;
7480 if (idx
< collection
->count
)
7482 memmove(&collection
->elements
[idx
+ 1], &collection
->elements
[idx
],
7483 (collection
->count
- idx
) * sizeof(*collection
->elements
));
7484 collection
->count
++;
7488 for (i
= collection
->count
; i
< idx
; ++i
)
7489 collection
->elements
[i
] = NULL
;
7490 collection
->count
= idx
+ 1;
7493 collection
->elements
[idx
] = element
;
7494 if (collection
->elements
[idx
])
7495 IUnknown_AddRef(collection
->elements
[idx
]);
7500 static HRESULT WINAPI
collection_RemoveAllElements(IMFCollection
*iface
)
7502 struct collection
*collection
= impl_from_IMFCollection(iface
);
7504 TRACE("%p.\n", iface
);
7506 collection_clear(collection
);
7511 static const IMFCollectionVtbl mfcollectionvtbl
=
7513 collection_QueryInterface
,
7516 collection_GetElementCount
,
7517 collection_GetElement
,
7518 collection_AddElement
,
7519 collection_RemoveElement
,
7520 collection_InsertElementAt
,
7521 collection_RemoveAllElements
,
7524 /***********************************************************************
7525 * MFCreateCollection (mfplat.@)
7527 HRESULT WINAPI
MFCreateCollection(IMFCollection
**collection
)
7529 struct collection
*object
;
7531 TRACE("%p\n", collection
);
7536 object
= heap_alloc_zero(sizeof(*object
));
7538 return E_OUTOFMEMORY
;
7540 object
->IMFCollection_iface
.lpVtbl
= &mfcollectionvtbl
;
7541 object
->refcount
= 1;
7543 *collection
= &object
->IMFCollection_iface
;
7548 /***********************************************************************
7549 * MFHeapAlloc (mfplat.@)
7551 void *WINAPI
MFHeapAlloc(SIZE_T size
, ULONG flags
, char *file
, int line
, EAllocationType type
)
7553 TRACE("%lu, %#x, %s, %d, %#x.\n", size
, flags
, debugstr_a(file
), line
, type
);
7554 return HeapAlloc(GetProcessHeap(), flags
, size
);
7557 /***********************************************************************
7558 * MFHeapFree (mfplat.@)
7560 void WINAPI
MFHeapFree(void *p
)
7563 HeapFree(GetProcessHeap(), 0, p
);
7566 /***********************************************************************
7567 * MFCreateMFByteStreamOnStreamEx (mfplat.@)
7569 HRESULT WINAPI
MFCreateMFByteStreamOnStreamEx(IUnknown
*stream
, IMFByteStream
**bytestream
)
7571 FIXME("(%p, %p): stub\n", stream
, bytestream
);
7576 static HRESULT WINAPI
system_clock_QueryInterface(IMFClock
*iface
, REFIID riid
, void **obj
)
7578 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7580 if (IsEqualIID(riid
, &IID_IMFClock
) ||
7581 IsEqualIID(riid
, &IID_IUnknown
))
7584 IMFClock_AddRef(iface
);
7588 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7590 return E_NOINTERFACE
;
7593 static ULONG WINAPI
system_clock_AddRef(IMFClock
*iface
)
7595 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7596 ULONG refcount
= InterlockedIncrement(&clock
->refcount
);
7598 TRACE("%p, refcount %u.\n", iface
, refcount
);
7603 static ULONG WINAPI
system_clock_Release(IMFClock
*iface
)
7605 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7606 ULONG refcount
= InterlockedDecrement(&clock
->refcount
);
7608 TRACE("%p, refcount %u.\n", iface
, refcount
);
7616 static HRESULT WINAPI
system_clock_GetClockCharacteristics(IMFClock
*iface
, DWORD
*flags
)
7618 TRACE("%p, %p.\n", iface
, flags
);
7620 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING
|
7621 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7626 static HRESULT WINAPI
system_clock_GetCorrelatedTime(IMFClock
*iface
, DWORD reserved
, LONGLONG
*clock_time
,
7627 MFTIME
*system_time
)
7629 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7631 *clock_time
= *system_time
= MFGetSystemTime();
7636 static HRESULT WINAPI
system_clock_GetContinuityKey(IMFClock
*iface
, DWORD
*key
)
7638 TRACE("%p, %p.\n", iface
, key
);
7645 static HRESULT WINAPI
system_clock_GetState(IMFClock
*iface
, DWORD reserved
, MFCLOCK_STATE
*state
)
7647 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7649 *state
= MFCLOCK_STATE_RUNNING
;
7654 static HRESULT WINAPI
system_clock_GetProperties(IMFClock
*iface
, MFCLOCK_PROPERTIES
*props
)
7656 TRACE("%p, %p.\n", iface
, props
);
7661 memset(props
, 0, sizeof(*props
));
7662 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7663 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7664 props
->dwClockJitter
= 1;
7669 static const IMFClockVtbl system_clock_vtbl
=
7671 system_clock_QueryInterface
,
7672 system_clock_AddRef
,
7673 system_clock_Release
,
7674 system_clock_GetClockCharacteristics
,
7675 system_clock_GetCorrelatedTime
,
7676 system_clock_GetContinuityKey
,
7677 system_clock_GetState
,
7678 system_clock_GetProperties
,
7681 static HRESULT
create_system_clock(IMFClock
**clock
)
7683 struct system_clock
*object
;
7685 if (!(object
= heap_alloc(sizeof(*object
))))
7686 return E_OUTOFMEMORY
;
7688 object
->IMFClock_iface
.lpVtbl
= &system_clock_vtbl
;
7689 object
->refcount
= 1;
7691 *clock
= &object
->IMFClock_iface
;
7696 static HRESULT WINAPI
system_time_source_QueryInterface(IMFPresentationTimeSource
*iface
, REFIID riid
, void **obj
)
7698 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7700 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7702 if (IsEqualIID(riid
, &IID_IMFPresentationTimeSource
) ||
7703 IsEqualIID(riid
, &IID_IUnknown
))
7705 *obj
= &source
->IMFPresentationTimeSource_iface
;
7707 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
7709 *obj
= &source
->IMFClockStateSink_iface
;
7713 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7715 return E_NOINTERFACE
;
7718 IUnknown_AddRef((IUnknown
*)*obj
);
7722 static ULONG WINAPI
system_time_source_AddRef(IMFPresentationTimeSource
*iface
)
7724 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7725 ULONG refcount
= InterlockedIncrement(&source
->refcount
);
7727 TRACE("%p, refcount %u.\n", iface
, refcount
);
7732 static ULONG WINAPI
system_time_source_Release(IMFPresentationTimeSource
*iface
)
7734 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7735 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
7737 TRACE("%p, refcount %u.\n", iface
, refcount
);
7742 IMFClock_Release(source
->clock
);
7743 DeleteCriticalSection(&source
->cs
);
7750 static HRESULT WINAPI
system_time_source_GetClockCharacteristics(IMFPresentationTimeSource
*iface
, DWORD
*flags
)
7752 TRACE("%p, %p.\n", iface
, flags
);
7754 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7759 static HRESULT WINAPI
system_time_source_GetCorrelatedTime(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7760 LONGLONG
*clock_time
, MFTIME
*system_time
)
7762 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7765 TRACE("%p, %#x, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7767 EnterCriticalSection(&source
->cs
);
7768 if (SUCCEEDED(hr
= IMFClock_GetCorrelatedTime(source
->clock
, 0, clock_time
, system_time
)))
7770 if (source
->state
== MFCLOCK_STATE_RUNNING
)
7772 system_time_source_apply_rate(source
, clock_time
);
7773 *clock_time
+= source
->start_offset
;
7776 *clock_time
= source
->start_offset
;
7778 LeaveCriticalSection(&source
->cs
);
7783 static HRESULT WINAPI
system_time_source_GetContinuityKey(IMFPresentationTimeSource
*iface
, DWORD
*key
)
7785 TRACE("%p, %p.\n", iface
, key
);
7792 static HRESULT WINAPI
system_time_source_GetState(IMFPresentationTimeSource
*iface
, DWORD reserved
,
7793 MFCLOCK_STATE
*state
)
7795 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7797 TRACE("%p, %#x, %p.\n", iface
, reserved
, state
);
7799 EnterCriticalSection(&source
->cs
);
7800 *state
= source
->state
;
7801 LeaveCriticalSection(&source
->cs
);
7806 static HRESULT WINAPI
system_time_source_GetProperties(IMFPresentationTimeSource
*iface
, MFCLOCK_PROPERTIES
*props
)
7808 TRACE("%p, %p.\n", iface
, props
);
7813 memset(props
, 0, sizeof(*props
));
7814 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7815 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7816 props
->dwClockJitter
= 1;
7821 static HRESULT WINAPI
system_time_source_GetUnderlyingClock(IMFPresentationTimeSource
*iface
, IMFClock
**clock
)
7823 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7825 TRACE("%p, %p.\n", iface
, clock
);
7827 *clock
= source
->clock
;
7828 IMFClock_AddRef(*clock
);
7833 static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl
=
7835 system_time_source_QueryInterface
,
7836 system_time_source_AddRef
,
7837 system_time_source_Release
,
7838 system_time_source_GetClockCharacteristics
,
7839 system_time_source_GetCorrelatedTime
,
7840 system_time_source_GetContinuityKey
,
7841 system_time_source_GetState
,
7842 system_time_source_GetProperties
,
7843 system_time_source_GetUnderlyingClock
,
7846 static HRESULT WINAPI
system_time_source_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **out
)
7848 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7849 return IMFPresentationTimeSource_QueryInterface(&source
->IMFPresentationTimeSource_iface
, riid
, out
);
7852 static ULONG WINAPI
system_time_source_sink_AddRef(IMFClockStateSink
*iface
)
7854 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7855 return IMFPresentationTimeSource_AddRef(&source
->IMFPresentationTimeSource_iface
);
7858 static ULONG WINAPI
system_time_source_sink_Release(IMFClockStateSink
*iface
)
7860 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7861 return IMFPresentationTimeSource_Release(&source
->IMFPresentationTimeSource_iface
);
7866 CLOCK_CMD_START
= 0,
7873 static HRESULT
system_time_source_change_state(struct system_time_source
*source
, enum clock_command command
)
7875 static const BYTE state_change_is_allowed
[MFCLOCK_STATE_PAUSED
+1][CLOCK_CMD_MAX
] =
7877 /* INVALID */ { 1, 0, 1, 0 },
7878 /* RUNNING */ { 1, 1, 1, 0 },
7879 /* STOPPED */ { 1, 1, 0, 0 },
7880 /* PAUSED */ { 1, 1, 0, 1 },
7882 static const MFCLOCK_STATE states
[CLOCK_CMD_MAX
] =
7884 /* CLOCK_CMD_START */ MFCLOCK_STATE_RUNNING
,
7885 /* CLOCK_CMD_STOP */ MFCLOCK_STATE_STOPPED
,
7886 /* CLOCK_CMD_PAUSE */ MFCLOCK_STATE_PAUSED
,
7887 /* CLOCK_CMD_RESTART */ MFCLOCK_STATE_RUNNING
,
7890 /* Special case that go against usual state change vs return value behavior. */
7891 if (source
->state
== MFCLOCK_STATE_INVALID
&& command
== CLOCK_CMD_STOP
)
7894 if (!state_change_is_allowed
[source
->state
][command
])
7895 return MF_E_INVALIDREQUEST
;
7897 source
->state
= states
[command
];
7902 static HRESULT WINAPI
system_time_source_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
,
7903 LONGLONG start_offset
)
7905 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7906 MFCLOCK_STATE state
;
7909 TRACE("%p, %s, %s.\n", iface
, debugstr_time(system_time
), debugstr_time(start_offset
));
7911 EnterCriticalSection(&source
->cs
);
7912 state
= source
->state
;
7913 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_START
)))
7915 system_time_source_apply_rate(source
, &system_time
);
7916 if (start_offset
== PRESENTATION_CURRENT_POSITION
)
7920 case MFCLOCK_STATE_RUNNING
:
7922 case MFCLOCK_STATE_PAUSED
:
7923 source
->start_offset
-= system_time
;
7926 source
->start_offset
= -system_time
;
7933 source
->start_offset
= -system_time
+ start_offset
;
7936 LeaveCriticalSection(&source
->cs
);
7941 static HRESULT WINAPI
system_time_source_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
7943 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7946 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7948 EnterCriticalSection(&source
->cs
);
7949 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_STOP
)))
7950 source
->start_offset
= 0;
7951 LeaveCriticalSection(&source
->cs
);
7956 static HRESULT WINAPI
system_time_source_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
7958 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7961 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7963 EnterCriticalSection(&source
->cs
);
7964 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_PAUSE
)))
7966 system_time_source_apply_rate(source
, &system_time
);
7967 source
->start_offset
+= system_time
;
7969 LeaveCriticalSection(&source
->cs
);
7974 static HRESULT WINAPI
system_time_source_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
7976 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7979 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
7981 EnterCriticalSection(&source
->cs
);
7982 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_RESTART
)))
7984 system_time_source_apply_rate(source
, &system_time
);
7985 source
->start_offset
-= system_time
;
7987 LeaveCriticalSection(&source
->cs
);
7992 static HRESULT WINAPI
system_time_source_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
7994 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
7997 TRACE("%p, %s, %f.\n", iface
, debugstr_time(system_time
), rate
);
8000 return MF_E_UNSUPPORTED_RATE
;
8002 modf(rate
, &intpart
);
8004 EnterCriticalSection(&source
->cs
);
8005 source
->rate
= rate
;
8006 source
->i_rate
= rate
== intpart
? rate
: 0;
8007 LeaveCriticalSection(&source
->cs
);
8012 static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl
=
8014 system_time_source_sink_QueryInterface
,
8015 system_time_source_sink_AddRef
,
8016 system_time_source_sink_Release
,
8017 system_time_source_sink_OnClockStart
,
8018 system_time_source_sink_OnClockStop
,
8019 system_time_source_sink_OnClockPause
,
8020 system_time_source_sink_OnClockRestart
,
8021 system_time_source_sink_OnClockSetRate
,
8024 /***********************************************************************
8025 * MFCreateSystemTimeSource (mfplat.@)
8027 HRESULT WINAPI
MFCreateSystemTimeSource(IMFPresentationTimeSource
**time_source
)
8029 struct system_time_source
*object
;
8032 TRACE("%p.\n", time_source
);
8034 object
= heap_alloc_zero(sizeof(*object
));
8036 return E_OUTOFMEMORY
;
8038 object
->IMFPresentationTimeSource_iface
.lpVtbl
= &systemtimesourcevtbl
;
8039 object
->IMFClockStateSink_iface
.lpVtbl
= &systemtimesourcesinkvtbl
;
8040 object
->refcount
= 1;
8041 object
->rate
= 1.0f
;
8043 InitializeCriticalSection(&object
->cs
);
8045 if (FAILED(hr
= create_system_clock(&object
->clock
)))
8047 IMFPresentationTimeSource_Release(&object
->IMFPresentationTimeSource_iface
);
8051 *time_source
= &object
->IMFPresentationTimeSource_iface
;
8056 struct async_create_file
8058 IRtwqAsyncCallback IRtwqAsyncCallback_iface
;
8060 MF_FILE_ACCESSMODE access_mode
;
8061 MF_FILE_OPENMODE open_mode
;
8062 MF_FILE_FLAGS flags
;
8066 struct async_create_file_result
8069 IRtwqAsyncResult
*result
;
8070 IMFByteStream
*stream
;
8073 static struct list async_create_file_results
= LIST_INIT(async_create_file_results
);
8074 static CRITICAL_SECTION async_create_file_cs
= { NULL
, -1, 0, 0, 0, 0 };
8076 static struct async_create_file
*impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
8078 return CONTAINING_RECORD(iface
, struct async_create_file
, IRtwqAsyncCallback_iface
);
8081 static HRESULT WINAPI
async_create_file_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
8083 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
8084 IsEqualIID(riid
, &IID_IUnknown
))
8087 IRtwqAsyncCallback_AddRef(iface
);
8092 return E_NOINTERFACE
;
8095 static ULONG WINAPI
async_create_file_callback_AddRef(IRtwqAsyncCallback
*iface
)
8097 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8098 ULONG refcount
= InterlockedIncrement(&async
->refcount
);
8100 TRACE("%p, refcount %u.\n", iface
, refcount
);
8105 static ULONG WINAPI
async_create_file_callback_Release(IRtwqAsyncCallback
*iface
)
8107 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8108 ULONG refcount
= InterlockedDecrement(&async
->refcount
);
8110 TRACE("%p, refcount %u.\n", iface
, refcount
);
8114 heap_free(async
->path
);
8121 static HRESULT WINAPI
async_create_file_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
8126 static HRESULT WINAPI
async_create_file_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
8128 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8129 IRtwqAsyncResult
*caller
;
8130 IMFByteStream
*stream
;
8133 caller
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
8135 hr
= MFCreateFile(async
->access_mode
, async
->open_mode
, async
->flags
, async
->path
, &stream
);
8138 struct async_create_file_result
*result_item
;
8140 result_item
= heap_alloc(sizeof(*result_item
));
8143 result_item
->result
= caller
;
8144 IRtwqAsyncResult_AddRef(caller
);
8145 result_item
->stream
= stream
;
8146 IMFByteStream_AddRef(stream
);
8148 EnterCriticalSection(&async_create_file_cs
);
8149 list_add_tail(&async_create_file_results
, &result_item
->entry
);
8150 LeaveCriticalSection(&async_create_file_cs
);
8153 IMFByteStream_Release(stream
);
8156 IRtwqAsyncResult_SetStatus(caller
, hr
);
8158 RtwqInvokeCallback(caller
);
8163 static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl
=
8165 async_create_file_callback_QueryInterface
,
8166 async_create_file_callback_AddRef
,
8167 async_create_file_callback_Release
,
8168 async_create_file_callback_GetParameters
,
8169 async_create_file_callback_Invoke
,
8172 /***********************************************************************
8173 * MFBeginCreateFile (mfplat.@)
8175 HRESULT WINAPI
MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode
, MF_FILE_OPENMODE open_mode
, MF_FILE_FLAGS flags
,
8176 const WCHAR
*path
, IMFAsyncCallback
*callback
, IUnknown
*state
, IUnknown
**cancel_cookie
)
8178 struct async_create_file
*async
= NULL
;
8179 IRtwqAsyncResult
*caller
, *item
= NULL
;
8182 TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode
, open_mode
, flags
, debugstr_w(path
), callback
, state
,
8186 *cancel_cookie
= NULL
;
8188 if (FAILED(hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &caller
)))
8191 async
= heap_alloc(sizeof(*async
));
8198 async
->IRtwqAsyncCallback_iface
.lpVtbl
= &async_create_file_callback_vtbl
;
8199 async
->refcount
= 1;
8200 async
->access_mode
= access_mode
;
8201 async
->open_mode
= open_mode
;
8202 async
->flags
= flags
;
8203 if (FAILED(hr
= heap_strdupW(path
, &async
->path
)))
8206 hr
= RtwqCreateAsyncResult(NULL
, &async
->IRtwqAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
8212 *cancel_cookie
= (IUnknown
*)caller
;
8213 IUnknown_AddRef(*cancel_cookie
);
8216 hr
= RtwqInvokeCallback(item
);
8220 IRtwqAsyncCallback_Release(&async
->IRtwqAsyncCallback_iface
);
8222 IRtwqAsyncResult_Release(item
);
8224 IRtwqAsyncResult_Release(caller
);
8229 static HRESULT
async_create_file_pull_result(IUnknown
*unk
, IMFByteStream
**stream
)
8231 struct async_create_file_result
*item
;
8232 HRESULT hr
= MF_E_UNEXPECTED
;
8233 IRtwqAsyncResult
*result
;
8237 if (FAILED(IUnknown_QueryInterface(unk
, &IID_IRtwqAsyncResult
, (void **)&result
)))
8240 EnterCriticalSection(&async_create_file_cs
);
8242 LIST_FOR_EACH_ENTRY(item
, &async_create_file_results
, struct async_create_file_result
, entry
)
8244 if (result
== item
->result
)
8246 *stream
= item
->stream
;
8247 IRtwqAsyncResult_Release(item
->result
);
8248 list_remove(&item
->entry
);
8254 LeaveCriticalSection(&async_create_file_cs
);
8257 hr
= IRtwqAsyncResult_GetStatus(result
);
8259 IRtwqAsyncResult_Release(result
);
8264 /***********************************************************************
8265 * MFEndCreateFile (mfplat.@)
8267 HRESULT WINAPI
MFEndCreateFile(IMFAsyncResult
*result
, IMFByteStream
**stream
)
8269 TRACE("%p, %p.\n", result
, stream
);
8271 return async_create_file_pull_result((IUnknown
*)result
, stream
);
8274 /***********************************************************************
8275 * MFCancelCreateFile (mfplat.@)
8277 HRESULT WINAPI
MFCancelCreateFile(IUnknown
*cancel_cookie
)
8279 IMFByteStream
*stream
= NULL
;
8282 TRACE("%p.\n", cancel_cookie
);
8284 hr
= async_create_file_pull_result(cancel_cookie
, &stream
);
8287 IMFByteStream_Release(stream
);
8292 /***********************************************************************
8293 * MFRegisterLocalSchemeHandler (mfplat.@)
8295 HRESULT WINAPI
MFRegisterLocalSchemeHandler(const WCHAR
*scheme
, IMFActivate
*activate
)
8297 struct local_handler
*handler
;
8300 TRACE("%s, %p.\n", debugstr_w(scheme
), activate
);
8302 if (!scheme
|| !activate
)
8303 return E_INVALIDARG
;
8305 if (!(handler
= heap_alloc(sizeof(*handler
))))
8306 return E_OUTOFMEMORY
;
8308 if (FAILED(hr
= heap_strdupW(scheme
, &handler
->u
.scheme
)))
8313 handler
->activate
= activate
;
8314 IMFActivate_AddRef(handler
->activate
);
8316 EnterCriticalSection(&local_handlers_section
);
8317 list_add_head(&local_scheme_handlers
, &handler
->entry
);
8318 LeaveCriticalSection(&local_handlers_section
);
8323 /***********************************************************************
8324 * MFRegisterLocalByteStreamHandler (mfplat.@)
8326 HRESULT WINAPI
MFRegisterLocalByteStreamHandler(const WCHAR
*extension
, const WCHAR
*mime
, IMFActivate
*activate
)
8328 struct local_handler
*handler
;
8331 TRACE("%s, %s, %p.\n", debugstr_w(extension
), debugstr_w(mime
), activate
);
8333 if ((!extension
&& !mime
) || !activate
)
8334 return E_INVALIDARG
;
8336 if (!(handler
= heap_alloc_zero(sizeof(*handler
))))
8337 return E_OUTOFMEMORY
;
8339 hr
= heap_strdupW(extension
, &handler
->u
.bytestream
.extension
);
8341 hr
= heap_strdupW(mime
, &handler
->u
.bytestream
.mime
);
8346 EnterCriticalSection(&local_handlers_section
);
8347 list_add_head(&local_bytestream_handlers
, &handler
->entry
);
8348 LeaveCriticalSection(&local_handlers_section
);
8353 heap_free(handler
->u
.bytestream
.extension
);
8354 heap_free(handler
->u
.bytestream
.mime
);
8360 struct property_store
8362 IPropertyStore IPropertyStore_iface
;
8364 CRITICAL_SECTION cs
;
8365 size_t count
, capacity
;
8373 static struct property_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
8375 return CONTAINING_RECORD(iface
, struct property_store
, IPropertyStore_iface
);
8378 static HRESULT WINAPI
property_store_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
8380 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8382 if (IsEqualIID(riid
, &IID_IPropertyStore
) || IsEqualIID(riid
, &IID_IUnknown
))
8385 IPropertyStore_AddRef(iface
);
8390 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
8391 return E_NOINTERFACE
;
8394 static ULONG WINAPI
property_store_AddRef(IPropertyStore
*iface
)
8396 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8397 ULONG refcount
= InterlockedIncrement(&store
->refcount
);
8399 TRACE("%p, refcount %d.\n", iface
, refcount
);
8404 static ULONG WINAPI
property_store_Release(IPropertyStore
*iface
)
8406 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8407 ULONG refcount
= InterlockedDecrement(&store
->refcount
);
8409 TRACE("%p, refcount %d.\n", iface
, refcount
);
8413 DeleteCriticalSection(&store
->cs
);
8414 heap_free(store
->values
);
8421 static HRESULT WINAPI
property_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
8423 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8425 TRACE("%p, %p.\n", iface
, count
);
8428 return E_INVALIDARG
;
8430 EnterCriticalSection(&store
->cs
);
8431 *count
= store
->count
;
8432 LeaveCriticalSection(&store
->cs
);
8436 static HRESULT WINAPI
property_store_GetAt(IPropertyStore
*iface
, DWORD index
, PROPERTYKEY
*key
)
8438 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8440 TRACE("%p, %u, %p.\n", iface
, index
, key
);
8442 EnterCriticalSection(&store
->cs
);
8444 if (index
>= store
->count
)
8446 LeaveCriticalSection(&store
->cs
);
8447 return E_INVALIDARG
;
8450 *key
= store
->values
[index
].key
;
8452 LeaveCriticalSection(&store
->cs
);
8456 static HRESULT WINAPI
property_store_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
8458 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8461 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8464 return E_INVALIDARG
;
8469 EnterCriticalSection(&store
->cs
);
8471 for (i
= 0; i
< store
->count
; ++i
)
8473 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8475 PropVariantCopy(value
, &store
->values
[i
].value
);
8476 LeaveCriticalSection(&store
->cs
);
8481 LeaveCriticalSection(&store
->cs
);
8485 static HRESULT WINAPI
property_store_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
8487 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8490 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8492 EnterCriticalSection(&store
->cs
);
8494 for (i
= 0; i
< store
->count
; ++i
)
8496 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8498 PropVariantCopy(&store
->values
[i
].value
, value
);
8499 LeaveCriticalSection(&store
->cs
);
8504 if (!mf_array_reserve((void **)&store
->values
, &store
->capacity
, store
->count
+ 1, sizeof(*store
->values
)))
8506 LeaveCriticalSection(&store
->cs
);
8507 return E_OUTOFMEMORY
;
8510 store
->values
[store
->count
].key
= *key
;
8511 PropVariantCopy(&store
->values
[store
->count
].value
, value
);
8514 LeaveCriticalSection(&store
->cs
);
8518 static HRESULT WINAPI
property_store_Commit(IPropertyStore
*iface
)
8520 TRACE("%p.\n", iface
);
8525 static const IPropertyStoreVtbl property_store_vtbl
=
8527 property_store_QueryInterface
,
8528 property_store_AddRef
,
8529 property_store_Release
,
8530 property_store_GetCount
,
8531 property_store_GetAt
,
8532 property_store_GetValue
,
8533 property_store_SetValue
,
8534 property_store_Commit
,
8537 /***********************************************************************
8538 * CreatePropertyStore (mfplat.@)
8540 HRESULT WINAPI
CreatePropertyStore(IPropertyStore
**store
)
8542 struct property_store
*object
;
8544 TRACE("%p.\n", store
);
8547 return E_INVALIDARG
;
8549 if (!(object
= heap_alloc_zero(sizeof(*object
))))
8550 return E_OUTOFMEMORY
;
8552 object
->IPropertyStore_iface
.lpVtbl
= &property_store_vtbl
;
8553 object
->refcount
= 1;
8554 InitializeCriticalSection(&object
->cs
);
8556 TRACE("Created store %p.\n", object
);
8557 *store
= &object
->IPropertyStore_iface
;
8562 enum dxgi_device_handle_flags
8564 DXGI_DEVICE_HANDLE_FLAG_OPEN
= 0x1,
8565 DXGI_DEVICE_HANDLE_FLAG_INVALID
= 0x2,
8566 DXGI_DEVICE_HANDLE_FLAG_LOCKED
= 0x4,
8569 struct dxgi_device_manager
8571 IMFDXGIDeviceManager IMFDXGIDeviceManager_iface
;
8574 IDXGIDevice
*device
;
8576 unsigned int *handles
;
8581 unsigned int locking_tid
;
8583 CRITICAL_SECTION cs
;
8584 CONDITION_VARIABLE lock
;
8587 static struct dxgi_device_manager
*impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager
*iface
)
8589 return CONTAINING_RECORD(iface
, struct dxgi_device_manager
, IMFDXGIDeviceManager_iface
);
8592 static HRESULT
dxgi_device_manager_get_handle_index(struct dxgi_device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
8594 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
8596 *idx
= (ULONG_PTR
)hdevice
- 1;
8600 static HRESULT WINAPI
dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager
*iface
, REFIID riid
, void **obj
)
8602 TRACE("(%p, %s, %p).\n", iface
, debugstr_guid(riid
), obj
);
8604 if (IsEqualIID(riid
, &IID_IMFDXGIDeviceManager
) ||
8605 IsEqualGUID(riid
, &IID_IUnknown
))
8608 IMFDXGIDeviceManager_AddRef(iface
);
8612 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8614 return E_NOINTERFACE
;
8617 static ULONG WINAPI
dxgi_device_manager_AddRef(IMFDXGIDeviceManager
*iface
)
8619 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8620 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
8622 TRACE("(%p) ref=%u.\n", iface
, refcount
);
8627 static ULONG WINAPI
dxgi_device_manager_Release(IMFDXGIDeviceManager
*iface
)
8629 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8630 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
8632 TRACE("(%p) ref=%u.\n", iface
, refcount
);
8636 if (manager
->device
)
8637 IDXGIDevice_Release(manager
->device
);
8638 DeleteCriticalSection(&manager
->cs
);
8639 heap_free(manager
->handles
);
8646 static void dxgi_device_manager_lock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8648 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
)
8651 manager
->handles
[idx
] |= DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8655 static void dxgi_device_manager_unlock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8657 if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
))
8660 manager
->handles
[idx
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8661 if (!--manager
->locks
)
8662 manager
->locking_tid
= 0;
8665 static HRESULT WINAPI
dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8667 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8671 TRACE("%p, %p.\n", iface
, hdevice
);
8673 EnterCriticalSection(&manager
->cs
);
8675 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8677 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8679 dxgi_device_manager_unlock_handle(manager
, idx
);
8680 manager
->handles
[idx
] = 0;
8681 if (idx
== manager
->count
- 1)
8688 LeaveCriticalSection(&manager
->cs
);
8690 WakeAllConditionVariable(&manager
->lock
);
8695 static HRESULT WINAPI
dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8696 REFIID riid
, void **service
)
8698 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8702 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), service
);
8704 EnterCriticalSection(&manager
->cs
);
8706 if (!manager
->device
)
8707 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8708 else if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8710 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8711 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8712 else if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8713 hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, service
);
8718 LeaveCriticalSection(&manager
->cs
);
8723 static HRESULT WINAPI
dxgi_device_manager_LockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8724 REFIID riid
, void **obj
, BOOL block
)
8726 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8730 TRACE("%p, %p, %s, %p, %d.\n", iface
, hdevice
, wine_dbgstr_guid(riid
), obj
, block
);
8732 EnterCriticalSection(&manager
->cs
);
8734 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8736 if (!manager
->device
)
8738 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8740 else if (manager
->locking_tid
== GetCurrentThreadId())
8742 if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8743 dxgi_device_manager_lock_handle(manager
, idx
);
8745 else if (manager
->locking_tid
&& !block
)
8747 hr
= MF_E_DXGI_VIDEO_DEVICE_LOCKED
;
8751 while (manager
->locking_tid
)
8753 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
8756 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8758 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8759 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8760 else if (SUCCEEDED(hr
= IDXGIDevice_QueryInterface(manager
->device
, riid
, obj
)))
8762 manager
->locking_tid
= GetCurrentThreadId();
8763 dxgi_device_manager_lock_handle(manager
, idx
);
8769 LeaveCriticalSection(&manager
->cs
);
8774 static HRESULT WINAPI
dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE
*hdevice
)
8776 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8780 TRACE("%p, %p.\n", iface
, hdevice
);
8784 EnterCriticalSection(&manager
->cs
);
8786 if (!manager
->device
)
8787 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8790 for (i
= 0; i
< manager
->count
; ++i
)
8792 if (!(manager
->handles
[i
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8794 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8795 *hdevice
= ULongToHandle(i
+ 1);
8800 if (mf_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
8801 sizeof(*manager
->handles
)))
8803 *hdevice
= ULongToHandle(manager
->count
+ 1);
8804 manager
->handles
[manager
->count
++] = DXGI_DEVICE_HANDLE_FLAG_OPEN
;
8810 LeaveCriticalSection(&manager
->cs
);
8815 static HRESULT WINAPI
dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager
*iface
, IUnknown
*device
, UINT token
)
8817 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8818 IDXGIDevice
*dxgi_device
;
8821 TRACE("%p, %p, %u.\n", iface
, device
, token
);
8823 if (!device
|| token
!= manager
->token
)
8824 return E_INVALIDARG
;
8826 if (FAILED(IUnknown_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
)))
8827 return E_INVALIDARG
;
8829 EnterCriticalSection(&manager
->cs
);
8831 if (manager
->device
)
8833 for (i
= 0; i
< manager
->count
; ++i
)
8835 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_INVALID
;
8836 manager
->handles
[i
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8838 manager
->locking_tid
= 0;
8840 IDXGIDevice_Release(manager
->device
);
8842 manager
->device
= dxgi_device
;
8844 LeaveCriticalSection(&manager
->cs
);
8846 WakeAllConditionVariable(&manager
->lock
);
8851 static HRESULT WINAPI
dxgi_device_manager_TestDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8853 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8857 TRACE("%p, %p.\n", iface
, hdevice
);
8859 EnterCriticalSection(&manager
->cs
);
8861 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8863 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8864 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
8865 else if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
8869 LeaveCriticalSection(&manager
->cs
);
8874 static HRESULT WINAPI
dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8877 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8878 HRESULT hr
= E_FAIL
;
8881 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
8883 EnterCriticalSection(&manager
->cs
);
8885 if (SUCCEEDED(dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8887 hr
= manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
? S_OK
: E_INVALIDARG
;
8889 dxgi_device_manager_unlock_handle(manager
, idx
);
8892 LeaveCriticalSection(&manager
->cs
);
8894 WakeAllConditionVariable(&manager
->lock
);
8899 static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl
=
8901 dxgi_device_manager_QueryInterface
,
8902 dxgi_device_manager_AddRef
,
8903 dxgi_device_manager_Release
,
8904 dxgi_device_manager_CloseDeviceHandle
,
8905 dxgi_device_manager_GetVideoService
,
8906 dxgi_device_manager_LockDevice
,
8907 dxgi_device_manager_OpenDeviceHandle
,
8908 dxgi_device_manager_ResetDevice
,
8909 dxgi_device_manager_TestDevice
,
8910 dxgi_device_manager_UnlockDevice
,
8913 HRESULT WINAPI
MFCreateDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
8915 struct dxgi_device_manager
*object
;
8917 TRACE("%p, %p.\n", token
, manager
);
8919 if (!token
|| !manager
)
8922 if (!(object
= heap_alloc_zero(sizeof(*object
))))
8923 return E_OUTOFMEMORY
;
8925 object
->IMFDXGIDeviceManager_iface
.lpVtbl
= &dxgi_device_manager_vtbl
;
8926 object
->refcount
= 1;
8927 object
->token
= GetTickCount();
8928 InitializeCriticalSection(&object
->cs
);
8929 InitializeConditionVariable(&object
->lock
);
8931 TRACE("Created device manager: %p, token: %u.\n", object
, object
->token
);
8933 *token
= object
->token
;
8934 *manager
= &object
->IMFDXGIDeviceManager_iface
;