2 * Copyright 2014 Austin English
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSUNION
39 #include "wine/list.h"
41 #include "mfplat_private.h"
42 #include "mfreadwrite.h"
43 #include "mfmediaengine.h"
44 #include "propvarutil.h"
48 /* mfd3d12 guids are not included in mfuuid */
51 #define EXTERN_GUID DEFINE_GUID
58 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
72 IMFActivate
*activate
;
75 static CRITICAL_SECTION local_handlers_section
= { NULL
, -1, 0, 0, 0, 0 };
77 static struct list local_scheme_handlers
= LIST_INIT(local_scheme_handlers
);
78 static struct list local_bytestream_handlers
= LIST_INIT(local_bytestream_handlers
);
80 struct mft_registration
83 IClassFactory
*factory
;
88 MFT_REGISTER_TYPE_INFO
*input_types
;
89 UINT32 input_types_count
;
90 MFT_REGISTER_TYPE_INFO
*output_types
;
91 UINT32 output_types_count
;
95 static const char *debugstr_reg_typeinfo(const MFT_REGISTER_TYPE_INFO
*info
)
97 return info
? wine_dbg_sprintf("%p{%s,%s}", info
, debugstr_mf_guid(&info
->guidMajorType
),
98 debugstr_mf_guid(&info
->guidSubtype
)) : wine_dbg_sprintf("%p", info
);
101 static CRITICAL_SECTION local_mfts_section
= { NULL
, -1, 0, 0, 0, 0 };
103 static struct list local_mfts
= LIST_INIT(local_mfts
);
105 struct transform_activate
107 struct attributes attributes
;
108 IMFActivate IMFActivate_iface
;
109 IClassFactory
*factory
;
110 IMFTransform
*transform
;
115 IMFClock IMFClock_iface
;
119 struct system_time_source
121 IMFPresentationTimeSource IMFPresentationTimeSource_iface
;
122 IMFClockStateSink IMFClockStateSink_iface
;
126 LONGLONG start_offset
;
127 LONGLONG system_time
;
134 static void system_time_source_update_clock_time(struct system_time_source
*source
, LONGLONG system_time
)
136 LONGLONG diff
= system_time
- source
->system_time
;
137 if (source
->i_rate
) diff
*= source
->i_rate
;
138 else if (source
->rate
!= 1.0f
) diff
*= source
->rate
;
139 source
->clock_time
+= diff
;
140 source
->system_time
= system_time
;
143 static struct system_time_source
*impl_from_IMFPresentationTimeSource(IMFPresentationTimeSource
*iface
)
145 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFPresentationTimeSource_iface
);
148 static struct system_time_source
*impl_from_IMFClockStateSink(IMFClockStateSink
*iface
)
150 return CONTAINING_RECORD(iface
, struct system_time_source
, IMFClockStateSink_iface
);
153 static struct system_clock
*impl_from_IMFClock(IMFClock
*iface
)
155 return CONTAINING_RECORD(iface
, struct system_clock
, IMFClock_iface
);
158 static struct transform_activate
*impl_from_IMFActivate(IMFActivate
*iface
)
160 return CONTAINING_RECORD(iface
, struct transform_activate
, IMFActivate_iface
);
163 static HRESULT WINAPI
transform_activate_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **out
)
165 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
167 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
168 IsEqualIID(riid
, &IID_IMFAttributes
) ||
169 IsEqualIID(riid
, &IID_IUnknown
))
172 IMFActivate_AddRef(iface
);
176 WARN("Unsupported %s.\n", debugstr_guid(riid
));
178 return E_NOINTERFACE
;
181 static ULONG WINAPI
transform_activate_AddRef(IMFActivate
*iface
)
183 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
184 ULONG refcount
= InterlockedIncrement(&activate
->attributes
.ref
);
186 TRACE("%p, refcount %lu.\n", iface
, refcount
);
191 static ULONG WINAPI
transform_activate_Release(IMFActivate
*iface
)
193 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
194 ULONG refcount
= InterlockedDecrement(&activate
->attributes
.ref
);
196 TRACE("%p, refcount %lu.\n", iface
, refcount
);
200 clear_attributes_object(&activate
->attributes
);
201 if (activate
->factory
)
202 IClassFactory_Release(activate
->factory
);
203 if (activate
->transform
)
204 IMFTransform_Release(activate
->transform
);
211 static HRESULT WINAPI
transform_activate_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
213 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
215 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
217 return attributes_GetItem(&activate
->attributes
, key
, value
);
220 static HRESULT WINAPI
transform_activate_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
222 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
224 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
226 return attributes_GetItemType(&activate
->attributes
, key
, type
);
229 static HRESULT WINAPI
transform_activate_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
,
232 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
234 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
236 return attributes_CompareItem(&activate
->attributes
, key
, value
, result
);
239 static HRESULT WINAPI
transform_activate_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
,
240 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
242 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
244 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
246 return attributes_Compare(&activate
->attributes
, theirs
, match_type
, ret
);
249 static HRESULT WINAPI
transform_activate_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
251 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
253 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
255 return attributes_GetUINT32(&activate
->attributes
, key
, value
);
258 static HRESULT WINAPI
transform_activate_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
260 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
262 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
264 return attributes_GetUINT64(&activate
->attributes
, key
, value
);
267 static HRESULT WINAPI
transform_activate_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
269 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
271 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
273 return attributes_GetDouble(&activate
->attributes
, key
, value
);
276 static HRESULT WINAPI
transform_activate_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
278 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
280 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
282 return attributes_GetGUID(&activate
->attributes
, key
, value
);
285 static HRESULT WINAPI
transform_activate_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
287 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
289 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
291 return attributes_GetStringLength(&activate
->attributes
, key
, length
);
294 static HRESULT WINAPI
transform_activate_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
295 UINT32 size
, UINT32
*length
)
297 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
299 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
301 return attributes_GetString(&activate
->attributes
, key
, value
, size
, length
);
304 static HRESULT WINAPI
transform_activate_GetAllocatedString(IMFActivate
*iface
, REFGUID key
, WCHAR
**value
,
307 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
309 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
311 return attributes_GetAllocatedString(&activate
->attributes
, key
, value
, length
);
314 static HRESULT WINAPI
transform_activate_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
316 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
318 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
320 return attributes_GetBlobSize(&activate
->attributes
, key
, size
);
323 static HRESULT WINAPI
transform_activate_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
,
326 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
328 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
330 return attributes_GetBlob(&activate
->attributes
, key
, buf
, bufsize
, blobsize
);
333 static HRESULT WINAPI
transform_activate_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
335 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
337 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
339 return attributes_GetAllocatedBlob(&activate
->attributes
, key
, buf
, size
);
342 static HRESULT WINAPI
transform_activate_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **out
)
344 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
346 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
348 return attributes_GetUnknown(&activate
->attributes
, key
, riid
, out
);
351 static HRESULT WINAPI
transform_activate_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
353 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
355 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
357 return attributes_SetItem(&activate
->attributes
, key
, value
);
360 static HRESULT WINAPI
transform_activate_DeleteItem(IMFActivate
*iface
, REFGUID key
)
362 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
364 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
366 return attributes_DeleteItem(&activate
->attributes
, key
);
369 static HRESULT WINAPI
transform_activate_DeleteAllItems(IMFActivate
*iface
)
371 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
373 TRACE("%p.\n", iface
);
375 return attributes_DeleteAllItems(&activate
->attributes
);
378 static HRESULT WINAPI
transform_activate_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
380 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
382 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
384 return attributes_SetUINT32(&activate
->attributes
, key
, value
);
387 static HRESULT WINAPI
transform_activate_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
389 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
391 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
393 return attributes_SetUINT64(&activate
->attributes
, key
, value
);
396 static HRESULT WINAPI
transform_activate_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
398 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
400 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
402 return attributes_SetDouble(&activate
->attributes
, key
, value
);
405 static HRESULT WINAPI
transform_activate_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
407 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
409 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
411 return attributes_SetGUID(&activate
->attributes
, key
, value
);
414 static HRESULT WINAPI
transform_activate_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
416 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
418 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
420 return attributes_SetString(&activate
->attributes
, key
, value
);
423 static HRESULT WINAPI
transform_activate_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
425 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
427 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
429 return attributes_SetBlob(&activate
->attributes
, key
, buf
, size
);
432 static HRESULT WINAPI
transform_activate_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
434 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
436 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
438 return attributes_SetUnknown(&activate
->attributes
, key
, unknown
);
441 static HRESULT WINAPI
transform_activate_LockStore(IMFActivate
*iface
)
443 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
445 TRACE("%p.\n", iface
);
447 return attributes_LockStore(&activate
->attributes
);
450 static HRESULT WINAPI
transform_activate_UnlockStore(IMFActivate
*iface
)
452 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
454 TRACE("%p.\n", iface
);
456 return attributes_UnlockStore(&activate
->attributes
);
459 static HRESULT WINAPI
transform_activate_GetCount(IMFActivate
*iface
, UINT32
*count
)
461 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
463 TRACE("%p, %p.\n", iface
, count
);
465 return attributes_GetCount(&activate
->attributes
, count
);
468 static HRESULT WINAPI
transform_activate_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
,
471 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
473 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
475 return attributes_GetItemByIndex(&activate
->attributes
, index
, key
, value
);
478 static HRESULT WINAPI
transform_activate_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
480 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
482 TRACE("%p, %p.\n", iface
, dest
);
484 return attributes_CopyAllItems(&activate
->attributes
, dest
);
487 static HRESULT WINAPI
transform_activate_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
489 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
493 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
495 EnterCriticalSection(&activate
->attributes
.cs
);
497 if (!activate
->transform
)
499 if (activate
->factory
)
501 if (FAILED(hr
= IClassFactory_CreateInstance(activate
->factory
, NULL
, &IID_IMFTransform
,
502 (void **)&activate
->transform
)))
504 hr
= MF_E_INVALIDREQUEST
;
509 if (SUCCEEDED(hr
= attributes_GetGUID(&activate
->attributes
, &MFT_TRANSFORM_CLSID_Attribute
, &clsid
)))
511 if (FAILED(hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
512 (void **)&activate
->transform
)))
514 hr
= MF_E_INVALIDREQUEST
;
520 if (activate
->transform
)
521 hr
= IMFTransform_QueryInterface(activate
->transform
, riid
, obj
);
523 LeaveCriticalSection(&activate
->attributes
.cs
);
528 static HRESULT WINAPI
transform_activate_ShutdownObject(IMFActivate
*iface
)
530 struct transform_activate
*activate
= impl_from_IMFActivate(iface
);
532 TRACE("%p.\n", iface
);
534 EnterCriticalSection(&activate
->attributes
.cs
);
536 if (activate
->transform
)
538 IMFTransform_Release(activate
->transform
);
539 activate
->transform
= NULL
;
542 LeaveCriticalSection(&activate
->attributes
.cs
);
547 static HRESULT WINAPI
transform_activate_DetachObject(IMFActivate
*iface
)
549 TRACE("%p.\n", iface
);
554 static const IMFActivateVtbl transform_activate_vtbl
=
556 transform_activate_QueryInterface
,
557 transform_activate_AddRef
,
558 transform_activate_Release
,
559 transform_activate_GetItem
,
560 transform_activate_GetItemType
,
561 transform_activate_CompareItem
,
562 transform_activate_Compare
,
563 transform_activate_GetUINT32
,
564 transform_activate_GetUINT64
,
565 transform_activate_GetDouble
,
566 transform_activate_GetGUID
,
567 transform_activate_GetStringLength
,
568 transform_activate_GetString
,
569 transform_activate_GetAllocatedString
,
570 transform_activate_GetBlobSize
,
571 transform_activate_GetBlob
,
572 transform_activate_GetAllocatedBlob
,
573 transform_activate_GetUnknown
,
574 transform_activate_SetItem
,
575 transform_activate_DeleteItem
,
576 transform_activate_DeleteAllItems
,
577 transform_activate_SetUINT32
,
578 transform_activate_SetUINT64
,
579 transform_activate_SetDouble
,
580 transform_activate_SetGUID
,
581 transform_activate_SetString
,
582 transform_activate_SetBlob
,
583 transform_activate_SetUnknown
,
584 transform_activate_LockStore
,
585 transform_activate_UnlockStore
,
586 transform_activate_GetCount
,
587 transform_activate_GetItemByIndex
,
588 transform_activate_CopyAllItems
,
589 transform_activate_ActivateObject
,
590 transform_activate_ShutdownObject
,
591 transform_activate_DetachObject
,
594 static HRESULT
create_transform_activate(IClassFactory
*factory
, IMFActivate
**activate
)
596 struct transform_activate
*object
;
599 if (!(object
= calloc(1, sizeof(*object
))))
600 return E_OUTOFMEMORY
;
602 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
608 object
->IMFActivate_iface
.lpVtbl
= &transform_activate_vtbl
;
609 object
->factory
= factory
;
611 IClassFactory_AddRef(object
->factory
);
613 *activate
= &object
->IMFActivate_iface
;
618 HRESULT WINAPI
MFCreateTransformActivate(IMFActivate
**activate
)
620 TRACE("%p.\n", activate
);
622 return create_transform_activate(NULL
, activate
);
625 static const WCHAR transform_keyW
[] = L
"MediaFoundation\\Transforms";
626 static const WCHAR categories_keyW
[] = L
"MediaFoundation\\Transforms\\Categories";
628 static const BYTE guid_conv_table
[256] =
630 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
631 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
632 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
633 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
634 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
636 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
639 static WCHAR
* guid_to_string(WCHAR
*str
, REFGUID guid
)
641 swprintf(str
, 39, L
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
642 guid
->Data1
, guid
->Data2
, guid
->Data3
, guid
->Data4
[0], guid
->Data4
[1],
643 guid
->Data4
[2], guid
->Data4
[3], guid
->Data4
[4], guid
->Data4
[5],
644 guid
->Data4
[6], guid
->Data4
[7]);
649 static inline BOOL
is_valid_hex(WCHAR c
)
651 if (!(((c
>= '0') && (c
<= '9')) ||
652 ((c
>= 'a') && (c
<= 'f')) ||
653 ((c
>= 'A') && (c
<= 'F'))))
658 static BOOL
GUIDFromString(LPCWSTR s
, GUID
*id
)
662 /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
665 for (i
= 0; i
< 8; i
++)
667 if (!is_valid_hex(s
[i
])) return FALSE
;
668 id
->Data1
= (id
->Data1
<< 4) | guid_conv_table
[s
[i
]];
670 if (s
[8]!='-') return FALSE
;
673 for (i
= 9; i
< 13; i
++)
675 if (!is_valid_hex(s
[i
])) return FALSE
;
676 id
->Data2
= (id
->Data2
<< 4) | guid_conv_table
[s
[i
]];
678 if (s
[13]!='-') return FALSE
;
681 for (i
= 14; i
< 18; i
++)
683 if (!is_valid_hex(s
[i
])) return FALSE
;
684 id
->Data3
= (id
->Data3
<< 4) | guid_conv_table
[s
[i
]];
686 if (s
[18]!='-') return FALSE
;
688 for (i
= 19; i
< 36; i
+=2)
692 if (s
[i
]!='-') return FALSE
;
695 if (!is_valid_hex(s
[i
]) || !is_valid_hex(s
[i
+1])) return FALSE
;
696 id
->Data4
[(i
-19)/2] = guid_conv_table
[s
[i
]] << 4 | guid_conv_table
[s
[i
+1]];
699 if (!s
[36]) return TRUE
;
703 static HRESULT
register_transform(const CLSID
*clsid
, const WCHAR
*name
, UINT32 flags
,
704 UINT32 cinput
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
705 const MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
715 guid_to_string(buffer
, clsid
);
716 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s", transform_keyW
, buffer
);
718 if ((ret
= RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &hclsid
)))
719 hr
= HRESULT_FROM_WIN32(ret
);
723 size
= (lstrlenW(name
) + 1) * sizeof(WCHAR
);
724 if ((ret
= RegSetValueExW(hclsid
, NULL
, 0, REG_SZ
, (BYTE
*)name
, size
)))
725 hr
= HRESULT_FROM_WIN32(ret
);
728 if (SUCCEEDED(hr
) && cinput
&& input_types
)
730 size
= cinput
* sizeof(MFT_REGISTER_TYPE_INFO
);
731 if ((ret
= RegSetValueExW(hclsid
, L
"InputTypes", 0, REG_BINARY
, (BYTE
*)input_types
, size
)))
732 hr
= HRESULT_FROM_WIN32(ret
);
735 if (SUCCEEDED(hr
) && coutput
&& output_types
)
737 size
= coutput
* sizeof(MFT_REGISTER_TYPE_INFO
);
738 if ((ret
= RegSetValueExW(hclsid
, L
"OutputTypes", 0, REG_BINARY
, (BYTE
*)output_types
, size
)))
739 hr
= HRESULT_FROM_WIN32(ret
);
742 if (SUCCEEDED(hr
) && attributes
)
744 if (SUCCEEDED(hr
= MFGetAttributesAsBlobSize(attributes
, &size
)))
746 if ((blob
= malloc(size
)))
748 if (SUCCEEDED(hr
= MFGetAttributesAsBlob(attributes
, blob
, size
)))
750 if ((ret
= RegSetValueExW(hclsid
, L
"Attributes", 0, REG_BINARY
, blob
, size
)))
751 hr
= HRESULT_FROM_WIN32(ret
);
760 if (SUCCEEDED(hr
) && flags
)
762 if ((ret
= RegSetValueExW(hclsid
, L
"MFTFlags", 0, REG_DWORD
, (BYTE
*)&flags
, sizeof(flags
))))
763 hr
= HRESULT_FROM_WIN32(ret
);
770 static HRESULT
register_category(CLSID
*clsid
, GUID
*category
)
773 WCHAR guid1
[64], guid2
[64];
776 guid_to_string(guid1
, category
);
777 guid_to_string(guid2
, clsid
);
779 swprintf(str
, ARRAY_SIZE(str
), L
"%s\\%s\\%s", categories_keyW
, guid1
, guid2
);
781 if (RegCreateKeyW(HKEY_CLASSES_ROOT
, str
, &htmp1
))
788 /***********************************************************************
789 * MFTRegister (mfplat.@)
791 HRESULT WINAPI
MFTRegister(CLSID clsid
, GUID category
, LPWSTR name
, UINT32 flags
, UINT32 cinput
,
792 MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 coutput
,
793 MFT_REGISTER_TYPE_INFO
*output_types
, IMFAttributes
*attributes
)
797 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p, %p.\n", debugstr_guid(&clsid
), debugstr_guid(&category
),
798 debugstr_w(name
), flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
800 hr
= register_transform(&clsid
, name
, flags
, cinput
, input_types
, coutput
, output_types
, attributes
);
802 ERR("Failed to write register transform\n");
805 hr
= register_category(&clsid
, &category
);
810 static void release_mft_registration(struct mft_registration
*mft
)
813 IClassFactory_Release(mft
->factory
);
815 free(mft
->input_types
);
816 free(mft
->output_types
);
820 static HRESULT
mft_register_local(IClassFactory
*factory
, REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
821 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
822 const MFT_REGISTER_TYPE_INFO
*output_types
)
824 struct mft_registration
*mft
, *cur
, *unreg_mft
= NULL
;
827 if (!factory
&& !clsid
)
829 WARN("Can't register without factory or CLSID.\n");
833 if (!(mft
= calloc(1, sizeof(*mft
))))
834 return E_OUTOFMEMORY
;
836 mft
->factory
= factory
;
838 IClassFactory_AddRef(mft
->factory
);
841 mft
->category
= *category
;
842 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
843 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
846 if (name
&& !(mft
->name
= wcsdup(name
)))
852 if (input_count
&& input_types
)
854 mft
->input_types_count
= input_count
;
855 if (!(mft
->input_types
= calloc(mft
->input_types_count
, sizeof(*input_types
))))
860 memcpy(mft
->input_types
, input_types
, mft
->input_types_count
* sizeof(*input_types
));
863 if (output_count
&& output_types
)
865 mft
->output_types_count
= output_count
;
866 if (!(mft
->output_types
= calloc(mft
->output_types_count
, sizeof(*output_types
))))
871 memcpy(mft
->output_types
, output_types
, mft
->output_types_count
* sizeof(*output_types
));
874 EnterCriticalSection(&local_mfts_section
);
876 LIST_FOR_EACH_ENTRY(cur
, &local_mfts
, struct mft_registration
, entry
)
878 if (cur
->factory
== factory
)
881 list_remove(&cur
->entry
);
885 list_add_tail(&local_mfts
, &mft
->entry
);
887 LeaveCriticalSection(&local_mfts_section
);
890 release_mft_registration(unreg_mft
);
894 release_mft_registration(mft
);
899 HRESULT WINAPI
MFTRegisterLocal(IClassFactory
*factory
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
900 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
901 const MFT_REGISTER_TYPE_INFO
*output_types
)
903 TRACE("%p, %s, %s, %#x, %u, %p, %u, %p.\n", factory
, debugstr_guid(category
), debugstr_w(name
), flags
, input_count
,
904 input_types
, output_count
, output_types
);
906 return mft_register_local(factory
, NULL
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
909 HRESULT WINAPI
MFTRegisterLocalByCLSID(REFCLSID clsid
, REFGUID category
, LPCWSTR name
, UINT32 flags
,
910 UINT32 input_count
, const MFT_REGISTER_TYPE_INFO
*input_types
, UINT32 output_count
,
911 const MFT_REGISTER_TYPE_INFO
*output_types
)
913 TRACE("%s, %s, %s, %#x, %u, %p, %u, %p.\n", debugstr_guid(clsid
), debugstr_guid(category
), debugstr_w(name
), flags
,
914 input_count
, input_types
, output_count
, output_types
);
916 return mft_register_local(NULL
, clsid
, category
, name
, flags
, input_count
, input_types
, output_count
, output_types
);
919 static HRESULT
mft_unregister_local(IClassFactory
*factory
, REFCLSID clsid
)
921 struct mft_registration
*cur
, *cur2
;
922 BOOL unregister_all
= !factory
&& !clsid
;
927 EnterCriticalSection(&local_mfts_section
);
929 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &local_mfts
, struct mft_registration
, entry
)
933 if ((factory
&& cur
->factory
== factory
) || IsEqualCLSID(&cur
->clsid
, clsid
))
935 list_remove(&cur
->entry
);
936 list_add_tail(&unreg
, &cur
->entry
);
942 list_remove(&cur
->entry
);
943 list_add_tail(&unreg
, &cur
->entry
);
947 LeaveCriticalSection(&local_mfts_section
);
949 if (!unregister_all
&& list_empty(&unreg
))
950 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND
);
952 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &unreg
, struct mft_registration
, entry
)
954 list_remove(&cur
->entry
);
955 release_mft_registration(cur
);
961 HRESULT WINAPI
MFTUnregisterLocalByCLSID(CLSID clsid
)
963 TRACE("%s.\n", debugstr_guid(&clsid
));
965 return mft_unregister_local(NULL
, &clsid
);
968 HRESULT WINAPI
MFTUnregisterLocal(IClassFactory
*factory
)
970 TRACE("%p.\n", factory
);
972 return mft_unregister_local(factory
, NULL
);
975 MFTIME WINAPI
MFGetSystemTime(void)
979 GetSystemTimeAsFileTime( (FILETIME
*)&mf
);
984 static BOOL
mft_is_type_info_match(struct mft_registration
*mft
, const GUID
*category
, UINT32 flags
,
985 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
986 const MFT_REGISTER_TYPE_INFO
*output_type
)
988 BOOL matching
= TRUE
;
992 if (!IsEqualGUID(category
, &mft
->category
))
995 /* Default model is synchronous. */
996 model
= mft
->flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
);
998 model
= MFT_ENUM_FLAG_SYNCMFT
;
999 if (!(model
& flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1002 /* These flags should be explicitly enabled. */
1003 if (mft
->flags
& ~flags
& (MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_TRANSCODE_ONLY
))
1006 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
&& !mft
->factory
&& plugin_control
1007 && IMFPluginControl_IsDisabled(plugin_control
, MF_Plugin_Type_MFT
, &mft
->clsid
) == S_OK
)
1014 for (i
= 0, matching
= FALSE
; input_type
&& i
< mft
->input_types_count
; ++i
)
1016 if (!memcmp(&mft
->input_types
[i
], input_type
, sizeof(*input_type
)))
1024 if (output_type
&& matching
)
1026 for (i
= 0, matching
= FALSE
; i
< mft
->output_types_count
; ++i
)
1028 if (!memcmp(&mft
->output_types
[i
], output_type
, sizeof(*output_type
)))
1039 static void mft_get_reg_type_info_internal(const WCHAR
*clsidW
, const WCHAR
*typeW
, MFT_REGISTER_TYPE_INFO
**type
,
1042 HKEY htransform
, hfilter
;
1043 DWORD reg_type
, size
;
1048 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1051 if (RegOpenKeyW(htransform
, clsidW
, &hfilter
))
1053 RegCloseKey(htransform
);
1057 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, NULL
, &size
))
1060 if (reg_type
!= REG_BINARY
)
1063 if (!size
|| size
% sizeof(**type
))
1066 if (!(*type
= malloc(size
)))
1069 *count
= size
/ sizeof(**type
);
1071 if (RegQueryValueExW(hfilter
, typeW
, NULL
, ®_type
, (BYTE
*)*type
, &size
))
1079 RegCloseKey(hfilter
);
1080 RegCloseKey(htransform
);
1083 static void mft_get_reg_flags(const WCHAR
*clsidW
, const WCHAR
*nameW
, DWORD
*flags
)
1085 DWORD ret
, reg_type
, size
;
1090 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
))
1093 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1099 if (!RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, NULL
, &size
) && reg_type
== REG_DWORD
)
1100 RegQueryValueExW(hmft
, nameW
, NULL
, ®_type
, (BYTE
*)flags
, &size
);
1105 static HRESULT
mft_collect_machine_reg(struct list
*mfts
, const GUID
*category
, UINT32 flags
,
1106 IMFPluginControl
*plugin_control
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1107 const MFT_REGISTER_TYPE_INFO
*output_type
)
1109 struct mft_registration mft
, *cur
;
1110 HKEY hcategory
, hlist
;
1115 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1118 guid_to_string(clsidW
, category
);
1119 ret
= RegOpenKeyW(hcategory
, clsidW
, &hlist
);
1120 RegCloseKey(hcategory
);
1124 size
= ARRAY_SIZE(clsidW
);
1125 while (!RegEnumKeyExW(hlist
, index
, clsidW
, &size
, NULL
, NULL
, NULL
, NULL
))
1127 memset(&mft
, 0, sizeof(mft
));
1128 mft
.category
= *category
;
1129 if (!GUIDFromString(clsidW
, &mft
.clsid
))
1132 mft_get_reg_flags(clsidW
, L
"MFTFlags", &mft
.flags
);
1135 mft_get_reg_type_info_internal(clsidW
, L
"OutputTypes", &mft
.output_types
, &mft
.output_types_count
);
1138 mft_get_reg_type_info_internal(clsidW
, L
"InputTypes", &mft
.input_types
, &mft
.input_types_count
);
1140 if (!mft_is_type_info_match(&mft
, category
, flags
, plugin_control
, input_type
, output_type
))
1142 free(mft
.input_types
);
1143 free(mft
.output_types
);
1147 cur
= malloc(sizeof(*cur
));
1148 /* Reuse allocated type arrays. */
1150 list_add_tail(mfts
, &cur
->entry
);
1153 size
= ARRAY_SIZE(clsidW
);
1160 static BOOL
mft_is_preferred(IMFPluginControl
*plugin_control
, const CLSID
*clsid
)
1166 while (SUCCEEDED(IMFPluginControl_GetPreferredClsidByIndex(plugin_control
, MF_Plugin_Type_MFT
, index
++, &selector
,
1169 CoTaskMemFree(selector
);
1171 if (IsEqualGUID(&preferred
, clsid
))
1178 static HRESULT
mft_enum(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1179 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1181 IMFPluginControl
*plugin_control
= NULL
;
1182 struct list mfts
, mfts_sorted
, *result
= &mfts
;
1183 struct mft_registration
*mft
, *mft2
;
1184 unsigned int obj_count
;
1191 flags
= MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_SORTANDFILTER
;
1193 /* Synchronous processing is default. */
1194 if (!(flags
& (MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
)))
1195 flags
|= MFT_ENUM_FLAG_SYNCMFT
;
1197 if (FAILED(hr
= MFGetPluginControl(&plugin_control
)))
1199 WARN("Failed to get plugin control instance, hr %#lx.\n", hr
);
1205 /* Collect from registry */
1206 mft_collect_machine_reg(&mfts
, &category
, flags
, plugin_control
, input_type
, output_type
);
1208 /* Collect locally registered ones. */
1209 if (flags
& MFT_ENUM_FLAG_LOCALMFT
)
1211 struct mft_registration
*local
;
1213 EnterCriticalSection(&local_mfts_section
);
1215 LIST_FOR_EACH_ENTRY(local
, &local_mfts
, struct mft_registration
, entry
)
1217 if (mft_is_type_info_match(local
, &category
, flags
, plugin_control
, input_type
, output_type
))
1219 mft
= calloc(1, sizeof(*mft
));
1221 mft
->clsid
= local
->clsid
;
1222 mft
->factory
= local
->factory
;
1224 IClassFactory_AddRef(mft
->factory
);
1225 mft
->flags
= local
->flags
;
1226 mft
->local
= local
->local
;
1228 list_add_tail(&mfts
, &mft
->entry
);
1232 LeaveCriticalSection(&local_mfts_section
);
1235 list_init(&mfts_sorted
);
1237 if (flags
& MFT_ENUM_FLAG_SORTANDFILTER
)
1239 /* Local registrations. */
1240 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1244 list_remove(&mft
->entry
);
1245 list_add_tail(&mfts_sorted
, &mft
->entry
);
1249 /* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */
1251 /* Preferred transforms. */
1252 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1254 if (!mft
->factory
&& mft_is_preferred(plugin_control
, &mft
->clsid
))
1256 list_remove(&mft
->entry
);
1257 list_add_tail(&mfts_sorted
, &mft
->entry
);
1261 /* Append the rest. */
1262 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1264 list_remove(&mft
->entry
);
1265 list_add_tail(&mfts_sorted
, &mft
->entry
);
1268 result
= &mfts_sorted
;
1271 IMFPluginControl_Release(plugin_control
);
1273 /* Create activation objects from CLSID/IClassFactory. */
1275 obj_count
= list_count(result
);
1279 if (!(*activate
= CoTaskMemAlloc(obj_count
* sizeof(**activate
))))
1284 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, result
, struct mft_registration
, entry
)
1286 IMFActivate
*mft_activate
;
1290 if (SUCCEEDED(create_transform_activate(mft
->factory
, &mft_activate
)))
1292 (*activate
)[obj_count
] = mft_activate
;
1296 IMFActivate_SetUINT32(mft_activate
, &MFT_PROCESS_LOCAL_Attribute
, 1);
1301 IMFActivate_SetString(mft_activate
, &MFT_FRIENDLY_NAME_Attribute
, mft
->name
);
1302 if (mft
->input_types
)
1303 IMFActivate_SetBlob(mft_activate
, &MFT_INPUT_TYPES_Attributes
, (const UINT8
*)mft
->input_types
,
1304 sizeof(*mft
->input_types
) * mft
->input_types_count
);
1305 if (mft
->output_types
)
1306 IMFActivate_SetBlob(mft_activate
, &MFT_OUTPUT_TYPES_Attributes
, (const UINT8
*)mft
->output_types
,
1307 sizeof(*mft
->output_types
) * mft
->output_types_count
);
1311 IMFActivate_SetGUID(mft_activate
, &MFT_TRANSFORM_CLSID_Attribute
, &mft
->clsid
);
1313 IMFActivate_SetUINT32(mft_activate
, &MF_TRANSFORM_FLAGS_Attribute
, mft
->flags
);
1314 IMFActivate_SetGUID(mft_activate
, &MF_TRANSFORM_CATEGORY_Attribute
, &mft
->category
);
1320 list_remove(&mft
->entry
);
1321 release_mft_registration(mft
);
1327 CoTaskMemFree(*activate
);
1335 /***********************************************************************
1336 * MFTEnum (mfplat.@)
1338 HRESULT WINAPI
MFTEnum(GUID category
, UINT32 flags
, MFT_REGISTER_TYPE_INFO
*input_type
,
1339 MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, CLSID
**clsids
, UINT32
*count
)
1341 struct mft_registration
*mft
, *mft2
;
1342 unsigned int mft_count
;
1346 TRACE("%s, %#x, %s, %s, %p, %p, %p.\n", debugstr_mf_guid(&category
), flags
, debugstr_reg_typeinfo(input_type
),
1347 debugstr_reg_typeinfo(output_type
), attributes
, clsids
, count
);
1349 if (!clsids
|| !count
)
1350 return E_INVALIDARG
;
1356 if (FAILED(hr
= mft_collect_machine_reg(&mfts
, &category
, MFT_ENUM_FLAG_SYNCMFT
, NULL
, input_type
, output_type
)))
1359 mft_count
= list_count(&mfts
);
1363 if (!(*clsids
= CoTaskMemAlloc(mft_count
* sizeof(**clsids
))))
1367 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1370 (*clsids
)[mft_count
++] = mft
->clsid
;
1371 list_remove(&mft
->entry
);
1372 release_mft_registration(mft
);
1378 CoTaskMemFree(*clsids
);
1386 /***********************************************************************
1387 * MFTEnumEx (mfplat.@)
1389 HRESULT WINAPI
MFTEnumEx(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1390 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFActivate
***activate
, UINT32
*count
)
1392 TRACE("%s, %#x, %s, %s, %p, %p.\n", debugstr_mf_guid(&category
), flags
, debugstr_reg_typeinfo(input_type
),
1393 debugstr_reg_typeinfo(output_type
), activate
, count
);
1395 return mft_enum(category
, flags
, input_type
, output_type
, NULL
, activate
, count
);
1398 /***********************************************************************
1399 * MFTEnum2 (mfplat.@)
1401 HRESULT WINAPI
MFTEnum2(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1402 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1404 TRACE("%s, %#x, %s, %s, %p, %p, %p.\n", debugstr_mf_guid(&category
), flags
, debugstr_reg_typeinfo(input_type
),
1405 debugstr_reg_typeinfo(output_type
), attributes
, activate
, count
);
1408 FIXME("Ignoring attributes.\n");
1410 return mft_enum(category
, flags
, input_type
, output_type
, attributes
, activate
, count
);
1413 /***********************************************************************
1414 * MFTUnregister (mfplat.@)
1416 HRESULT WINAPI
MFTUnregister(CLSID clsid
)
1418 WCHAR buffer
[64], category
[MAX_PATH
];
1419 HKEY htransform
, hcategory
, htmp
;
1420 DWORD size
= MAX_PATH
;
1423 TRACE("(%s)\n", debugstr_guid(&clsid
));
1425 guid_to_string(buffer
, &clsid
);
1427 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1429 RegDeleteKeyW(htransform
, buffer
);
1430 RegCloseKey(htransform
);
1433 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1435 while (RegEnumKeyExW(hcategory
, index
, category
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1437 if (!RegOpenKeyW(hcategory
, category
, &htmp
))
1439 RegDeleteKeyW(htmp
, buffer
);
1445 RegCloseKey(hcategory
);
1451 static HRESULT
mft_get_name(HKEY hkey
, WCHAR
**name
)
1460 if (!RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, NULL
, &size
))
1462 if (!(*name
= CoTaskMemAlloc(size
)))
1463 return E_OUTOFMEMORY
;
1465 RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (BYTE
*)*name
, &size
);
1471 static HRESULT
mft_get_reg_type_info(const WCHAR
*clsid
, const WCHAR
*key
, MFT_REGISTER_TYPE_INFO
**ret_types
,
1474 MFT_REGISTER_TYPE_INFO
*types
= NULL
;
1480 mft_get_reg_type_info_internal(clsid
, key
, &types
, &count
);
1483 if (!(*ret_types
= CoTaskMemAlloc(count
* sizeof(**ret_types
))))
1486 return E_OUTOFMEMORY
;
1489 memcpy(*ret_types
, types
, count
* sizeof(**ret_types
));
1498 static HRESULT
mft_get_attributes(HKEY hkey
, IMFAttributes
**ret
)
1500 IMFAttributes
*attributes
;
1508 if (FAILED(hr
= MFCreateAttributes(&attributes
, 0)))
1511 if (!RegQueryValueExW(hkey
, L
"Attributes", NULL
, NULL
, NULL
, &size
) && size
)
1513 if (!(blob
= malloc(size
)))
1515 IMFAttributes_Release(attributes
);
1516 return E_OUTOFMEMORY
;
1519 if (!RegQueryValueExW(hkey
, L
"Attributes", NULL
, NULL
, blob
, &size
))
1521 if (FAILED(hr
= MFInitAttributesFromBlob(attributes
, blob
, size
)))
1522 WARN("Failed to initialize attributes, hr %#lx.\n", hr
);
1531 IMFAttributes_AddRef(*ret
);
1534 IMFAttributes_Release(attributes
);
1539 /***********************************************************************
1540 * MFTGetInfo (mfplat.@)
1542 HRESULT WINAPI
MFTGetInfo(CLSID clsid
, WCHAR
**name
, MFT_REGISTER_TYPE_INFO
**input_types
,
1543 UINT32
*input_types_count
, MFT_REGISTER_TYPE_INFO
**output_types
, UINT32
*output_types_count
,
1544 IMFAttributes
**attributes
)
1551 TRACE("%s, %p, %p, %p, %p, %p, %p.\n", debugstr_guid(&clsid
), name
, input_types
,
1552 input_types_count
, output_types
, output_types_count
, attributes
);
1554 guid_to_string(clsidW
, &clsid
);
1556 if ((ret
= RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
)))
1557 return HRESULT_FROM_WIN32(ret
);
1559 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1562 return HRESULT_FROM_WIN32(ret
);
1564 if (input_types_count
)
1565 *input_types_count
= 0;
1567 if (output_types_count
)
1568 *output_types_count
= 0;
1570 hr
= mft_get_name(hmft
, name
);
1573 hr
= mft_get_reg_type_info(clsidW
, L
"InputTypes", input_types
, input_types_count
);
1576 hr
= mft_get_reg_type_info(clsidW
, L
"OutputTypes", output_types
, output_types_count
);
1579 hr
= mft_get_attributes(hmft
, attributes
);
1586 /***********************************************************************
1587 * MFStartup (mfplat.@)
1589 HRESULT WINAPI
MFStartup(ULONG version
, DWORD flags
)
1591 #define MF_VERSION_XP MAKELONG( MF_API_VERSION, 1 )
1592 #define MF_VERSION_WIN7 MAKELONG( MF_API_VERSION, 2 )
1594 TRACE("%#lx, %#lx.\n", version
, flags
);
1596 if (version
!= MF_VERSION_XP
&& version
!= MF_VERSION_WIN7
)
1597 return MF_E_BAD_STARTUP_VERSION
;
1604 /***********************************************************************
1605 * MFShutdown (mfplat.@)
1607 HRESULT WINAPI
MFShutdown(void)
1616 /***********************************************************************
1617 * MFCopyImage (mfplat.@)
1619 HRESULT WINAPI
MFCopyImage(BYTE
*dest
, LONG deststride
, const BYTE
*src
, LONG srcstride
, DWORD width
, DWORD lines
)
1621 TRACE("%p, %ld, %p, %ld, %lu, %lu.\n", dest
, deststride
, src
, srcstride
, width
, lines
);
1625 memcpy(dest
, src
, width
);
1639 static int __cdecl
debug_compare_guid(const void *a
, const void *b
)
1641 const GUID
*guid
= a
;
1642 const struct guid_def
*guid_def
= b
;
1643 return memcmp(guid
, guid_def
->guid
, sizeof(*guid
));
1646 const char *debugstr_attr(const GUID
*guid
)
1648 static const struct guid_def guid_defs
[] =
1650 #define X(g) { &(g), #g }
1651 #define MF_READER_WRITER_D3D_MANAGER MF_SOURCE_READER_D3D_MANAGER
1652 X(MF_READWRITE_MMCSS_CLASS
),
1653 X(MF_TOPONODE_MARKIN_HERE
),
1654 X(MF_MT_H264_SUPPORTED_SYNC_FRAME_TYPES
),
1655 X(MF_TOPONODE_MARKOUT_HERE
),
1656 X(EVRConfig_ForceBob
),
1657 X(MF_TOPONODE_DECODER
),
1658 X(EVRConfig_AllowDropToBob
),
1659 X(MF_TOPOLOGY_PROJECTSTART
),
1660 X(EVRConfig_ForceThrottle
),
1661 X(MF_VIDEO_MAX_MB_PER_SEC
),
1662 X(MF_TOPOLOGY_PROJECTSTOP
),
1663 X(MF_SINK_WRITER_ENCODER_CONFIG
),
1664 X(EVRConfig_AllowDropToThrottle
),
1665 X(MF_TOPOLOGY_NO_MARKIN_MARKOUT
),
1666 X(EVRConfig_ForceHalfInterlace
),
1667 X(EVRConfig_AllowDropToHalfInterlace
),
1668 X(EVRConfig_ForceScaling
),
1669 X(MF_MT_H264_CAPABILITIES
),
1670 X(EVRConfig_AllowScaling
),
1671 X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS
),
1672 X(MFT_PREFERRED_ENCODER_PROFILE
),
1673 X(EVRConfig_ForceBatching
),
1674 X(EVRConfig_AllowBatching
),
1675 X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED
),
1676 X(MF_MT_VIDEO_PROFILE
),
1677 X(MF_MT_DV_AAUX_CTRL_PACK_1
),
1678 X(MF_MT_ALPHA_MODE
),
1679 X(MF_MT_MPEG2_TIMECODE
),
1680 X(MF_PMP_SERVER_CONTEXT
),
1681 X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
),
1682 X(MF_MEDIA_ENGINE_TRACK_ID
),
1683 X(MF_MT_CUSTOM_VIDEO_PRIMARIES
),
1684 X(MF_MT_TIMESTAMP_CAN_BE_DTS
),
1685 X(MFT_CODEC_MERIT_Attribute
),
1686 X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS
),
1687 X(MF_XVP_DISABLE_FRC
),
1689 X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
),
1690 X(MF_MT_MPEG2_FLAGS
),
1691 X(MF_MEDIA_ENGINE_AUDIO_CATEGORY
),
1692 X(MF_MT_PIXEL_ASPECT_RATIO
),
1693 X(MF_VIDEO_PROCESSOR_ALGORITHM
),
1694 X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK
),
1695 X(MFT_CONNECTED_STREAM_ATTRIBUTE
),
1696 X(MF_MT_REALTIME_CONTENT
),
1697 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
),
1698 X(MF_MT_WRAPPED_TYPE
),
1700 X(MF_MT_AVG_BITRATE
),
1701 X(MF_MT_DECODER_USE_MAX_RESOLUTION
),
1702 X(MF_MT_MAX_LUMINANCE_LEVEL
),
1703 X(MFT_CONNECTED_TO_HW_STREAM
),
1705 X(MF_XVP_SAMPLE_LOCK_TIMEOUT
),
1706 X(MF_MT_MAX_KEYFRAME_SPACING
),
1707 X(MFT_TRANSFORM_CLSID_Attribute
),
1708 X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
),
1709 X(MF_MT_AM_FORMAT_TYPE
),
1710 X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME
),
1711 X(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
),
1712 X(MF_MT_H264_MAX_MB_PER_SEC
),
1713 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS
),
1714 X(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
1715 X(MF_PD_PMPHOST_CONTEXT
),
1716 X(MF_PD_APP_CONTEXT
),
1718 X(MF_PD_TOTAL_FILE_SIZE
),
1719 X(MF_PD_AUDIO_ENCODING_BITRATE
),
1720 X(MF_PD_VIDEO_ENCODING_BITRATE
),
1721 X(MFSampleExtension_TargetGlobalLuminance
),
1723 X(MF_MT_H264_SUPPORTED_SLICE_MODES
),
1724 X(MF_PD_LAST_MODIFIED_TIME
),
1726 X(MF_PD_PLAYBACK_ELEMENT_ID
),
1727 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
),
1728 X(MF_MT_ALL_SAMPLES_INDEPENDENT
),
1729 X(MF_SA_D3D12_CLEAR_VALUE
),
1730 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER
),
1731 X(MF_PD_PREFERRED_LANGUAGE
),
1732 X(MF_PD_PLAYBACK_BOUNDARY_TIME
),
1733 X(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
),
1734 X(MF_ACTIVATE_MFT_LOCKED
),
1735 X(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
),
1736 X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
),
1737 X(MF_MT_FRAME_SIZE
),
1738 X(MF_MT_H264_SIMULCAST_SUPPORT
),
1739 X(MF_SINK_WRITER_ASYNC_CALLBACK
),
1740 X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH
),
1741 X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
),
1742 X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
),
1743 X(MF_MT_FRAME_RATE_RANGE_MAX
),
1745 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID
),
1746 X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS
),
1747 X(MF_SA_D3D11_USAGE
),
1748 X(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
),
1749 X(MF_MT_GEOMETRIC_APERTURE
),
1750 X(MF_MT_ORIGINAL_WAVE_FORMAT_TAG
),
1751 X(MF_MT_DV_AAUX_SRC_PACK_1
),
1752 X(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
),
1753 X(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
),
1754 X(MF_MEDIA_ENGINE_EXTENSION
),
1755 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
),
1756 X(MF_MT_DEFAULT_STRIDE
),
1757 X(MF_MT_ARBITRARY_FORMAT
),
1758 X(MF_TRANSFORM_CATEGORY_Attribute
),
1759 X(MF_MT_MPEG2_HDCP
),
1760 X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
1761 X(MF_MT_SPATIAL_AUDIO_MAX_DYNAMIC_OBJECTS
),
1762 X(MF_MT_DECODER_MAX_DPB_COUNT
),
1763 X(MFSampleExtension_ForwardedDecodeUnits
),
1764 X(MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
1765 X(MF_MT_DV_AAUX_CTRL_PACK_0
),
1766 X(MF_MT_YUV_MATRIX
),
1767 X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED
),
1768 X(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY
),
1769 X(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL
),
1770 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID
),
1771 X(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
),
1772 X(MF_MT_VIDEO_ROTATION
),
1773 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK
),
1774 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
),
1776 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
),
1777 X(MF_MT_MIN_MASTERING_LUMINANCE
),
1778 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
),
1779 X(MF_SA_REQUIRED_SAMPLE_COUNT
),
1780 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
),
1781 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
),
1782 X(MF_EVENT_STREAM_METADATA_SYSTEMID
),
1783 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
),
1784 X(MF_MT_AUDIO_CHANNEL_MASK
),
1785 X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN
),
1786 X(MF_READWRITE_DISABLE_CONVERTERS
),
1787 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
),
1788 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
),
1789 X(MF_SA_D3D12_HEAP_FLAGS
),
1790 X(MF_MT_MINIMUM_DISPLAY_APERTURE
),
1791 X(MFSampleExtension_Token
),
1792 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY
),
1793 X(MF_D3D12_SYNCHRONIZATION_OBJECT
),
1794 X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
1795 X(MF_TRANSFORM_ASYNC_UNLOCK
),
1796 X(MF_DISABLE_FRAME_CORRUPTION_INFO
),
1797 X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
),
1798 X(MF_MT_VIDEO_NO_FRAME_ORDERING
),
1799 X(MF_MEDIA_ENGINE_PLAYBACK_VISUAL
),
1800 X(MF_MT_VIDEO_CHROMA_SITING
),
1801 X(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY
),
1802 X(MF_SA_BUFFERS_PER_SAMPLE
),
1803 X(MFSampleExtension_3DVideo_SampleFormat
),
1804 X(MF_MT_H264_RESOLUTION_SCALING
),
1805 X(MF_MT_VIDEO_LEVEL
),
1806 X(MF_SA_D3D12_HEAP_TYPE
),
1807 X(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET
),
1808 X(MF_MT_SAMPLE_SIZE
),
1809 X(MF_MT_AAC_PAYLOAD_TYPE
),
1810 X(MF_TOPOLOGY_PLAYBACK_FRAMERATE
),
1811 X(MF_SOURCE_READER_D3D11_BIND_FLAGS
),
1812 X(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
1813 X(MF_MT_AUDIO_WMADRC_PEAKREF
),
1814 X(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
1815 X(MF_TRANSFORM_FLAGS_Attribute
),
1816 X(MF_MT_H264_SUPPORTED_RATE_CONTROL_MODES
),
1817 X(MF_PD_SAMI_STYLELIST
),
1818 X(MF_MT_AUDIO_WMADRC_AVGREF
),
1819 X(MF_MT_AUDIO_BITS_PER_SAMPLE
),
1821 X(MF_MT_AUDIO_WMADRC_AVGTARGET
),
1823 X(MF_SESSION_TOPOLOADER
),
1824 X(MF_SESSION_GLOBAL_TIME
),
1825 X(MF_SESSION_QUALITY_MANAGER
),
1826 X(MF_SESSION_CONTENT_PROTECTION_MANAGER
),
1827 X(MF_MT_MPEG4_SAMPLE_DESCRIPTION
),
1828 X(MF_MT_D3D_RESOURCE_VERSION
),
1829 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET
),
1830 X(MF_MT_MPEG_START_TIME_CODE
),
1831 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1832 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1833 X(MF_READWRITE_MMCSS_PRIORITY_AUDIO
),
1834 X(MF_MT_H264_MAX_CODEC_CONFIG_DELAY
),
1835 X(MF_MT_DV_AAUX_SRC_PACK_0
),
1836 X(MF_BYTESTREAM_ORIGIN_NAME
),
1837 X(MF_BYTESTREAM_CONTENT_TYPE
),
1838 X(MF_MT_DEPTH_MEASUREMENT
),
1839 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
),
1840 X(MF_MT_VIDEO_3D_NUM_VIEWS
),
1841 X(MF_BYTESTREAM_DURATION
),
1842 X(MF_SD_SAMI_LANGUAGE
),
1843 X(MF_EVENT_OUTPUT_NODE
),
1844 X(MF_BYTESTREAM_LAST_MODIFIED_TIME
),
1845 X(MFT_ENUM_ADAPTER_LUID
),
1846 X(MF_MT_FRAME_RATE_RANGE_MIN
),
1847 X(MF_BYTESTREAM_IFO_FILE_URI
),
1848 X(MF_EVENT_TOPOLOGY_STATUS
),
1849 X(MF_BYTESTREAM_DLNA_PROFILE_ID
),
1850 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE
),
1851 X(MF_MT_MAJOR_TYPE
),
1852 X(MF_SA_REQUIRED_SAMPLE_COUNT_PROGRESSIVE
),
1853 X(MF_MT_IN_BAND_PARAMETER_SET
),
1854 X(MF_EVENT_SOURCE_CHARACTERISTICS
),
1855 X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD
),
1856 X(MF_SESSION_SERVER_CONTEXT
),
1857 X(MF_MT_VIDEO_3D_FIRST_IS_LEFT
),
1858 X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT
),
1859 X(MF_PD_ADAPTIVE_STREAMING
),
1860 X(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
),
1861 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
),
1862 X(MF_MT_H264_SUPPORTED_USAGES
),
1863 X(MFT_PREFERRED_OUTPUTTYPE_Attribute
),
1864 X(MFSampleExtension_Timestamp
),
1865 X(MF_TOPONODE_PRIMARYOUTPUT
),
1867 X(MF_TRANSFORM_ASYNC
),
1868 X(MF_TOPONODE_STREAMID
),
1869 X(MF_MEDIA_ENGINE_PLAYBACK_HWND
),
1870 X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
),
1871 X(MF_MT_VIDEO_LIGHTING
),
1872 X(MF_SD_MUTUALLY_EXCLUSIVE
),
1873 X(MF_SD_STREAM_NAME
),
1874 X(MF_MT_DV_VAUX_SRC_PACK
),
1875 X(MF_TOPONODE_RATELESS
),
1876 X(MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS
),
1877 X(MF_TOPONODE_DISABLE_PREROLL
),
1878 X(MF_SA_D3D11_ALLOW_DYNAMIC_YUV_TEXTURE
),
1879 X(MF_MT_VIDEO_3D_FORMAT
),
1880 X(MF_EVENT_STREAM_METADATA_KEYDATA
),
1881 X(MF_READER_WRITER_D3D_MANAGER
),
1882 X(MFSampleExtension_3DVideo
),
1883 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE
),
1884 X(MF_MT_H264_USAGE
),
1885 X(MF_MEDIA_ENGINE_EME_CALLBACK
),
1886 X(MF_EVENT_SOURCE_FAKE_START
),
1887 X(MF_EVENT_SOURCE_PROJECTSTART
),
1888 X(MF_EVENT_SOURCE_ACTUAL_START
),
1889 X(MF_MT_D3D12_TEXTURE_LAYOUT
),
1890 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
),
1891 X(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
1892 X(MFT_ENUM_HARDWARE_URL_Attribute
),
1893 X(MF_SOURCE_READER_ASYNC_CALLBACK
),
1894 X(MF_MT_D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE
),
1895 X(MF_MT_OUTPUT_BUFFER_NUM
),
1896 X(MF_SA_D3D11_BINDFLAGS
),
1897 X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT
),
1898 X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE
),
1899 X(MFT_FRIENDLY_NAME_Attribute
),
1900 X(MF_MT_FIXED_SIZE_SAMPLES
),
1901 X(MFT_SUPPORT_3DVIDEO
),
1902 X(MFT_SUPPORT_3DVIDEO
),
1903 X(MFT_INPUT_TYPES_Attributes
),
1904 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS
),
1905 X(MF_MT_H264_LAYOUT_PER_STREAM
),
1906 X(MF_EVENT_SCRUBSAMPLE_TIME
),
1907 X(MF_MT_SPATIAL_AUDIO_MAX_METADATA_ITEMS
),
1908 X(MF_MT_MPEG2_ONE_FRAME_PER_PACKET
),
1909 X(MF_MT_INTERLACE_MODE
),
1910 X(MF_MEDIA_ENGINE_CALLBACK
),
1911 X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE
),
1912 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE
),
1913 X(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
1914 X(MF_XVP_CALLER_ALLOCATES_OUTPUT
),
1915 X(MF_MT_H264_SVC_CAPABILITIES
),
1916 X(MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
),
1917 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_LENGTH
),
1918 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_FORMAT_ID
),
1919 X(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
),
1920 X(MF_SA_D3D11_SHARED
),
1921 X(MF_MT_PAN_SCAN_ENABLED
),
1922 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL
),
1923 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
),
1924 X(MF_MT_DV_VAUX_CTRL_PACK
),
1925 X(MFSampleExtension_ForwardedDecodeUnitType
),
1926 X(MF_SA_D3D11_AWARE
),
1927 X(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
1928 X(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS
),
1929 X(MF_MT_SPATIAL_AUDIO_MIN_METADATA_ITEM_OFFSET_SPACING
),
1930 X(MF_TOPONODE_TRANSFORM_OBJECTID
),
1931 X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE
),
1932 X(MF_EVENT_MFT_INPUT_STREAM_ID
),
1933 X(MF_MT_SOURCE_CONTENT_HINT
),
1934 X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute
),
1935 X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE
),
1936 X(MF_READWRITE_MMCSS_PRIORITY
),
1938 X(MF_EVENT_START_PRESENTATION_TIME
),
1939 X(MF_EVENT_SESSIONCAPS
),
1940 X(MF_EVENT_PRESENTATION_TIME_OFFSET
),
1941 X(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
),
1942 X(MF_EVENT_SESSIONCAPS_DELTA
),
1943 X(MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT
),
1944 X(MFSampleExtension_DecodeTimestamp
),
1945 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE
),
1946 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT
),
1947 X(MF_MT_VIDEO_H264_NO_FMOASO
),
1948 X(MF_MT_AVG_BIT_ERROR_RATE
),
1949 X(MF_MT_VIDEO_PRIMARIES
),
1950 X(MF_SINK_WRITER_DISABLE_THROTTLING
),
1951 X(MF_MT_H264_RATE_CONTROL_MODES
),
1952 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
),
1953 X(MF_READWRITE_D3D_OPTIONAL
),
1954 X(MF_SA_D3D11_HW_PROTECTED
),
1955 X(MF_MEDIA_ENGINE_DXGI_MANAGER
),
1956 X(MF_READWRITE_MMCSS_CLASS_AUDIO
),
1957 X(MF_MEDIA_ENGINE_COREWINDOW
),
1958 X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS
),
1959 X(MF_MT_MPEG4_TRACK_TYPE
),
1960 X(MF_ACTIVATE_VIDEO_WINDOW
),
1961 X(MF_MT_PAN_SCAN_APERTURE
),
1962 X(MF_TOPOLOGY_RESOLUTION_STATUS
),
1963 X(MF_MT_ORIGINAL_4CC
),
1964 X(MF_PD_AUDIO_ISVARIABLEBITRATE
),
1965 X(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS
),
1966 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
),
1967 X(MF_MT_D3D12_CPU_READBACK
),
1968 X(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID
),
1969 X(MF_MT_MPEG2_CONTENT_PACKET
),
1970 X(MFT_PROCESS_LOCAL_Attribute
),
1971 X(MFT_PROCESS_LOCAL_Attribute
),
1972 X(MF_MT_PAD_CONTROL_FLAGS
),
1973 X(MF_MT_VIDEO_NOMINAL_RANGE
),
1974 X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
1975 X(MF_MT_MPEG_SEQUENCE_HEADER
),
1976 X(MF_MEDIA_ENGINE_OPM_HWND
),
1977 X(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
1978 X(MF_MT_SPATIAL_AUDIO_DATA_PRESENT
),
1979 X(MF_MT_FRAME_RATE
),
1980 X(MF_TOPONODE_FLUSH
),
1981 X(MF_MT_MPEG2_STANDARD
),
1982 X(MF_TOPONODE_DRAIN
),
1983 X(MF_MT_TRANSFER_FUNCTION
),
1984 X(MF_TOPONODE_MEDIASTART
),
1985 X(MF_TOPONODE_MEDIASTOP
),
1986 X(MF_SOURCE_READER_MEDIASOURCE_CONFIG
),
1987 X(MF_TOPONODE_SOURCE
),
1988 X(MF_TOPONODE_PRESENTATION_DESCRIPTOR
),
1989 X(MF_TOPONODE_D3DAWARE
),
1990 X(MF_MT_COMPRESSED
),
1991 X(MF_TOPONODE_STREAM_DESCRIPTOR
),
1992 X(MF_TOPONODE_ERRORCODE
),
1993 X(MF_TOPONODE_SEQUENCE_ELEMENTID
),
1994 X(MF_EVENT_MFT_CONTEXT
),
1995 X(MF_MT_FORWARD_CUSTOM_SEI
),
1996 X(MF_TOPONODE_CONNECT_METHOD
),
1997 X(MFT_OUTPUT_TYPES_Attributes
),
1998 X(MF_MT_IMAGE_LOSS_TOLERANT
),
1999 X(MF_SESSION_REMOTE_SOURCE_MODE
),
2000 X(MF_MT_DEPTH_VALUE_UNIT
),
2001 X(MF_MT_AUDIO_NUM_CHANNELS
),
2002 X(MF_MT_ARBITRARY_HEADER
),
2003 X(MF_TOPOLOGY_DXVA_MODE
),
2004 X(MF_TOPONODE_LOCKED
),
2005 X(MF_TOPONODE_WORKQUEUE_ID
),
2006 X(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
),
2007 X(MF_TOPONODE_WORKQUEUE_MMCSS_CLASS
),
2008 X(MF_TOPONODE_DECRYPTOR
),
2009 X(MF_EVENT_DO_THINNING
),
2010 X(MF_TOPONODE_DISCARDABLE
),
2011 X(MF_TOPOLOGY_HARDWARE_MODE
),
2012 X(MF_SOURCE_READER_DISABLE_DXVA
),
2013 X(MF_MT_FORWARD_CUSTOM_NALU
),
2014 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
),
2015 X(MF_TOPONODE_ERROR_MAJORTYPE
),
2017 X(MFT_FIELDOFUSE_UNLOCK_Attribute
),
2018 X(MF_TOPONODE_ERROR_SUBTYPE
),
2019 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
),
2020 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
),
2021 X(MF_MT_VIDEO_3D_LEFT_IS_BASE
),
2022 X(MF_TOPONODE_WORKQUEUE_MMCSS_TASKID
),
2023 #undef MF_READER_WRITER_D3D_MANAGER
2026 struct guid_def
*ret
= NULL
;
2029 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2031 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2034 const char *debugstr_mf_guid(const GUID
*guid
)
2036 static const struct guid_def guid_defs
[] =
2038 #define X(g) { &(g), #g }
2039 X(MFAudioFormat_ADTS
),
2040 X(MFAudioFormat_PCM
),
2041 X(MFAudioFormat_PCM_HDCP
),
2042 X(MFAudioFormat_Float
),
2043 X(MFAudioFormat_DTS
),
2044 X(MFAudioFormat_DRM
),
2045 X(MFAudioFormat_MSP1
),
2046 X(MFAudioFormat_Vorbis
),
2047 X(MFAudioFormat_AAC
),
2048 X(MFVideoFormat_RGB24
),
2049 X(MFVideoFormat_ARGB32
),
2050 X(MFVideoFormat_RGB32
),
2051 X(MFVideoFormat_RGB565
),
2052 X(MFVideoFormat_RGB555
),
2053 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
),
2054 X(MFT_CATEGORY_MULTIPLEXER
),
2055 X(MFVideoFormat_A2R10G10B10
),
2056 X(MFT_CATEGORY_VIDEO_EFFECT
),
2057 X(MFMediaType_Script
),
2058 X(MFMediaType_Image
),
2059 X(MFMediaType_HTML
),
2060 X(MFMediaType_Binary
),
2061 X(MFVideoFormat_MPEG2
),
2062 X(MFMediaType_FileTransfer
),
2063 X(MFVideoFormat_RGB8
),
2064 X(MFAudioFormat_Dolby_AC3
),
2065 X(MFVideoFormat_L8
),
2066 X(MFAudioFormat_LPCM
),
2067 X(MFVideoFormat_420O
),
2068 X(MFVideoFormat_AI44
),
2069 X(MFVideoFormat_AV1
),
2070 X(MFVideoFormat_AYUV
),
2071 X(MFVideoFormat_H263
),
2072 X(MFVideoFormat_H264
),
2073 X(MFVideoFormat_H265
),
2074 X(MFVideoFormat_HEVC
),
2075 X(MFVideoFormat_HEVC_ES
),
2076 X(MFT_CATEGORY_AUDIO_EFFECT
),
2077 X(MFVideoFormat_I420
),
2078 X(MFVideoFormat_IYUV
),
2079 X(MFT_CATEGORY_VIDEO_DECODER
),
2080 X(MFVideoFormat_M4S2
),
2081 X(MFVideoFormat_MJPG
),
2082 X(MFVideoFormat_MP43
),
2083 X(MFVideoFormat_MP4S
),
2084 X(MFVideoFormat_MP4V
),
2085 X(MFVideoFormat_MPG1
),
2086 X(MFVideoFormat_MSS1
),
2087 X(MFVideoFormat_MSS2
),
2088 X(MFVideoFormat_NV11
),
2089 X(MFVideoFormat_NV12
),
2090 X(MFVideoFormat_ORAW
),
2091 X(MFAudioFormat_Opus
),
2092 X(MFAudioFormat_MPEG
),
2093 X(MFVideoFormat_D16
),
2094 X(MFVideoFormat_P010
),
2095 X(MFVideoFormat_P016
),
2096 X(MFVideoFormat_P210
),
2097 X(MFVideoFormat_P216
),
2098 X(MFVideoFormat_L16
),
2099 X(MFAudioFormat_MP3
),
2100 X(MFVideoFormat_UYVY
),
2101 X(MFVideoFormat_VP10
),
2102 X(MFVideoFormat_VP80
),
2103 X(MFVideoFormat_VP90
),
2104 X(MFVideoFormat_WMV1
),
2105 X(MFVideoFormat_WMV2
),
2106 X(MFVideoFormat_WMV3
),
2107 X(MFVideoFormat_WVC1
),
2108 X(MFT_CATEGORY_OTHER
),
2109 X(MFVideoFormat_Y210
),
2110 X(MFVideoFormat_Y216
),
2111 X(MFVideoFormat_Y410
),
2112 X(MFVideoFormat_Y416
),
2113 X(MFVideoFormat_Y41P
),
2114 X(MFVideoFormat_Y41T
),
2115 X(MFVideoFormat_Y42T
),
2116 X(MFVideoFormat_YUY2
),
2117 X(MFVideoFormat_YV12
),
2118 X(MFVideoFormat_YVU9
),
2119 X(MFVideoFormat_YVYU
),
2120 X(MFAudioFormat_WMAudioV8
),
2121 X(MFAudioFormat_ALAC
),
2122 X(MFAudioFormat_AMR_NB
),
2123 X(MFMediaType_Audio
),
2124 X(MFAudioFormat_WMAudioV9
),
2125 X(MFAudioFormat_AMR_WB
),
2126 X(MFAudioFormat_WMAudio_Lossless
),
2127 X(MFAudioFormat_AMR_WP
),
2128 X(MFAudioFormat_WMASPDIF
),
2129 X(MFVideoFormat_DV25
),
2130 X(MFVideoFormat_DV50
),
2131 X(MFVideoFormat_DVC
),
2132 X(MFVideoFormat_DVH1
),
2133 X(MFVideoFormat_DVHD
),
2134 X(MFVideoFormat_DVSD
),
2135 X(MFVideoFormat_DVSL
),
2136 X(MFVideoFormat_A16B16G16R16F
),
2137 X(MFVideoFormat_v210
),
2138 X(MFVideoFormat_v216
),
2139 X(MFVideoFormat_v410
),
2140 X(MFMediaType_Video
),
2141 X(MFAudioFormat_AAC_HDCP
),
2142 X(MFT_CATEGORY_DEMULTIPLEXER
),
2143 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
),
2144 X(MFT_CATEGORY_VIDEO_ENCODER
),
2145 X(MFAudioFormat_Dolby_AC3_HDCP
),
2146 X(MFMediaType_Subtitle
),
2147 X(MFMediaType_Stream
),
2148 X(MFAudioFormat_Dolby_AC3_SPDIF
),
2149 X(MFAudioFormat_Float_SpatialObjects
),
2150 X(MFMediaType_SAMI
),
2151 X(MFAudioFormat_ADTS_HDCP
),
2152 X(MFAudioFormat_FLAC
),
2153 X(MFAudioFormat_Dolby_DDPlus
),
2154 X(MFMediaType_MultiplexedFrames
),
2155 X(MFT_CATEGORY_AUDIO_DECODER
),
2156 X(MFAudioFormat_Base_HDCP
),
2157 X(MFT_CATEGORY_AUDIO_ENCODER
),
2158 X(MFVideoFormat_Base_HDCP
),
2159 X(MFVideoFormat_H264_HDCP
),
2160 X(MFVideoFormat_HEVC_HDCP
),
2161 X(MFMediaType_Default
),
2162 X(MFMediaType_Protected
),
2163 X(MFVideoFormat_H264_ES
),
2164 X(MFMediaType_Perception
),
2165 X(MFT_CATEGORY_VIDEO_PROCESSOR
),
2168 struct guid_def
*ret
= NULL
;
2171 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2173 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2182 static int __cdecl
debug_event_id(const void *a
, const void *b
)
2184 const DWORD
*id
= a
;
2185 const struct event_id
*event_id
= b
;
2186 return *id
- event_id
->id
;
2189 static const char *debugstr_eventid(DWORD event
)
2191 static const struct event_id
2198 #define X(e) { e, #e }
2203 X(MESessionUnknown
),
2204 X(MESessionTopologySet
),
2205 X(MESessionTopologiesCleared
),
2206 X(MESessionStarted
),
2208 X(MESessionStopped
),
2211 X(MESessionRateChanged
),
2212 X(MESessionScrubSampleComplete
),
2213 X(MESessionCapabilitiesChanged
),
2214 X(MESessionTopologyStatus
),
2215 X(MESessionNotifyPresentationTime
),
2216 X(MENewPresentation
),
2217 X(MELicenseAcquisitionStart
),
2218 X(MELicenseAcquisitionCompleted
),
2219 X(MEIndividualizationStart
),
2220 X(MEIndividualizationCompleted
),
2221 X(MEEnablerProgress
),
2222 X(MEEnablerCompleted
),
2225 X(MEBufferingStarted
),
2226 X(MEBufferingStopped
),
2229 X(MEReconnectStart
),
2232 X(MESessionStreamSinkFormatChanged
),
2244 X(MEEndOfPresentation
),
2248 X(MEStreamThinMode
),
2249 X(MEStreamFormatChanged
),
2250 X(MESourceRateChanged
),
2251 X(MEEndOfPresentationSegment
),
2252 X(MESourceCharacteristicsChanged
),
2253 X(MESourceRateChangeRequested
),
2254 X(MESourceMetadataChanged
),
2255 X(MESequencerSourceTopologyUpdated
),
2257 X(MEStreamSinkStarted
),
2258 X(MEStreamSinkStopped
),
2259 X(MEStreamSinkPaused
),
2260 X(MEStreamSinkRateChanged
),
2261 X(MEStreamSinkRequestSample
),
2262 X(MEStreamSinkMarker
),
2263 X(MEStreamSinkPrerolled
),
2264 X(MEStreamSinkScrubSampleComplete
),
2265 X(MEStreamSinkFormatChanged
),
2266 X(MEStreamSinkDeviceChanged
),
2268 X(MESinkInvalidated
),
2269 X(MEAudioSessionNameChanged
),
2270 X(MEAudioSessionVolumeChanged
),
2271 X(MEAudioSessionDeviceRemoved
),
2272 X(MEAudioSessionServerShutdown
),
2273 X(MEAudioSessionGroupingParamChanged
),
2274 X(MEAudioSessionIconChanged
),
2275 X(MEAudioSessionFormatChanged
),
2276 X(MEAudioSessionDisconnected
),
2277 X(MEAudioSessionExclusiveModeOverride
),
2278 X(MECaptureAudioSessionVolumeChanged
),
2279 X(MECaptureAudioSessionDeviceRemoved
),
2280 X(MECaptureAudioSessionFormatChanged
),
2281 X(MECaptureAudioSessionDisconnected
),
2282 X(MECaptureAudioSessionExclusiveModeOverride
),
2283 X(MECaptureAudioSessionServerShutdown
),
2286 X(MEContentProtectionMessage
),
2288 X(MEWMDRMLicenseBackupCompleted
),
2289 X(MEWMDRMLicenseBackupProgress
),
2290 X(MEWMDRMLicenseRestoreCompleted
),
2291 X(MEWMDRMLicenseRestoreProgress
),
2292 X(MEWMDRMLicenseAcquisitionCompleted
),
2293 X(MEWMDRMIndividualizationCompleted
),
2294 X(MEWMDRMIndividualizationProgress
),
2295 X(MEWMDRMProximityCompleted
),
2296 X(MEWMDRMLicenseStoreCleaned
),
2297 X(MEWMDRMRevocationDownloadCompleted
),
2298 X(METransformUnknown
),
2299 X(METransformNeedInput
),
2300 X(METransformHaveOutput
),
2301 X(METransformDrainComplete
),
2302 X(METransformMarker
),
2303 X(METransformInputStreamStateChanged
),
2304 X(MEByteStreamCharacteristicsChanged
),
2305 X(MEVideoCaptureDeviceRemoved
),
2306 X(MEVideoCaptureDevicePreempted
),
2307 X(MEStreamSinkFormatInvalidated
),
2308 X(MEEncodingParameters
),
2309 X(MEContentProtectionMetadata
),
2310 X(MEDeviceThermalStateChanged
),
2314 struct event_id
*ret
= bsearch(&event
, event_ids
, ARRAY_SIZE(event_ids
), sizeof(*event_ids
), debug_event_id
);
2315 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbg_sprintf("%lu", event
);
2318 static inline struct attributes
*impl_from_IMFAttributes(IMFAttributes
*iface
)
2320 return CONTAINING_RECORD(iface
, struct attributes
, IMFAttributes_iface
);
2323 static HRESULT WINAPI
mfattributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
2325 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2327 if (IsEqualIID(riid
, &IID_IMFAttributes
) ||
2328 IsEqualGUID(riid
, &IID_IUnknown
))
2331 IMFAttributes_AddRef(iface
);
2335 WARN("Unsupported %s.\n", debugstr_guid(riid
));
2337 return E_NOINTERFACE
;
2340 static ULONG WINAPI
mfattributes_AddRef(IMFAttributes
*iface
)
2342 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2343 ULONG refcount
= InterlockedIncrement(&attributes
->ref
);
2345 TRACE("%p, refcount %ld.\n", iface
, refcount
);
2350 static ULONG WINAPI
mfattributes_Release(IMFAttributes
*iface
)
2352 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2353 ULONG refcount
= InterlockedDecrement(&attributes
->ref
);
2355 TRACE("%p, refcount %ld.\n", iface
, refcount
);
2359 clear_attributes_object(attributes
);
2366 static struct attribute
*attributes_find_item(struct attributes
*attributes
, REFGUID key
, size_t *index
)
2370 for (i
= 0; i
< attributes
->count
; ++i
)
2372 if (IsEqualGUID(key
, &attributes
->attributes
[i
].key
))
2376 return &attributes
->attributes
[i
];
2383 static HRESULT
attributes_get_item(struct attributes
*attributes
, const GUID
*key
, PROPVARIANT
*value
)
2385 struct attribute
*attribute
;
2388 EnterCriticalSection(&attributes
->cs
);
2390 attribute
= attributes_find_item(attributes
, key
, NULL
);
2393 if (attribute
->value
.vt
== value
->vt
&& !(value
->vt
== VT_UNKNOWN
&& !attribute
->value
.punkVal
))
2394 hr
= PropVariantCopy(value
, &attribute
->value
);
2396 hr
= MF_E_INVALIDTYPE
;
2399 hr
= MF_E_ATTRIBUTENOTFOUND
;
2401 LeaveCriticalSection(&attributes
->cs
);
2406 HRESULT
attributes_GetItem(struct attributes
*attributes
, REFGUID key
, PROPVARIANT
*value
)
2408 struct attribute
*attribute
;
2411 EnterCriticalSection(&attributes
->cs
);
2413 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2414 hr
= value
? PropVariantCopy(value
, &attribute
->value
) : S_OK
;
2416 hr
= MF_E_ATTRIBUTENOTFOUND
;
2418 LeaveCriticalSection(&attributes
->cs
);
2423 HRESULT
attributes_GetItemType(struct attributes
*attributes
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2425 struct attribute
*attribute
;
2428 EnterCriticalSection(&attributes
->cs
);
2430 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2432 *type
= attribute
->value
.vt
;
2435 hr
= MF_E_ATTRIBUTENOTFOUND
;
2437 LeaveCriticalSection(&attributes
->cs
);
2442 HRESULT
attributes_CompareItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2444 struct attribute
*attribute
;
2448 EnterCriticalSection(&attributes
->cs
);
2450 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2452 *result
= attribute
->value
.vt
== value
->vt
&&
2453 !PropVariantCompareEx(&attribute
->value
, value
, PVCU_DEFAULT
, PVCF_DEFAULT
);
2456 LeaveCriticalSection(&attributes
->cs
);
2461 HRESULT
attributes_Compare(struct attributes
*attributes
, IMFAttributes
*theirs
,
2462 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2464 IMFAttributes
*smaller
, *other
;
2465 MF_ATTRIBUTE_TYPE type
;
2471 if (FAILED(hr
= IMFAttributes_GetCount(theirs
, &count
)))
2474 EnterCriticalSection(&attributes
->cs
);
2480 case MF_ATTRIBUTES_MATCH_OUR_ITEMS
:
2481 for (i
= 0; i
< attributes
->count
; ++i
)
2483 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2484 &attributes
->attributes
[i
].value
, &result
)))
2490 case MF_ATTRIBUTES_MATCH_THEIR_ITEMS
:
2491 hr
= IMFAttributes_Compare(theirs
, &attributes
->IMFAttributes_iface
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2493 case MF_ATTRIBUTES_MATCH_ALL_ITEMS
:
2494 if (count
!= attributes
->count
)
2499 for (i
= 0; i
< count
; ++i
)
2501 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2502 &attributes
->attributes
[i
].value
, &result
)))
2508 case MF_ATTRIBUTES_MATCH_INTERSECTION
:
2509 for (i
= 0; i
< attributes
->count
; ++i
)
2511 if (FAILED(IMFAttributes_GetItemType(theirs
, &attributes
->attributes
[i
].key
, &type
)))
2514 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2515 &attributes
->attributes
[i
].value
, &result
)))
2522 case MF_ATTRIBUTES_MATCH_SMALLER
:
2523 smaller
= attributes
->count
> count
? theirs
: &attributes
->IMFAttributes_iface
;
2524 other
= attributes
->count
> count
? &attributes
->IMFAttributes_iface
: theirs
;
2525 hr
= IMFAttributes_Compare(smaller
, other
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2528 WARN("Unknown match type %d.\n", match_type
);
2532 LeaveCriticalSection(&attributes
->cs
);
2540 HRESULT
attributes_GetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32
*value
)
2542 PROPVARIANT attrval
;
2545 PropVariantInit(&attrval
);
2546 attrval
.vt
= VT_UI4
;
2547 hr
= attributes_get_item(attributes
, key
, &attrval
);
2549 *value
= attrval
.ulVal
;
2554 HRESULT
attributes_GetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64
*value
)
2556 PROPVARIANT attrval
;
2559 PropVariantInit(&attrval
);
2560 attrval
.vt
= VT_UI8
;
2561 hr
= attributes_get_item(attributes
, key
, &attrval
);
2563 *value
= attrval
.uhVal
.QuadPart
;
2568 HRESULT
attributes_GetDouble(struct attributes
*attributes
, REFGUID key
, double *value
)
2570 PROPVARIANT attrval
;
2573 PropVariantInit(&attrval
);
2575 hr
= attributes_get_item(attributes
, key
, &attrval
);
2577 *value
= attrval
.dblVal
;
2582 HRESULT
attributes_GetGUID(struct attributes
*attributes
, REFGUID key
, GUID
*value
)
2584 struct attribute
*attribute
;
2587 EnterCriticalSection(&attributes
->cs
);
2589 attribute
= attributes_find_item(attributes
, key
, NULL
);
2592 if (attribute
->value
.vt
== MF_ATTRIBUTE_GUID
)
2593 *value
= *attribute
->value
.puuid
;
2595 hr
= MF_E_INVALIDTYPE
;
2598 hr
= MF_E_ATTRIBUTENOTFOUND
;
2600 LeaveCriticalSection(&attributes
->cs
);
2605 HRESULT
attributes_GetStringLength(struct attributes
*attributes
, REFGUID key
, UINT32
*length
)
2607 struct attribute
*attribute
;
2610 EnterCriticalSection(&attributes
->cs
);
2612 attribute
= attributes_find_item(attributes
, key
, NULL
);
2615 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2616 *length
= lstrlenW(attribute
->value
.pwszVal
);
2618 hr
= MF_E_INVALIDTYPE
;
2621 hr
= MF_E_ATTRIBUTENOTFOUND
;
2623 LeaveCriticalSection(&attributes
->cs
);
2628 HRESULT
attributes_GetString(struct attributes
*attributes
, REFGUID key
, WCHAR
*value
,
2629 UINT32 size
, UINT32
*length
)
2631 struct attribute
*attribute
;
2634 EnterCriticalSection(&attributes
->cs
);
2636 attribute
= attributes_find_item(attributes
, key
, NULL
);
2639 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2641 int len
= lstrlenW(attribute
->value
.pwszVal
);
2647 hr
= STRSAFE_E_INSUFFICIENT_BUFFER
;
2649 memcpy(value
, attribute
->value
.pwszVal
, (len
+ 1) * sizeof(WCHAR
));
2652 hr
= MF_E_INVALIDTYPE
;
2655 hr
= MF_E_ATTRIBUTENOTFOUND
;
2657 LeaveCriticalSection(&attributes
->cs
);
2662 HRESULT
attributes_GetAllocatedString(struct attributes
*attributes
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2664 PROPVARIANT attrval
;
2667 PropVariantInit(&attrval
);
2668 attrval
.vt
= VT_LPWSTR
;
2669 hr
= attributes_get_item(attributes
, key
, &attrval
);
2672 *value
= attrval
.pwszVal
;
2673 *length
= lstrlenW(*value
);
2679 HRESULT
attributes_GetBlobSize(struct attributes
*attributes
, REFGUID key
, UINT32
*size
)
2681 struct attribute
*attribute
;
2684 EnterCriticalSection(&attributes
->cs
);
2686 attribute
= attributes_find_item(attributes
, key
, NULL
);
2689 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2690 *size
= attribute
->value
.caub
.cElems
;
2692 hr
= MF_E_INVALIDTYPE
;
2695 hr
= MF_E_ATTRIBUTENOTFOUND
;
2697 LeaveCriticalSection(&attributes
->cs
);
2702 HRESULT
attributes_GetBlob(struct attributes
*attributes
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
, UINT32
*blobsize
)
2704 struct attribute
*attribute
;
2707 EnterCriticalSection(&attributes
->cs
);
2709 attribute
= attributes_find_item(attributes
, key
, NULL
);
2712 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2714 UINT32 size
= attribute
->value
.caub
.cElems
;
2716 if (bufsize
>= size
)
2717 hr
= PropVariantToBuffer(&attribute
->value
, buf
, size
);
2719 hr
= E_NOT_SUFFICIENT_BUFFER
;
2725 hr
= MF_E_INVALIDTYPE
;
2728 hr
= MF_E_ATTRIBUTENOTFOUND
;
2730 LeaveCriticalSection(&attributes
->cs
);
2735 HRESULT
attributes_GetAllocatedBlob(struct attributes
*attributes
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2737 PROPVARIANT attrval
;
2740 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2741 hr
= attributes_get_item(attributes
, key
, &attrval
);
2744 *buf
= attrval
.caub
.pElems
;
2745 *size
= attrval
.caub
.cElems
;
2751 HRESULT
attributes_GetUnknown(struct attributes
*attributes
, REFGUID key
, REFIID riid
, void **out
)
2753 PROPVARIANT attrval
;
2756 PropVariantInit(&attrval
);
2757 attrval
.vt
= VT_UNKNOWN
;
2758 hr
= attributes_get_item(attributes
, key
, &attrval
);
2760 hr
= IUnknown_QueryInterface(attrval
.punkVal
, riid
, out
);
2761 PropVariantClear(&attrval
);
2765 static HRESULT
attributes_set_item(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2767 struct attribute
*attribute
;
2769 EnterCriticalSection(&attributes
->cs
);
2771 attribute
= attributes_find_item(attributes
, key
, NULL
);
2774 if (!mf_array_reserve((void **)&attributes
->attributes
, &attributes
->capacity
, attributes
->count
+ 1,
2775 sizeof(*attributes
->attributes
)))
2777 LeaveCriticalSection(&attributes
->cs
);
2778 return E_OUTOFMEMORY
;
2780 attributes
->attributes
[attributes
->count
].key
= *key
;
2781 attribute
= &attributes
->attributes
[attributes
->count
++];
2784 PropVariantClear(&attribute
->value
);
2786 PropVariantCopy(&attribute
->value
, value
);
2788 LeaveCriticalSection(&attributes
->cs
);
2793 HRESULT
attributes_SetItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2799 case MF_ATTRIBUTE_UINT32
:
2800 case MF_ATTRIBUTE_UINT64
:
2801 case MF_ATTRIBUTE_DOUBLE
:
2802 case MF_ATTRIBUTE_GUID
:
2803 case MF_ATTRIBUTE_STRING
:
2804 case MF_ATTRIBUTE_BLOB
:
2805 case MF_ATTRIBUTE_IUNKNOWN
:
2806 return attributes_set_item(attributes
, key
, value
);
2808 PropVariantInit(&empty
);
2809 attributes_set_item(attributes
, key
, &empty
);
2810 return MF_E_INVALIDTYPE
;
2814 HRESULT
attributes_DeleteItem(struct attributes
*attributes
, REFGUID key
)
2816 struct attribute
*attribute
;
2819 EnterCriticalSection(&attributes
->cs
);
2821 if ((attribute
= attributes_find_item(attributes
, key
, &index
)))
2825 PropVariantClear(&attribute
->value
);
2827 attributes
->count
--;
2828 count
= attributes
->count
- index
;
2830 memmove(&attributes
->attributes
[index
], &attributes
->attributes
[index
+ 1], count
* sizeof(*attributes
->attributes
));
2833 LeaveCriticalSection(&attributes
->cs
);
2838 HRESULT
attributes_DeleteAllItems(struct attributes
*attributes
)
2840 EnterCriticalSection(&attributes
->cs
);
2842 while (attributes
->count
)
2844 PropVariantClear(&attributes
->attributes
[--attributes
->count
].value
);
2846 free(attributes
->attributes
);
2847 attributes
->attributes
= NULL
;
2848 attributes
->capacity
= 0;
2850 LeaveCriticalSection(&attributes
->cs
);
2855 HRESULT
attributes_SetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32 value
)
2857 PROPVARIANT attrval
;
2859 attrval
.vt
= VT_UI4
;
2860 attrval
.ulVal
= value
;
2861 return attributes_set_item(attributes
, key
, &attrval
);
2864 HRESULT
attributes_SetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64 value
)
2866 PROPVARIANT attrval
;
2868 attrval
.vt
= VT_UI8
;
2869 attrval
.uhVal
.QuadPart
= value
;
2870 return attributes_set_item(attributes
, key
, &attrval
);
2873 HRESULT
attributes_SetDouble(struct attributes
*attributes
, REFGUID key
, double value
)
2875 PROPVARIANT attrval
;
2878 attrval
.dblVal
= value
;
2879 return attributes_set_item(attributes
, key
, &attrval
);
2882 HRESULT
attributes_SetGUID(struct attributes
*attributes
, REFGUID key
, REFGUID value
)
2884 PROPVARIANT attrval
;
2886 attrval
.vt
= VT_CLSID
;
2887 attrval
.puuid
= (CLSID
*)value
;
2888 return attributes_set_item(attributes
, key
, &attrval
);
2891 HRESULT
attributes_SetString(struct attributes
*attributes
, REFGUID key
, const WCHAR
*value
)
2893 PROPVARIANT attrval
;
2895 attrval
.vt
= VT_LPWSTR
;
2896 attrval
.pwszVal
= (WCHAR
*)value
;
2897 return attributes_set_item(attributes
, key
, &attrval
);
2900 HRESULT
attributes_SetBlob(struct attributes
*attributes
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
2902 PROPVARIANT attrval
;
2904 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2905 attrval
.caub
.cElems
= size
;
2906 attrval
.caub
.pElems
= (UINT8
*)buf
;
2907 return attributes_set_item(attributes
, key
, &attrval
);
2910 HRESULT
attributes_SetUnknown(struct attributes
*attributes
, REFGUID key
, IUnknown
*unknown
)
2912 PROPVARIANT attrval
;
2914 attrval
.vt
= VT_UNKNOWN
;
2915 attrval
.punkVal
= unknown
;
2916 return attributes_set_item(attributes
, key
, &attrval
);
2919 HRESULT
attributes_LockStore(struct attributes
*attributes
)
2921 EnterCriticalSection(&attributes
->cs
);
2926 HRESULT
attributes_UnlockStore(struct attributes
*attributes
)
2928 LeaveCriticalSection(&attributes
->cs
);
2933 HRESULT
attributes_GetCount(struct attributes
*attributes
, UINT32
*count
)
2935 EnterCriticalSection(&attributes
->cs
);
2936 *count
= attributes
->count
;
2937 LeaveCriticalSection(&attributes
->cs
);
2942 HRESULT
attributes_GetItemByIndex(struct attributes
*attributes
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
2946 EnterCriticalSection(&attributes
->cs
);
2948 if (index
< attributes
->count
)
2950 *key
= attributes
->attributes
[index
].key
;
2952 PropVariantCopy(value
, &attributes
->attributes
[index
].value
);
2957 LeaveCriticalSection(&attributes
->cs
);
2962 HRESULT
attributes_CopyAllItems(struct attributes
*attributes
, IMFAttributes
*dest
)
2967 EnterCriticalSection(&attributes
->cs
);
2969 IMFAttributes_LockStore(dest
);
2971 IMFAttributes_DeleteAllItems(dest
);
2973 for (i
= 0; i
< attributes
->count
; ++i
)
2975 hr
= IMFAttributes_SetItem(dest
, &attributes
->attributes
[i
].key
, &attributes
->attributes
[i
].value
);
2980 IMFAttributes_UnlockStore(dest
);
2982 LeaveCriticalSection(&attributes
->cs
);
2987 static HRESULT WINAPI
mfattributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
2989 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2991 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
2993 return attributes_GetItem(attributes
, key
, value
);
2996 static HRESULT WINAPI
mfattributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2998 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3000 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
3002 return attributes_GetItemType(attributes
, key
, type
);
3005 static HRESULT WINAPI
mfattributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
3007 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3009 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
3011 return attributes_CompareItem(attributes
, key
, value
, result
);
3014 static HRESULT WINAPI
mfattributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
3015 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
3017 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3019 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
3021 return attributes_Compare(attributes
, theirs
, match_type
, ret
);
3024 static HRESULT WINAPI
mfattributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
3026 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3028 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3030 return attributes_GetUINT32(attributes
, key
, value
);
3033 static HRESULT WINAPI
mfattributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
3035 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3037 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3039 return attributes_GetUINT64(attributes
, key
, value
);
3042 static HRESULT WINAPI
mfattributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
3044 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3046 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3048 return attributes_GetDouble(attributes
, key
, value
);
3051 static HRESULT WINAPI
mfattributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
3053 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3055 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3057 return attributes_GetGUID(attributes
, key
, value
);
3060 static HRESULT WINAPI
mfattributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
3062 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3064 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
3066 return attributes_GetStringLength(attributes
, key
, length
);
3069 static HRESULT WINAPI
mfattributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
3070 UINT32 size
, UINT32
*length
)
3072 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3074 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
3076 return attributes_GetString(attributes
, key
, value
, size
, length
);
3079 static HRESULT WINAPI
mfattributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
3081 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3083 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
3085 return attributes_GetAllocatedString(attributes
, key
, value
, length
);
3088 static HRESULT WINAPI
mfattributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
3090 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3092 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
3094 return attributes_GetBlobSize(attributes
, key
, size
);
3097 static HRESULT WINAPI
mfattributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
3098 UINT32 bufsize
, UINT32
*blobsize
)
3100 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3102 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
3104 return attributes_GetBlob(attributes
, key
, buf
, bufsize
, blobsize
);
3107 static HRESULT WINAPI
mfattributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
3109 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3111 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
3113 return attributes_GetAllocatedBlob(attributes
, key
, buf
, size
);
3116 static HRESULT WINAPI
mfattributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
3118 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3120 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
3122 return attributes_GetUnknown(attributes
, key
, riid
, out
);
3125 static HRESULT WINAPI
mfattributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
3127 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3129 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
3131 return attributes_SetItem(attributes
, key
, value
);
3134 static HRESULT WINAPI
mfattributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
3136 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3138 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
3140 return attributes_DeleteItem(attributes
, key
);
3143 static HRESULT WINAPI
mfattributes_DeleteAllItems(IMFAttributes
*iface
)
3145 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3147 TRACE("%p.\n", iface
);
3149 return attributes_DeleteAllItems(attributes
);
3152 static HRESULT WINAPI
mfattributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
3154 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3156 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
3158 return attributes_SetUINT32(attributes
, key
, value
);
3161 static HRESULT WINAPI
mfattributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
3163 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3165 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
3167 return attributes_SetUINT64(attributes
, key
, value
);
3170 static HRESULT WINAPI
mfattributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
3172 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3174 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
3176 return attributes_SetDouble(attributes
, key
, value
);
3179 static HRESULT WINAPI
mfattributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
3181 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3183 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
3185 return attributes_SetGUID(attributes
, key
, value
);
3188 static HRESULT WINAPI
mfattributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
3190 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3192 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
3194 return attributes_SetString(attributes
, key
, value
);
3197 static HRESULT WINAPI
mfattributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
3199 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3201 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
3203 return attributes_SetBlob(attributes
, key
, buf
, size
);
3206 static HRESULT WINAPI
mfattributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
3208 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3210 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
3212 return attributes_SetUnknown(attributes
, key
, unknown
);
3215 static HRESULT WINAPI
mfattributes_LockStore(IMFAttributes
*iface
)
3217 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3219 TRACE("%p.\n", iface
);
3221 return attributes_LockStore(attributes
);
3224 static HRESULT WINAPI
mfattributes_UnlockStore(IMFAttributes
*iface
)
3226 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3228 TRACE("%p.\n", iface
);
3230 return attributes_UnlockStore(attributes
);
3233 static HRESULT WINAPI
mfattributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
3235 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3237 TRACE("%p, %p.\n", iface
, count
);
3239 return attributes_GetCount(attributes
, count
);
3242 static HRESULT WINAPI
mfattributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
3244 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3246 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
3248 return attributes_GetItemByIndex(attributes
, index
, key
, value
);
3251 static HRESULT WINAPI
mfattributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
3253 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3255 TRACE("%p, %p.\n", iface
, dest
);
3257 return attributes_CopyAllItems(attributes
, dest
);
3260 static const IMFAttributesVtbl mfattributes_vtbl
=
3262 mfattributes_QueryInterface
,
3263 mfattributes_AddRef
,
3264 mfattributes_Release
,
3265 mfattributes_GetItem
,
3266 mfattributes_GetItemType
,
3267 mfattributes_CompareItem
,
3268 mfattributes_Compare
,
3269 mfattributes_GetUINT32
,
3270 mfattributes_GetUINT64
,
3271 mfattributes_GetDouble
,
3272 mfattributes_GetGUID
,
3273 mfattributes_GetStringLength
,
3274 mfattributes_GetString
,
3275 mfattributes_GetAllocatedString
,
3276 mfattributes_GetBlobSize
,
3277 mfattributes_GetBlob
,
3278 mfattributes_GetAllocatedBlob
,
3279 mfattributes_GetUnknown
,
3280 mfattributes_SetItem
,
3281 mfattributes_DeleteItem
,
3282 mfattributes_DeleteAllItems
,
3283 mfattributes_SetUINT32
,
3284 mfattributes_SetUINT64
,
3285 mfattributes_SetDouble
,
3286 mfattributes_SetGUID
,
3287 mfattributes_SetString
,
3288 mfattributes_SetBlob
,
3289 mfattributes_SetUnknown
,
3290 mfattributes_LockStore
,
3291 mfattributes_UnlockStore
,
3292 mfattributes_GetCount
,
3293 mfattributes_GetItemByIndex
,
3294 mfattributes_CopyAllItems
3297 HRESULT
init_attributes_object(struct attributes
*object
, UINT32 size
)
3299 object
->IMFAttributes_iface
.lpVtbl
= &mfattributes_vtbl
;
3301 InitializeCriticalSection(&object
->cs
);
3303 object
->attributes
= NULL
;
3305 object
->capacity
= 0;
3306 if (!mf_array_reserve((void **)&object
->attributes
, &object
->capacity
, size
,
3307 sizeof(*object
->attributes
)))
3309 DeleteCriticalSection(&object
->cs
);
3310 return E_OUTOFMEMORY
;
3316 void clear_attributes_object(struct attributes
*object
)
3320 for (i
= 0; i
< object
->count
; i
++)
3321 PropVariantClear(&object
->attributes
[i
].value
);
3322 free(object
->attributes
);
3324 DeleteCriticalSection(&object
->cs
);
3327 /***********************************************************************
3328 * MFCreateAttributes (mfplat.@)
3330 HRESULT WINAPI
MFCreateAttributes(IMFAttributes
**attributes
, UINT32 size
)
3332 struct attributes
*object
;
3335 TRACE("%p, %d\n", attributes
, size
);
3337 if (!(object
= calloc(1, sizeof(*object
))))
3338 return E_OUTOFMEMORY
;
3340 if (FAILED(hr
= init_attributes_object(object
, size
)))
3345 *attributes
= &object
->IMFAttributes_iface
;
3350 #define ATTRIBUTES_STORE_MAGIC 0x494d4641 /* IMFA */
3352 struct attributes_store_header
3358 struct attributes_store_item
3375 /***********************************************************************
3376 * MFGetAttributesAsBlobSize (mfplat.@)
3378 HRESULT WINAPI
MFGetAttributesAsBlobSize(IMFAttributes
*attributes
, UINT32
*size
)
3380 unsigned int i
, count
, length
;
3384 TRACE("%p, %p.\n", attributes
, size
);
3386 IMFAttributes_LockStore(attributes
);
3388 hr
= IMFAttributes_GetCount(attributes
, &count
);
3390 *size
= sizeof(struct attributes_store_header
);
3392 for (i
= 0; i
< count
; ++i
)
3394 MF_ATTRIBUTE_TYPE type
;
3396 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &key
, NULL
);
3400 *size
+= sizeof(struct attributes_store_item
);
3402 IMFAttributes_GetItemType(attributes
, &key
, &type
);
3406 case MF_ATTRIBUTE_GUID
:
3407 *size
+= sizeof(GUID
);
3409 case MF_ATTRIBUTE_STRING
:
3410 IMFAttributes_GetStringLength(attributes
, &key
, &length
);
3411 *size
+= (length
+ 1) * sizeof(WCHAR
);
3413 case MF_ATTRIBUTE_BLOB
:
3414 IMFAttributes_GetBlobSize(attributes
, &key
, &length
);
3417 case MF_ATTRIBUTE_UINT32
:
3418 case MF_ATTRIBUTE_UINT64
:
3419 case MF_ATTRIBUTE_DOUBLE
:
3420 case MF_ATTRIBUTE_IUNKNOWN
:
3426 IMFAttributes_UnlockStore(attributes
);
3431 struct attr_serialize_context
3438 static void attributes_serialize_write(struct attr_serialize_context
*context
, const void *value
, unsigned int size
)
3440 memcpy(context
->ptr
, value
, size
);
3441 context
->ptr
+= size
;
3444 static BOOL
attributes_serialize_write_item(struct attr_serialize_context
*context
, struct attributes_store_item
*item
,
3449 case MF_ATTRIBUTE_UINT32
:
3450 case MF_ATTRIBUTE_UINT64
:
3451 case MF_ATTRIBUTE_DOUBLE
:
3452 attributes_serialize_write(context
, item
, sizeof(*item
));
3454 case MF_ATTRIBUTE_GUID
:
3455 case MF_ATTRIBUTE_STRING
:
3456 case MF_ATTRIBUTE_BLOB
:
3457 item
->u
.subheader
.offset
= context
->size
- item
->u
.subheader
.size
;
3458 attributes_serialize_write(context
, item
, sizeof(*item
));
3459 memcpy(context
->buffer
+ item
->u
.subheader
.offset
, value
, item
->u
.subheader
.size
);
3460 context
->size
-= item
->u
.subheader
.size
;
3469 /***********************************************************************
3470 * MFGetAttributesAsBlob (mfplat.@)
3472 HRESULT WINAPI
MFGetAttributesAsBlob(IMFAttributes
*attributes
, UINT8
*buffer
, UINT size
)
3474 struct attributes_store_header header
;
3475 struct attr_serialize_context context
;
3476 unsigned int required_size
, i
;
3481 TRACE("%p, %p, %u.\n", attributes
, buffer
, size
);
3483 if (FAILED(hr
= MFGetAttributesAsBlobSize(attributes
, &required_size
)))
3486 if (required_size
> size
)
3487 return MF_E_BUFFERTOOSMALL
;
3489 context
.buffer
= buffer
;
3490 context
.ptr
= buffer
;
3491 context
.size
= required_size
;
3493 IMFAttributes_LockStore(attributes
);
3495 header
.magic
= ATTRIBUTES_STORE_MAGIC
;
3496 header
.count
= 0; /* Will be updated later */
3497 IMFAttributes_GetCount(attributes
, &count
);
3499 attributes_serialize_write(&context
, &header
, sizeof(header
));
3501 for (i
= 0; i
< count
; ++i
)
3503 struct attributes_store_item item
;
3504 const void *data
= NULL
;
3506 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &item
.key
, &value
);
3510 item
.type
= value
.vt
;
3514 case MF_ATTRIBUTE_UINT32
:
3515 case MF_ATTRIBUTE_UINT64
:
3516 item
.u
.i64
= value
.uhVal
.QuadPart
;
3518 case MF_ATTRIBUTE_DOUBLE
:
3519 item
.u
.f
= value
.dblVal
;
3521 case MF_ATTRIBUTE_GUID
:
3522 item
.u
.subheader
.size
= sizeof(*value
.puuid
);
3525 case MF_ATTRIBUTE_STRING
:
3526 item
.u
.subheader
.size
= (lstrlenW(value
.pwszVal
) + 1) * sizeof(WCHAR
);
3527 data
= value
.pwszVal
;
3529 case MF_ATTRIBUTE_BLOB
:
3530 item
.u
.subheader
.size
= value
.caub
.cElems
;
3531 data
= value
.caub
.pElems
;
3533 case MF_ATTRIBUTE_IUNKNOWN
:
3536 WARN("Unknown attribute type %#x.\n", value
.vt
);
3539 if (attributes_serialize_write_item(&context
, &item
, data
))
3542 PropVariantClear(&value
);
3545 memcpy(context
.buffer
, &header
, sizeof(header
));
3547 IMFAttributes_UnlockStore(attributes
);
3552 static HRESULT
attributes_deserialize_read(struct attr_serialize_context
*context
, void *value
, unsigned int size
)
3554 if (context
->size
< (context
->ptr
- context
->buffer
) + size
)
3555 return E_INVALIDARG
;
3557 memcpy(value
, context
->ptr
, size
);
3558 context
->ptr
+= size
;
3563 /***********************************************************************
3564 * MFInitAttributesFromBlob (mfplat.@)
3566 HRESULT WINAPI
MFInitAttributesFromBlob(IMFAttributes
*dest
, const UINT8
*buffer
, UINT size
)
3568 struct attr_serialize_context context
;
3569 struct attributes_store_header header
;
3570 struct attributes_store_item item
;
3571 IMFAttributes
*attributes
;
3575 TRACE("%p, %p, %u.\n", dest
, buffer
, size
);
3577 context
.buffer
= (UINT8
*)buffer
;
3578 context
.ptr
= (UINT8
*)buffer
;
3579 context
.size
= size
;
3581 /* Validate buffer structure. */
3582 if (FAILED(hr
= attributes_deserialize_read(&context
, &header
, sizeof(header
))))
3585 if (header
.magic
!= ATTRIBUTES_STORE_MAGIC
)
3586 return E_UNEXPECTED
;
3588 if (FAILED(hr
= MFCreateAttributes(&attributes
, header
.count
)))
3591 for (i
= 0; i
< header
.count
; ++i
)
3593 if (FAILED(hr
= attributes_deserialize_read(&context
, &item
, sizeof(item
))))
3600 case MF_ATTRIBUTE_UINT32
:
3601 hr
= IMFAttributes_SetUINT32(attributes
, &item
.key
, item
.u
.i32
);
3603 case MF_ATTRIBUTE_UINT64
:
3604 hr
= IMFAttributes_SetUINT64(attributes
, &item
.key
, item
.u
.i64
);
3606 case MF_ATTRIBUTE_DOUBLE
:
3607 hr
= IMFAttributes_SetDouble(attributes
, &item
.key
, item
.u
.f
);
3609 case MF_ATTRIBUTE_GUID
:
3610 if (item
.u
.subheader
.size
== sizeof(GUID
) &&
3611 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3613 hr
= IMFAttributes_SetGUID(attributes
, &item
.key
,
3614 (const GUID
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3617 case MF_ATTRIBUTE_STRING
:
3618 if (item
.u
.subheader
.size
>= sizeof(WCHAR
) &&
3619 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3621 hr
= IMFAttributes_SetString(attributes
, &item
.key
,
3622 (const WCHAR
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3625 case MF_ATTRIBUTE_BLOB
:
3626 if (item
.u
.subheader
.size
> 0 && item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3628 hr
= IMFAttributes_SetBlob(attributes
, &item
.key
, context
.buffer
+ item
.u
.subheader
.offset
,
3629 item
.u
.subheader
.size
);
3642 IMFAttributes_DeleteAllItems(dest
);
3643 hr
= IMFAttributes_CopyAllItems(attributes
, dest
);
3646 IMFAttributes_Release(attributes
);
3653 struct attributes attributes
;
3654 IMFByteStream IMFByteStream_iface
;
3655 IMFGetService IMFGetService_iface
;
3656 IRtwqAsyncCallback read_callback
;
3657 IRtwqAsyncCallback write_callback
;
3662 struct list pending
;
3663 CRITICAL_SECTION cs
;
3666 static inline struct bytestream
*impl_from_IMFByteStream(IMFByteStream
*iface
)
3668 return CONTAINING_RECORD(iface
, struct bytestream
, IMFByteStream_iface
);
3671 static struct bytestream
*impl_bytestream_from_IMFGetService(IMFGetService
*iface
)
3673 return CONTAINING_RECORD(iface
, struct bytestream
, IMFGetService_iface
);
3676 static struct bytestream
*impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3678 return CONTAINING_RECORD(iface
, struct bytestream
, read_callback
);
3681 static struct bytestream
*impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3683 return CONTAINING_RECORD(iface
, struct bytestream
, write_callback
);
3686 enum async_stream_op_type
3688 ASYNC_STREAM_OP_READ
,
3689 ASYNC_STREAM_OP_WRITE
,
3692 struct async_stream_op
3694 IUnknown IUnknown_iface
;
3702 ULONG requested_length
;
3703 ULONG actual_length
;
3704 IMFAsyncResult
*caller
;
3706 enum async_stream_op_type type
;
3709 static struct async_stream_op
*impl_async_stream_op_from_IUnknown(IUnknown
*iface
)
3711 return CONTAINING_RECORD(iface
, struct async_stream_op
, IUnknown_iface
);
3714 static HRESULT WINAPI
async_stream_op_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
3716 if (IsEqualIID(riid
, &IID_IUnknown
))
3719 IUnknown_AddRef(iface
);
3723 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3725 return E_NOINTERFACE
;
3728 static ULONG WINAPI
async_stream_op_AddRef(IUnknown
*iface
)
3730 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3731 ULONG refcount
= InterlockedIncrement(&op
->refcount
);
3733 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3738 static ULONG WINAPI
async_stream_op_Release(IUnknown
*iface
)
3740 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3741 ULONG refcount
= InterlockedDecrement(&op
->refcount
);
3743 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3748 IMFAsyncResult_Release(op
->caller
);
3755 static const IUnknownVtbl async_stream_op_vtbl
=
3757 async_stream_op_QueryInterface
,
3758 async_stream_op_AddRef
,
3759 async_stream_op_Release
,
3762 static HRESULT
bytestream_create_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3763 const BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
, IUnknown
*state
)
3765 struct async_stream_op
*op
;
3766 IRtwqAsyncResult
*request
;
3769 op
= malloc(sizeof(*op
));
3771 return E_OUTOFMEMORY
;
3773 op
->IUnknown_iface
.lpVtbl
= &async_stream_op_vtbl
;
3776 op
->position
= stream
->position
;
3777 op
->requested_length
= size
;
3779 if (FAILED(hr
= RtwqCreateAsyncResult((IUnknown
*)&stream
->IMFByteStream_iface
, (IRtwqAsyncCallback
*)callback
, state
,
3780 (IRtwqAsyncResult
**)&op
->caller
)))
3785 if (FAILED(hr
= RtwqCreateAsyncResult(&op
->IUnknown_iface
, type
== ASYNC_STREAM_OP_READ
? &stream
->read_callback
:
3786 &stream
->write_callback
, NULL
, &request
)))
3789 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, request
);
3790 IRtwqAsyncResult_Release(request
);
3793 IUnknown_Release(&op
->IUnknown_iface
);
3797 static HRESULT
bytestream_complete_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3798 IMFAsyncResult
*result
, ULONG
*actual_length
)
3800 struct async_stream_op
*op
= NULL
, *cur
;
3803 EnterCriticalSection(&stream
->cs
);
3804 LIST_FOR_EACH_ENTRY(cur
, &stream
->pending
, struct async_stream_op
, entry
)
3806 if (cur
->caller
== result
&& cur
->type
== type
)
3809 list_remove(&cur
->entry
);
3813 LeaveCriticalSection(&stream
->cs
);
3816 return E_INVALIDARG
;
3818 if (SUCCEEDED(hr
= IMFAsyncResult_GetStatus(result
)))
3819 *actual_length
= op
->actual_length
;
3821 IUnknown_Release(&op
->IUnknown_iface
);
3826 static HRESULT WINAPI
bytestream_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
3828 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
3829 IsEqualIID(riid
, &IID_IUnknown
))
3832 IRtwqAsyncCallback_AddRef(iface
);
3836 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3838 return E_NOINTERFACE
;
3841 static ULONG WINAPI
bytestream_read_callback_AddRef(IRtwqAsyncCallback
*iface
)
3843 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3844 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3847 static ULONG WINAPI
bytestream_read_callback_Release(IRtwqAsyncCallback
*iface
)
3849 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3850 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3853 static HRESULT WINAPI
bytestream_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
3858 static ULONG WINAPI
bytestream_write_callback_AddRef(IRtwqAsyncCallback
*iface
)
3860 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3861 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3864 static ULONG WINAPI
bytestream_write_callback_Release(IRtwqAsyncCallback
*iface
)
3866 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3867 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3870 static HRESULT WINAPI
bytestream_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
3872 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3874 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
3876 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
3877 IsEqualIID(riid
, &IID_IUnknown
))
3879 *out
= &stream
->IMFByteStream_iface
;
3881 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
3883 *out
= &stream
->attributes
.IMFAttributes_iface
;
3885 else if (stream
->IMFGetService_iface
.lpVtbl
&& IsEqualIID(riid
, &IID_IMFGetService
))
3887 *out
= &stream
->IMFGetService_iface
;
3891 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3893 return E_NOINTERFACE
;
3896 IUnknown_AddRef((IUnknown
*)*out
);
3900 static ULONG WINAPI
bytestream_AddRef(IMFByteStream
*iface
)
3902 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3903 ULONG refcount
= InterlockedIncrement(&stream
->attributes
.ref
);
3905 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3910 static ULONG WINAPI
bytestream_Release(IMFByteStream
*iface
)
3912 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3913 ULONG refcount
= InterlockedDecrement(&stream
->attributes
.ref
);
3914 struct async_stream_op
*cur
, *cur2
;
3916 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3920 clear_attributes_object(&stream
->attributes
);
3921 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &stream
->pending
, struct async_stream_op
, entry
)
3923 list_remove(&cur
->entry
);
3924 IUnknown_Release(&cur
->IUnknown_iface
);
3926 DeleteCriticalSection(&stream
->cs
);
3928 IStream_Release(stream
->stream
);
3930 CloseHandle(stream
->hfile
);
3937 static HRESULT WINAPI
bytestream_stream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3939 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3943 TRACE("%p, %p.\n", iface
, capabilities
);
3945 if (FAILED(hr
= IStream_Stat(stream
->stream
, &stat
, STATFLAG_NONAME
)))
3948 *capabilities
= MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_SEEKABLE
;
3949 if (stat
.grfMode
& (STGM_WRITE
| STGM_READWRITE
))
3950 *capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
3955 static HRESULT WINAPI
bytestream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3957 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3959 TRACE("%p, %p.\n", iface
, capabilities
);
3961 *capabilities
= stream
->capabilities
;
3966 static HRESULT WINAPI
bytestream_SetLength(IMFByteStream
*iface
, QWORD length
)
3968 FIXME("%p, %s\n", iface
, wine_dbgstr_longlong(length
));
3973 static HRESULT WINAPI
bytestream_file_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
3975 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3977 TRACE("%p, %p.\n", iface
, position
);
3980 return E_INVALIDARG
;
3982 *position
= stream
->position
;
3987 static HRESULT WINAPI
bytestream_file_GetLength(IMFByteStream
*iface
, QWORD
*length
)
3989 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3992 TRACE("%p, %p.\n", iface
, length
);
3995 return E_INVALIDARG
;
3997 if (GetFileSizeEx(stream
->hfile
, &li
))
3998 *length
= li
.QuadPart
;
4000 return HRESULT_FROM_WIN32(GetLastError());
4005 static HRESULT WINAPI
bytestream_file_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4007 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4008 LARGE_INTEGER position
, length
;
4011 TRACE("%p, %p.\n", iface
, ret
);
4013 EnterCriticalSection(&stream
->cs
);
4015 position
.QuadPart
= 0;
4016 if (SetFilePointerEx(stream
->hfile
, position
, &length
, FILE_END
))
4017 *ret
= stream
->position
>= length
.QuadPart
;
4019 hr
= HRESULT_FROM_WIN32(GetLastError());
4021 LeaveCriticalSection(&stream
->cs
);
4026 static HRESULT WINAPI
bytestream_file_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4028 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4029 LARGE_INTEGER position
;
4033 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, read_len
);
4035 EnterCriticalSection(&stream
->cs
);
4037 position
.QuadPart
= stream
->position
;
4038 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
4040 if ((ret
= ReadFile(stream
->hfile
, buffer
, size
, read_len
, NULL
)))
4041 stream
->position
+= *read_len
;
4045 hr
= HRESULT_FROM_WIN32(GetLastError());
4047 LeaveCriticalSection(&stream
->cs
);
4052 static HRESULT WINAPI
bytestream_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
,
4055 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4057 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4059 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_READ
, data
, size
, callback
, state
);
4062 static HRESULT WINAPI
bytestream_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4064 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4066 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4068 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_READ
, result
, byte_read
);
4071 static HRESULT WINAPI
bytestream_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4073 FIXME("%p, %p, %lu, %p\n", iface
, data
, count
, written
);
4078 static HRESULT WINAPI
bytestream_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4079 IMFAsyncCallback
*callback
, IUnknown
*state
)
4081 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4083 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4085 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_WRITE
, data
, size
, callback
, state
);
4088 static HRESULT WINAPI
bytestream_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4090 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4092 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4094 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_WRITE
, result
, written
);
4097 static HRESULT WINAPI
bytestream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
4098 DWORD flags
, QWORD
*current
)
4100 FIXME("%p, %u, %s, 0x%08lx, %p\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
4105 static HRESULT WINAPI
bytestream_Flush(IMFByteStream
*iface
)
4107 FIXME("%p\n", iface
);
4112 static HRESULT WINAPI
bytestream_Close(IMFByteStream
*iface
)
4114 FIXME("%p\n", iface
);
4119 static HRESULT WINAPI
bytestream_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4121 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4123 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4125 EnterCriticalSection(&stream
->cs
);
4126 stream
->position
= position
;
4127 LeaveCriticalSection(&stream
->cs
);
4132 static const IMFByteStreamVtbl bytestream_file_vtbl
=
4134 bytestream_QueryInterface
,
4137 bytestream_GetCapabilities
,
4138 bytestream_file_GetLength
,
4139 bytestream_SetLength
,
4140 bytestream_file_GetCurrentPosition
,
4141 bytestream_SetCurrentPosition
,
4142 bytestream_file_IsEndOfStream
,
4143 bytestream_file_Read
,
4144 bytestream_BeginRead
,
4147 bytestream_BeginWrite
,
4148 bytestream_EndWrite
,
4154 static HRESULT WINAPI
bytestream_stream_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4156 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4160 TRACE("%p, %p.\n", iface
, length
);
4162 if (FAILED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4165 *length
= statstg
.cbSize
.QuadPart
;
4170 static HRESULT WINAPI
bytestream_stream_SetLength(IMFByteStream
*iface
, QWORD length
)
4172 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4173 ULARGE_INTEGER size
;
4176 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4178 EnterCriticalSection(&stream
->cs
);
4180 size
.QuadPart
= length
;
4181 hr
= IStream_SetSize(stream
->stream
, size
);
4183 LeaveCriticalSection(&stream
->cs
);
4188 static HRESULT WINAPI
bytestream_stream_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4190 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4192 TRACE("%p, %p.\n", iface
, position
);
4194 *position
= stream
->position
;
4199 static HRESULT WINAPI
bytestream_stream_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4201 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4205 TRACE("%p, %p.\n", iface
, ret
);
4207 EnterCriticalSection(&stream
->cs
);
4209 if (SUCCEEDED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4210 *ret
= stream
->position
>= statstg
.cbSize
.QuadPart
;
4212 LeaveCriticalSection(&stream
->cs
);
4217 static HRESULT WINAPI
bytestream_stream_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4219 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4220 LARGE_INTEGER position
;
4223 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, read_len
);
4225 EnterCriticalSection(&stream
->cs
);
4227 position
.QuadPart
= stream
->position
;
4228 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4230 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, buffer
, size
, read_len
)))
4231 stream
->position
+= *read_len
;
4234 LeaveCriticalSection(&stream
->cs
);
4239 static HRESULT WINAPI
bytestream_stream_Write(IMFByteStream
*iface
, const BYTE
*buffer
, ULONG size
, ULONG
*written
)
4241 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4242 LARGE_INTEGER position
;
4245 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, written
);
4247 EnterCriticalSection(&stream
->cs
);
4249 position
.QuadPart
= stream
->position
;
4250 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4252 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, buffer
, size
, written
)))
4253 stream
->position
+= *written
;
4256 LeaveCriticalSection(&stream
->cs
);
4261 static HRESULT WINAPI
bytestream_stream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN origin
, LONGLONG offset
,
4262 DWORD flags
, QWORD
*current
)
4264 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4267 TRACE("%p, %u, %s, %#lx, %p.\n", iface
, origin
, wine_dbgstr_longlong(offset
), flags
, current
);
4269 EnterCriticalSection(&stream
->cs
);
4274 stream
->position
= offset
;
4277 stream
->position
+= offset
;
4280 WARN("Unknown origin mode %d.\n", origin
);
4284 *current
= stream
->position
;
4286 LeaveCriticalSection(&stream
->cs
);
4291 static HRESULT WINAPI
bytestream_stream_Flush(IMFByteStream
*iface
)
4293 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4295 TRACE("%p.\n", iface
);
4297 return IStream_Commit(stream
->stream
, STGC_DEFAULT
);
4300 static HRESULT WINAPI
bytestream_stream_Close(IMFByteStream
*iface
)
4302 TRACE("%p.\n", iface
);
4307 static const IMFByteStreamVtbl bytestream_stream_vtbl
=
4309 bytestream_QueryInterface
,
4312 bytestream_stream_GetCapabilities
,
4313 bytestream_stream_GetLength
,
4314 bytestream_stream_SetLength
,
4315 bytestream_stream_GetCurrentPosition
,
4316 bytestream_SetCurrentPosition
,
4317 bytestream_stream_IsEndOfStream
,
4318 bytestream_stream_Read
,
4319 bytestream_BeginRead
,
4321 bytestream_stream_Write
,
4322 bytestream_BeginWrite
,
4323 bytestream_EndWrite
,
4324 bytestream_stream_Seek
,
4325 bytestream_stream_Flush
,
4326 bytestream_stream_Close
,
4329 static inline struct bytestream
*impl_from_IMFByteStream_IMFAttributes(IMFAttributes
*iface
)
4331 return CONTAINING_RECORD(iface
, struct bytestream
, attributes
.IMFAttributes_iface
);
4334 static HRESULT WINAPI
bytestream_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
4336 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4337 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, out
);
4340 static ULONG WINAPI
bytestream_attributes_AddRef(IMFAttributes
*iface
)
4342 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4343 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4346 static ULONG WINAPI
bytestream_attributes_Release(IMFAttributes
*iface
)
4348 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4349 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4352 static const IMFAttributesVtbl bytestream_attributes_vtbl
=
4354 bytestream_attributes_QueryInterface
,
4355 bytestream_attributes_AddRef
,
4356 bytestream_attributes_Release
,
4357 mfattributes_GetItem
,
4358 mfattributes_GetItemType
,
4359 mfattributes_CompareItem
,
4360 mfattributes_Compare
,
4361 mfattributes_GetUINT32
,
4362 mfattributes_GetUINT64
,
4363 mfattributes_GetDouble
,
4364 mfattributes_GetGUID
,
4365 mfattributes_GetStringLength
,
4366 mfattributes_GetString
,
4367 mfattributes_GetAllocatedString
,
4368 mfattributes_GetBlobSize
,
4369 mfattributes_GetBlob
,
4370 mfattributes_GetAllocatedBlob
,
4371 mfattributes_GetUnknown
,
4372 mfattributes_SetItem
,
4373 mfattributes_DeleteItem
,
4374 mfattributes_DeleteAllItems
,
4375 mfattributes_SetUINT32
,
4376 mfattributes_SetUINT64
,
4377 mfattributes_SetDouble
,
4378 mfattributes_SetGUID
,
4379 mfattributes_SetString
,
4380 mfattributes_SetBlob
,
4381 mfattributes_SetUnknown
,
4382 mfattributes_LockStore
,
4383 mfattributes_UnlockStore
,
4384 mfattributes_GetCount
,
4385 mfattributes_GetItemByIndex
,
4386 mfattributes_CopyAllItems
4389 static HRESULT WINAPI
bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4391 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4392 struct async_stream_op
*op
;
4393 LARGE_INTEGER position
;
4397 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4400 op
= impl_async_stream_op_from_IUnknown(object
);
4402 EnterCriticalSection(&stream
->cs
);
4404 position
.QuadPart
= op
->position
;
4405 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4407 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, op
->u
.dest
, op
->requested_length
, &op
->actual_length
)))
4408 stream
->position
+= op
->actual_length
;
4411 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4412 list_add_tail(&stream
->pending
, &op
->entry
);
4414 LeaveCriticalSection(&stream
->cs
);
4416 MFInvokeCallback(op
->caller
);
4421 static HRESULT WINAPI
bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4423 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4424 struct async_stream_op
*op
;
4425 LARGE_INTEGER position
;
4429 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4432 op
= impl_async_stream_op_from_IUnknown(object
);
4434 EnterCriticalSection(&stream
->cs
);
4436 position
.QuadPart
= op
->position
;
4437 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4439 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, op
->u
.src
, op
->requested_length
, &op
->actual_length
)))
4440 stream
->position
+= op
->actual_length
;
4443 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4444 list_add_tail(&stream
->pending
, &op
->entry
);
4446 LeaveCriticalSection(&stream
->cs
);
4448 MFInvokeCallback(op
->caller
);
4453 static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl
=
4455 bytestream_callback_QueryInterface
,
4456 bytestream_read_callback_AddRef
,
4457 bytestream_read_callback_Release
,
4458 bytestream_callback_GetParameters
,
4459 bytestream_stream_read_callback_Invoke
,
4462 static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl
=
4464 bytestream_callback_QueryInterface
,
4465 bytestream_write_callback_AddRef
,
4466 bytestream_write_callback_Release
,
4467 bytestream_callback_GetParameters
,
4468 bytestream_stream_write_callback_Invoke
,
4471 /***********************************************************************
4472 * MFCreateMFByteStreamOnStream (mfplat.@)
4474 HRESULT WINAPI
MFCreateMFByteStreamOnStream(IStream
*stream
, IMFByteStream
**bytestream
)
4476 struct bytestream
*object
;
4477 LARGE_INTEGER position
;
4481 TRACE("%p, %p.\n", stream
, bytestream
);
4483 if (!(object
= calloc(1, sizeof(*object
))))
4484 return E_OUTOFMEMORY
;
4486 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
4492 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_stream_vtbl
;
4493 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4494 object
->read_callback
.lpVtbl
= &bytestream_stream_read_callback_vtbl
;
4495 object
->write_callback
.lpVtbl
= &bytestream_stream_write_callback_vtbl
;
4496 InitializeCriticalSection(&object
->cs
);
4497 list_init(&object
->pending
);
4499 object
->stream
= stream
;
4500 IStream_AddRef(object
->stream
);
4501 position
.QuadPart
= 0;
4502 IStream_Seek(object
->stream
, position
, STREAM_SEEK_SET
, NULL
);
4504 if (SUCCEEDED(IStream_Stat(object
->stream
, &stat
, 0)))
4508 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
,
4510 CoTaskMemFree(stat
.pwcsName
);
4514 *bytestream
= &object
->IMFByteStream_iface
;
4519 static HRESULT WINAPI
bytestream_file_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4521 FIXME("%p, %p.\n", iface
, result
);
4526 static HRESULT WINAPI
bytestream_file_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4528 FIXME("%p, %p.\n", iface
, result
);
4533 static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl
=
4535 bytestream_callback_QueryInterface
,
4536 bytestream_read_callback_AddRef
,
4537 bytestream_read_callback_Release
,
4538 bytestream_callback_GetParameters
,
4539 bytestream_file_read_callback_Invoke
,
4542 static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl
=
4544 bytestream_callback_QueryInterface
,
4545 bytestream_write_callback_AddRef
,
4546 bytestream_write_callback_Release
,
4547 bytestream_callback_GetParameters
,
4548 bytestream_file_write_callback_Invoke
,
4551 static HRESULT WINAPI
bytestream_file_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
4553 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4554 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, obj
);
4557 static ULONG WINAPI
bytestream_file_getservice_AddRef(IMFGetService
*iface
)
4559 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4560 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4563 static ULONG WINAPI
bytestream_file_getservice_Release(IMFGetService
*iface
)
4565 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4566 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4569 static HRESULT WINAPI
bytestream_file_getservice_GetService(IMFGetService
*iface
, REFGUID service
,
4570 REFIID riid
, void **obj
)
4572 FIXME("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
4577 static const IMFGetServiceVtbl bytestream_file_getservice_vtbl
=
4579 bytestream_file_getservice_QueryInterface
,
4580 bytestream_file_getservice_AddRef
,
4581 bytestream_file_getservice_Release
,
4582 bytestream_file_getservice_GetService
,
4585 static HRESULT
create_file_bytestream(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4586 const WCHAR
*path
, BOOL is_tempfile
, IMFByteStream
**bytestream
)
4588 DWORD capabilities
= MFBYTESTREAM_IS_SEEKABLE
| MFBYTESTREAM_DOES_NOT_USE_NETWORK
;
4589 DWORD filecreation_disposition
= 0, fileaccessmode
= 0, fileattributes
= 0;
4590 DWORD filesharemode
= FILE_SHARE_READ
| FILE_SHARE_DELETE
;
4591 struct bytestream
*object
;
4598 case MF_ACCESSMODE_READ
:
4599 fileaccessmode
= GENERIC_READ
;
4600 capabilities
|= MFBYTESTREAM_IS_READABLE
;
4602 case MF_ACCESSMODE_WRITE
:
4603 fileaccessmode
= GENERIC_WRITE
;
4604 capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
4606 case MF_ACCESSMODE_READWRITE
:
4607 fileaccessmode
= GENERIC_READ
| GENERIC_WRITE
;
4608 capabilities
|= (MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_WRITABLE
);
4614 case MF_OPENMODE_FAIL_IF_NOT_EXIST
:
4615 filecreation_disposition
= OPEN_EXISTING
;
4617 case MF_OPENMODE_FAIL_IF_EXIST
:
4618 filecreation_disposition
= CREATE_NEW
;
4620 case MF_OPENMODE_RESET_IF_EXIST
:
4621 filecreation_disposition
= TRUNCATE_EXISTING
;
4623 case MF_OPENMODE_APPEND_IF_EXIST
:
4624 filecreation_disposition
= OPEN_ALWAYS
;
4625 fileaccessmode
|= FILE_APPEND_DATA
;
4627 case MF_OPENMODE_DELETE_IF_EXIST
:
4628 filecreation_disposition
= CREATE_ALWAYS
;
4632 if (flags
& MF_FILEFLAGS_NOBUFFERING
)
4633 fileattributes
|= FILE_FLAG_NO_BUFFERING
;
4635 fileattributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
4637 /* Open HANDLE to file */
4638 file
= CreateFileW(path
, fileaccessmode
, filesharemode
, NULL
, filecreation_disposition
, fileattributes
, 0);
4639 if (file
== INVALID_HANDLE_VALUE
)
4640 return HRESULT_FROM_WIN32(GetLastError());
4642 if (!(object
= calloc(1, sizeof(*object
))))
4645 return E_OUTOFMEMORY
;
4648 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 2)))
4654 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_file_vtbl
;
4655 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4656 object
->IMFGetService_iface
.lpVtbl
= &bytestream_file_getservice_vtbl
;
4657 object
->read_callback
.lpVtbl
= &bytestream_file_read_callback_vtbl
;
4658 object
->write_callback
.lpVtbl
= &bytestream_file_write_callback_vtbl
;
4659 InitializeCriticalSection(&object
->cs
);
4660 list_init(&object
->pending
);
4661 object
->capabilities
= capabilities
;
4662 object
->hfile
= file
;
4664 if (!is_tempfile
&& GetFileTime(file
, NULL
, NULL
, &writetime
))
4666 IMFAttributes_SetBlob(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_LAST_MODIFIED_TIME
,
4667 (const UINT8
*)&writetime
, sizeof(writetime
));
4670 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
, path
);
4672 *bytestream
= &object
->IMFByteStream_iface
;
4677 /***********************************************************************
4678 * MFCreateFile (mfplat.@)
4680 HRESULT WINAPI
MFCreateFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4681 const WCHAR
*path
, IMFByteStream
**bytestream
)
4683 TRACE("%d, %d, %#x, %s, %p.\n", accessmode
, openmode
, flags
, debugstr_w(path
), bytestream
);
4685 return create_file_bytestream(accessmode
, openmode
, flags
, path
, FALSE
, bytestream
);
4688 /***********************************************************************
4689 * MFCreateTempFile (mfplat.@)
4691 HRESULT WINAPI
MFCreateTempFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4692 IMFByteStream
**bytestream
)
4694 WCHAR name
[24], tmppath
[MAX_PATH
], *path
;
4699 TRACE("%d, %d, %#x, %p.\n", accessmode
, openmode
, flags
, bytestream
);
4701 BCryptGenRandom(NULL
, (UCHAR
*)&rnd
, sizeof(rnd
), BCRYPT_USE_SYSTEM_PREFERRED_RNG
);
4702 swprintf(name
, ARRAY_SIZE(name
), L
"MFP%llX.TMP", rnd
);
4703 GetTempPathW(ARRAY_SIZE(tmppath
), tmppath
);
4705 len
= wcslen(tmppath
) + wcslen(name
) + 2;
4706 if (!(path
= malloc(len
* sizeof(*path
))))
4707 return E_OUTOFMEMORY
;
4709 wcscpy(path
, tmppath
);
4710 PathCchAppend(path
, len
, name
);
4712 hr
= create_file_bytestream(accessmode
, openmode
, flags
, path
, TRUE
, bytestream
);
4719 struct bytestream_wrapper
4721 IMFByteStreamCacheControl IMFByteStreamCacheControl_iface
;
4722 IMFByteStreamBuffering IMFByteStreamBuffering_iface
;
4723 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
4724 IMFByteStreamTimeSeek IMFByteStreamTimeSeek_iface
;
4725 IMFSampleOutputStream IMFSampleOutputStream_iface
;
4726 IPropertyStore IPropertyStore_iface
;
4727 IMFByteStream IMFByteStream_iface
;
4728 IMFAttributes IMFAttributes_iface
;
4731 IMFByteStreamCacheControl
*cache_control
;
4732 IMFByteStreamBuffering
*stream_buffering
;
4733 IMFMediaEventGenerator
*event_generator
;
4734 IMFByteStreamTimeSeek
*time_seek
;
4735 IMFSampleOutputStream
*sample_output
;
4736 IPropertyStore
*propstore
;
4737 IMFByteStream
*stream
;
4738 IMFAttributes
*attributes
;
4742 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStream(IMFByteStream
*iface
)
4744 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStream_iface
);
4747 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamCacheControl(IMFByteStreamCacheControl
*iface
)
4749 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamCacheControl_iface
);
4752 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamBuffering(IMFByteStreamBuffering
*iface
)
4754 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamBuffering_iface
);
4757 static struct bytestream_wrapper
*impl_wrapper_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
4759 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFMediaEventGenerator_iface
);
4762 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamTimeSeek(IMFByteStreamTimeSeek
*iface
)
4764 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamTimeSeek_iface
);
4767 static struct bytestream_wrapper
*impl_wrapper_from_IMFSampleOutputStream(IMFSampleOutputStream
*iface
)
4769 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFSampleOutputStream_iface
);
4772 static struct bytestream_wrapper
*impl_wrapper_from_IPropertyStore(IPropertyStore
*iface
)
4774 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IPropertyStore_iface
);
4777 static struct bytestream_wrapper
*impl_wrapper_from_IMFAttributes(IMFAttributes
*iface
)
4779 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFAttributes_iface
);
4782 static HRESULT WINAPI
bytestream_wrapper_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
4784 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4786 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
4788 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
4789 IsEqualIID(riid
, &IID_IUnknown
))
4791 *out
= &wrapper
->IMFByteStream_iface
;
4793 else if (wrapper
->cache_control
&& IsEqualIID(riid
, &IID_IMFByteStreamCacheControl
))
4795 *out
= &wrapper
->IMFByteStreamCacheControl_iface
;
4797 else if (wrapper
->stream_buffering
&& IsEqualIID(riid
, &IID_IMFByteStreamBuffering
))
4799 *out
= &wrapper
->IMFByteStreamBuffering_iface
;
4801 else if (wrapper
->event_generator
&& IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
4803 *out
= &wrapper
->IMFMediaEventGenerator_iface
;
4805 else if (wrapper
->time_seek
&& IsEqualIID(riid
, &IID_IMFByteStreamTimeSeek
))
4807 *out
= &wrapper
->IMFByteStreamTimeSeek_iface
;
4809 else if (wrapper
->sample_output
&& IsEqualIID(riid
, &IID_IMFSampleOutputStream
))
4811 *out
= &wrapper
->IMFSampleOutputStream_iface
;
4813 else if (wrapper
->propstore
&& IsEqualIID(riid
, &IID_IPropertyStore
))
4815 *out
= &wrapper
->IPropertyStore_iface
;
4817 else if (wrapper
->attributes
&& IsEqualIID(riid
, &IID_IMFAttributes
))
4819 *out
= &wrapper
->IMFAttributes_iface
;
4823 WARN("Unsupported %s.\n", debugstr_guid(riid
));
4825 return E_NOINTERFACE
;
4828 IUnknown_AddRef((IUnknown
*)*out
);
4832 static ULONG WINAPI
bytestream_wrapper_AddRef(IMFByteStream
*iface
)
4834 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4835 ULONG refcount
= InterlockedIncrement(&wrapper
->refcount
);
4837 TRACE("%p, refcount %ld.\n", iface
, refcount
);
4842 static ULONG WINAPI
bytestream_wrapper_Release(IMFByteStream
*iface
)
4844 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4845 ULONG refcount
= InterlockedDecrement(&wrapper
->refcount
);
4847 TRACE("%p, refcount %ld.\n", iface
, refcount
);
4851 if (wrapper
->cache_control
)
4852 IMFByteStreamCacheControl_Release(wrapper
->cache_control
);
4853 if (wrapper
->stream_buffering
)
4854 IMFByteStreamBuffering_Release(wrapper
->stream_buffering
);
4855 if (wrapper
->event_generator
)
4856 IMFMediaEventGenerator_Release(wrapper
->event_generator
);
4857 if (wrapper
->time_seek
)
4858 IMFByteStreamTimeSeek_Release(wrapper
->time_seek
);
4859 if (wrapper
->sample_output
)
4860 IMFSampleOutputStream_Release(wrapper
->sample_output
);
4861 if (wrapper
->propstore
)
4862 IPropertyStore_Release(wrapper
->propstore
);
4863 if (wrapper
->attributes
)
4864 IMFAttributes_Release(wrapper
->attributes
);
4865 IMFByteStream_Release(wrapper
->stream
);
4872 static HRESULT WINAPI
bytestream_wrapper_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
4874 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4876 TRACE("%p, %p.\n", iface
, capabilities
);
4878 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4879 IMFByteStream_GetCapabilities(wrapper
->stream
, capabilities
);
4882 static HRESULT WINAPI
bytestream_wrapper_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4884 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4886 TRACE("%p, %p.\n", iface
, length
);
4888 if (wrapper
->is_closed
)
4889 return MF_E_INVALIDREQUEST
;
4891 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4892 IMFByteStream_GetLength(wrapper
->stream
, length
);
4895 static HRESULT WINAPI
bytestream_wrapper_SetLength(IMFByteStream
*iface
, QWORD length
)
4897 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4899 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4901 if (wrapper
->is_closed
)
4902 return MF_E_INVALIDREQUEST
;
4904 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4905 IMFByteStream_SetLength(wrapper
->stream
, length
);
4908 static HRESULT WINAPI
bytestream_wrapper_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4910 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4912 TRACE("%p, %p.\n", iface
, position
);
4914 if (wrapper
->is_closed
)
4915 return MF_E_INVALIDREQUEST
;
4917 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4918 IMFByteStream_GetCurrentPosition(wrapper
->stream
, position
);
4921 static HRESULT WINAPI
bytestream_wrapper_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4923 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4925 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4927 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4928 IMFByteStream_SetCurrentPosition(wrapper
->stream
, position
);
4931 static HRESULT WINAPI
bytestream_wrapper_IsEndOfStream(IMFByteStream
*iface
, BOOL
*eos
)
4933 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4935 TRACE("%p, %p.\n", iface
, eos
);
4937 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4938 IMFByteStream_IsEndOfStream(wrapper
->stream
, eos
);
4941 static HRESULT WINAPI
bytestream_wrapper_Read(IMFByteStream
*iface
, BYTE
*data
, ULONG count
, ULONG
*byte_read
)
4943 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4945 TRACE("%p, %p, %lu, %p.\n", iface
, data
, count
, byte_read
);
4947 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4948 IMFByteStream_Read(wrapper
->stream
, data
, count
, byte_read
);
4951 static HRESULT WINAPI
bytestream_wrapper_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
,
4952 IMFAsyncCallback
*callback
, IUnknown
*state
)
4954 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4956 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4958 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4959 IMFByteStream_BeginRead(wrapper
->stream
, data
, size
, callback
, state
);
4962 static HRESULT WINAPI
bytestream_wrapper_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4964 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4966 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4968 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4969 IMFByteStream_EndRead(wrapper
->stream
, result
, byte_read
);
4972 static HRESULT WINAPI
bytestream_wrapper_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4974 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4976 TRACE("%p, %p, %lu, %p.\n", iface
, data
, count
, written
);
4978 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4979 IMFByteStream_Write(wrapper
->stream
, data
, count
, written
);
4982 static HRESULT WINAPI
bytestream_wrapper_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4983 IMFAsyncCallback
*callback
, IUnknown
*state
)
4985 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4987 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4989 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4990 IMFByteStream_BeginWrite(wrapper
->stream
, data
, size
, callback
, state
);
4993 static HRESULT WINAPI
bytestream_wrapper_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4995 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4997 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4999 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
5000 IMFByteStream_EndWrite(wrapper
->stream
, result
, written
);
5003 static HRESULT WINAPI
bytestream_wrapper_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
5004 DWORD flags
, QWORD
*current
)
5006 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
5008 TRACE("%p, %u, %s, %#lx, %p.\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
5010 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
5011 IMFByteStream_Seek(wrapper
->stream
, seek
, offset
, flags
, current
);
5014 static HRESULT WINAPI
bytestream_wrapper_Flush(IMFByteStream
*iface
)
5016 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
5018 TRACE("%p\n", iface
);
5020 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
: IMFByteStream_Flush(wrapper
->stream
);
5023 static HRESULT WINAPI
bytestream_wrapper_Close(IMFByteStream
*iface
)
5025 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
5027 TRACE("%p\n", iface
);
5029 wrapper
->is_closed
= TRUE
;
5034 static const IMFByteStreamVtbl bytestream_wrapper_vtbl
=
5036 bytestream_wrapper_QueryInterface
,
5037 bytestream_wrapper_AddRef
,
5038 bytestream_wrapper_Release
,
5039 bytestream_wrapper_GetCapabilities
,
5040 bytestream_wrapper_GetLength
,
5041 bytestream_wrapper_SetLength
,
5042 bytestream_wrapper_GetCurrentPosition
,
5043 bytestream_wrapper_SetCurrentPosition
,
5044 bytestream_wrapper_IsEndOfStream
,
5045 bytestream_wrapper_Read
,
5046 bytestream_wrapper_BeginRead
,
5047 bytestream_wrapper_EndRead
,
5048 bytestream_wrapper_Write
,
5049 bytestream_wrapper_BeginWrite
,
5050 bytestream_wrapper_EndWrite
,
5051 bytestream_wrapper_Seek
,
5052 bytestream_wrapper_Flush
,
5053 bytestream_wrapper_Close
,
5056 static HRESULT WINAPI
bytestream_wrapper_cache_control_QueryInterface(IMFByteStreamCacheControl
*iface
,
5057 REFIID riid
, void **obj
)
5059 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5060 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5063 static ULONG WINAPI
bytestream_wrapper_cache_control_AddRef(IMFByteStreamCacheControl
*iface
)
5065 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5066 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5069 static ULONG WINAPI
bytestream_wrapper_cache_control_Release(IMFByteStreamCacheControl
*iface
)
5071 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5072 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5075 static HRESULT WINAPI
bytestream_wrapper_cache_control_StopBackgroundTransfer(IMFByteStreamCacheControl
*iface
)
5077 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5079 TRACE("%p.\n", iface
);
5081 return IMFByteStreamCacheControl_StopBackgroundTransfer(wrapper
->cache_control
);
5084 static const IMFByteStreamCacheControlVtbl bytestream_wrapper_cache_control_vtbl
=
5086 bytestream_wrapper_cache_control_QueryInterface
,
5087 bytestream_wrapper_cache_control_AddRef
,
5088 bytestream_wrapper_cache_control_Release
,
5089 bytestream_wrapper_cache_control_StopBackgroundTransfer
,
5092 static HRESULT WINAPI
bytestream_wrapper_buffering_QueryInterface(IMFByteStreamBuffering
*iface
,
5093 REFIID riid
, void **obj
)
5095 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5096 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5099 static ULONG WINAPI
bytestream_wrapper_buffering_AddRef(IMFByteStreamBuffering
*iface
)
5101 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5102 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5105 static ULONG WINAPI
bytestream_wrapper_buffering_Release(IMFByteStreamBuffering
*iface
)
5107 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5108 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5111 static HRESULT WINAPI
bytestream_wrapper_buffering_SetBufferingParams(IMFByteStreamBuffering
*iface
,
5112 MFBYTESTREAM_BUFFERING_PARAMS
*params
)
5114 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5116 TRACE("%p, %p.\n", iface
, params
);
5118 return IMFByteStreamBuffering_SetBufferingParams(wrapper
->stream_buffering
, params
);
5121 static HRESULT WINAPI
bytestream_wrapper_buffering_EnableBuffering(IMFByteStreamBuffering
*iface
,
5124 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5126 TRACE("%p, %d.\n", iface
, enable
);
5128 return IMFByteStreamBuffering_EnableBuffering(wrapper
->stream_buffering
, enable
);
5131 static HRESULT WINAPI
bytestream_wrapper_buffering_StopBuffering(IMFByteStreamBuffering
*iface
)
5133 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5135 TRACE("%p.\n", iface
);
5137 return IMFByteStreamBuffering_StopBuffering(wrapper
->stream_buffering
);
5140 static const IMFByteStreamBufferingVtbl bytestream_wrapper_buffering_vtbl
=
5142 bytestream_wrapper_buffering_QueryInterface
,
5143 bytestream_wrapper_buffering_AddRef
,
5144 bytestream_wrapper_buffering_Release
,
5145 bytestream_wrapper_buffering_SetBufferingParams
,
5146 bytestream_wrapper_buffering_EnableBuffering
,
5147 bytestream_wrapper_buffering_StopBuffering
,
5150 static HRESULT WINAPI
bytestream_wrapper_timeseek_QueryInterface(IMFByteStreamTimeSeek
*iface
,
5151 REFIID riid
, void **obj
)
5153 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5154 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5157 static ULONG WINAPI
bytestream_wrapper_timeseek_AddRef(IMFByteStreamTimeSeek
*iface
)
5159 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5160 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5163 static ULONG WINAPI
bytestream_wrapper_timeseek_Release(IMFByteStreamTimeSeek
*iface
)
5165 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5166 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5169 static HRESULT WINAPI
bytestream_wrapper_timeseek_IsTimeSeekSupported(IMFByteStreamTimeSeek
*iface
, BOOL
*result
)
5171 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5173 TRACE("%p, %p.\n", iface
, result
);
5175 return IMFByteStreamTimeSeek_IsTimeSeekSupported(wrapper
->time_seek
, result
);
5178 static HRESULT WINAPI
bytestream_wrapper_timeseek_TimeSeek(IMFByteStreamTimeSeek
*iface
, QWORD position
)
5180 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5182 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
5184 return IMFByteStreamTimeSeek_TimeSeek(wrapper
->time_seek
, position
);
5187 static HRESULT WINAPI
bytestream_wrapper_timeseek_GetTimeSeekResult(IMFByteStreamTimeSeek
*iface
, QWORD
*start_time
,
5188 QWORD
*stop_time
, QWORD
*duration
)
5190 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5192 TRACE("%p, %p, %p, %p.\n", iface
, start_time
, stop_time
, duration
);
5194 return IMFByteStreamTimeSeek_GetTimeSeekResult(wrapper
->time_seek
, start_time
, stop_time
, duration
);
5197 static const IMFByteStreamTimeSeekVtbl bytestream_wrapper_timeseek_vtbl
=
5199 bytestream_wrapper_timeseek_QueryInterface
,
5200 bytestream_wrapper_timeseek_AddRef
,
5201 bytestream_wrapper_timeseek_Release
,
5202 bytestream_wrapper_timeseek_IsTimeSeekSupported
,
5203 bytestream_wrapper_timeseek_TimeSeek
,
5204 bytestream_wrapper_timeseek_GetTimeSeekResult
,
5207 static HRESULT WINAPI
bytestream_wrapper_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
5209 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5210 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5213 static ULONG WINAPI
bytestream_wrapper_events_AddRef(IMFMediaEventGenerator
*iface
)
5215 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5216 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5219 static ULONG WINAPI
bytestream_wrapper_events_Release(IMFMediaEventGenerator
*iface
)
5221 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5222 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5225 static HRESULT WINAPI
bytestream_wrapper_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
5227 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5229 TRACE("%p, %#lx, %p.\n", iface
, flags
, event
);
5231 return IMFMediaEventGenerator_GetEvent(wrapper
->event_generator
, flags
, event
);
5234 static HRESULT WINAPI
bytestream_wrapper_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
5236 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5238 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
5240 return IMFMediaEventGenerator_BeginGetEvent(wrapper
->event_generator
, callback
, state
);
5243 static HRESULT WINAPI
bytestream_wrapper_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
5245 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5247 TRACE("%p, %p, %p.\n", iface
, result
, event
);
5249 return IMFMediaEventGenerator_EndGetEvent(wrapper
->event_generator
, result
, event
);
5252 static HRESULT WINAPI
bytestream_wrapper_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType type
,
5253 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
5255 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5257 TRACE("%p, %ld, %s, %#lx, %s.\n", iface
, type
, debugstr_guid(ext_type
), hr
, debugstr_propvar(value
));
5259 return IMFMediaEventGenerator_QueueEvent(wrapper
->event_generator
, type
, ext_type
, hr
, value
);
5262 static const IMFMediaEventGeneratorVtbl bytestream_wrapper_events_vtbl
=
5264 bytestream_wrapper_events_QueryInterface
,
5265 bytestream_wrapper_events_AddRef
,
5266 bytestream_wrapper_events_Release
,
5267 bytestream_wrapper_events_GetEvent
,
5268 bytestream_wrapper_events_BeginGetEvent
,
5269 bytestream_wrapper_events_EndGetEvent
,
5270 bytestream_wrapper_events_QueueEvent
,
5273 static HRESULT WINAPI
bytestream_wrapper_sample_output_QueryInterface(IMFSampleOutputStream
*iface
, REFIID riid
, void **obj
)
5275 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5276 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5279 static ULONG WINAPI
bytestream_wrapper_sample_output_AddRef(IMFSampleOutputStream
*iface
)
5281 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5282 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5285 static ULONG WINAPI
bytestream_wrapper_sample_output_Release(IMFSampleOutputStream
*iface
)
5287 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5288 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5291 static HRESULT WINAPI
bytestream_wrapper_sample_output_BeginWriteSample(IMFSampleOutputStream
*iface
, IMFSample
*sample
,
5292 IMFAsyncCallback
*callback
, IUnknown
*state
)
5294 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5296 TRACE("%p, %p, %p, %p.\n", iface
, sample
, callback
, state
);
5298 return IMFSampleOutputStream_BeginWriteSample(wrapper
->sample_output
, sample
, callback
, state
);
5301 static HRESULT WINAPI
bytestream_wrapper_sample_output_EndWriteSample(IMFSampleOutputStream
*iface
, IMFAsyncResult
*result
)
5303 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5305 TRACE("%p, %p.\n", iface
, result
);
5307 return IMFSampleOutputStream_EndWriteSample(wrapper
->sample_output
, result
);
5310 static HRESULT WINAPI
bytestream_wrapper_sample_output_Close(IMFSampleOutputStream
*iface
)
5312 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5314 TRACE("%p.\n", iface
);
5316 return IMFSampleOutputStream_Close(wrapper
->sample_output
);
5319 static const IMFSampleOutputStreamVtbl bytestream_wrapper_sample_output_vtbl
=
5321 bytestream_wrapper_sample_output_QueryInterface
,
5322 bytestream_wrapper_sample_output_AddRef
,
5323 bytestream_wrapper_sample_output_Release
,
5324 bytestream_wrapper_sample_output_BeginWriteSample
,
5325 bytestream_wrapper_sample_output_EndWriteSample
,
5326 bytestream_wrapper_sample_output_Close
,
5329 static HRESULT WINAPI
bytestream_wrapper_propstore_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
5331 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5332 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5335 static ULONG WINAPI
bytestream_wrapper_propstore_AddRef(IPropertyStore
*iface
)
5337 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5338 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5341 static ULONG WINAPI
bytestream_wrapper_propstore_Release(IPropertyStore
*iface
)
5343 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5344 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5347 static HRESULT WINAPI
bytestream_wrapper_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
5349 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5351 TRACE("%p, %p.\n", iface
, count
);
5353 return IPropertyStore_GetCount(wrapper
->propstore
, count
);
5356 static HRESULT WINAPI
bytestream_wrapper_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
5358 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5360 TRACE("%p, %lu, %p.\n", iface
, prop
, key
);
5362 return IPropertyStore_GetAt(wrapper
->propstore
, prop
, key
);
5365 static HRESULT WINAPI
bytestream_wrapper_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
5367 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5369 TRACE("%p, %p, %p.\n", iface
, key
, value
);
5371 return IPropertyStore_GetValue(wrapper
->propstore
, key
, value
);
5374 static HRESULT WINAPI
bytestream_wrapper_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
,
5375 const PROPVARIANT
*value
)
5377 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5379 TRACE("%p, %p, %s.\n", iface
, key
, debugstr_propvar(value
));
5381 return IPropertyStore_SetValue(wrapper
->propstore
, key
, value
);
5384 static HRESULT WINAPI
bytestream_wrapper_propstore_Commit(IPropertyStore
*iface
)
5386 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5388 TRACE("%p.\n", iface
);
5390 return IPropertyStore_Commit(wrapper
->propstore
);
5393 static const IPropertyStoreVtbl bytestream_wrapper_propstore_vtbl
=
5395 bytestream_wrapper_propstore_QueryInterface
,
5396 bytestream_wrapper_propstore_AddRef
,
5397 bytestream_wrapper_propstore_Release
,
5398 bytestream_wrapper_propstore_GetCount
,
5399 bytestream_wrapper_propstore_GetAt
,
5400 bytestream_wrapper_propstore_GetValue
,
5401 bytestream_wrapper_propstore_SetValue
,
5402 bytestream_wrapper_propstore_Commit
,
5405 static HRESULT WINAPI
bytestream_wrapper_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
5407 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5408 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5411 static ULONG WINAPI
bytestream_wrapper_attributes_AddRef(IMFAttributes
*iface
)
5413 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5414 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5417 static ULONG WINAPI
bytestream_wrapper_attributes_Release(IMFAttributes
*iface
)
5419 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5420 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5423 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
5425 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5427 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5429 return IMFAttributes_GetItem(wrapper
->attributes
, key
, value
);
5432 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
5434 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5436 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
5438 return IMFAttributes_GetItemType(wrapper
->attributes
, key
, type
);
5441 static HRESULT WINAPI
bytestream_wrapper_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
5442 REFPROPVARIANT value
, BOOL
*result
)
5444 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5446 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
5448 return IMFAttributes_CompareItem(wrapper
->attributes
, key
, value
, result
);
5451 static HRESULT WINAPI
bytestream_wrapper_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
5452 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
5454 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5456 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
5458 return IMFAttributes_Compare(wrapper
->attributes
, theirs
, match_type
, ret
);
5461 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
5463 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5465 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5467 return IMFAttributes_GetUINT32(wrapper
->attributes
, key
, value
);
5470 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
5472 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5474 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5476 return IMFAttributes_GetUINT64(wrapper
->attributes
, key
, value
);
5479 static HRESULT WINAPI
bytestream_wrapper_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
5481 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5483 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5485 return IMFAttributes_GetDouble(wrapper
->attributes
, key
, value
);
5488 static HRESULT WINAPI
bytestream_wrapper_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
5490 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5492 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5494 return IMFAttributes_GetGUID(wrapper
->attributes
, key
, value
);
5497 static HRESULT WINAPI
bytestream_wrapper_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
5499 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5501 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
5503 return IMFAttributes_GetStringLength(wrapper
->attributes
, key
, length
);
5506 static HRESULT WINAPI
bytestream_wrapper_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
5507 UINT32 size
, UINT32
*length
)
5509 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5511 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
5513 return IMFAttributes_GetString(wrapper
->attributes
, key
, value
, size
, length
);
5516 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
5518 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5520 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
5522 return IMFAttributes_GetAllocatedString(wrapper
->attributes
, key
, value
, length
);
5525 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
5527 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5529 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
5531 return IMFAttributes_GetBlobSize(wrapper
->attributes
, key
, size
);
5534 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
5535 UINT32 bufsize
, UINT32
*blobsize
)
5537 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5539 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
5541 return IMFAttributes_GetBlob(wrapper
->attributes
, key
, buf
, bufsize
, blobsize
);
5544 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
5546 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5548 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
5550 return IMFAttributes_GetAllocatedBlob(wrapper
->attributes
, key
, buf
, size
);
5553 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **obj
)
5555 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5557 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), obj
);
5559 return IMFAttributes_GetUnknown(wrapper
->attributes
, key
, riid
, obj
);
5562 static HRESULT WINAPI
bytestream_wrapper_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
5564 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5566 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
5568 return IMFAttributes_SetItem(wrapper
->attributes
, key
, value
);
5571 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
5573 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5575 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
5577 return IMFAttributes_DeleteItem(wrapper
->attributes
, key
);
5580 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteAllItems(IMFAttributes
*iface
)
5582 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5584 TRACE("%p.\n", iface
);
5586 return IMFAttributes_DeleteAllItems(wrapper
->attributes
);
5589 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
5591 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5593 TRACE("%p, %s, %d.\n", iface
, debugstr_attr(key
), value
);
5595 return IMFAttributes_SetUINT32(wrapper
->attributes
, key
, value
);
5598 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
5600 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5602 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
5604 return IMFAttributes_SetUINT64(wrapper
->attributes
, key
, value
);
5607 static HRESULT WINAPI
bytestream_wrapper_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
5609 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5611 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
5613 return IMFAttributes_SetDouble(wrapper
->attributes
, key
, value
);
5616 static HRESULT WINAPI
bytestream_wrapper_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
5618 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5620 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
5622 return IMFAttributes_SetGUID(wrapper
->attributes
, key
, value
);
5625 static HRESULT WINAPI
bytestream_wrapper_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
5627 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5629 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
5631 return IMFAttributes_SetString(wrapper
->attributes
, key
, value
);
5634 static HRESULT WINAPI
bytestream_wrapper_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
5636 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5638 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
5640 return IMFAttributes_SetBlob(wrapper
->attributes
, key
, buf
, size
);
5643 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
5645 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5647 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
5649 return IMFAttributes_SetUnknown(wrapper
->attributes
, key
, unknown
);
5652 static HRESULT WINAPI
bytestream_wrapper_attributes_LockStore(IMFAttributes
*iface
)
5654 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5656 TRACE("%p.\n", iface
);
5658 return IMFAttributes_LockStore(wrapper
->attributes
);
5661 static HRESULT WINAPI
bytestream_wrapper_attributes_UnlockStore(IMFAttributes
*iface
)
5663 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5665 TRACE("%p.\n", iface
);
5667 return IMFAttributes_UnlockStore(wrapper
->attributes
);
5670 static HRESULT WINAPI
bytestream_wrapper_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
5672 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5674 TRACE("%p, %p.\n", iface
, count
);
5676 return IMFAttributes_GetCount(wrapper
->attributes
, count
);
5679 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
5681 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5683 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
5685 return IMFAttributes_GetItemByIndex(wrapper
->attributes
, index
, key
, value
);
5688 static HRESULT WINAPI
bytestream_wrapper_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
5690 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5692 TRACE("%p, %p.\n", iface
, dest
);
5694 return IMFAttributes_CopyAllItems(wrapper
->attributes
, dest
);
5697 static const IMFAttributesVtbl bytestream_wrapper_attributes_vtbl
=
5699 bytestream_wrapper_attributes_QueryInterface
,
5700 bytestream_wrapper_attributes_AddRef
,
5701 bytestream_wrapper_attributes_Release
,
5702 bytestream_wrapper_attributes_GetItem
,
5703 bytestream_wrapper_attributes_GetItemType
,
5704 bytestream_wrapper_attributes_CompareItem
,
5705 bytestream_wrapper_attributes_Compare
,
5706 bytestream_wrapper_attributes_GetUINT32
,
5707 bytestream_wrapper_attributes_GetUINT64
,
5708 bytestream_wrapper_attributes_GetDouble
,
5709 bytestream_wrapper_attributes_GetGUID
,
5710 bytestream_wrapper_attributes_GetStringLength
,
5711 bytestream_wrapper_attributes_GetString
,
5712 bytestream_wrapper_attributes_GetAllocatedString
,
5713 bytestream_wrapper_attributes_GetBlobSize
,
5714 bytestream_wrapper_attributes_GetBlob
,
5715 bytestream_wrapper_attributes_GetAllocatedBlob
,
5716 bytestream_wrapper_attributes_GetUnknown
,
5717 bytestream_wrapper_attributes_SetItem
,
5718 bytestream_wrapper_attributes_DeleteItem
,
5719 bytestream_wrapper_attributes_DeleteAllItems
,
5720 bytestream_wrapper_attributes_SetUINT32
,
5721 bytestream_wrapper_attributes_SetUINT64
,
5722 bytestream_wrapper_attributes_SetDouble
,
5723 bytestream_wrapper_attributes_SetGUID
,
5724 bytestream_wrapper_attributes_SetString
,
5725 bytestream_wrapper_attributes_SetBlob
,
5726 bytestream_wrapper_attributes_SetUnknown
,
5727 bytestream_wrapper_attributes_LockStore
,
5728 bytestream_wrapper_attributes_UnlockStore
,
5729 bytestream_wrapper_attributes_GetCount
,
5730 bytestream_wrapper_attributes_GetItemByIndex
,
5731 bytestream_wrapper_attributes_CopyAllItems
5734 /***********************************************************************
5735 * MFCreateMFByteStreamWrapper (mfplat.@)
5737 HRESULT WINAPI
MFCreateMFByteStreamWrapper(IMFByteStream
*stream
, IMFByteStream
**wrapper
)
5739 struct bytestream_wrapper
*object
;
5741 TRACE("%p, %p.\n", stream
, wrapper
);
5743 if (!(object
= calloc(1, sizeof(*object
))))
5744 return E_OUTOFMEMORY
;
5746 object
->IMFByteStreamCacheControl_iface
.lpVtbl
= &bytestream_wrapper_cache_control_vtbl
;
5747 object
->IMFByteStreamBuffering_iface
.lpVtbl
= &bytestream_wrapper_buffering_vtbl
;
5748 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &bytestream_wrapper_events_vtbl
;
5749 object
->IMFByteStreamTimeSeek_iface
.lpVtbl
= &bytestream_wrapper_timeseek_vtbl
;
5750 object
->IMFSampleOutputStream_iface
.lpVtbl
= &bytestream_wrapper_sample_output_vtbl
;
5751 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_wrapper_vtbl
;
5752 object
->IPropertyStore_iface
.lpVtbl
= &bytestream_wrapper_propstore_vtbl
;
5753 object
->IMFAttributes_iface
.lpVtbl
= &bytestream_wrapper_attributes_vtbl
;
5755 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamCacheControl
, (void **)&object
->cache_control
);
5756 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamBuffering
, (void **)&object
->stream_buffering
);
5757 IMFByteStream_QueryInterface(stream
, &IID_IMFMediaEventGenerator
, (void **)&object
->event_generator
);
5758 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamTimeSeek
, (void **)&object
->time_seek
);
5759 IMFByteStream_QueryInterface(stream
, &IID_IMFSampleOutputStream
, (void **)&object
->sample_output
);
5760 IMFByteStream_QueryInterface(stream
, &IID_IPropertyStore
, (void **)&object
->propstore
);
5761 IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&object
->attributes
);
5763 object
->stream
= stream
;
5764 IMFByteStream_AddRef(object
->stream
);
5766 object
->refcount
= 1;
5768 *wrapper
= &object
->IMFByteStream_iface
;
5773 static HRESULT WINAPI
MFPluginControl_QueryInterface(IMFPluginControl
*iface
, REFIID riid
, void **ppv
)
5775 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
5776 TRACE("(IID_IUnknown %p)\n", ppv
);
5778 }else if(IsEqualGUID(riid
, &IID_IMFPluginControl
)) {
5779 TRACE("(IID_IMFPluginControl %p)\n", ppv
);
5782 FIXME("(%s %p)\n", debugstr_guid(riid
), ppv
);
5784 return E_NOINTERFACE
;
5787 IUnknown_AddRef((IUnknown
*)*ppv
);
5791 static ULONG WINAPI
MFPluginControl_AddRef(IMFPluginControl
*iface
)
5797 static ULONG WINAPI
MFPluginControl_Release(IMFPluginControl
*iface
)
5803 static HRESULT WINAPI
MFPluginControl_GetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5804 const WCHAR
*selector
, CLSID
*clsid
)
5806 FIXME("(%ld %s %p)\n", plugin_type
, debugstr_w(selector
), clsid
);
5810 static HRESULT WINAPI
MFPluginControl_GetPreferredClsidByIndex(IMFPluginControl
*iface
, DWORD plugin_type
,
5811 DWORD index
, WCHAR
**selector
, CLSID
*clsid
)
5813 FIXME("(%ld %ld %p %p)\n", plugin_type
, index
, selector
, clsid
);
5817 static HRESULT WINAPI
MFPluginControl_SetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5818 const WCHAR
*selector
, const CLSID
*clsid
)
5820 FIXME("(%ld %s %s)\n", plugin_type
, debugstr_w(selector
), debugstr_guid(clsid
));
5824 static HRESULT WINAPI
MFPluginControl_IsDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
)
5826 FIXME("(%ld %s)\n", plugin_type
, debugstr_guid(clsid
));
5830 static HRESULT WINAPI
MFPluginControl_GetDisabledByIndex(IMFPluginControl
*iface
, DWORD plugin_type
, DWORD index
, CLSID
*clsid
)
5832 FIXME("(%ld %ld %p)\n", plugin_type
, index
, clsid
);
5836 static HRESULT WINAPI
MFPluginControl_SetDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
, BOOL disabled
)
5838 FIXME("(%ld %s %x)\n", plugin_type
, debugstr_guid(clsid
), disabled
);
5842 static const IMFPluginControlVtbl MFPluginControlVtbl
= {
5843 MFPluginControl_QueryInterface
,
5844 MFPluginControl_AddRef
,
5845 MFPluginControl_Release
,
5846 MFPluginControl_GetPreferredClsid
,
5847 MFPluginControl_GetPreferredClsidByIndex
,
5848 MFPluginControl_SetPreferredClsid
,
5849 MFPluginControl_IsDisabled
,
5850 MFPluginControl_GetDisabledByIndex
,
5851 MFPluginControl_SetDisabled
5854 static IMFPluginControl plugin_control
= { &MFPluginControlVtbl
};
5856 /***********************************************************************
5857 * MFGetPluginControl (mfplat.@)
5859 HRESULT WINAPI
MFGetPluginControl(IMFPluginControl
**ret
)
5861 TRACE("(%p)\n", ret
);
5863 *ret
= &plugin_control
;
5867 enum resolved_object_origin
5869 OBJECT_FROM_BYTESTREAM
,
5873 struct resolver_queued_result
5877 MF_OBJECT_TYPE obj_type
;
5879 IRtwqAsyncResult
*inner_result
;
5880 enum resolved_object_origin origin
;
5883 struct resolver_cancel_object
5885 IUnknown IUnknown_iface
;
5890 IMFByteStreamHandler
*stream_handler
;
5891 IMFSchemeHandler
*scheme_handler
;
5893 IUnknown
*cancel_cookie
;
5894 enum resolved_object_origin origin
;
5897 struct source_resolver
5899 IMFSourceResolver IMFSourceResolver_iface
;
5901 IRtwqAsyncCallback stream_callback
;
5902 IRtwqAsyncCallback url_callback
;
5903 CRITICAL_SECTION cs
;
5904 struct list pending
;
5907 static struct source_resolver
*impl_from_IMFSourceResolver(IMFSourceResolver
*iface
)
5909 return CONTAINING_RECORD(iface
, struct source_resolver
, IMFSourceResolver_iface
);
5912 static struct source_resolver
*impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5914 return CONTAINING_RECORD(iface
, struct source_resolver
, stream_callback
);
5917 static struct source_resolver
*impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5919 return CONTAINING_RECORD(iface
, struct source_resolver
, url_callback
);
5922 static HRESULT
resolver_handler_end_create(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
5923 IRtwqAsyncResult
*result
)
5925 IRtwqAsyncResult
*inner_result
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
5926 RTWQASYNCRESULT
*data
= (RTWQASYNCRESULT
*)inner_result
;
5927 struct resolver_queued_result
*queued_result
;
5931 IMFByteStreamHandler
*stream_handler
;
5932 IMFSchemeHandler
*scheme_handler
;
5935 if (!(queued_result
= calloc(1, sizeof(*queued_result
))))
5936 return E_OUTOFMEMORY
;
5938 queued_result
->origin
= origin
;
5940 IRtwqAsyncResult_GetObject(inner_result
, &handler
.handler
);
5944 case OBJECT_FROM_BYTESTREAM
:
5945 queued_result
->hr
= IMFByteStreamHandler_EndCreateObject(handler
.stream_handler
, (IMFAsyncResult
*)result
,
5946 &queued_result
->obj_type
, &queued_result
->object
);
5948 case OBJECT_FROM_URL
:
5949 queued_result
->hr
= IMFSchemeHandler_EndCreateObject(handler
.scheme_handler
, (IMFAsyncResult
*)result
,
5950 &queued_result
->obj_type
, &queued_result
->object
);
5953 queued_result
->hr
= E_FAIL
;
5956 IUnknown_Release(handler
.handler
);
5960 queued_result
->inner_result
= inner_result
;
5961 IRtwqAsyncResult_AddRef(queued_result
->inner_result
);
5964 /* Push resolved object type and created object, so we don't have to guess on End*() call. */
5965 EnterCriticalSection(&resolver
->cs
);
5966 list_add_tail(&resolver
->pending
, &queued_result
->entry
);
5967 LeaveCriticalSection(&resolver
->cs
);
5970 SetEvent(data
->hEvent
);
5973 IUnknown
*caller_state
= IRtwqAsyncResult_GetStateNoAddRef(inner_result
);
5974 IRtwqAsyncResult
*caller_result
;
5976 if (SUCCEEDED(RtwqCreateAsyncResult(queued_result
->object
, data
->pCallback
, caller_state
, &caller_result
)))
5978 RtwqInvokeCallback(caller_result
);
5979 IRtwqAsyncResult_Release(caller_result
);
5986 static struct resolver_cancel_object
*impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5988 return CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
);
5991 static HRESULT WINAPI
resolver_cancel_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
5993 if (IsEqualIID(riid
, &IID_IUnknown
))
5996 IUnknown_AddRef(iface
);
6001 return E_NOINTERFACE
;
6004 static ULONG WINAPI
resolver_cancel_object_AddRef(IUnknown
*iface
)
6006 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
6007 return InterlockedIncrement(&object
->refcount
);
6010 static ULONG WINAPI
resolver_cancel_object_Release(IUnknown
*iface
)
6012 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
6013 ULONG refcount
= InterlockedDecrement(&object
->refcount
);
6017 if (object
->cancel_cookie
)
6018 IUnknown_Release(object
->cancel_cookie
);
6019 IUnknown_Release(object
->u
.handler
);
6026 static const IUnknownVtbl resolver_cancel_object_vtbl
=
6028 resolver_cancel_object_QueryInterface
,
6029 resolver_cancel_object_AddRef
,
6030 resolver_cancel_object_Release
,
6033 static struct resolver_cancel_object
*unsafe_impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
6038 return (iface
->lpVtbl
== &resolver_cancel_object_vtbl
) ?
6039 CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
) : NULL
;
6042 static HRESULT
resolver_create_cancel_object(IUnknown
*handler
, enum resolved_object_origin origin
,
6043 IUnknown
*cancel_cookie
, IUnknown
**cancel_object
)
6045 struct resolver_cancel_object
*object
;
6047 if (!(object
= calloc(1, sizeof(*object
))))
6048 return E_OUTOFMEMORY
;
6050 object
->IUnknown_iface
.lpVtbl
= &resolver_cancel_object_vtbl
;
6051 object
->refcount
= 1;
6052 object
->u
.handler
= handler
;
6053 IUnknown_AddRef(object
->u
.handler
);
6054 object
->cancel_cookie
= cancel_cookie
;
6055 IUnknown_AddRef(object
->cancel_cookie
);
6056 object
->origin
= origin
;
6058 *cancel_object
= &object
->IUnknown_iface
;
6063 static HRESULT WINAPI
source_resolver_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
6065 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
6066 IsEqualIID(riid
, &IID_IUnknown
))
6069 IRtwqAsyncCallback_AddRef(iface
);
6074 return E_NOINTERFACE
;
6077 static ULONG WINAPI
source_resolver_callback_stream_AddRef(IRtwqAsyncCallback
*iface
)
6079 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6080 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
6083 static ULONG WINAPI
source_resolver_callback_stream_Release(IRtwqAsyncCallback
*iface
)
6085 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6086 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
6089 static HRESULT WINAPI
source_resolver_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
6094 static HRESULT WINAPI
source_resolver_callback_stream_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
6096 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6098 return resolver_handler_end_create(resolver
, OBJECT_FROM_BYTESTREAM
, result
);
6101 static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl
=
6103 source_resolver_callback_QueryInterface
,
6104 source_resolver_callback_stream_AddRef
,
6105 source_resolver_callback_stream_Release
,
6106 source_resolver_callback_GetParameters
,
6107 source_resolver_callback_stream_Invoke
,
6110 static ULONG WINAPI
source_resolver_callback_url_AddRef(IRtwqAsyncCallback
*iface
)
6112 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6113 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
6116 static ULONG WINAPI
source_resolver_callback_url_Release(IRtwqAsyncCallback
*iface
)
6118 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6119 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
6122 static HRESULT WINAPI
source_resolver_callback_url_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
6124 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6126 return resolver_handler_end_create(resolver
, OBJECT_FROM_URL
, result
);
6129 static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl
=
6131 source_resolver_callback_QueryInterface
,
6132 source_resolver_callback_url_AddRef
,
6133 source_resolver_callback_url_Release
,
6134 source_resolver_callback_GetParameters
,
6135 source_resolver_callback_url_Invoke
,
6138 static HRESULT
resolver_create_registered_handler(HKEY hkey
, REFIID riid
, void **handler
)
6140 DWORD name_length
, type
;
6141 HRESULT hr
= E_FAIL
;
6146 name_length
= ARRAY_SIZE(clsidW
);
6147 while (!RegEnumValueW(hkey
, j
++, clsidW
, &name_length
, NULL
, &type
, NULL
, NULL
))
6151 if (SUCCEEDED(CLSIDFromString(clsidW
, &clsid
)))
6153 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, handler
);
6159 name_length
= ARRAY_SIZE(clsidW
);
6165 static HRESULT
resolver_create_bytestream_handler(IMFByteStream
*stream
, DWORD flags
, const WCHAR
*mime
,
6166 const WCHAR
*extension
, IMFByteStreamHandler
**handler
)
6168 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6169 HRESULT hr
= E_FAIL
;
6174 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6176 struct local_handler
*local_handler
;
6178 EnterCriticalSection(&local_handlers_section
);
6180 LIST_FOR_EACH_ENTRY(local_handler
, &local_bytestream_handlers
, struct local_handler
, entry
)
6182 if ((mime
&& !lstrcmpiW(mime
, local_handler
->u
.bytestream
.mime
))
6183 || (extension
&& !lstrcmpiW(extension
, local_handler
->u
.bytestream
.extension
)))
6185 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFByteStreamHandler
,
6191 LeaveCriticalSection(&local_handlers_section
);
6197 for (i
= 0, hr
= E_FAIL
; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6199 const WCHAR
*namesW
[2] = { mime
, extension
};
6200 HKEY hkey
, hkey_handler
;
6202 if (RegOpenKeyW(hkey_roots
[i
], L
"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers", &hkey
))
6205 for (j
= 0; j
< ARRAY_SIZE(namesW
); ++j
)
6210 if (!RegOpenKeyW(hkey
, namesW
[j
], &hkey_handler
))
6212 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFByteStreamHandler
, (void **)handler
);
6213 RegCloseKey(hkey_handler
);
6229 static HRESULT
resolver_get_bytestream_url_hint(IMFByteStream
*stream
, WCHAR
const **url
)
6231 static const unsigned char asfmagic
[] = {0x30,0x26,0xb2,0x75,0x8e,0x66,0xcf,0x11,0xa6,0xd9,0x00,0xaa,0x00,0x62,0xce,0x6c};
6232 static const unsigned char wavmagic
[] = { 'R', 'I', 'F', 'F',0x00,0x00,0x00,0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' '};
6233 static const unsigned char wavmask
[] = {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
6234 static const unsigned char isommagic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'i', 's', 'o', 'm',0x00,0x00,0x00,0x00};
6235 static const unsigned char mp4_magic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'M', 'S', 'N', 'V',0x00,0x00,0x00,0x00};
6236 static const unsigned char mp42magic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'm', 'p', '4', '2',0x00,0x00,0x00,0x00};
6237 static const unsigned char mp4vmagic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'M', '4', 'V', ' ',0x00,0x00,0x00,0x00};
6238 static const unsigned char mp4mask
[] = {0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00};
6239 static const struct stream_content_url_hint
6241 const unsigned char *magic
;
6243 const unsigned char *mask
;
6247 { asfmagic
, L
".asf" },
6248 { wavmagic
, L
".wav", wavmask
},
6249 { isommagic
, L
".mp4", mp4mask
},
6250 { mp42magic
, L
".mp4", mp4mask
},
6251 { mp4_magic
, L
".mp4", mp4mask
},
6252 { mp4vmagic
, L
".m4v", mp4mask
},
6254 unsigned char buffer
[4 * sizeof(unsigned int)], pattern
[4 * sizeof(unsigned int)];
6255 IMFAttributes
*attributes
;
6256 DWORD length
= 0, caps
= 0;
6263 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
6265 UINT32 string_length
= 0;
6266 IMFAttributes_GetStringLength(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &string_length
);
6267 IMFAttributes_Release(attributes
);
6273 if (FAILED(hr
= IMFByteStream_GetCapabilities(stream
, &caps
)))
6276 if (!(caps
& MFBYTESTREAM_IS_SEEKABLE
))
6277 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6279 if (FAILED(hr
= IMFByteStream_GetCurrentPosition(stream
, &position
)))
6282 hr
= IMFByteStream_Read(stream
, buffer
, sizeof(buffer
), &length
);
6283 IMFByteStream_SetCurrentPosition(stream
, position
);
6287 if (length
< sizeof(buffer
))
6290 for (i
= 0; i
< ARRAY_SIZE(url_hints
); ++i
)
6292 memcpy(pattern
, buffer
, sizeof(buffer
));
6293 if (url_hints
[i
].mask
)
6295 unsigned int *mask
= (unsigned int *)url_hints
[i
].mask
;
6296 unsigned int *data
= (unsigned int *)pattern
;
6298 for (j
= 0; j
< sizeof(buffer
) / sizeof(unsigned int); ++j
)
6302 if (!memcmp(pattern
, url_hints
[i
].magic
, sizeof(pattern
)))
6304 *url
= url_hints
[i
].url
;
6310 TRACE("Content type guessed as %s from %s.\n", debugstr_w(*url
), debugstr_an((char *)buffer
, length
));
6312 WARN("Unrecognized content type %s.\n", debugstr_an((char *)buffer
, length
));
6317 static HRESULT
resolver_create_gstreamer_handler(IMFByteStreamHandler
**handler
)
6319 static const GUID CLSID_GStreamerByteStreamHandler
= {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
6320 return CoCreateInstance(&CLSID_GStreamerByteStreamHandler
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFByteStreamHandler
, (void **)handler
);
6323 static HRESULT
resolver_get_bytestream_handler(IMFByteStream
*stream
, const WCHAR
*url
, DWORD flags
,
6324 IMFByteStreamHandler
**handler
)
6326 WCHAR
*mimeW
= NULL
, *urlW
= NULL
;
6327 IMFAttributes
*attributes
;
6328 const WCHAR
*url_ext
;
6329 HRESULT hr
= E_FAIL
;
6335 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
6337 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &mimeW
, &length
);
6340 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_ORIGIN_NAME
, &urlW
, &length
);
6343 IMFAttributes_Release(attributes
);
6347 url_ext
= url
? wcsrchr(url
, '.') : NULL
;
6349 /* If content type was provided by the caller, it's tried first. Otherwise an attempt to deduce
6350 content type from the content itself is made.
6352 TODO: wine specific fallback to predefined handler could be replaced by normally registering
6353 this handler for all possible types.
6356 if (url_ext
|| mimeW
)
6358 hr
= resolver_create_bytestream_handler(stream
, flags
, mimeW
, url_ext
, handler
);
6361 hr
= resolver_create_gstreamer_handler(handler
);
6364 CoTaskMemFree(mimeW
);
6365 CoTaskMemFree(urlW
);
6370 if (!(flags
& MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE
))
6371 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6373 if (FAILED(hr
= resolver_get_bytestream_url_hint(stream
, &url_ext
)))
6376 hr
= resolver_create_bytestream_handler(stream
, flags
, NULL
, url_ext
, handler
);
6379 hr
= resolver_create_gstreamer_handler(handler
);
6384 static HRESULT
resolver_create_scheme_handler(const WCHAR
*scheme
, DWORD flags
, IMFSchemeHandler
**handler
)
6386 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6387 HRESULT hr
= MF_E_UNSUPPORTED_SCHEME
;
6390 TRACE("%s, %#lx, %p.\n", debugstr_w(scheme
), flags
, handler
);
6394 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6396 struct local_handler
*local_handler
;
6398 EnterCriticalSection(&local_handlers_section
);
6400 LIST_FOR_EACH_ENTRY(local_handler
, &local_scheme_handlers
, struct local_handler
, entry
)
6402 if (!lstrcmpiW(scheme
, local_handler
->u
.scheme
))
6404 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFSchemeHandler
,
6410 LeaveCriticalSection(&local_handlers_section
);
6416 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6418 HKEY hkey
, hkey_handler
;
6420 hr
= MF_E_UNSUPPORTED_SCHEME
;
6422 if (RegOpenKeyW(hkey_roots
[i
], L
"Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers", &hkey
))
6425 if (!RegOpenKeyW(hkey
, scheme
, &hkey_handler
))
6427 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFSchemeHandler
, (void **)handler
);
6428 RegCloseKey(hkey_handler
);
6440 static HRESULT
resolver_get_scheme_handler(const WCHAR
*url
, DWORD flags
, IMFSchemeHandler
**handler
)
6442 static const WCHAR fileschemeW
[] = L
"file:";
6443 const WCHAR
*ptr
= url
;
6448 /* RFC 3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
6451 WCHAR ch
= towlower(*ptr
);
6453 if (*ptr
== '*' && ptr
== url
)
6458 else if (!(*ptr
>= '0' && *ptr
<= '9') &&
6459 !(ch
>= 'a' && ch
<= 'z') &&
6460 *ptr
!= '+' && *ptr
!= '-' && *ptr
!= '.')
6468 /* Schemes must end with a ':', if not found try "file:" */
6469 if (ptr
== url
|| *ptr
!= ':')
6472 len
= ARRAY_SIZE(fileschemeW
) - 1;
6475 len
= ptr
- url
+ 1;
6477 scheme
= malloc((len
+ 1) * sizeof(WCHAR
));
6479 return E_OUTOFMEMORY
;
6481 memcpy(scheme
, url
, len
* sizeof(WCHAR
));
6484 hr
= resolver_create_scheme_handler(scheme
, flags
, handler
);
6485 if (FAILED(hr
) && url
!= fileschemeW
)
6486 hr
= resolver_create_scheme_handler(fileschemeW
, flags
, handler
);
6493 static HRESULT
resolver_end_create_object(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
6494 IRtwqAsyncResult
*result
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**out
)
6496 struct resolver_queued_result
*queued_result
= NULL
, *iter
;
6500 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
6503 EnterCriticalSection(&resolver
->cs
);
6505 LIST_FOR_EACH_ENTRY(iter
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6507 if (iter
->inner_result
== result
|| (iter
->object
== object
&& iter
->origin
== origin
))
6509 list_remove(&iter
->entry
);
6510 queued_result
= iter
;
6515 LeaveCriticalSection(&resolver
->cs
);
6517 IUnknown_Release(object
);
6521 *out
= queued_result
->object
;
6522 *obj_type
= queued_result
->obj_type
;
6523 hr
= queued_result
->hr
;
6524 if (queued_result
->inner_result
)
6525 IRtwqAsyncResult_Release(queued_result
->inner_result
);
6526 free(queued_result
);
6534 static HRESULT WINAPI
source_resolver_QueryInterface(IMFSourceResolver
*iface
, REFIID riid
, void **obj
)
6536 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6538 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
6540 if (IsEqualIID(riid
, &IID_IMFSourceResolver
) ||
6541 IsEqualIID(riid
, &IID_IUnknown
))
6543 *obj
= &resolver
->IMFSourceResolver_iface
;
6548 FIXME("unsupported interface %s\n", debugstr_guid(riid
));
6549 return E_NOINTERFACE
;
6552 IUnknown_AddRef((IUnknown
*)*obj
);
6556 static ULONG WINAPI
source_resolver_AddRef(IMFSourceResolver
*iface
)
6558 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6559 ULONG refcount
= InterlockedIncrement(&resolver
->refcount
);
6561 TRACE("%p, refcount %ld.\n", iface
, refcount
);
6566 static ULONG WINAPI
source_resolver_Release(IMFSourceResolver
*iface
)
6568 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6569 ULONG refcount
= InterlockedDecrement(&resolver
->refcount
);
6570 struct resolver_queued_result
*result
, *result2
;
6572 TRACE("%p, refcount %ld.\n", iface
, refcount
);
6576 LIST_FOR_EACH_ENTRY_SAFE(result
, result2
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6579 IUnknown_Release(result
->object
);
6580 list_remove(&result
->entry
);
6583 DeleteCriticalSection(&resolver
->cs
);
6590 static HRESULT WINAPI
source_resolver_CreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6591 DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6593 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6594 IMFSchemeHandler
*handler
;
6595 IRtwqAsyncResult
*result
;
6596 RTWQASYNCRESULT
*data
;
6599 TRACE("%p, %s, %#lx, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6601 if (!url
|| !obj_type
|| !object
)
6604 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6607 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6608 IMFSchemeHandler_Release(handler
);
6612 data
= (RTWQASYNCRESULT
*)result
;
6613 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6615 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, NULL
, (IMFAsyncCallback
*)&resolver
->url_callback
,
6616 (IUnknown
*)result
);
6619 IRtwqAsyncResult_Release(result
);
6623 WaitForSingleObject(data
->hEvent
, INFINITE
);
6625 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_URL
, result
, obj_type
, object
);
6626 IRtwqAsyncResult_Release(result
);
6631 static HRESULT WINAPI
source_resolver_CreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6632 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6634 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6635 IMFByteStreamHandler
*handler
;
6636 IRtwqAsyncResult
*result
;
6637 RTWQASYNCRESULT
*data
;
6640 TRACE("%p, %p, %s, %#lx, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6642 if (!stream
|| !obj_type
|| !object
)
6645 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6646 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6648 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6649 IMFByteStreamHandler_Release(handler
);
6653 data
= (RTWQASYNCRESULT
*)result
;
6654 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6656 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
, NULL
,
6657 (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6660 IRtwqAsyncResult_Release(result
);
6664 WaitForSingleObject(data
->hEvent
, INFINITE
);
6666 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, result
, obj_type
, object
);
6667 IRtwqAsyncResult_Release(result
);
6672 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6673 DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
6675 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6676 IMFSchemeHandler
*handler
;
6677 IUnknown
*inner_cookie
= NULL
;
6678 IRtwqAsyncResult
*result
;
6681 TRACE("%p, %s, %#lx, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
6683 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6687 *cancel_cookie
= NULL
;
6689 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6690 IMFSchemeHandler_Release(handler
);
6694 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, cancel_cookie
? &inner_cookie
: NULL
,
6695 (IMFAsyncCallback
*)&resolver
->url_callback
, (IUnknown
*)result
);
6697 if (SUCCEEDED(hr
) && inner_cookie
)
6698 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_URL
, inner_cookie
, cancel_cookie
);
6700 IRtwqAsyncResult_Release(result
);
6705 static HRESULT WINAPI
source_resolver_EndCreateObjectFromURL(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6706 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6708 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6710 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6712 return resolver_end_create_object(resolver
, OBJECT_FROM_URL
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6715 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6716 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
,
6719 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6720 IMFByteStreamHandler
*handler
;
6721 IUnknown
*inner_cookie
= NULL
;
6722 IRtwqAsyncResult
*result
;
6725 TRACE("%p, %p, %s, %#lx, %p, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, cancel_cookie
,
6728 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6732 *cancel_cookie
= NULL
;
6734 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6735 IMFByteStreamHandler_Release(handler
);
6739 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
,
6740 cancel_cookie
? &inner_cookie
: NULL
, (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6742 /* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */
6743 if (SUCCEEDED(hr
) && inner_cookie
)
6744 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_BYTESTREAM
, inner_cookie
, cancel_cookie
);
6746 IRtwqAsyncResult_Release(result
);
6751 static HRESULT WINAPI
source_resolver_EndCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6752 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6754 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6756 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6758 return resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6761 static HRESULT WINAPI
source_resolver_CancelObjectCreation(IMFSourceResolver
*iface
, IUnknown
*cancel_cookie
)
6763 struct resolver_cancel_object
*object
;
6766 TRACE("%p, %p.\n", iface
, cancel_cookie
);
6768 if (!(object
= unsafe_impl_cancel_obj_from_IUnknown(cancel_cookie
)))
6769 return E_UNEXPECTED
;
6771 switch (object
->origin
)
6773 case OBJECT_FROM_BYTESTREAM
:
6774 hr
= IMFByteStreamHandler_CancelObjectCreation(object
->u
.stream_handler
, object
->cancel_cookie
);
6776 case OBJECT_FROM_URL
:
6777 hr
= IMFSchemeHandler_CancelObjectCreation(object
->u
.scheme_handler
, object
->cancel_cookie
);
6786 static const IMFSourceResolverVtbl mfsourceresolvervtbl
=
6788 source_resolver_QueryInterface
,
6789 source_resolver_AddRef
,
6790 source_resolver_Release
,
6791 source_resolver_CreateObjectFromURL
,
6792 source_resolver_CreateObjectFromByteStream
,
6793 source_resolver_BeginCreateObjectFromURL
,
6794 source_resolver_EndCreateObjectFromURL
,
6795 source_resolver_BeginCreateObjectFromByteStream
,
6796 source_resolver_EndCreateObjectFromByteStream
,
6797 source_resolver_CancelObjectCreation
,
6800 /***********************************************************************
6801 * MFCreateSourceResolver (mfplat.@)
6803 HRESULT WINAPI
MFCreateSourceResolver(IMFSourceResolver
**resolver
)
6805 struct source_resolver
*object
;
6807 TRACE("%p\n", resolver
);
6812 if (!(object
= calloc(1, sizeof(*object
))))
6813 return E_OUTOFMEMORY
;
6815 object
->IMFSourceResolver_iface
.lpVtbl
= &mfsourceresolvervtbl
;
6816 object
->stream_callback
.lpVtbl
= &source_resolver_callback_stream_vtbl
;
6817 object
->url_callback
.lpVtbl
= &source_resolver_callback_url_vtbl
;
6818 object
->refcount
= 1;
6819 list_init(&object
->pending
);
6820 InitializeCriticalSection(&object
->cs
);
6822 *resolver
= &object
->IMFSourceResolver_iface
;
6829 struct attributes attributes
;
6830 IMFMediaEvent IMFMediaEvent_iface
;
6832 MediaEventType type
;
6838 static inline struct media_event
*impl_from_IMFMediaEvent(IMFMediaEvent
*iface
)
6840 return CONTAINING_RECORD(iface
, struct media_event
, IMFMediaEvent_iface
);
6843 static HRESULT WINAPI
mfmediaevent_QueryInterface(IMFMediaEvent
*iface
, REFIID riid
, void **out
)
6845 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6847 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
6849 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
6850 IsEqualGUID(riid
, &IID_IMFAttributes
) ||
6851 IsEqualGUID(riid
, &IID_IMFMediaEvent
))
6853 *out
= &event
->IMFMediaEvent_iface
;
6857 FIXME("%s, %p.\n", debugstr_guid(riid
), out
);
6859 return E_NOINTERFACE
;
6862 IUnknown_AddRef((IUnknown
*)*out
);
6866 static ULONG WINAPI
mfmediaevent_AddRef(IMFMediaEvent
*iface
)
6868 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6869 ULONG refcount
= InterlockedIncrement(&event
->attributes
.ref
);
6871 TRACE("%p, refcount %lu.\n", iface
, refcount
);
6876 static ULONG WINAPI
mfmediaevent_Release(IMFMediaEvent
*iface
)
6878 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6879 ULONG refcount
= InterlockedDecrement(&event
->attributes
.ref
);
6881 TRACE("%p, refcount %lu.\n", iface
, refcount
);
6885 clear_attributes_object(&event
->attributes
);
6886 PropVariantClear(&event
->value
);
6893 static HRESULT WINAPI
mfmediaevent_GetItem(IMFMediaEvent
*iface
, REFGUID key
, PROPVARIANT
*value
)
6895 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6897 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6899 return attributes_GetItem(&event
->attributes
, key
, value
);
6902 static HRESULT WINAPI
mfmediaevent_GetItemType(IMFMediaEvent
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
6904 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6906 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
6908 return attributes_GetItemType(&event
->attributes
, key
, type
);
6911 static HRESULT WINAPI
mfmediaevent_CompareItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
6913 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6915 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
6917 return attributes_CompareItem(&event
->attributes
, key
, value
, result
);
6920 static HRESULT WINAPI
mfmediaevent_Compare(IMFMediaEvent
*iface
, IMFAttributes
*attrs
, MF_ATTRIBUTES_MATCH_TYPE type
,
6923 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6925 TRACE("%p, %p, %d, %p.\n", iface
, attrs
, type
, result
);
6927 return attributes_Compare(&event
->attributes
, attrs
, type
, result
);
6930 static HRESULT WINAPI
mfmediaevent_GetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*value
)
6932 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6934 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6936 return attributes_GetUINT32(&event
->attributes
, key
, value
);
6939 static HRESULT WINAPI
mfmediaevent_GetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64
*value
)
6941 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6943 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6945 return attributes_GetUINT64(&event
->attributes
, key
, value
);
6948 static HRESULT WINAPI
mfmediaevent_GetDouble(IMFMediaEvent
*iface
, REFGUID key
, double *value
)
6950 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6952 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6954 return attributes_GetDouble(&event
->attributes
, key
, value
);
6957 static HRESULT WINAPI
mfmediaevent_GetGUID(IMFMediaEvent
*iface
, REFGUID key
, GUID
*value
)
6959 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6961 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6963 return attributes_GetGUID(&event
->attributes
, key
, value
);
6966 static HRESULT WINAPI
mfmediaevent_GetStringLength(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*length
)
6968 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6970 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
6972 return attributes_GetStringLength(&event
->attributes
, key
, length
);
6975 static HRESULT WINAPI
mfmediaevent_GetString(IMFMediaEvent
*iface
, REFGUID key
, WCHAR
*value
,
6976 UINT32 size
, UINT32
*length
)
6978 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6980 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
6982 return attributes_GetString(&event
->attributes
, key
, value
, size
, length
);
6985 static HRESULT WINAPI
mfmediaevent_GetAllocatedString(IMFMediaEvent
*iface
, REFGUID key
,
6986 WCHAR
**value
, UINT32
*length
)
6988 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6990 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
6992 return attributes_GetAllocatedString(&event
->attributes
, key
, value
, length
);
6995 static HRESULT WINAPI
mfmediaevent_GetBlobSize(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*size
)
6997 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6999 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
7001 return attributes_GetBlobSize(&event
->attributes
, key
, size
);
7004 static HRESULT WINAPI
mfmediaevent_GetBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
*buf
,
7005 UINT32 bufsize
, UINT32
*blobsize
)
7007 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7009 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
7011 return attributes_GetBlob(&event
->attributes
, key
, buf
, bufsize
, blobsize
);
7014 static HRESULT WINAPI
mfmediaevent_GetAllocatedBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
7016 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7018 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
7020 return attributes_GetAllocatedBlob(&event
->attributes
, key
, buf
, size
);
7023 static HRESULT WINAPI
mfmediaevent_GetUnknown(IMFMediaEvent
*iface
, REFGUID key
, REFIID riid
, void **out
)
7025 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7027 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
7029 return attributes_GetUnknown(&event
->attributes
, key
, riid
, out
);
7032 static HRESULT WINAPI
mfmediaevent_SetItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
)
7034 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7036 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
7038 return attributes_SetItem(&event
->attributes
, key
, value
);
7041 static HRESULT WINAPI
mfmediaevent_DeleteItem(IMFMediaEvent
*iface
, REFGUID key
)
7043 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7045 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
7047 return attributes_DeleteItem(&event
->attributes
, key
);
7050 static HRESULT WINAPI
mfmediaevent_DeleteAllItems(IMFMediaEvent
*iface
)
7052 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7054 TRACE("%p.\n", iface
);
7056 return attributes_DeleteAllItems(&event
->attributes
);
7059 static HRESULT WINAPI
mfmediaevent_SetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32 value
)
7061 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7063 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
7065 return attributes_SetUINT32(&event
->attributes
, key
, value
);
7068 static HRESULT WINAPI
mfmediaevent_SetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64 value
)
7070 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7072 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
7074 return attributes_SetUINT64(&event
->attributes
, key
, value
);
7077 static HRESULT WINAPI
mfmediaevent_SetDouble(IMFMediaEvent
*iface
, REFGUID key
, double value
)
7079 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7081 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
7083 return attributes_SetDouble(&event
->attributes
, key
, value
);
7086 static HRESULT WINAPI
mfmediaevent_SetGUID(IMFMediaEvent
*iface
, REFGUID key
, REFGUID value
)
7088 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7090 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
7092 return attributes_SetGUID(&event
->attributes
, key
, value
);
7095 static HRESULT WINAPI
mfmediaevent_SetString(IMFMediaEvent
*iface
, REFGUID key
, const WCHAR
*value
)
7097 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7099 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
7101 return attributes_SetString(&event
->attributes
, key
, value
);
7104 static HRESULT WINAPI
mfmediaevent_SetBlob(IMFMediaEvent
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
7106 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7108 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
7110 return attributes_SetBlob(&event
->attributes
, key
, buf
, size
);
7113 static HRESULT WINAPI
mfmediaevent_SetUnknown(IMFMediaEvent
*iface
, REFGUID key
, IUnknown
*unknown
)
7115 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7117 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
7119 return attributes_SetUnknown(&event
->attributes
, key
, unknown
);
7122 static HRESULT WINAPI
mfmediaevent_LockStore(IMFMediaEvent
*iface
)
7124 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7126 TRACE("%p.\n", iface
);
7128 return attributes_LockStore(&event
->attributes
);
7131 static HRESULT WINAPI
mfmediaevent_UnlockStore(IMFMediaEvent
*iface
)
7133 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7135 TRACE("%p.\n", iface
);
7137 return attributes_UnlockStore(&event
->attributes
);
7140 static HRESULT WINAPI
mfmediaevent_GetCount(IMFMediaEvent
*iface
, UINT32
*count
)
7142 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7144 TRACE("%p, %p.\n", iface
, count
);
7146 return attributes_GetCount(&event
->attributes
, count
);
7149 static HRESULT WINAPI
mfmediaevent_GetItemByIndex(IMFMediaEvent
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
7151 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7153 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
7155 return attributes_GetItemByIndex(&event
->attributes
, index
, key
, value
);
7158 static HRESULT WINAPI
mfmediaevent_CopyAllItems(IMFMediaEvent
*iface
, IMFAttributes
*dest
)
7160 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7162 TRACE("%p, %p.\n", iface
, dest
);
7164 return attributes_CopyAllItems(&event
->attributes
, dest
);
7167 static HRESULT WINAPI
mfmediaevent_GetType(IMFMediaEvent
*iface
, MediaEventType
*type
)
7169 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7171 TRACE("%p, %p.\n", iface
, type
);
7173 *type
= event
->type
;
7178 static HRESULT WINAPI
mfmediaevent_GetExtendedType(IMFMediaEvent
*iface
, GUID
*extended_type
)
7180 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7182 TRACE("%p, %p.\n", iface
, extended_type
);
7184 *extended_type
= event
->extended_type
;
7189 static HRESULT WINAPI
mfmediaevent_GetStatus(IMFMediaEvent
*iface
, HRESULT
*status
)
7191 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7193 TRACE("%p, %p.\n", iface
, status
);
7195 *status
= event
->status
;
7200 static HRESULT WINAPI
mfmediaevent_GetValue(IMFMediaEvent
*iface
, PROPVARIANT
*value
)
7202 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7204 TRACE("%p, %p.\n", iface
, value
);
7206 PropVariantCopy(value
, &event
->value
);
7211 static const IMFMediaEventVtbl mfmediaevent_vtbl
=
7213 mfmediaevent_QueryInterface
,
7214 mfmediaevent_AddRef
,
7215 mfmediaevent_Release
,
7216 mfmediaevent_GetItem
,
7217 mfmediaevent_GetItemType
,
7218 mfmediaevent_CompareItem
,
7219 mfmediaevent_Compare
,
7220 mfmediaevent_GetUINT32
,
7221 mfmediaevent_GetUINT64
,
7222 mfmediaevent_GetDouble
,
7223 mfmediaevent_GetGUID
,
7224 mfmediaevent_GetStringLength
,
7225 mfmediaevent_GetString
,
7226 mfmediaevent_GetAllocatedString
,
7227 mfmediaevent_GetBlobSize
,
7228 mfmediaevent_GetBlob
,
7229 mfmediaevent_GetAllocatedBlob
,
7230 mfmediaevent_GetUnknown
,
7231 mfmediaevent_SetItem
,
7232 mfmediaevent_DeleteItem
,
7233 mfmediaevent_DeleteAllItems
,
7234 mfmediaevent_SetUINT32
,
7235 mfmediaevent_SetUINT64
,
7236 mfmediaevent_SetDouble
,
7237 mfmediaevent_SetGUID
,
7238 mfmediaevent_SetString
,
7239 mfmediaevent_SetBlob
,
7240 mfmediaevent_SetUnknown
,
7241 mfmediaevent_LockStore
,
7242 mfmediaevent_UnlockStore
,
7243 mfmediaevent_GetCount
,
7244 mfmediaevent_GetItemByIndex
,
7245 mfmediaevent_CopyAllItems
,
7246 mfmediaevent_GetType
,
7247 mfmediaevent_GetExtendedType
,
7248 mfmediaevent_GetStatus
,
7249 mfmediaevent_GetValue
,
7252 /***********************************************************************
7253 * MFCreateMediaEvent (mfplat.@)
7255 HRESULT WINAPI
MFCreateMediaEvent(MediaEventType type
, REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
,
7256 IMFMediaEvent
**event
)
7258 struct media_event
*object
;
7261 TRACE("%s, %s, %#lx, %s, %p.\n", debugstr_eventid(type
), debugstr_guid(extended_type
), status
,
7262 debugstr_propvar(value
), event
);
7264 object
= malloc(sizeof(*object
));
7266 return E_OUTOFMEMORY
;
7268 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
7273 object
->IMFMediaEvent_iface
.lpVtbl
= &mfmediaevent_vtbl
;
7275 object
->type
= type
;
7276 object
->extended_type
= *extended_type
;
7277 object
->status
= status
;
7279 PropVariantInit(&object
->value
);
7281 PropVariantCopy(&object
->value
, value
);
7283 *event
= &object
->IMFMediaEvent_iface
;
7285 TRACE("Created event %p.\n", *event
);
7292 IMFMediaEventQueue IMFMediaEventQueue_iface
;
7295 CRITICAL_SECTION cs
;
7296 CONDITION_VARIABLE update_event
;
7300 IRtwqAsyncResult
*subscriber
;
7306 IMFMediaEvent
*event
;
7309 static inline struct event_queue
*impl_from_IMFMediaEventQueue(IMFMediaEventQueue
*iface
)
7311 return CONTAINING_RECORD(iface
, struct event_queue
, IMFMediaEventQueue_iface
);
7314 static IMFMediaEvent
*queue_pop_event(struct event_queue
*queue
)
7316 struct list
*head
= list_head(&queue
->events
);
7317 struct queued_event
*queued_event
;
7318 IMFMediaEvent
*event
;
7323 queued_event
= LIST_ENTRY(head
, struct queued_event
, entry
);
7324 event
= queued_event
->event
;
7325 list_remove(&queued_event
->entry
);
7330 static void event_queue_clear_subscriber(struct event_queue
*queue
)
7332 if (queue
->subscriber
)
7333 IRtwqAsyncResult_Release(queue
->subscriber
);
7334 queue
->subscriber
= NULL
;
7337 static void event_queue_cleanup(struct event_queue
*queue
)
7339 IMFMediaEvent
*event
;
7341 while ((event
= queue_pop_event(queue
)))
7342 IMFMediaEvent_Release(event
);
7343 event_queue_clear_subscriber(queue
);
7346 static HRESULT WINAPI
eventqueue_QueryInterface(IMFMediaEventQueue
*iface
, REFIID riid
, void **out
)
7348 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7350 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7352 if (IsEqualIID(riid
, &IID_IMFMediaEventQueue
) ||
7353 IsEqualIID(riid
, &IID_IUnknown
))
7355 *out
= &queue
->IMFMediaEventQueue_iface
;
7356 IMFMediaEventQueue_AddRef(iface
);
7360 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7362 return E_NOINTERFACE
;
7365 static ULONG WINAPI
eventqueue_AddRef(IMFMediaEventQueue
*iface
)
7367 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7368 ULONG refcount
= InterlockedIncrement(&queue
->refcount
);
7370 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7375 static ULONG WINAPI
eventqueue_Release(IMFMediaEventQueue
*iface
)
7377 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7378 ULONG refcount
= InterlockedDecrement(&queue
->refcount
);
7380 TRACE("%p, refcount %lu.\n", queue
, refcount
);
7384 event_queue_cleanup(queue
);
7385 DeleteCriticalSection(&queue
->cs
);
7392 static HRESULT WINAPI
eventqueue_GetEvent(IMFMediaEventQueue
*iface
, DWORD flags
, IMFMediaEvent
**event
)
7394 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7397 TRACE("%p, %p.\n", iface
, event
);
7399 EnterCriticalSection(&queue
->cs
);
7401 if (queue
->is_shut_down
)
7403 else if (queue
->subscriber
)
7404 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7407 if (flags
& MF_EVENT_FLAG_NO_WAIT
)
7409 if (!(*event
= queue_pop_event(queue
)))
7410 hr
= MF_E_NO_EVENTS_AVAILABLE
;
7414 while (list_empty(&queue
->events
) && !queue
->is_shut_down
)
7416 SleepConditionVariableCS(&queue
->update_event
, &queue
->cs
, INFINITE
);
7418 *event
= queue_pop_event(queue
);
7419 if (queue
->is_shut_down
)
7424 LeaveCriticalSection(&queue
->cs
);
7429 static void queue_notify_subscriber(struct event_queue
*queue
)
7431 if (list_empty(&queue
->events
) || !queue
->subscriber
|| queue
->notified
)
7434 queue
->notified
= TRUE
;
7435 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, queue
->subscriber
);
7438 static HRESULT WINAPI
eventqueue_BeginGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
7440 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7441 RTWQASYNCRESULT
*result_data
;
7444 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
7447 return E_INVALIDARG
;
7449 EnterCriticalSection(&queue
->cs
);
7451 if (queue
->is_shut_down
)
7453 else if ((result_data
= (RTWQASYNCRESULT
*)queue
->subscriber
))
7455 if (result_data
->pCallback
== (IRtwqAsyncCallback
*)callback
)
7456 hr
= IRtwqAsyncResult_GetStateNoAddRef(queue
->subscriber
) == state
?
7457 MF_S_MULTIPLE_BEGIN
: MF_E_MULTIPLE_BEGIN
;
7459 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7463 hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &queue
->subscriber
);
7465 queue_notify_subscriber(queue
);
7468 LeaveCriticalSection(&queue
->cs
);
7473 static HRESULT WINAPI
eventqueue_EndGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
7475 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7476 HRESULT hr
= E_FAIL
;
7478 TRACE("%p, %p, %p.\n", iface
, result
, event
);
7480 EnterCriticalSection(&queue
->cs
);
7482 if (queue
->is_shut_down
)
7484 else if (queue
->subscriber
== (IRtwqAsyncResult
*)result
)
7486 *event
= queue_pop_event(queue
);
7487 event_queue_clear_subscriber(queue
);
7488 queue
->notified
= FALSE
;
7489 hr
= *event
? S_OK
: E_FAIL
;
7492 LeaveCriticalSection(&queue
->cs
);
7497 static HRESULT
eventqueue_queue_event(struct event_queue
*queue
, IMFMediaEvent
*event
)
7499 struct queued_event
*queued_event
;
7502 queued_event
= malloc(sizeof(*queued_event
));
7504 return E_OUTOFMEMORY
;
7506 queued_event
->event
= event
;
7508 EnterCriticalSection(&queue
->cs
);
7510 if (queue
->is_shut_down
)
7514 IMFMediaEvent_AddRef(queued_event
->event
);
7515 list_add_tail(&queue
->events
, &queued_event
->entry
);
7516 queue_notify_subscriber(queue
);
7519 LeaveCriticalSection(&queue
->cs
);
7524 WakeAllConditionVariable(&queue
->update_event
);
7529 static HRESULT WINAPI
eventqueue_QueueEvent(IMFMediaEventQueue
*iface
, IMFMediaEvent
*event
)
7531 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7533 TRACE("%p, %p.\n", iface
, event
);
7535 return eventqueue_queue_event(queue
, event
);
7538 static HRESULT WINAPI
eventqueue_QueueEventParamVar(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7539 REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
)
7541 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7542 IMFMediaEvent
*event
;
7545 TRACE("%p, %s, %s, %#lx, %s\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
,
7546 debugstr_propvar(value
));
7548 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, value
, &event
)))
7551 hr
= eventqueue_queue_event(queue
, event
);
7552 IMFMediaEvent_Release(event
);
7556 static HRESULT WINAPI
eventqueue_QueueEventParamUnk(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7557 REFGUID extended_type
, HRESULT status
, IUnknown
*unk
)
7559 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7560 IMFMediaEvent
*event
;
7564 TRACE("%p, %s, %s, %#lx, %p.\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
, unk
);
7566 value
.vt
= VT_UNKNOWN
;
7567 value
.punkVal
= unk
;
7569 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, &value
, &event
)))
7572 hr
= eventqueue_queue_event(queue
, event
);
7573 IMFMediaEvent_Release(event
);
7577 static HRESULT WINAPI
eventqueue_Shutdown(IMFMediaEventQueue
*iface
)
7579 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7581 TRACE("%p\n", queue
);
7583 EnterCriticalSection(&queue
->cs
);
7585 if (!queue
->is_shut_down
)
7587 event_queue_cleanup(queue
);
7588 queue
->is_shut_down
= TRUE
;
7591 LeaveCriticalSection(&queue
->cs
);
7593 WakeAllConditionVariable(&queue
->update_event
);
7598 static const IMFMediaEventQueueVtbl eventqueuevtbl
=
7600 eventqueue_QueryInterface
,
7603 eventqueue_GetEvent
,
7604 eventqueue_BeginGetEvent
,
7605 eventqueue_EndGetEvent
,
7606 eventqueue_QueueEvent
,
7607 eventqueue_QueueEventParamVar
,
7608 eventqueue_QueueEventParamUnk
,
7612 /***********************************************************************
7613 * MFCreateEventQueue (mfplat.@)
7615 HRESULT WINAPI
MFCreateEventQueue(IMFMediaEventQueue
**queue
)
7617 struct event_queue
*object
;
7619 TRACE("%p\n", queue
);
7621 if (!(object
= calloc(1, sizeof(*object
))))
7622 return E_OUTOFMEMORY
;
7624 object
->IMFMediaEventQueue_iface
.lpVtbl
= &eventqueuevtbl
;
7625 object
->refcount
= 1;
7626 list_init(&object
->events
);
7627 InitializeCriticalSection(&object
->cs
);
7628 InitializeConditionVariable(&object
->update_event
);
7630 *queue
= &object
->IMFMediaEventQueue_iface
;
7637 IMFCollection IMFCollection_iface
;
7639 IUnknown
**elements
;
7644 static struct collection
*impl_from_IMFCollection(IMFCollection
*iface
)
7646 return CONTAINING_RECORD(iface
, struct collection
, IMFCollection_iface
);
7649 static void collection_clear(struct collection
*collection
)
7653 for (i
= 0; i
< collection
->count
; ++i
)
7655 if (collection
->elements
[i
])
7656 IUnknown_Release(collection
->elements
[i
]);
7659 free(collection
->elements
);
7660 collection
->elements
= NULL
;
7661 collection
->count
= 0;
7662 collection
->capacity
= 0;
7665 static HRESULT WINAPI
collection_QueryInterface(IMFCollection
*iface
, REFIID riid
, void **out
)
7667 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7669 if (IsEqualIID(riid
, &IID_IMFCollection
) ||
7670 IsEqualIID(riid
, &IID_IUnknown
))
7673 IMFCollection_AddRef(iface
);
7677 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
7679 return E_NOINTERFACE
;
7682 static ULONG WINAPI
collection_AddRef(IMFCollection
*iface
)
7684 struct collection
*collection
= impl_from_IMFCollection(iface
);
7685 ULONG refcount
= InterlockedIncrement(&collection
->refcount
);
7687 TRACE("%p, %ld.\n", collection
, refcount
);
7692 static ULONG WINAPI
collection_Release(IMFCollection
*iface
)
7694 struct collection
*collection
= impl_from_IMFCollection(iface
);
7695 ULONG refcount
= InterlockedDecrement(&collection
->refcount
);
7697 TRACE("%p, %ld.\n", collection
, refcount
);
7701 collection_clear(collection
);
7702 free(collection
->elements
);
7709 static HRESULT WINAPI
collection_GetElementCount(IMFCollection
*iface
, DWORD
*count
)
7711 struct collection
*collection
= impl_from_IMFCollection(iface
);
7713 TRACE("%p, %p.\n", iface
, count
);
7718 *count
= collection
->count
;
7723 static HRESULT WINAPI
collection_GetElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7725 struct collection
*collection
= impl_from_IMFCollection(iface
);
7727 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7732 if (idx
>= collection
->count
)
7733 return E_INVALIDARG
;
7735 *element
= collection
->elements
[idx
];
7737 IUnknown_AddRef(*element
);
7739 return *element
? S_OK
: E_UNEXPECTED
;
7742 static HRESULT WINAPI
collection_AddElement(IMFCollection
*iface
, IUnknown
*element
)
7744 struct collection
*collection
= impl_from_IMFCollection(iface
);
7746 TRACE("%p, %p.\n", iface
, element
);
7748 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, collection
->count
+ 1,
7749 sizeof(*collection
->elements
)))
7750 return E_OUTOFMEMORY
;
7752 collection
->elements
[collection
->count
++] = element
;
7754 IUnknown_AddRef(element
);
7759 static HRESULT WINAPI
collection_RemoveElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7761 struct collection
*collection
= impl_from_IMFCollection(iface
);
7764 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7769 if (idx
>= collection
->count
)
7770 return E_INVALIDARG
;
7772 *element
= collection
->elements
[idx
];
7774 count
= collection
->count
- idx
- 1;
7776 memmove(&collection
->elements
[idx
], &collection
->elements
[idx
+ 1], count
* sizeof(*collection
->elements
));
7777 collection
->count
--;
7782 static HRESULT WINAPI
collection_InsertElementAt(IMFCollection
*iface
, DWORD idx
, IUnknown
*element
)
7784 struct collection
*collection
= impl_from_IMFCollection(iface
);
7787 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7789 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, idx
+ 1,
7790 sizeof(*collection
->elements
)))
7791 return E_OUTOFMEMORY
;
7793 if (idx
< collection
->count
)
7795 memmove(&collection
->elements
[idx
+ 1], &collection
->elements
[idx
],
7796 (collection
->count
- idx
) * sizeof(*collection
->elements
));
7797 collection
->count
++;
7801 for (i
= collection
->count
; i
< idx
; ++i
)
7802 collection
->elements
[i
] = NULL
;
7803 collection
->count
= idx
+ 1;
7806 collection
->elements
[idx
] = element
;
7807 if (collection
->elements
[idx
])
7808 IUnknown_AddRef(collection
->elements
[idx
]);
7813 static HRESULT WINAPI
collection_RemoveAllElements(IMFCollection
*iface
)
7815 struct collection
*collection
= impl_from_IMFCollection(iface
);
7817 TRACE("%p.\n", iface
);
7819 collection_clear(collection
);
7824 static const IMFCollectionVtbl mfcollectionvtbl
=
7826 collection_QueryInterface
,
7829 collection_GetElementCount
,
7830 collection_GetElement
,
7831 collection_AddElement
,
7832 collection_RemoveElement
,
7833 collection_InsertElementAt
,
7834 collection_RemoveAllElements
,
7837 /***********************************************************************
7838 * MFCreateCollection (mfplat.@)
7840 HRESULT WINAPI
MFCreateCollection(IMFCollection
**collection
)
7842 struct collection
*object
;
7844 TRACE("%p\n", collection
);
7849 if (!(object
= calloc(1, sizeof(*object
))))
7850 return E_OUTOFMEMORY
;
7852 object
->IMFCollection_iface
.lpVtbl
= &mfcollectionvtbl
;
7853 object
->refcount
= 1;
7855 *collection
= &object
->IMFCollection_iface
;
7860 /***********************************************************************
7861 * MFHeapAlloc (mfplat.@)
7863 void *WINAPI
MFHeapAlloc(SIZE_T size
, ULONG flags
, char *file
, int line
, EAllocationType type
)
7865 TRACE("%Iu, %#lx, %s, %d, %#x.\n", size
, flags
, debugstr_a(file
), line
, type
);
7866 return HeapAlloc(GetProcessHeap(), flags
, size
);
7869 /***********************************************************************
7870 * MFHeapFree (mfplat.@)
7872 void WINAPI
MFHeapFree(void *p
)
7875 HeapFree(GetProcessHeap(), 0, p
);
7878 /***********************************************************************
7879 * MFCreateMFByteStreamOnStreamEx (mfplat.@)
7881 HRESULT WINAPI
MFCreateMFByteStreamOnStreamEx(IUnknown
*stream
, IMFByteStream
**bytestream
)
7883 FIXME("(%p, %p): stub\n", stream
, bytestream
);
7888 static HRESULT WINAPI
system_clock_QueryInterface(IMFClock
*iface
, REFIID riid
, void **obj
)
7890 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7892 if (IsEqualIID(riid
, &IID_IMFClock
) ||
7893 IsEqualIID(riid
, &IID_IUnknown
))
7896 IMFClock_AddRef(iface
);
7900 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7902 return E_NOINTERFACE
;
7905 static ULONG WINAPI
system_clock_AddRef(IMFClock
*iface
)
7907 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7908 ULONG refcount
= InterlockedIncrement(&clock
->refcount
);
7910 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7915 static ULONG WINAPI
system_clock_Release(IMFClock
*iface
)
7917 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7918 ULONG refcount
= InterlockedDecrement(&clock
->refcount
);
7920 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7928 static HRESULT WINAPI
system_clock_GetClockCharacteristics(IMFClock
*iface
, DWORD
*flags
)
7930 TRACE("%p, %p.\n", iface
, flags
);
7932 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING
|
7933 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7938 static HRESULT WINAPI
system_clock_GetCorrelatedTime(IMFClock
*iface
, DWORD reserved
, LONGLONG
*clock_time
,
7939 MFTIME
*system_time
)
7941 TRACE("%p, %#lx, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7943 *clock_time
= *system_time
= MFGetSystemTime();
7948 static HRESULT WINAPI
system_clock_GetContinuityKey(IMFClock
*iface
, DWORD
*key
)
7950 TRACE("%p, %p.\n", iface
, key
);
7957 static HRESULT WINAPI
system_clock_GetState(IMFClock
*iface
, DWORD reserved
, MFCLOCK_STATE
*state
)
7959 TRACE("%p, %#lx, %p.\n", iface
, reserved
, state
);
7961 *state
= MFCLOCK_STATE_RUNNING
;
7966 static HRESULT WINAPI
system_clock_GetProperties(IMFClock
*iface
, MFCLOCK_PROPERTIES
*props
)
7968 TRACE("%p, %p.\n", iface
, props
);
7973 memset(props
, 0, sizeof(*props
));
7974 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7975 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7976 props
->dwClockJitter
= 1;
7981 static const IMFClockVtbl system_clock_vtbl
=
7983 system_clock_QueryInterface
,
7984 system_clock_AddRef
,
7985 system_clock_Release
,
7986 system_clock_GetClockCharacteristics
,
7987 system_clock_GetCorrelatedTime
,
7988 system_clock_GetContinuityKey
,
7989 system_clock_GetState
,
7990 system_clock_GetProperties
,
7993 static HRESULT
create_system_clock(IMFClock
**clock
)
7995 struct system_clock
*object
;
7997 if (!(object
= malloc(sizeof(*object
))))
7998 return E_OUTOFMEMORY
;
8000 object
->IMFClock_iface
.lpVtbl
= &system_clock_vtbl
;
8001 object
->refcount
= 1;
8003 *clock
= &object
->IMFClock_iface
;
8008 static HRESULT WINAPI
system_time_source_QueryInterface(IMFPresentationTimeSource
*iface
, REFIID riid
, void **obj
)
8010 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8012 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8014 if (IsEqualIID(riid
, &IID_IMFPresentationTimeSource
) ||
8015 IsEqualIID(riid
, &IID_IUnknown
))
8017 *obj
= &source
->IMFPresentationTimeSource_iface
;
8019 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
8021 *obj
= &source
->IMFClockStateSink_iface
;
8025 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8027 return E_NOINTERFACE
;
8030 IUnknown_AddRef((IUnknown
*)*obj
);
8034 static ULONG WINAPI
system_time_source_AddRef(IMFPresentationTimeSource
*iface
)
8036 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8037 ULONG refcount
= InterlockedIncrement(&source
->refcount
);
8039 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8044 static ULONG WINAPI
system_time_source_Release(IMFPresentationTimeSource
*iface
)
8046 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8047 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
8049 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8054 IMFClock_Release(source
->clock
);
8055 DeleteCriticalSection(&source
->cs
);
8062 static HRESULT WINAPI
system_time_source_GetClockCharacteristics(IMFPresentationTimeSource
*iface
, DWORD
*flags
)
8064 TRACE("%p, %p.\n", iface
, flags
);
8066 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
8071 static HRESULT WINAPI
system_time_source_GetCorrelatedTime(IMFPresentationTimeSource
*iface
, DWORD reserved
,
8072 LONGLONG
*clock_time
, MFTIME
*system_time
)
8074 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8077 TRACE("%p, %#lx, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
8079 EnterCriticalSection(&source
->cs
);
8080 if (SUCCEEDED(hr
= IMFClock_GetCorrelatedTime(source
->clock
, 0, clock_time
, system_time
)))
8082 if (source
->state
== MFCLOCK_STATE_RUNNING
)
8083 system_time_source_update_clock_time(source
, *system_time
);
8084 *clock_time
= source
->start_offset
+ source
->clock_time
;
8086 LeaveCriticalSection(&source
->cs
);
8091 static HRESULT WINAPI
system_time_source_GetContinuityKey(IMFPresentationTimeSource
*iface
, DWORD
*key
)
8093 TRACE("%p, %p.\n", iface
, key
);
8100 static HRESULT WINAPI
system_time_source_GetState(IMFPresentationTimeSource
*iface
, DWORD reserved
,
8101 MFCLOCK_STATE
*state
)
8103 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8105 TRACE("%p, %#lx, %p.\n", iface
, reserved
, state
);
8107 EnterCriticalSection(&source
->cs
);
8108 *state
= source
->state
;
8109 LeaveCriticalSection(&source
->cs
);
8114 static HRESULT WINAPI
system_time_source_GetProperties(IMFPresentationTimeSource
*iface
, MFCLOCK_PROPERTIES
*props
)
8116 TRACE("%p, %p.\n", iface
, props
);
8121 memset(props
, 0, sizeof(*props
));
8122 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
8123 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
8124 props
->dwClockJitter
= 1;
8129 static HRESULT WINAPI
system_time_source_GetUnderlyingClock(IMFPresentationTimeSource
*iface
, IMFClock
**clock
)
8131 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8133 TRACE("%p, %p.\n", iface
, clock
);
8135 *clock
= source
->clock
;
8136 IMFClock_AddRef(*clock
);
8141 static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl
=
8143 system_time_source_QueryInterface
,
8144 system_time_source_AddRef
,
8145 system_time_source_Release
,
8146 system_time_source_GetClockCharacteristics
,
8147 system_time_source_GetCorrelatedTime
,
8148 system_time_source_GetContinuityKey
,
8149 system_time_source_GetState
,
8150 system_time_source_GetProperties
,
8151 system_time_source_GetUnderlyingClock
,
8154 static HRESULT WINAPI
system_time_source_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **out
)
8156 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8157 return IMFPresentationTimeSource_QueryInterface(&source
->IMFPresentationTimeSource_iface
, riid
, out
);
8160 static ULONG WINAPI
system_time_source_sink_AddRef(IMFClockStateSink
*iface
)
8162 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8163 return IMFPresentationTimeSource_AddRef(&source
->IMFPresentationTimeSource_iface
);
8166 static ULONG WINAPI
system_time_source_sink_Release(IMFClockStateSink
*iface
)
8168 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8169 return IMFPresentationTimeSource_Release(&source
->IMFPresentationTimeSource_iface
);
8174 CLOCK_CMD_START
= 0,
8181 static HRESULT
system_time_source_change_state(struct system_time_source
*source
, enum clock_command command
)
8183 static const BYTE state_change_is_allowed
[MFCLOCK_STATE_PAUSED
+1][CLOCK_CMD_MAX
] =
8185 /* INVALID */ { 1, 0, 1, 0 },
8186 /* RUNNING */ { 1, 1, 1, 0 },
8187 /* STOPPED */ { 1, 1, 0, 0 },
8188 /* PAUSED */ { 1, 1, 0, 1 },
8190 static const MFCLOCK_STATE states
[CLOCK_CMD_MAX
] =
8192 /* CLOCK_CMD_START */ MFCLOCK_STATE_RUNNING
,
8193 /* CLOCK_CMD_STOP */ MFCLOCK_STATE_STOPPED
,
8194 /* CLOCK_CMD_PAUSE */ MFCLOCK_STATE_PAUSED
,
8195 /* CLOCK_CMD_RESTART */ MFCLOCK_STATE_RUNNING
,
8198 /* Special case that go against usual state change vs return value behavior. */
8199 if (source
->state
== MFCLOCK_STATE_INVALID
&& command
== CLOCK_CMD_STOP
)
8202 if (!state_change_is_allowed
[source
->state
][command
])
8203 return MF_E_INVALIDREQUEST
;
8205 source
->state
= states
[command
];
8210 static HRESULT WINAPI
system_time_source_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
,
8211 LONGLONG start_offset
)
8213 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8214 MFCLOCK_STATE state
;
8217 TRACE("%p, %s, %s.\n", iface
, debugstr_time(system_time
), debugstr_time(start_offset
));
8219 EnterCriticalSection(&source
->cs
);
8220 state
= source
->state
;
8221 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_START
)))
8223 if (start_offset
== PRESENTATION_CURRENT_POSITION
)
8225 if (state
!= MFCLOCK_STATE_RUNNING
)
8227 source
->start_offset
-= system_time
;
8228 source
->system_time
= 0;
8233 source
->start_offset
= start_offset
;
8234 source
->system_time
= system_time
;
8235 source
->clock_time
= 0;
8238 LeaveCriticalSection(&source
->cs
);
8243 static HRESULT WINAPI
system_time_source_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
8245 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8248 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8250 EnterCriticalSection(&source
->cs
);
8251 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_STOP
)))
8253 source
->start_offset
= source
->system_time
= source
->clock_time
= 0;
8255 LeaveCriticalSection(&source
->cs
);
8260 static HRESULT WINAPI
system_time_source_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
8262 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8265 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8267 EnterCriticalSection(&source
->cs
);
8268 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_PAUSE
)))
8270 system_time_source_update_clock_time(source
, system_time
);
8272 LeaveCriticalSection(&source
->cs
);
8277 static HRESULT WINAPI
system_time_source_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
8279 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8282 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8284 EnterCriticalSection(&source
->cs
);
8285 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_RESTART
)))
8287 source
->system_time
= system_time
;
8289 LeaveCriticalSection(&source
->cs
);
8294 static HRESULT WINAPI
system_time_source_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
8296 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8299 TRACE("%p, %s, %f.\n", iface
, debugstr_time(system_time
), rate
);
8302 return MF_E_UNSUPPORTED_RATE
;
8304 modf(rate
, &intpart
);
8306 EnterCriticalSection(&source
->cs
);
8307 source
->rate
= rate
;
8308 source
->i_rate
= rate
== intpart
? rate
: 0;
8309 LeaveCriticalSection(&source
->cs
);
8314 static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl
=
8316 system_time_source_sink_QueryInterface
,
8317 system_time_source_sink_AddRef
,
8318 system_time_source_sink_Release
,
8319 system_time_source_sink_OnClockStart
,
8320 system_time_source_sink_OnClockStop
,
8321 system_time_source_sink_OnClockPause
,
8322 system_time_source_sink_OnClockRestart
,
8323 system_time_source_sink_OnClockSetRate
,
8326 /***********************************************************************
8327 * MFCreateSystemTimeSource (mfplat.@)
8329 HRESULT WINAPI
MFCreateSystemTimeSource(IMFPresentationTimeSource
**time_source
)
8331 struct system_time_source
*object
;
8334 TRACE("%p.\n", time_source
);
8336 object
= calloc(1, sizeof(*object
));
8338 return E_OUTOFMEMORY
;
8340 object
->IMFPresentationTimeSource_iface
.lpVtbl
= &systemtimesourcevtbl
;
8341 object
->IMFClockStateSink_iface
.lpVtbl
= &systemtimesourcesinkvtbl
;
8342 object
->refcount
= 1;
8343 object
->rate
= 1.0f
;
8345 InitializeCriticalSection(&object
->cs
);
8347 if (FAILED(hr
= create_system_clock(&object
->clock
)))
8349 IMFPresentationTimeSource_Release(&object
->IMFPresentationTimeSource_iface
);
8353 *time_source
= &object
->IMFPresentationTimeSource_iface
;
8358 struct async_create_file
8360 IRtwqAsyncCallback IRtwqAsyncCallback_iface
;
8362 MF_FILE_ACCESSMODE access_mode
;
8363 MF_FILE_OPENMODE open_mode
;
8364 MF_FILE_FLAGS flags
;
8368 struct async_create_file_result
8371 IRtwqAsyncResult
*result
;
8372 IMFByteStream
*stream
;
8375 static struct list async_create_file_results
= LIST_INIT(async_create_file_results
);
8376 static CRITICAL_SECTION async_create_file_cs
= { NULL
, -1, 0, 0, 0, 0 };
8378 static struct async_create_file
*impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
8380 return CONTAINING_RECORD(iface
, struct async_create_file
, IRtwqAsyncCallback_iface
);
8383 static HRESULT WINAPI
async_create_file_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
8385 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
8386 IsEqualIID(riid
, &IID_IUnknown
))
8389 IRtwqAsyncCallback_AddRef(iface
);
8394 return E_NOINTERFACE
;
8397 static ULONG WINAPI
async_create_file_callback_AddRef(IRtwqAsyncCallback
*iface
)
8399 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8400 ULONG refcount
= InterlockedIncrement(&async
->refcount
);
8402 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8407 static ULONG WINAPI
async_create_file_callback_Release(IRtwqAsyncCallback
*iface
)
8409 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8410 ULONG refcount
= InterlockedDecrement(&async
->refcount
);
8412 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8423 static HRESULT WINAPI
async_create_file_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
8428 static HRESULT WINAPI
async_create_file_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
8430 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8431 IRtwqAsyncResult
*caller
;
8432 IMFByteStream
*stream
;
8435 caller
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
8437 hr
= MFCreateFile(async
->access_mode
, async
->open_mode
, async
->flags
, async
->path
, &stream
);
8440 struct async_create_file_result
*result_item
;
8442 result_item
= malloc(sizeof(*result_item
));
8445 result_item
->result
= caller
;
8446 IRtwqAsyncResult_AddRef(caller
);
8447 result_item
->stream
= stream
;
8448 IMFByteStream_AddRef(stream
);
8450 EnterCriticalSection(&async_create_file_cs
);
8451 list_add_tail(&async_create_file_results
, &result_item
->entry
);
8452 LeaveCriticalSection(&async_create_file_cs
);
8455 IMFByteStream_Release(stream
);
8458 IRtwqAsyncResult_SetStatus(caller
, hr
);
8460 RtwqInvokeCallback(caller
);
8465 static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl
=
8467 async_create_file_callback_QueryInterface
,
8468 async_create_file_callback_AddRef
,
8469 async_create_file_callback_Release
,
8470 async_create_file_callback_GetParameters
,
8471 async_create_file_callback_Invoke
,
8474 /***********************************************************************
8475 * MFBeginCreateFile (mfplat.@)
8477 HRESULT WINAPI
MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode
, MF_FILE_OPENMODE open_mode
, MF_FILE_FLAGS flags
,
8478 const WCHAR
*path
, IMFAsyncCallback
*callback
, IUnknown
*state
, IUnknown
**cancel_cookie
)
8480 struct async_create_file
*async
= NULL
;
8481 IRtwqAsyncResult
*caller
, *item
= NULL
;
8484 TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode
, open_mode
, flags
, debugstr_w(path
), callback
, state
,
8488 *cancel_cookie
= NULL
;
8490 if (FAILED(hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &caller
)))
8493 if (!(async
= malloc(sizeof(*async
))))
8499 async
->IRtwqAsyncCallback_iface
.lpVtbl
= &async_create_file_callback_vtbl
;
8500 async
->refcount
= 1;
8501 async
->access_mode
= access_mode
;
8502 async
->open_mode
= open_mode
;
8503 async
->flags
= flags
;
8504 if (!(async
->path
= wcsdup(path
)))
8510 hr
= RtwqCreateAsyncResult(NULL
, &async
->IRtwqAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
8516 *cancel_cookie
= (IUnknown
*)caller
;
8517 IUnknown_AddRef(*cancel_cookie
);
8520 hr
= RtwqInvokeCallback(item
);
8524 IRtwqAsyncCallback_Release(&async
->IRtwqAsyncCallback_iface
);
8526 IRtwqAsyncResult_Release(item
);
8528 IRtwqAsyncResult_Release(caller
);
8533 static HRESULT
async_create_file_pull_result(IUnknown
*unk
, IMFByteStream
**stream
)
8535 struct async_create_file_result
*item
;
8536 HRESULT hr
= MF_E_UNEXPECTED
;
8537 IRtwqAsyncResult
*result
;
8541 if (FAILED(IUnknown_QueryInterface(unk
, &IID_IRtwqAsyncResult
, (void **)&result
)))
8544 EnterCriticalSection(&async_create_file_cs
);
8546 LIST_FOR_EACH_ENTRY(item
, &async_create_file_results
, struct async_create_file_result
, entry
)
8548 if (result
== item
->result
)
8550 *stream
= item
->stream
;
8551 IRtwqAsyncResult_Release(item
->result
);
8552 list_remove(&item
->entry
);
8558 LeaveCriticalSection(&async_create_file_cs
);
8561 hr
= IRtwqAsyncResult_GetStatus(result
);
8563 IRtwqAsyncResult_Release(result
);
8568 /***********************************************************************
8569 * MFEndCreateFile (mfplat.@)
8571 HRESULT WINAPI
MFEndCreateFile(IMFAsyncResult
*result
, IMFByteStream
**stream
)
8573 TRACE("%p, %p.\n", result
, stream
);
8575 return async_create_file_pull_result((IUnknown
*)result
, stream
);
8578 /***********************************************************************
8579 * MFCancelCreateFile (mfplat.@)
8581 HRESULT WINAPI
MFCancelCreateFile(IUnknown
*cancel_cookie
)
8583 IMFByteStream
*stream
= NULL
;
8586 TRACE("%p.\n", cancel_cookie
);
8588 hr
= async_create_file_pull_result(cancel_cookie
, &stream
);
8591 IMFByteStream_Release(stream
);
8596 /***********************************************************************
8597 * MFRegisterLocalSchemeHandler (mfplat.@)
8599 HRESULT WINAPI
MFRegisterLocalSchemeHandler(const WCHAR
*scheme
, IMFActivate
*activate
)
8601 struct local_handler
*handler
;
8603 TRACE("%s, %p.\n", debugstr_w(scheme
), activate
);
8605 if (!scheme
|| !activate
)
8606 return E_INVALIDARG
;
8608 if (!(handler
= malloc(sizeof(*handler
))))
8609 return E_OUTOFMEMORY
;
8611 if (!(handler
->u
.scheme
= wcsdup(scheme
)))
8614 return E_OUTOFMEMORY
;
8616 handler
->activate
= activate
;
8617 IMFActivate_AddRef(handler
->activate
);
8619 EnterCriticalSection(&local_handlers_section
);
8620 list_add_head(&local_scheme_handlers
, &handler
->entry
);
8621 LeaveCriticalSection(&local_handlers_section
);
8626 /***********************************************************************
8627 * MFRegisterLocalByteStreamHandler (mfplat.@)
8629 HRESULT WINAPI
MFRegisterLocalByteStreamHandler(const WCHAR
*extension
, const WCHAR
*mime
, IMFActivate
*activate
)
8631 struct local_handler
*handler
;
8633 TRACE("%s, %s, %p.\n", debugstr_w(extension
), debugstr_w(mime
), activate
);
8635 if ((!extension
&& !mime
) || !activate
)
8636 return E_INVALIDARG
;
8638 if (!(handler
= calloc(1, sizeof(*handler
))))
8639 return E_OUTOFMEMORY
;
8641 if (extension
&& !(handler
->u
.bytestream
.extension
= wcsdup(extension
)))
8643 if (mime
&& !(handler
->u
.bytestream
.mime
= wcsdup(mime
)))
8646 EnterCriticalSection(&local_handlers_section
);
8647 list_add_head(&local_bytestream_handlers
, &handler
->entry
);
8648 LeaveCriticalSection(&local_handlers_section
);
8653 free(handler
->u
.bytestream
.extension
);
8654 free(handler
->u
.bytestream
.mime
);
8657 return E_OUTOFMEMORY
;
8660 struct property_store
8662 IPropertyStore IPropertyStore_iface
;
8664 CRITICAL_SECTION cs
;
8665 size_t count
, capacity
;
8673 static struct property_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
8675 return CONTAINING_RECORD(iface
, struct property_store
, IPropertyStore_iface
);
8678 static HRESULT WINAPI
property_store_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
8680 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8682 if (IsEqualIID(riid
, &IID_IPropertyStore
) || IsEqualIID(riid
, &IID_IUnknown
))
8685 IPropertyStore_AddRef(iface
);
8690 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
8691 return E_NOINTERFACE
;
8694 static ULONG WINAPI
property_store_AddRef(IPropertyStore
*iface
)
8696 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8697 ULONG refcount
= InterlockedIncrement(&store
->refcount
);
8699 TRACE("%p, refcount %ld.\n", iface
, refcount
);
8704 static ULONG WINAPI
property_store_Release(IPropertyStore
*iface
)
8706 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8707 ULONG refcount
= InterlockedDecrement(&store
->refcount
);
8709 TRACE("%p, refcount %ld.\n", iface
, refcount
);
8713 DeleteCriticalSection(&store
->cs
);
8714 free(store
->values
);
8721 static HRESULT WINAPI
property_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
8723 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8725 TRACE("%p, %p.\n", iface
, count
);
8728 return E_INVALIDARG
;
8730 EnterCriticalSection(&store
->cs
);
8731 *count
= store
->count
;
8732 LeaveCriticalSection(&store
->cs
);
8736 static HRESULT WINAPI
property_store_GetAt(IPropertyStore
*iface
, DWORD index
, PROPERTYKEY
*key
)
8738 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8740 TRACE("%p, %lu, %p.\n", iface
, index
, key
);
8742 EnterCriticalSection(&store
->cs
);
8744 if (index
>= store
->count
)
8746 LeaveCriticalSection(&store
->cs
);
8747 return E_INVALIDARG
;
8750 *key
= store
->values
[index
].key
;
8752 LeaveCriticalSection(&store
->cs
);
8756 static HRESULT WINAPI
property_store_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
8758 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8761 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8764 return E_INVALIDARG
;
8769 EnterCriticalSection(&store
->cs
);
8771 for (i
= 0; i
< store
->count
; ++i
)
8773 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8775 PropVariantCopy(value
, &store
->values
[i
].value
);
8776 LeaveCriticalSection(&store
->cs
);
8781 LeaveCriticalSection(&store
->cs
);
8785 static HRESULT WINAPI
property_store_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
8787 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8790 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8792 EnterCriticalSection(&store
->cs
);
8794 for (i
= 0; i
< store
->count
; ++i
)
8796 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8798 PropVariantCopy(&store
->values
[i
].value
, value
);
8799 LeaveCriticalSection(&store
->cs
);
8804 if (!mf_array_reserve((void **)&store
->values
, &store
->capacity
, store
->count
+ 1, sizeof(*store
->values
)))
8806 LeaveCriticalSection(&store
->cs
);
8807 return E_OUTOFMEMORY
;
8810 store
->values
[store
->count
].key
= *key
;
8811 PropVariantCopy(&store
->values
[store
->count
].value
, value
);
8814 LeaveCriticalSection(&store
->cs
);
8818 static HRESULT WINAPI
property_store_Commit(IPropertyStore
*iface
)
8820 TRACE("%p.\n", iface
);
8825 static const IPropertyStoreVtbl property_store_vtbl
=
8827 property_store_QueryInterface
,
8828 property_store_AddRef
,
8829 property_store_Release
,
8830 property_store_GetCount
,
8831 property_store_GetAt
,
8832 property_store_GetValue
,
8833 property_store_SetValue
,
8834 property_store_Commit
,
8837 /***********************************************************************
8838 * CreatePropertyStore (mfplat.@)
8840 HRESULT WINAPI
CreatePropertyStore(IPropertyStore
**store
)
8842 struct property_store
*object
;
8844 TRACE("%p.\n", store
);
8847 return E_INVALIDARG
;
8849 if (!(object
= calloc(1, sizeof(*object
))))
8850 return E_OUTOFMEMORY
;
8852 object
->IPropertyStore_iface
.lpVtbl
= &property_store_vtbl
;
8853 object
->refcount
= 1;
8854 InitializeCriticalSection(&object
->cs
);
8856 TRACE("Created store %p.\n", object
);
8857 *store
= &object
->IPropertyStore_iface
;
8862 struct shared_dxgi_manager
8864 IMFDXGIDeviceManager
*manager
;
8869 static struct shared_dxgi_manager shared_dm
;
8870 static CRITICAL_SECTION shared_dm_cs
= { NULL
, -1, 0, 0, 0, 0 };
8872 enum dxgi_device_handle_flags
8874 DXGI_DEVICE_HANDLE_FLAG_OPEN
= 0x1,
8875 DXGI_DEVICE_HANDLE_FLAG_INVALID
= 0x2,
8876 DXGI_DEVICE_HANDLE_FLAG_LOCKED
= 0x4,
8879 struct dxgi_device_manager
8881 IMFDXGIDeviceManager IMFDXGIDeviceManager_iface
;
8886 unsigned int *handles
;
8891 unsigned int locking_tid
;
8893 CRITICAL_SECTION cs
;
8894 CONDITION_VARIABLE lock
;
8897 static struct dxgi_device_manager
*impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager
*iface
)
8899 return CONTAINING_RECORD(iface
, struct dxgi_device_manager
, IMFDXGIDeviceManager_iface
);
8902 static HRESULT
dxgi_device_manager_get_handle_index(struct dxgi_device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
8904 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
8906 *idx
= (ULONG_PTR
)hdevice
- 1;
8910 static HRESULT WINAPI
dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager
*iface
, REFIID riid
, void **obj
)
8912 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8914 if (IsEqualIID(riid
, &IID_IMFDXGIDeviceManager
) ||
8915 IsEqualGUID(riid
, &IID_IUnknown
))
8918 IMFDXGIDeviceManager_AddRef(iface
);
8922 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8924 return E_NOINTERFACE
;
8927 static ULONG WINAPI
dxgi_device_manager_AddRef(IMFDXGIDeviceManager
*iface
)
8929 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8930 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
8932 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8937 static ULONG WINAPI
dxgi_device_manager_Release(IMFDXGIDeviceManager
*iface
)
8939 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8940 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
8942 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8946 if (manager
->device
)
8947 IUnknown_Release(manager
->device
);
8948 DeleteCriticalSection(&manager
->cs
);
8949 free(manager
->handles
);
8956 static void dxgi_device_manager_lock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8958 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
)
8961 manager
->handles
[idx
] |= DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8965 static void dxgi_device_manager_unlock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8967 if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
))
8970 manager
->handles
[idx
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8971 if (!--manager
->locks
)
8972 manager
->locking_tid
= 0;
8975 static HRESULT WINAPI
dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8977 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8981 TRACE("%p, %p.\n", iface
, hdevice
);
8983 EnterCriticalSection(&manager
->cs
);
8985 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8987 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8989 dxgi_device_manager_unlock_handle(manager
, idx
);
8990 manager
->handles
[idx
] = 0;
8991 if (idx
== manager
->count
- 1)
8998 LeaveCriticalSection(&manager
->cs
);
9000 WakeAllConditionVariable(&manager
->lock
);
9005 static HRESULT WINAPI
dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
9006 REFIID riid
, void **service
)
9008 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9012 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), service
);
9014 EnterCriticalSection(&manager
->cs
);
9016 if (!manager
->device
)
9017 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
9018 else if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9020 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
9021 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9022 else if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
9023 hr
= IUnknown_QueryInterface(manager
->device
, riid
, service
);
9028 LeaveCriticalSection(&manager
->cs
);
9033 static HRESULT WINAPI
dxgi_device_manager_LockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
9034 REFIID riid
, void **obj
, BOOL block
)
9036 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9040 TRACE("%p, %p, %s, %p, %d.\n", iface
, hdevice
, wine_dbgstr_guid(riid
), obj
, block
);
9042 EnterCriticalSection(&manager
->cs
);
9044 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9046 if (!manager
->device
)
9048 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
9050 else if (manager
->locking_tid
== GetCurrentThreadId())
9052 if (SUCCEEDED(hr
= IUnknown_QueryInterface(manager
->device
, riid
, obj
)))
9053 dxgi_device_manager_lock_handle(manager
, idx
);
9055 else if (manager
->locking_tid
&& !block
)
9057 hr
= MF_E_DXGI_VIDEO_DEVICE_LOCKED
;
9061 while (manager
->locking_tid
)
9063 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
9066 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9068 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
9069 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9070 else if (SUCCEEDED(hr
= IUnknown_QueryInterface(manager
->device
, riid
, obj
)))
9072 manager
->locking_tid
= GetCurrentThreadId();
9073 dxgi_device_manager_lock_handle(manager
, idx
);
9079 LeaveCriticalSection(&manager
->cs
);
9084 static HRESULT WINAPI
dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE
*hdevice
)
9086 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9090 TRACE("%p, %p.\n", iface
, hdevice
);
9094 EnterCriticalSection(&manager
->cs
);
9096 if (!manager
->device
)
9097 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
9100 for (i
= 0; i
< manager
->count
; ++i
)
9102 if (!(manager
->handles
[i
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
9104 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_OPEN
;
9105 *hdevice
= ULongToHandle(i
+ 1);
9110 if (mf_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
9111 sizeof(*manager
->handles
)))
9113 *hdevice
= ULongToHandle(manager
->count
+ 1);
9114 manager
->handles
[manager
->count
++] = DXGI_DEVICE_HANDLE_FLAG_OPEN
;
9120 LeaveCriticalSection(&manager
->cs
);
9125 static HRESULT WINAPI
dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager
*iface
, IUnknown
*device
, UINT token
)
9127 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9128 IUnknown
*d3d_device
;
9131 TRACE("%p, %p, %u.\n", iface
, device
, token
);
9133 if (!device
|| token
!= manager
->token
)
9134 return E_INVALIDARG
;
9136 if (FAILED(IUnknown_QueryInterface(device
, &IID_ID3D11Device
, (void **)&d3d_device
)))
9138 if (FAILED(IUnknown_QueryInterface(device
, &IID_ID3D12Device
, (void **)&d3d_device
)))
9140 WARN("Unsupported device interface.\n");
9141 return E_INVALIDARG
;
9145 EnterCriticalSection(&manager
->cs
);
9147 if (manager
->device
)
9149 for (i
= 0; i
< manager
->count
; ++i
)
9151 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_INVALID
;
9152 manager
->handles
[i
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
9154 manager
->locking_tid
= 0;
9156 IUnknown_Release(manager
->device
);
9158 manager
->device
= d3d_device
;
9160 LeaveCriticalSection(&manager
->cs
);
9162 WakeAllConditionVariable(&manager
->lock
);
9167 static HRESULT WINAPI
dxgi_device_manager_TestDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
9169 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9173 TRACE("%p, %p.\n", iface
, hdevice
);
9175 EnterCriticalSection(&manager
->cs
);
9177 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9179 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
9180 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9181 else if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
9185 LeaveCriticalSection(&manager
->cs
);
9190 static HRESULT WINAPI
dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
9193 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9194 HRESULT hr
= E_FAIL
;
9197 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
9199 EnterCriticalSection(&manager
->cs
);
9201 if (SUCCEEDED(dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9203 hr
= manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
? S_OK
: E_INVALIDARG
;
9205 dxgi_device_manager_unlock_handle(manager
, idx
);
9208 LeaveCriticalSection(&manager
->cs
);
9210 WakeAllConditionVariable(&manager
->lock
);
9215 static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl
=
9217 dxgi_device_manager_QueryInterface
,
9218 dxgi_device_manager_AddRef
,
9219 dxgi_device_manager_Release
,
9220 dxgi_device_manager_CloseDeviceHandle
,
9221 dxgi_device_manager_GetVideoService
,
9222 dxgi_device_manager_LockDevice
,
9223 dxgi_device_manager_OpenDeviceHandle
,
9224 dxgi_device_manager_ResetDevice
,
9225 dxgi_device_manager_TestDevice
,
9226 dxgi_device_manager_UnlockDevice
,
9229 /***********************************************************************
9230 * MFCreateDXGIDeviceManager (mfplat.@)
9232 HRESULT WINAPI
MFCreateDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
9234 struct dxgi_device_manager
*object
;
9236 TRACE("%p, %p.\n", token
, manager
);
9238 if (!token
|| !manager
)
9241 if (!(object
= calloc(1, sizeof(*object
))))
9242 return E_OUTOFMEMORY
;
9244 object
->IMFDXGIDeviceManager_iface
.lpVtbl
= &dxgi_device_manager_vtbl
;
9245 object
->refcount
= 1;
9246 object
->token
= GetTickCount();
9247 InitializeCriticalSection(&object
->cs
);
9248 InitializeConditionVariable(&object
->lock
);
9250 TRACE("Created device manager: %p, token: %u.\n", object
, object
->token
);
9252 *token
= object
->token
;
9253 *manager
= &object
->IMFDXGIDeviceManager_iface
;
9258 /***********************************************************************
9259 * MFLockDXGIDeviceManager (mfplat.@)
9261 HRESULT WINAPI
MFLockDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
9265 TRACE("%p, %p.\n", token
, manager
);
9267 EnterCriticalSection(&shared_dm_cs
);
9269 if (!shared_dm
.manager
)
9270 hr
= MFCreateDXGIDeviceManager(&shared_dm
.token
, &shared_dm
.manager
);
9274 *manager
= shared_dm
.manager
;
9275 IMFDXGIDeviceManager_AddRef(*manager
);
9278 if (token
) *token
= shared_dm
.token
;
9281 LeaveCriticalSection(&shared_dm_cs
);
9286 /***********************************************************************
9287 * MFUnlockDXGIDeviceManager (mfplat.@)
9289 HRESULT WINAPI
MFUnlockDXGIDeviceManager(void)
9293 EnterCriticalSection(&shared_dm_cs
);
9295 if (shared_dm
.manager
)
9297 IMFDXGIDeviceManager_Release(shared_dm
.manager
);
9298 if (!--shared_dm
.locks
)
9300 shared_dm
.manager
= NULL
;
9301 shared_dm
.token
= 0;
9305 LeaveCriticalSection(&shared_dm_cs
);
9312 * MFllMulDiv implementation is derived from gstreamer utility functions code (gstutils.c),
9313 * released under LGPL2. Full authors list follows.
9314 * ===================================================================================
9315 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
9316 * 2000 Wim Taymans <wtay@chello.be>
9317 * 2002 Thomas Vander Stichele <thomas@apestaart.org>
9318 * 2004 Wim Taymans <wim@fluendo.com>
9319 * 2015 Jan Schmidt <jan@centricular.com>
9320 * ===================================================================================
9323 static void llmult128(ULARGE_INTEGER
*c1
, ULARGE_INTEGER
*c0
, LONGLONG val
, LONGLONG num
)
9325 ULARGE_INTEGER a1
, b0
, v
, n
;
9327 v
.QuadPart
= llabs(val
);
9328 n
.QuadPart
= llabs(num
);
9330 /* do 128 bits multiply
9338 * -------------------
9341 * "a0" is optimized away, result is stored directly in c0. "b1" is
9342 * optimized away, result is stored directly in c1.
9344 c0
->QuadPart
= (ULONGLONG
)v
.LowPart
* n
.LowPart
;
9345 a1
.QuadPart
= (ULONGLONG
)v
.LowPart
* n
.HighPart
;
9346 b0
.QuadPart
= (ULONGLONG
)v
.HighPart
* n
.LowPart
;
9348 /* add the high word of a0 to the low words of a1 and b0 using c1 as
9349 * scratch space to capture the carry. the low word of the result becomes
9350 * the final high word of c0 */
9351 c1
->QuadPart
= (ULONGLONG
)c0
->HighPart
+ a1
.LowPart
+ b0
.LowPart
;
9352 c0
->HighPart
= c1
->LowPart
;
9354 /* add the carry from the result above (found in the high word of c1) and
9355 * the high words of a1 and b0 to b1, the result is c1. */
9356 c1
->QuadPart
= (ULONGLONG
)v
.HighPart
* n
.HighPart
+ c1
->HighPart
+ a1
.HighPart
+ b0
.HighPart
;
9359 static ULONGLONG
lldiv128(ULARGE_INTEGER c1
, ULARGE_INTEGER c0
, LONGLONG denom
)
9361 ULARGE_INTEGER q1
, q0
, rhat
;
9362 ULARGE_INTEGER v
, cmp1
, cmp2
;
9365 v
.QuadPart
= llabs(denom
);
9367 /* 64bit numerator */
9368 if (c1
.QuadPart
== 0)
9369 return c0
.QuadPart
/ v
.QuadPart
;
9371 /* 96bit numerator, 32bit denominator */
9372 if (v
.HighPart
== 0 && c1
.HighPart
== 0)
9374 ULONGLONG low
= c0
.LowPart
, high
= c0
.HighPart
+ ((ULONGLONG
)c1
.LowPart
<< 32);
9375 low
+= (high
% v
.LowPart
) << 32;
9376 return ((high
/ v
.LowPart
) << 32) + (low
/ v
.LowPart
);
9379 /* 128bit numerator, 32bit denominator */
9380 if (v
.HighPart
== 0)
9383 /* count number of leading zeroes */
9384 BitScanReverse(&s
, v
.HighPart
);
9389 /* normalize divisor and dividend */
9391 c1
.QuadPart
= (c1
.QuadPart
<< s
) | (c0
.HighPart
>> (32 - s
));
9395 q1
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9396 rhat
.QuadPart
= c1
.QuadPart
- q1
.QuadPart
* v
.HighPart
;
9398 cmp1
.HighPart
= rhat
.LowPart
;
9399 cmp1
.LowPart
= c0
.HighPart
;
9400 cmp2
.QuadPart
= q1
.QuadPart
* v
.LowPart
;
9402 while (q1
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9405 rhat
.QuadPart
+= v
.HighPart
;
9408 cmp1
.HighPart
= rhat
.LowPart
;
9409 cmp2
.QuadPart
-= v
.LowPart
;
9411 c1
.HighPart
= c1
.LowPart
;
9412 c1
.LowPart
= c0
.HighPart
;
9413 c1
.QuadPart
-= q1
.QuadPart
* v
.QuadPart
;
9414 q0
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9415 rhat
.QuadPart
= c1
.QuadPart
- q0
.QuadPart
* v
.HighPart
;
9417 cmp1
.HighPart
= rhat
.LowPart
;
9418 cmp1
.LowPart
= c0
.LowPart
;
9419 cmp2
.QuadPart
= q0
.QuadPart
* v
.LowPart
;
9421 while (q0
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9424 rhat
.QuadPart
+= v
.HighPart
;
9427 cmp1
.HighPart
= rhat
.LowPart
;
9428 cmp2
.QuadPart
-= v
.LowPart
;
9430 q0
.HighPart
+= q1
.LowPart
;
9435 /***********************************************************************
9436 * MFllMulDiv (mfplat.@)
9438 LONGLONG WINAPI
MFllMulDiv(LONGLONG val
, LONGLONG num
, LONGLONG denom
, LONGLONG factor
)
9440 #define LLOVERFLOW (sign ? I64_MIN : I64_MAX)
9441 unsigned int sign
, factor_sign
, denom_sign
;
9442 ULARGE_INTEGER c1
, c0
;
9445 TRACE("%s, %s, %s, %s.\n", wine_dbgstr_longlong(val
), wine_dbgstr_longlong(num
),
9446 wine_dbgstr_longlong(denom
), wine_dbgstr_longlong(factor
));
9448 /* compute 128-bit numerator product */
9449 llmult128(&c1
, &c0
, val
, num
);
9451 sign
= (val
< 0) ^ (num
< 0);
9452 factor_sign
= factor
< 0;
9453 denom_sign
= denom
< 0;
9455 factor
= llabs(factor
);
9456 if (sign
== factor_sign
)
9458 if (UI64_MAX
- c0
.QuadPart
< factor
)
9460 if (c1
.QuadPart
== UI64_MAX
) return LLOVERFLOW
;
9463 c0
.QuadPart
+= factor
;
9467 if (c0
.QuadPart
>= factor
)
9468 c0
.QuadPart
-= factor
;
9476 c0
.QuadPart
= factor
- c0
.QuadPart
;
9480 if (c1
.QuadPart
>= denom
) return LLOVERFLOW
;
9482 /* compute quotient, fits in 64 bits */
9483 ret
= lldiv128(c1
, c0
, denom
);
9485 if (ret
>= I64_MAX
) return LLOVERFLOW
;
9486 return sign
? -(LONGLONG
)ret
: ret
;