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
;
1357 if (FAILED(hr
= mft_collect_machine_reg(&mfts
, &category
, MFT_ENUM_FLAG_SYNCMFT
, NULL
, input_type
, output_type
)))
1360 mft_count
= list_count(&mfts
);
1364 if (!(*clsids
= CoTaskMemAlloc(mft_count
* sizeof(**clsids
))))
1368 LIST_FOR_EACH_ENTRY_SAFE(mft
, mft2
, &mfts
, struct mft_registration
, entry
)
1371 (*clsids
)[mft_count
++] = mft
->clsid
;
1372 list_remove(&mft
->entry
);
1373 release_mft_registration(mft
);
1379 CoTaskMemFree(*clsids
);
1387 /***********************************************************************
1388 * MFTEnumEx (mfplat.@)
1390 HRESULT WINAPI
MFTEnumEx(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1391 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFActivate
***activate
, UINT32
*count
)
1393 TRACE("%s, %#x, %s, %s, %p, %p.\n", debugstr_mf_guid(&category
), flags
, debugstr_reg_typeinfo(input_type
),
1394 debugstr_reg_typeinfo(output_type
), activate
, count
);
1396 return mft_enum(category
, flags
, input_type
, output_type
, NULL
, activate
, count
);
1399 /***********************************************************************
1400 * MFTEnum2 (mfplat.@)
1402 HRESULT WINAPI
MFTEnum2(GUID category
, UINT32 flags
, const MFT_REGISTER_TYPE_INFO
*input_type
,
1403 const MFT_REGISTER_TYPE_INFO
*output_type
, IMFAttributes
*attributes
, IMFActivate
***activate
, UINT32
*count
)
1405 TRACE("%s, %#x, %s, %s, %p, %p, %p.\n", debugstr_mf_guid(&category
), flags
, debugstr_reg_typeinfo(input_type
),
1406 debugstr_reg_typeinfo(output_type
), attributes
, activate
, count
);
1409 FIXME("Ignoring attributes.\n");
1411 return mft_enum(category
, flags
, input_type
, output_type
, attributes
, activate
, count
);
1414 /***********************************************************************
1415 * MFTUnregister (mfplat.@)
1417 HRESULT WINAPI
MFTUnregister(CLSID clsid
)
1419 WCHAR buffer
[64], category
[MAX_PATH
];
1420 HKEY htransform
, hcategory
, htmp
;
1421 DWORD size
= MAX_PATH
;
1424 TRACE("(%s)\n", debugstr_guid(&clsid
));
1426 guid_to_string(buffer
, &clsid
);
1428 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &htransform
))
1430 RegDeleteKeyW(htransform
, buffer
);
1431 RegCloseKey(htransform
);
1434 if (!RegOpenKeyW(HKEY_CLASSES_ROOT
, categories_keyW
, &hcategory
))
1436 while (RegEnumKeyExW(hcategory
, index
, category
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1438 if (!RegOpenKeyW(hcategory
, category
, &htmp
))
1440 RegDeleteKeyW(htmp
, buffer
);
1446 RegCloseKey(hcategory
);
1452 static HRESULT
mft_get_name(HKEY hkey
, WCHAR
**name
)
1461 if (!RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, NULL
, &size
))
1463 if (!(*name
= CoTaskMemAlloc(size
)))
1464 return E_OUTOFMEMORY
;
1466 RegQueryValueExW(hkey
, NULL
, NULL
, NULL
, (BYTE
*)*name
, &size
);
1472 static HRESULT
mft_get_reg_type_info(const WCHAR
*clsid
, const WCHAR
*key
, MFT_REGISTER_TYPE_INFO
**ret_types
,
1475 MFT_REGISTER_TYPE_INFO
*types
= NULL
;
1481 mft_get_reg_type_info_internal(clsid
, key
, &types
, &count
);
1484 if (!(*ret_types
= CoTaskMemAlloc(count
* sizeof(**ret_types
))))
1487 return E_OUTOFMEMORY
;
1490 memcpy(*ret_types
, types
, count
* sizeof(**ret_types
));
1499 static HRESULT
mft_get_attributes(HKEY hkey
, IMFAttributes
**ret
)
1501 IMFAttributes
*attributes
;
1509 if (FAILED(hr
= MFCreateAttributes(&attributes
, 0)))
1512 if (!RegQueryValueExW(hkey
, L
"Attributes", NULL
, NULL
, NULL
, &size
) && size
)
1514 if (!(blob
= malloc(size
)))
1516 IMFAttributes_Release(attributes
);
1517 return E_OUTOFMEMORY
;
1520 if (!RegQueryValueExW(hkey
, L
"Attributes", NULL
, NULL
, blob
, &size
))
1522 if (FAILED(hr
= MFInitAttributesFromBlob(attributes
, blob
, size
)))
1523 WARN("Failed to initialize attributes, hr %#lx.\n", hr
);
1532 IMFAttributes_AddRef(*ret
);
1535 IMFAttributes_Release(attributes
);
1540 /***********************************************************************
1541 * MFTGetInfo (mfplat.@)
1543 HRESULT WINAPI
MFTGetInfo(CLSID clsid
, WCHAR
**name
, MFT_REGISTER_TYPE_INFO
**input_types
,
1544 UINT32
*input_types_count
, MFT_REGISTER_TYPE_INFO
**output_types
, UINT32
*output_types_count
,
1545 IMFAttributes
**attributes
)
1552 TRACE("%s, %p, %p, %p, %p, %p, %p.\n", debugstr_guid(&clsid
), name
, input_types
,
1553 input_types_count
, output_types
, output_types_count
, attributes
);
1555 guid_to_string(clsidW
, &clsid
);
1557 if ((ret
= RegOpenKeyW(HKEY_CLASSES_ROOT
, transform_keyW
, &hroot
)))
1558 return HRESULT_FROM_WIN32(ret
);
1560 ret
= RegOpenKeyW(hroot
, clsidW
, &hmft
);
1563 return HRESULT_FROM_WIN32(ret
);
1565 if (input_types_count
)
1566 *input_types_count
= 0;
1568 if (output_types_count
)
1569 *output_types_count
= 0;
1571 hr
= mft_get_name(hmft
, name
);
1574 hr
= mft_get_reg_type_info(clsidW
, L
"InputTypes", input_types
, input_types_count
);
1577 hr
= mft_get_reg_type_info(clsidW
, L
"OutputTypes", output_types
, output_types_count
);
1580 hr
= mft_get_attributes(hmft
, attributes
);
1587 /***********************************************************************
1588 * MFStartup (mfplat.@)
1590 HRESULT WINAPI
MFStartup(ULONG version
, DWORD flags
)
1592 #define MF_VERSION_XP MAKELONG( MF_API_VERSION, 1 )
1593 #define MF_VERSION_WIN7 MAKELONG( MF_API_VERSION, 2 )
1595 TRACE("%#lx, %#lx.\n", version
, flags
);
1597 if (version
!= MF_VERSION_XP
&& version
!= MF_VERSION_WIN7
)
1598 return MF_E_BAD_STARTUP_VERSION
;
1605 /***********************************************************************
1606 * MFShutdown (mfplat.@)
1608 HRESULT WINAPI
MFShutdown(void)
1617 /***********************************************************************
1618 * MFCopyImage (mfplat.@)
1620 HRESULT WINAPI
MFCopyImage(BYTE
*dest
, LONG deststride
, const BYTE
*src
, LONG srcstride
, DWORD width
, DWORD lines
)
1622 TRACE("%p, %ld, %p, %ld, %lu, %lu.\n", dest
, deststride
, src
, srcstride
, width
, lines
);
1626 memcpy(dest
, src
, width
);
1640 static int __cdecl
debug_compare_guid(const void *a
, const void *b
)
1642 const GUID
*guid
= a
;
1643 const struct guid_def
*guid_def
= b
;
1644 return memcmp(guid
, guid_def
->guid
, sizeof(*guid
));
1647 const char *debugstr_attr(const GUID
*guid
)
1649 static const struct guid_def guid_defs
[] =
1651 #define X(g) { &(g), #g }
1652 #define MF_READER_WRITER_D3D_MANAGER MF_SOURCE_READER_D3D_MANAGER
1653 X(MF_READWRITE_MMCSS_CLASS
),
1654 X(MF_TOPONODE_MARKIN_HERE
),
1655 X(MF_MT_H264_SUPPORTED_SYNC_FRAME_TYPES
),
1656 X(MF_TOPONODE_MARKOUT_HERE
),
1657 X(EVRConfig_ForceBob
),
1658 X(MF_TOPONODE_DECODER
),
1659 X(EVRConfig_AllowDropToBob
),
1660 X(MF_TOPOLOGY_PROJECTSTART
),
1661 X(EVRConfig_ForceThrottle
),
1662 X(MF_VIDEO_MAX_MB_PER_SEC
),
1663 X(MF_TOPOLOGY_PROJECTSTOP
),
1664 X(MF_SINK_WRITER_ENCODER_CONFIG
),
1665 X(EVRConfig_AllowDropToThrottle
),
1666 X(MF_TOPOLOGY_NO_MARKIN_MARKOUT
),
1667 X(EVRConfig_ForceHalfInterlace
),
1668 X(EVRConfig_AllowDropToHalfInterlace
),
1669 X(EVRConfig_ForceScaling
),
1670 X(MF_MT_H264_CAPABILITIES
),
1671 X(EVRConfig_AllowScaling
),
1672 X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS
),
1673 X(MFT_PREFERRED_ENCODER_PROFILE
),
1674 X(EVRConfig_ForceBatching
),
1675 X(EVRConfig_AllowBatching
),
1676 X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED
),
1677 X(MF_MT_VIDEO_PROFILE
),
1678 X(MF_MT_DV_AAUX_CTRL_PACK_1
),
1679 X(MF_MT_ALPHA_MODE
),
1680 X(MF_MT_MPEG2_TIMECODE
),
1681 X(MF_PMP_SERVER_CONTEXT
),
1682 X(MF_TRANSCODE_TOPOLOGYMODE
),
1683 X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
),
1684 X(MF_MEDIA_ENGINE_TRACK_ID
),
1685 X(MFTranscodeContainerType_MP3
),
1686 X(MF_MT_CUSTOM_VIDEO_PRIMARIES
),
1687 X(MF_MT_TIMESTAMP_CAN_BE_DTS
),
1688 X(MFT_CODEC_MERIT_Attribute
),
1689 X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS
),
1690 X(MF_XVP_DISABLE_FRC
),
1692 X(MF_TRANSCODE_ADJUST_PROFILE
),
1693 X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
),
1694 X(MF_MT_MPEG2_FLAGS
),
1695 X(MF_MEDIA_ENGINE_AUDIO_CATEGORY
),
1696 X(MF_MT_PIXEL_ASPECT_RATIO
),
1697 X(MF_VIDEO_PROCESSOR_ALGORITHM
),
1698 X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK
),
1699 X(MFT_CONNECTED_STREAM_ATTRIBUTE
),
1700 X(MF_MT_REALTIME_CONTENT
),
1701 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
),
1702 X(MF_MT_WRAPPED_TYPE
),
1704 X(MF_MT_AVG_BITRATE
),
1705 X(MF_MT_DECODER_USE_MAX_RESOLUTION
),
1706 X(MF_MT_MAX_LUMINANCE_LEVEL
),
1707 X(MFT_CONNECTED_TO_HW_STREAM
),
1709 X(MF_XVP_SAMPLE_LOCK_TIMEOUT
),
1710 X(MF_MT_MAX_KEYFRAME_SPACING
),
1711 X(MFT_TRANSFORM_CLSID_Attribute
),
1712 X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING
),
1713 X(MF_MT_AM_FORMAT_TYPE
),
1714 X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME
),
1715 X(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
),
1716 X(MF_MT_H264_MAX_MB_PER_SEC
),
1717 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS
),
1718 X(MF_MT_AUDIO_BLOCK_ALIGNMENT
),
1719 X(MF_PD_PMPHOST_CONTEXT
),
1720 X(MF_PD_APP_CONTEXT
),
1722 X(MF_PD_TOTAL_FILE_SIZE
),
1723 X(MF_PD_AUDIO_ENCODING_BITRATE
),
1724 X(MF_PD_VIDEO_ENCODING_BITRATE
),
1725 X(MFSampleExtension_TargetGlobalLuminance
),
1727 X(MF_MT_H264_SUPPORTED_SLICE_MODES
),
1728 X(MF_PD_LAST_MODIFIED_TIME
),
1730 X(MF_PD_PLAYBACK_ELEMENT_ID
),
1731 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
),
1732 X(MF_MT_ALL_SAMPLES_INDEPENDENT
),
1733 X(MF_SA_D3D12_CLEAR_VALUE
),
1734 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER
),
1735 X(MF_PD_PREFERRED_LANGUAGE
),
1736 X(MF_PD_PLAYBACK_BOUNDARY_TIME
),
1737 X(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
),
1738 X(MF_ACTIVATE_MFT_LOCKED
),
1739 X(MFTranscodeContainerType_WAVE
),
1740 X(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
),
1741 X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING
),
1742 X(MF_MT_FRAME_SIZE
),
1743 X(MF_MT_H264_SIMULCAST_SUPPORT
),
1744 X(MF_SINK_WRITER_ASYNC_CALLBACK
),
1745 X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH
),
1746 X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
),
1747 X(MF_TRANSCODE_CONTAINERTYPE
),
1748 X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY
),
1749 X(MF_MT_FRAME_RATE_RANGE_MAX
),
1751 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID
),
1752 X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS
),
1753 X(MF_SA_D3D11_USAGE
),
1754 X(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
),
1755 X(MF_MT_GEOMETRIC_APERTURE
),
1756 X(MF_MT_ORIGINAL_WAVE_FORMAT_TAG
),
1757 X(MF_MT_DV_AAUX_SRC_PACK_1
),
1758 X(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
),
1759 X(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
),
1760 X(MF_MEDIA_ENGINE_EXTENSION
),
1761 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
),
1762 X(MF_MT_DEFAULT_STRIDE
),
1763 X(MF_MT_ARBITRARY_FORMAT
),
1764 X(MF_TRANSFORM_CATEGORY_Attribute
),
1765 X(MF_MT_MPEG2_HDCP
),
1766 X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND
),
1767 X(MF_MT_SPATIAL_AUDIO_MAX_DYNAMIC_OBJECTS
),
1768 X(MF_MT_DECODER_MAX_DPB_COUNT
),
1769 X(MFSampleExtension_ForwardedDecodeUnits
),
1770 X(MF_SA_D3D11_SHARED_WITHOUT_MUTEX
),
1771 X(MF_MT_DV_AAUX_CTRL_PACK_0
),
1772 X(MF_MT_YUV_MATRIX
),
1773 X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED
),
1774 X(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY
),
1775 X(MF_MT_MAX_FRAME_AVERAGE_LUMINANCE_LEVEL
),
1776 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID
),
1777 X(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
),
1778 X(MF_MT_VIDEO_ROTATION
),
1779 X(MFTranscodeContainerType_MPEG4
),
1780 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK
),
1781 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
),
1783 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID
),
1784 X(MF_MT_MIN_MASTERING_LUMINANCE
),
1785 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE
),
1786 X(MF_SA_REQUIRED_SAMPLE_COUNT
),
1787 X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS
),
1788 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID
),
1789 X(MF_EVENT_STREAM_METADATA_SYSTEMID
),
1790 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE
),
1791 X(MF_MT_AUDIO_CHANNEL_MASK
),
1792 X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN
),
1793 X(MF_READWRITE_DISABLE_CONVERTERS
),
1794 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
),
1795 X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS
),
1796 X(MF_SA_D3D12_HEAP_FLAGS
),
1797 X(MF_MT_MINIMUM_DISPLAY_APERTURE
),
1798 X(MFSampleExtension_Token
),
1799 X(MFTranscodeContainerType_3GP
),
1800 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY
),
1801 X(MF_D3D12_SYNCHRONIZATION_OBJECT
),
1802 X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE
),
1803 X(MF_TRANSFORM_ASYNC_UNLOCK
),
1804 X(MF_DISABLE_FRAME_CORRUPTION_INFO
),
1805 X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
),
1806 X(MFTranscodeContainerType_ASF
),
1807 X(MF_MT_VIDEO_NO_FRAME_ORDERING
),
1808 X(MF_MEDIA_ENGINE_PLAYBACK_VISUAL
),
1809 X(MF_MT_VIDEO_CHROMA_SITING
),
1810 X(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY
),
1811 X(MF_SA_BUFFERS_PER_SAMPLE
),
1812 X(MFSampleExtension_3DVideo_SampleFormat
),
1813 X(MF_MT_H264_RESOLUTION_SCALING
),
1814 X(MF_MT_VIDEO_LEVEL
),
1815 X(MF_SA_D3D12_HEAP_TYPE
),
1816 X(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET
),
1817 X(MF_MT_SAMPLE_SIZE
),
1818 X(MF_MT_AAC_PAYLOAD_TYPE
),
1819 X(MF_TOPOLOGY_PLAYBACK_FRAMERATE
),
1820 X(MF_SOURCE_READER_D3D11_BIND_FLAGS
),
1821 X(MF_TRANSCODE_ENCODINGPROFILE
),
1822 X(MF_MT_AUDIO_FOLDDOWN_MATRIX
),
1823 X(MF_MT_AUDIO_WMADRC_PEAKREF
),
1824 X(MFTranscodeContainerType_ADTS
),
1825 X(MF_MT_AUDIO_WMADRC_PEAKTARGET
),
1826 X(MF_TRANSFORM_FLAGS_Attribute
),
1827 X(MF_MT_H264_SUPPORTED_RATE_CONTROL_MODES
),
1828 X(MF_PD_SAMI_STYLELIST
),
1829 X(MF_MT_AUDIO_WMADRC_AVGREF
),
1830 X(MF_MT_AUDIO_BITS_PER_SAMPLE
),
1832 X(MF_MT_AUDIO_WMADRC_AVGTARGET
),
1834 X(MF_SESSION_TOPOLOADER
),
1835 X(MF_SESSION_GLOBAL_TIME
),
1836 X(MF_SESSION_QUALITY_MANAGER
),
1837 X(MF_SESSION_CONTENT_PROTECTION_MANAGER
),
1838 X(MF_MT_MPEG4_SAMPLE_DESCRIPTION
),
1839 X(MF_MT_D3D_RESOURCE_VERSION
),
1840 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET
),
1841 X(MF_MT_MPEG_START_TIME_CODE
),
1842 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1843 X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT
),
1844 X(MF_READWRITE_MMCSS_PRIORITY_AUDIO
),
1845 X(MF_MT_H264_MAX_CODEC_CONFIG_DELAY
),
1846 X(MF_MT_DV_AAUX_SRC_PACK_0
),
1847 X(MF_BYTESTREAM_ORIGIN_NAME
),
1848 X(MF_BYTESTREAM_CONTENT_TYPE
),
1849 X(MF_MT_DEPTH_MEASUREMENT
),
1850 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
),
1851 X(MF_MT_VIDEO_3D_NUM_VIEWS
),
1852 X(MF_BYTESTREAM_DURATION
),
1853 X(MF_SD_SAMI_LANGUAGE
),
1854 X(MF_EVENT_OUTPUT_NODE
),
1855 X(MF_BYTESTREAM_LAST_MODIFIED_TIME
),
1856 X(MFT_ENUM_ADAPTER_LUID
),
1857 X(MF_MT_FRAME_RATE_RANGE_MIN
),
1858 X(MF_BYTESTREAM_IFO_FILE_URI
),
1859 X(MF_EVENT_TOPOLOGY_STATUS
),
1860 X(MF_BYTESTREAM_DLNA_PROFILE_ID
),
1861 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ROLE
),
1862 X(MF_MT_MAJOR_TYPE
),
1863 X(MF_SA_REQUIRED_SAMPLE_COUNT_PROGRESSIVE
),
1864 X(MF_MT_IN_BAND_PARAMETER_SET
),
1865 X(MF_EVENT_SOURCE_CHARACTERISTICS
),
1866 X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD
),
1867 X(MF_SESSION_SERVER_CONTEXT
),
1868 X(MF_MT_VIDEO_3D_FIRST_IS_LEFT
),
1869 X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT
),
1870 X(MF_PD_ADAPTIVE_STREAMING
),
1871 X(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
),
1872 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
),
1873 X(MF_MT_H264_SUPPORTED_USAGES
),
1874 X(MFT_PREFERRED_OUTPUTTYPE_Attribute
),
1875 X(MFSampleExtension_Timestamp
),
1876 X(MF_TOPONODE_PRIMARYOUTPUT
),
1878 X(MF_TRANSFORM_ASYNC
),
1879 X(MF_TOPONODE_STREAMID
),
1880 X(MF_MEDIA_ENGINE_PLAYBACK_HWND
),
1881 X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE
),
1882 X(MF_MT_VIDEO_LIGHTING
),
1883 X(MF_SD_MUTUALLY_EXCLUSIVE
),
1884 X(MF_SD_STREAM_NAME
),
1885 X(MF_MT_DV_VAUX_SRC_PACK
),
1886 X(MF_TOPONODE_RATELESS
),
1887 X(MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS
),
1888 X(MF_TOPONODE_DISABLE_PREROLL
),
1889 X(MF_SA_D3D11_ALLOW_DYNAMIC_YUV_TEXTURE
),
1890 X(MF_MT_VIDEO_3D_FORMAT
),
1891 X(MF_EVENT_STREAM_METADATA_KEYDATA
),
1892 X(MF_READER_WRITER_D3D_MANAGER
),
1893 X(MFTranscodeContainerType_FLAC
),
1894 X(MFSampleExtension_3DVideo
),
1895 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE
),
1896 X(MF_MT_H264_USAGE
),
1897 X(MF_MEDIA_ENGINE_EME_CALLBACK
),
1898 X(MF_EVENT_SOURCE_FAKE_START
),
1899 X(MF_EVENT_SOURCE_PROJECTSTART
),
1900 X(MF_EVENT_SOURCE_ACTUAL_START
),
1901 X(MF_MT_D3D12_TEXTURE_LAYOUT
),
1902 X(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
),
1903 X(MF_MT_AUDIO_SAMPLES_PER_BLOCK
),
1904 X(MFT_ENUM_HARDWARE_URL_Attribute
),
1905 X(MF_SOURCE_READER_ASYNC_CALLBACK
),
1906 X(MF_MT_D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE
),
1907 X(MF_MT_OUTPUT_BUFFER_NUM
),
1908 X(MF_SA_D3D11_BINDFLAGS
),
1909 X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT
),
1910 X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE
),
1911 X(MFT_FRIENDLY_NAME_Attribute
),
1912 X(MFTranscodeContainerType_AVI
),
1913 X(MF_MT_FIXED_SIZE_SAMPLES
),
1914 X(MFT_SUPPORT_3DVIDEO
),
1915 X(MFT_SUPPORT_3DVIDEO
),
1916 X(MFT_INPUT_TYPES_Attributes
),
1917 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS
),
1918 X(MF_MT_H264_LAYOUT_PER_STREAM
),
1919 X(MF_EVENT_SCRUBSAMPLE_TIME
),
1920 X(MF_MT_SPATIAL_AUDIO_MAX_METADATA_ITEMS
),
1921 X(MF_MT_MPEG2_ONE_FRAME_PER_PACKET
),
1922 X(MF_MT_INTERLACE_MODE
),
1923 X(MF_MEDIA_ENGINE_CALLBACK
),
1924 X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE
),
1925 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_HW_SOURCE
),
1926 X(MF_MT_AUDIO_PREFER_WAVEFORMATEX
),
1927 X(MF_XVP_CALLER_ALLOCATES_OUTPUT
),
1928 X(MF_MT_H264_SVC_CAPABILITIES
),
1929 X(MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY
),
1930 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_LENGTH
),
1931 X(MF_MT_SPATIAL_AUDIO_OBJECT_METADATA_FORMAT_ID
),
1932 X(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
),
1933 X(MF_SA_D3D11_SHARED
),
1934 X(MF_MT_PAN_SCAN_ENABLED
),
1935 X(MF_MT_D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL
),
1936 X(MFTranscodeContainerType_AC3
),
1937 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
),
1938 X(MF_MT_DV_VAUX_CTRL_PACK
),
1939 X(MFSampleExtension_ForwardedDecodeUnitType
),
1940 X(MF_SA_D3D11_AWARE
),
1941 X(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
),
1942 X(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS
),
1943 X(MF_MT_SPATIAL_AUDIO_MIN_METADATA_ITEM_OFFSET_SPACING
),
1944 X(MF_TOPONODE_TRANSFORM_OBJECTID
),
1945 X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE
),
1946 X(MF_EVENT_MFT_INPUT_STREAM_ID
),
1947 X(MF_MT_SOURCE_CONTENT_HINT
),
1948 X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute
),
1949 X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE
),
1950 X(MF_READWRITE_MMCSS_PRIORITY
),
1951 X(MF_TRANSCODE_DONOT_INSERT_ENCODER
),
1953 X(MF_EVENT_START_PRESENTATION_TIME
),
1954 X(MF_EVENT_SESSIONCAPS
),
1955 X(MF_EVENT_PRESENTATION_TIME_OFFSET
),
1956 X(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
),
1957 X(MF_EVENT_SESSIONCAPS_DELTA
),
1958 X(MF_EVENT_START_PRESENTATION_TIME_AT_OUTPUT
),
1959 X(MFTranscodeContainerType_AMR
),
1960 X(MFSampleExtension_DecodeTimestamp
),
1961 X(MF_MEDIA_ENGINE_COMPATIBILITY_MODE
),
1962 X(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT
),
1963 X(MF_MT_VIDEO_H264_NO_FMOASO
),
1964 X(MF_MT_AVG_BIT_ERROR_RATE
),
1965 X(MF_MT_VIDEO_PRIMARIES
),
1966 X(MF_SINK_WRITER_DISABLE_THROTTLING
),
1967 X(MF_MT_H264_RATE_CONTROL_MODES
),
1968 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
),
1969 X(MF_READWRITE_D3D_OPTIONAL
),
1970 X(MF_SA_D3D11_HW_PROTECTED
),
1971 X(MF_MEDIA_ENGINE_DXGI_MANAGER
),
1972 X(MF_READWRITE_MMCSS_CLASS_AUDIO
),
1973 X(MF_MEDIA_ENGINE_COREWINDOW
),
1974 X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS
),
1975 X(MF_MT_MPEG4_TRACK_TYPE
),
1976 X(MF_ACTIVATE_VIDEO_WINDOW
),
1977 X(MF_MT_PAN_SCAN_APERTURE
),
1978 X(MF_TOPOLOGY_RESOLUTION_STATUS
),
1979 X(MF_MT_ORIGINAL_4CC
),
1980 X(MF_PD_AUDIO_ISVARIABLEBITRATE
),
1981 X(MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS
),
1982 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
),
1983 X(MF_MT_D3D12_CPU_READBACK
),
1984 X(MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID
),
1985 X(MF_MT_MPEG2_CONTENT_PACKET
),
1986 X(MFT_PROCESS_LOCAL_Attribute
),
1987 X(MFT_PROCESS_LOCAL_Attribute
),
1988 X(MF_MT_PAD_CONTROL_FLAGS
),
1989 X(MF_MT_VIDEO_NOMINAL_RANGE
),
1990 X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
),
1991 X(MF_MT_MPEG_SEQUENCE_HEADER
),
1992 X(MF_MEDIA_ENGINE_OPM_HWND
),
1993 X(MF_MT_AUDIO_SAMPLES_PER_SECOND
),
1994 X(MF_MT_SPATIAL_AUDIO_DATA_PRESENT
),
1995 X(MF_MT_FRAME_RATE
),
1996 X(MF_TOPONODE_FLUSH
),
1997 X(MF_MT_MPEG2_STANDARD
),
1998 X(MF_TOPONODE_DRAIN
),
1999 X(MF_MT_TRANSFER_FUNCTION
),
2000 X(MF_TOPONODE_MEDIASTART
),
2001 X(MF_TOPONODE_MEDIASTOP
),
2002 X(MF_SOURCE_READER_MEDIASOURCE_CONFIG
),
2003 X(MF_TOPONODE_SOURCE
),
2004 X(MF_TOPONODE_PRESENTATION_DESCRIPTOR
),
2005 X(MF_TOPONODE_D3DAWARE
),
2006 X(MF_MT_COMPRESSED
),
2007 X(MF_TOPONODE_STREAM_DESCRIPTOR
),
2008 X(MF_TOPONODE_ERRORCODE
),
2009 X(MF_TOPONODE_SEQUENCE_ELEMENTID
),
2010 X(MF_TRANSCODE_SKIP_METADATA_TRANSFER
),
2011 X(MF_EVENT_MFT_CONTEXT
),
2012 X(MF_MT_FORWARD_CUSTOM_SEI
),
2013 X(MFTranscodeContainerType_FMPEG4
),
2014 X(MF_TOPONODE_CONNECT_METHOD
),
2015 X(MFT_OUTPUT_TYPES_Attributes
),
2016 X(MF_MT_IMAGE_LOSS_TOLERANT
),
2017 X(MF_SESSION_REMOTE_SOURCE_MODE
),
2018 X(MF_MT_DEPTH_VALUE_UNIT
),
2019 X(MF_MT_AUDIO_NUM_CHANNELS
),
2020 X(MF_MT_ARBITRARY_HEADER
),
2021 X(MF_TOPOLOGY_DXVA_MODE
),
2022 X(MF_TOPONODE_LOCKED
),
2023 X(MF_TRANSCODE_QUALITYVSSPEED
),
2024 X(MF_TOPONODE_WORKQUEUE_ID
),
2025 X(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
),
2026 X(MF_TOPONODE_WORKQUEUE_MMCSS_CLASS
),
2027 X(MFTranscodeContainerType_MPEG2
),
2028 X(MF_TOPONODE_DECRYPTOR
),
2029 X(MF_EVENT_DO_THINNING
),
2030 X(MF_TOPONODE_DISCARDABLE
),
2031 X(MF_TOPOLOGY_HARDWARE_MODE
),
2032 X(MF_SOURCE_READER_DISABLE_DXVA
),
2033 X(MF_MT_FORWARD_CUSTOM_NALU
),
2034 X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
),
2035 X(MF_TOPONODE_ERROR_MAJORTYPE
),
2037 X(MFT_FIELDOFUSE_UNLOCK_Attribute
),
2038 X(MF_TOPONODE_ERROR_SUBTYPE
),
2039 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
),
2040 X(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
),
2041 X(MF_MT_VIDEO_3D_LEFT_IS_BASE
),
2042 X(MF_TOPONODE_WORKQUEUE_MMCSS_TASKID
),
2043 #undef MF_READER_WRITER_D3D_MANAGER
2046 struct guid_def
*ret
= NULL
;
2049 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2051 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2054 const char *debugstr_mf_guid(const GUID
*guid
)
2056 static const struct guid_def guid_defs
[] =
2058 #define X(g) { &(g), #g }
2059 X(MFAudioFormat_ADTS
),
2060 X(MFAudioFormat_PCM
),
2061 X(MFAudioFormat_PCM_HDCP
),
2062 X(MFAudioFormat_Float
),
2063 X(MFAudioFormat_DTS
),
2064 X(MFAudioFormat_DRM
),
2065 X(MFAudioFormat_MSP1
),
2066 X(MFAudioFormat_Vorbis
),
2067 X(MFAudioFormat_AAC
),
2068 X(MFVideoFormat_RGB24
),
2069 X(MFVideoFormat_ARGB32
),
2070 X(MFVideoFormat_RGB32
),
2071 X(MFVideoFormat_RGB565
),
2072 X(MFVideoFormat_RGB555
),
2073 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
),
2074 X(MFT_CATEGORY_MULTIPLEXER
),
2075 X(MFVideoFormat_A2R10G10B10
),
2076 X(MFT_CATEGORY_VIDEO_EFFECT
),
2077 X(MFMediaType_Script
),
2078 X(MFMediaType_Image
),
2079 X(MFMediaType_HTML
),
2080 X(MFMediaType_Binary
),
2081 X(MFVideoFormat_MPEG2
),
2082 X(MFMediaType_FileTransfer
),
2083 X(MFVideoFormat_RGB8
),
2084 X(MFAudioFormat_Dolby_AC3
),
2085 X(MFVideoFormat_L8
),
2086 X(MFAudioFormat_LPCM
),
2087 X(MFVideoFormat_420O
),
2088 X(MFVideoFormat_AI44
),
2089 X(MFVideoFormat_AV1
),
2090 X(MFVideoFormat_AYUV
),
2091 X(MFVideoFormat_H263
),
2092 X(MFVideoFormat_H264
),
2093 X(MFVideoFormat_H265
),
2094 X(MFVideoFormat_HEVC
),
2095 X(MFVideoFormat_HEVC_ES
),
2096 X(MFT_CATEGORY_AUDIO_EFFECT
),
2097 X(MFVideoFormat_I420
),
2098 X(MFVideoFormat_IYUV
),
2099 X(MFT_CATEGORY_VIDEO_DECODER
),
2100 X(MFVideoFormat_M4S2
),
2101 X(MFVideoFormat_MJPG
),
2102 X(MFVideoFormat_MP43
),
2103 X(MFVideoFormat_MP4S
),
2104 X(MFVideoFormat_MP4V
),
2105 X(MFVideoFormat_MPG1
),
2106 X(MFVideoFormat_MSS1
),
2107 X(MFVideoFormat_MSS2
),
2108 X(MFVideoFormat_NV11
),
2109 X(MFVideoFormat_NV12
),
2110 X(MFVideoFormat_ORAW
),
2111 X(MFAudioFormat_Opus
),
2112 X(MFAudioFormat_MPEG
),
2113 X(MFVideoFormat_D16
),
2114 X(MFVideoFormat_P010
),
2115 X(MFVideoFormat_P016
),
2116 X(MFVideoFormat_P210
),
2117 X(MFVideoFormat_P216
),
2118 X(MFVideoFormat_L16
),
2119 X(MFAudioFormat_MP3
),
2120 X(MFVideoFormat_UYVY
),
2121 X(MFVideoFormat_VP10
),
2122 X(MFVideoFormat_VP80
),
2123 X(MFVideoFormat_VP90
),
2124 X(MFVideoFormat_WMV1
),
2125 X(MFVideoFormat_WMV2
),
2126 X(MFVideoFormat_WMV3
),
2127 X(MFVideoFormat_WVC1
),
2128 X(MFT_CATEGORY_OTHER
),
2129 X(MFVideoFormat_Y210
),
2130 X(MFVideoFormat_Y216
),
2131 X(MFVideoFormat_Y410
),
2132 X(MFVideoFormat_Y416
),
2133 X(MFVideoFormat_Y41P
),
2134 X(MFVideoFormat_Y41T
),
2135 X(MFVideoFormat_Y42T
),
2136 X(MFVideoFormat_YUY2
),
2137 X(MFVideoFormat_YV12
),
2138 X(MFVideoFormat_YVU9
),
2139 X(MFVideoFormat_YVYU
),
2140 X(MFAudioFormat_WMAudioV8
),
2141 X(MFAudioFormat_ALAC
),
2142 X(MFAudioFormat_AMR_NB
),
2143 X(MFMediaType_Audio
),
2144 X(MFAudioFormat_WMAudioV9
),
2145 X(MFAudioFormat_AMR_WB
),
2146 X(MFAudioFormat_WMAudio_Lossless
),
2147 X(MFAudioFormat_AMR_WP
),
2148 X(MFAudioFormat_WMASPDIF
),
2149 X(MFVideoFormat_DV25
),
2150 X(MFVideoFormat_DV50
),
2151 X(MFVideoFormat_DVC
),
2152 X(MFVideoFormat_DVH1
),
2153 X(MFVideoFormat_DVHD
),
2154 X(MFVideoFormat_DVSD
),
2155 X(MFVideoFormat_DVSL
),
2156 X(MFVideoFormat_A16B16G16R16F
),
2157 X(MFVideoFormat_v210
),
2158 X(MFVideoFormat_v216
),
2159 X(MFVideoFormat_v410
),
2160 X(MFMediaType_Video
),
2161 X(MFAudioFormat_AAC_HDCP
),
2162 X(MFT_CATEGORY_DEMULTIPLEXER
),
2163 X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
),
2164 X(MFT_CATEGORY_VIDEO_ENCODER
),
2165 X(MFAudioFormat_Dolby_AC3_HDCP
),
2166 X(MFMediaType_Subtitle
),
2167 X(MFMediaType_Stream
),
2168 X(MFAudioFormat_Dolby_AC3_SPDIF
),
2169 X(MFAudioFormat_Float_SpatialObjects
),
2170 X(MFMediaType_SAMI
),
2171 X(MFAudioFormat_ADTS_HDCP
),
2172 X(MFAudioFormat_FLAC
),
2173 X(MFAudioFormat_Dolby_DDPlus
),
2174 X(MFMediaType_MultiplexedFrames
),
2175 X(MFT_CATEGORY_AUDIO_DECODER
),
2176 X(MFAudioFormat_Base_HDCP
),
2177 X(MFT_CATEGORY_AUDIO_ENCODER
),
2178 X(MFVideoFormat_Base_HDCP
),
2179 X(MFVideoFormat_H264_HDCP
),
2180 X(MFVideoFormat_HEVC_HDCP
),
2181 X(MFMediaType_Default
),
2182 X(MFMediaType_Protected
),
2183 X(MFVideoFormat_H264_ES
),
2184 X(MFMediaType_Perception
),
2185 X(MFT_CATEGORY_VIDEO_PROCESSOR
),
2188 struct guid_def
*ret
= NULL
;
2191 ret
= bsearch(guid
, guid_defs
, ARRAY_SIZE(guid_defs
), sizeof(*guid_defs
), debug_compare_guid
);
2193 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbgstr_guid(guid
);
2202 static int __cdecl
debug_event_id(const void *a
, const void *b
)
2204 const DWORD
*id
= a
;
2205 const struct event_id
*event_id
= b
;
2206 return *id
- event_id
->id
;
2209 static const char *debugstr_eventid(DWORD event
)
2211 static const struct event_id
2218 #define X(e) { e, #e }
2223 X(MESessionUnknown
),
2224 X(MESessionTopologySet
),
2225 X(MESessionTopologiesCleared
),
2226 X(MESessionStarted
),
2228 X(MESessionStopped
),
2231 X(MESessionRateChanged
),
2232 X(MESessionScrubSampleComplete
),
2233 X(MESessionCapabilitiesChanged
),
2234 X(MESessionTopologyStatus
),
2235 X(MESessionNotifyPresentationTime
),
2236 X(MENewPresentation
),
2237 X(MELicenseAcquisitionStart
),
2238 X(MELicenseAcquisitionCompleted
),
2239 X(MEIndividualizationStart
),
2240 X(MEIndividualizationCompleted
),
2241 X(MEEnablerProgress
),
2242 X(MEEnablerCompleted
),
2245 X(MEBufferingStarted
),
2246 X(MEBufferingStopped
),
2249 X(MEReconnectStart
),
2252 X(MESessionStreamSinkFormatChanged
),
2264 X(MEEndOfPresentation
),
2268 X(MEStreamThinMode
),
2269 X(MEStreamFormatChanged
),
2270 X(MESourceRateChanged
),
2271 X(MEEndOfPresentationSegment
),
2272 X(MESourceCharacteristicsChanged
),
2273 X(MESourceRateChangeRequested
),
2274 X(MESourceMetadataChanged
),
2275 X(MESequencerSourceTopologyUpdated
),
2277 X(MEStreamSinkStarted
),
2278 X(MEStreamSinkStopped
),
2279 X(MEStreamSinkPaused
),
2280 X(MEStreamSinkRateChanged
),
2281 X(MEStreamSinkRequestSample
),
2282 X(MEStreamSinkMarker
),
2283 X(MEStreamSinkPrerolled
),
2284 X(MEStreamSinkScrubSampleComplete
),
2285 X(MEStreamSinkFormatChanged
),
2286 X(MEStreamSinkDeviceChanged
),
2288 X(MESinkInvalidated
),
2289 X(MEAudioSessionNameChanged
),
2290 X(MEAudioSessionVolumeChanged
),
2291 X(MEAudioSessionDeviceRemoved
),
2292 X(MEAudioSessionServerShutdown
),
2293 X(MEAudioSessionGroupingParamChanged
),
2294 X(MEAudioSessionIconChanged
),
2295 X(MEAudioSessionFormatChanged
),
2296 X(MEAudioSessionDisconnected
),
2297 X(MEAudioSessionExclusiveModeOverride
),
2298 X(MECaptureAudioSessionVolumeChanged
),
2299 X(MECaptureAudioSessionDeviceRemoved
),
2300 X(MECaptureAudioSessionFormatChanged
),
2301 X(MECaptureAudioSessionDisconnected
),
2302 X(MECaptureAudioSessionExclusiveModeOverride
),
2303 X(MECaptureAudioSessionServerShutdown
),
2306 X(MEContentProtectionMessage
),
2308 X(MEWMDRMLicenseBackupCompleted
),
2309 X(MEWMDRMLicenseBackupProgress
),
2310 X(MEWMDRMLicenseRestoreCompleted
),
2311 X(MEWMDRMLicenseRestoreProgress
),
2312 X(MEWMDRMLicenseAcquisitionCompleted
),
2313 X(MEWMDRMIndividualizationCompleted
),
2314 X(MEWMDRMIndividualizationProgress
),
2315 X(MEWMDRMProximityCompleted
),
2316 X(MEWMDRMLicenseStoreCleaned
),
2317 X(MEWMDRMRevocationDownloadCompleted
),
2318 X(METransformUnknown
),
2319 X(METransformNeedInput
),
2320 X(METransformHaveOutput
),
2321 X(METransformDrainComplete
),
2322 X(METransformMarker
),
2323 X(METransformInputStreamStateChanged
),
2324 X(MEByteStreamCharacteristicsChanged
),
2325 X(MEVideoCaptureDeviceRemoved
),
2326 X(MEVideoCaptureDevicePreempted
),
2327 X(MEStreamSinkFormatInvalidated
),
2328 X(MEEncodingParameters
),
2329 X(MEContentProtectionMetadata
),
2330 X(MEDeviceThermalStateChanged
),
2334 struct event_id
*ret
= bsearch(&event
, event_ids
, ARRAY_SIZE(event_ids
), sizeof(*event_ids
), debug_event_id
);
2335 return ret
? wine_dbg_sprintf("%s", ret
->name
) : wine_dbg_sprintf("%lu", event
);
2338 static inline struct attributes
*impl_from_IMFAttributes(IMFAttributes
*iface
)
2340 return CONTAINING_RECORD(iface
, struct attributes
, IMFAttributes_iface
);
2343 static HRESULT WINAPI
mfattributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
2345 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
2347 if (IsEqualIID(riid
, &IID_IMFAttributes
) ||
2348 IsEqualGUID(riid
, &IID_IUnknown
))
2351 IMFAttributes_AddRef(iface
);
2355 WARN("Unsupported %s.\n", debugstr_guid(riid
));
2357 return E_NOINTERFACE
;
2360 static ULONG WINAPI
mfattributes_AddRef(IMFAttributes
*iface
)
2362 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2363 ULONG refcount
= InterlockedIncrement(&attributes
->ref
);
2365 TRACE("%p, refcount %ld.\n", iface
, refcount
);
2370 static ULONG WINAPI
mfattributes_Release(IMFAttributes
*iface
)
2372 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
2373 ULONG refcount
= InterlockedDecrement(&attributes
->ref
);
2375 TRACE("%p, refcount %ld.\n", iface
, refcount
);
2379 clear_attributes_object(attributes
);
2386 static struct attribute
*attributes_find_item(struct attributes
*attributes
, REFGUID key
, size_t *index
)
2390 for (i
= 0; i
< attributes
->count
; ++i
)
2392 if (IsEqualGUID(key
, &attributes
->attributes
[i
].key
))
2396 return &attributes
->attributes
[i
];
2403 static HRESULT
attributes_get_item(struct attributes
*attributes
, const GUID
*key
, PROPVARIANT
*value
)
2405 struct attribute
*attribute
;
2408 EnterCriticalSection(&attributes
->cs
);
2410 attribute
= attributes_find_item(attributes
, key
, NULL
);
2413 if (attribute
->value
.vt
== value
->vt
&& !(value
->vt
== VT_UNKNOWN
&& !attribute
->value
.punkVal
))
2414 hr
= PropVariantCopy(value
, &attribute
->value
);
2416 hr
= MF_E_INVALIDTYPE
;
2419 hr
= MF_E_ATTRIBUTENOTFOUND
;
2421 LeaveCriticalSection(&attributes
->cs
);
2426 HRESULT
attributes_GetItem(struct attributes
*attributes
, REFGUID key
, PROPVARIANT
*value
)
2428 struct attribute
*attribute
;
2431 EnterCriticalSection(&attributes
->cs
);
2433 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2434 hr
= value
? PropVariantCopy(value
, &attribute
->value
) : S_OK
;
2436 hr
= MF_E_ATTRIBUTENOTFOUND
;
2438 LeaveCriticalSection(&attributes
->cs
);
2443 HRESULT
attributes_GetItemType(struct attributes
*attributes
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
2445 struct attribute
*attribute
;
2448 EnterCriticalSection(&attributes
->cs
);
2450 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2452 *type
= attribute
->value
.vt
;
2455 hr
= MF_E_ATTRIBUTENOTFOUND
;
2457 LeaveCriticalSection(&attributes
->cs
);
2462 HRESULT
attributes_CompareItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
2464 struct attribute
*attribute
;
2468 EnterCriticalSection(&attributes
->cs
);
2470 if ((attribute
= attributes_find_item(attributes
, key
, NULL
)))
2472 *result
= attribute
->value
.vt
== value
->vt
&&
2473 !PropVariantCompareEx(&attribute
->value
, value
, PVCU_DEFAULT
, PVCF_DEFAULT
);
2476 LeaveCriticalSection(&attributes
->cs
);
2481 HRESULT
attributes_Compare(struct attributes
*attributes
, IMFAttributes
*theirs
,
2482 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
2484 IMFAttributes
*smaller
, *other
;
2485 MF_ATTRIBUTE_TYPE type
;
2491 if (FAILED(hr
= IMFAttributes_GetCount(theirs
, &count
)))
2494 EnterCriticalSection(&attributes
->cs
);
2500 case MF_ATTRIBUTES_MATCH_OUR_ITEMS
:
2501 for (i
= 0; i
< attributes
->count
; ++i
)
2503 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2504 &attributes
->attributes
[i
].value
, &result
)))
2510 case MF_ATTRIBUTES_MATCH_THEIR_ITEMS
:
2511 hr
= IMFAttributes_Compare(theirs
, &attributes
->IMFAttributes_iface
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2513 case MF_ATTRIBUTES_MATCH_ALL_ITEMS
:
2514 if (count
!= attributes
->count
)
2519 for (i
= 0; i
< count
; ++i
)
2521 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2522 &attributes
->attributes
[i
].value
, &result
)))
2528 case MF_ATTRIBUTES_MATCH_INTERSECTION
:
2529 for (i
= 0; i
< attributes
->count
; ++i
)
2531 if (FAILED(IMFAttributes_GetItemType(theirs
, &attributes
->attributes
[i
].key
, &type
)))
2534 if (FAILED(hr
= IMFAttributes_CompareItem(theirs
, &attributes
->attributes
[i
].key
,
2535 &attributes
->attributes
[i
].value
, &result
)))
2542 case MF_ATTRIBUTES_MATCH_SMALLER
:
2543 smaller
= attributes
->count
> count
? theirs
: &attributes
->IMFAttributes_iface
;
2544 other
= attributes
->count
> count
? &attributes
->IMFAttributes_iface
: theirs
;
2545 hr
= IMFAttributes_Compare(smaller
, other
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &result
);
2548 WARN("Unknown match type %d.\n", match_type
);
2552 LeaveCriticalSection(&attributes
->cs
);
2560 HRESULT
attributes_GetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32
*value
)
2562 PROPVARIANT attrval
;
2565 PropVariantInit(&attrval
);
2566 attrval
.vt
= VT_UI4
;
2567 hr
= attributes_get_item(attributes
, key
, &attrval
);
2569 *value
= attrval
.ulVal
;
2574 HRESULT
attributes_GetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64
*value
)
2576 PROPVARIANT attrval
;
2579 PropVariantInit(&attrval
);
2580 attrval
.vt
= VT_UI8
;
2581 hr
= attributes_get_item(attributes
, key
, &attrval
);
2583 *value
= attrval
.uhVal
.QuadPart
;
2588 HRESULT
attributes_GetDouble(struct attributes
*attributes
, REFGUID key
, double *value
)
2590 PROPVARIANT attrval
;
2593 PropVariantInit(&attrval
);
2595 hr
= attributes_get_item(attributes
, key
, &attrval
);
2597 *value
= attrval
.dblVal
;
2602 HRESULT
attributes_GetGUID(struct attributes
*attributes
, REFGUID key
, GUID
*value
)
2604 struct attribute
*attribute
;
2607 EnterCriticalSection(&attributes
->cs
);
2609 attribute
= attributes_find_item(attributes
, key
, NULL
);
2612 if (attribute
->value
.vt
== MF_ATTRIBUTE_GUID
)
2613 *value
= *attribute
->value
.puuid
;
2615 hr
= MF_E_INVALIDTYPE
;
2618 hr
= MF_E_ATTRIBUTENOTFOUND
;
2620 LeaveCriticalSection(&attributes
->cs
);
2625 HRESULT
attributes_GetStringLength(struct attributes
*attributes
, REFGUID key
, UINT32
*length
)
2627 struct attribute
*attribute
;
2630 EnterCriticalSection(&attributes
->cs
);
2632 attribute
= attributes_find_item(attributes
, key
, NULL
);
2635 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2636 *length
= lstrlenW(attribute
->value
.pwszVal
);
2638 hr
= MF_E_INVALIDTYPE
;
2641 hr
= MF_E_ATTRIBUTENOTFOUND
;
2643 LeaveCriticalSection(&attributes
->cs
);
2648 HRESULT
attributes_GetString(struct attributes
*attributes
, REFGUID key
, WCHAR
*value
,
2649 UINT32 size
, UINT32
*length
)
2651 struct attribute
*attribute
;
2654 EnterCriticalSection(&attributes
->cs
);
2656 attribute
= attributes_find_item(attributes
, key
, NULL
);
2659 if (attribute
->value
.vt
== MF_ATTRIBUTE_STRING
)
2661 int len
= lstrlenW(attribute
->value
.pwszVal
);
2667 hr
= STRSAFE_E_INSUFFICIENT_BUFFER
;
2669 memcpy(value
, attribute
->value
.pwszVal
, (len
+ 1) * sizeof(WCHAR
));
2672 hr
= MF_E_INVALIDTYPE
;
2675 hr
= MF_E_ATTRIBUTENOTFOUND
;
2677 LeaveCriticalSection(&attributes
->cs
);
2682 HRESULT
attributes_GetAllocatedString(struct attributes
*attributes
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
2684 PROPVARIANT attrval
;
2687 PropVariantInit(&attrval
);
2688 attrval
.vt
= VT_LPWSTR
;
2689 hr
= attributes_get_item(attributes
, key
, &attrval
);
2692 *value
= attrval
.pwszVal
;
2694 *length
= lstrlenW(*value
);
2700 HRESULT
attributes_GetBlobSize(struct attributes
*attributes
, REFGUID key
, UINT32
*size
)
2702 struct attribute
*attribute
;
2705 EnterCriticalSection(&attributes
->cs
);
2707 attribute
= attributes_find_item(attributes
, key
, NULL
);
2710 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2711 *size
= attribute
->value
.caub
.cElems
;
2713 hr
= MF_E_INVALIDTYPE
;
2716 hr
= MF_E_ATTRIBUTENOTFOUND
;
2718 LeaveCriticalSection(&attributes
->cs
);
2723 HRESULT
attributes_GetBlob(struct attributes
*attributes
, REFGUID key
, UINT8
*buf
, UINT32 bufsize
, UINT32
*blobsize
)
2725 struct attribute
*attribute
;
2728 EnterCriticalSection(&attributes
->cs
);
2730 attribute
= attributes_find_item(attributes
, key
, NULL
);
2733 if (attribute
->value
.vt
== MF_ATTRIBUTE_BLOB
)
2735 UINT32 size
= attribute
->value
.caub
.cElems
;
2737 if (bufsize
>= size
)
2738 hr
= PropVariantToBuffer(&attribute
->value
, buf
, size
);
2740 hr
= E_NOT_SUFFICIENT_BUFFER
;
2746 hr
= MF_E_INVALIDTYPE
;
2749 hr
= MF_E_ATTRIBUTENOTFOUND
;
2751 LeaveCriticalSection(&attributes
->cs
);
2756 HRESULT
attributes_GetAllocatedBlob(struct attributes
*attributes
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
2758 PROPVARIANT attrval
;
2761 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2762 hr
= attributes_get_item(attributes
, key
, &attrval
);
2765 *buf
= attrval
.caub
.pElems
;
2767 *size
= attrval
.caub
.cElems
;
2773 HRESULT
attributes_GetUnknown(struct attributes
*attributes
, REFGUID key
, REFIID riid
, void **out
)
2775 PROPVARIANT attrval
;
2778 PropVariantInit(&attrval
);
2779 attrval
.vt
= VT_UNKNOWN
;
2780 hr
= attributes_get_item(attributes
, key
, &attrval
);
2782 hr
= IUnknown_QueryInterface(attrval
.punkVal
, riid
, out
);
2783 PropVariantClear(&attrval
);
2787 static HRESULT
attributes_set_item(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2789 struct attribute
*attribute
;
2791 EnterCriticalSection(&attributes
->cs
);
2793 attribute
= attributes_find_item(attributes
, key
, NULL
);
2796 if (!mf_array_reserve((void **)&attributes
->attributes
, &attributes
->capacity
, attributes
->count
+ 1,
2797 sizeof(*attributes
->attributes
)))
2799 LeaveCriticalSection(&attributes
->cs
);
2800 return E_OUTOFMEMORY
;
2802 attributes
->attributes
[attributes
->count
].key
= *key
;
2803 attribute
= &attributes
->attributes
[attributes
->count
++];
2806 PropVariantClear(&attribute
->value
);
2808 PropVariantCopy(&attribute
->value
, value
);
2810 LeaveCriticalSection(&attributes
->cs
);
2815 HRESULT
attributes_SetItem(struct attributes
*attributes
, REFGUID key
, REFPROPVARIANT value
)
2821 case MF_ATTRIBUTE_UINT32
:
2822 case MF_ATTRIBUTE_UINT64
:
2823 case MF_ATTRIBUTE_DOUBLE
:
2824 case MF_ATTRIBUTE_GUID
:
2825 case MF_ATTRIBUTE_STRING
:
2826 case MF_ATTRIBUTE_BLOB
:
2827 case MF_ATTRIBUTE_IUNKNOWN
:
2828 return attributes_set_item(attributes
, key
, value
);
2830 PropVariantInit(&empty
);
2831 attributes_set_item(attributes
, key
, &empty
);
2832 return MF_E_INVALIDTYPE
;
2836 HRESULT
attributes_DeleteItem(struct attributes
*attributes
, REFGUID key
)
2838 struct attribute
*attribute
;
2841 EnterCriticalSection(&attributes
->cs
);
2843 if ((attribute
= attributes_find_item(attributes
, key
, &index
)))
2847 PropVariantClear(&attribute
->value
);
2849 attributes
->count
--;
2850 count
= attributes
->count
- index
;
2852 memmove(&attributes
->attributes
[index
], &attributes
->attributes
[index
+ 1], count
* sizeof(*attributes
->attributes
));
2855 LeaveCriticalSection(&attributes
->cs
);
2860 HRESULT
attributes_DeleteAllItems(struct attributes
*attributes
)
2862 EnterCriticalSection(&attributes
->cs
);
2864 while (attributes
->count
)
2866 PropVariantClear(&attributes
->attributes
[--attributes
->count
].value
);
2868 free(attributes
->attributes
);
2869 attributes
->attributes
= NULL
;
2870 attributes
->capacity
= 0;
2872 LeaveCriticalSection(&attributes
->cs
);
2877 HRESULT
attributes_SetUINT32(struct attributes
*attributes
, REFGUID key
, UINT32 value
)
2879 PROPVARIANT attrval
;
2881 attrval
.vt
= VT_UI4
;
2882 attrval
.ulVal
= value
;
2883 return attributes_set_item(attributes
, key
, &attrval
);
2886 HRESULT
attributes_SetUINT64(struct attributes
*attributes
, REFGUID key
, UINT64 value
)
2888 PROPVARIANT attrval
;
2890 attrval
.vt
= VT_UI8
;
2891 attrval
.uhVal
.QuadPart
= value
;
2892 return attributes_set_item(attributes
, key
, &attrval
);
2895 HRESULT
attributes_SetDouble(struct attributes
*attributes
, REFGUID key
, double value
)
2897 PROPVARIANT attrval
;
2900 attrval
.dblVal
= value
;
2901 return attributes_set_item(attributes
, key
, &attrval
);
2904 HRESULT
attributes_SetGUID(struct attributes
*attributes
, REFGUID key
, REFGUID value
)
2906 PROPVARIANT attrval
;
2908 attrval
.vt
= VT_CLSID
;
2909 attrval
.puuid
= (CLSID
*)value
;
2910 return attributes_set_item(attributes
, key
, &attrval
);
2913 HRESULT
attributes_SetString(struct attributes
*attributes
, REFGUID key
, const WCHAR
*value
)
2915 PROPVARIANT attrval
;
2917 attrval
.vt
= VT_LPWSTR
;
2918 attrval
.pwszVal
= (WCHAR
*)value
;
2919 return attributes_set_item(attributes
, key
, &attrval
);
2922 HRESULT
attributes_SetBlob(struct attributes
*attributes
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
2924 PROPVARIANT attrval
;
2926 attrval
.vt
= VT_VECTOR
| VT_UI1
;
2927 attrval
.caub
.cElems
= size
;
2928 attrval
.caub
.pElems
= (UINT8
*)buf
;
2929 return attributes_set_item(attributes
, key
, &attrval
);
2932 HRESULT
attributes_SetUnknown(struct attributes
*attributes
, REFGUID key
, IUnknown
*unknown
)
2934 PROPVARIANT attrval
;
2936 attrval
.vt
= VT_UNKNOWN
;
2937 attrval
.punkVal
= unknown
;
2938 return attributes_set_item(attributes
, key
, &attrval
);
2941 HRESULT
attributes_LockStore(struct attributes
*attributes
)
2943 EnterCriticalSection(&attributes
->cs
);
2948 HRESULT
attributes_UnlockStore(struct attributes
*attributes
)
2950 LeaveCriticalSection(&attributes
->cs
);
2955 HRESULT
attributes_GetCount(struct attributes
*attributes
, UINT32
*count
)
2957 EnterCriticalSection(&attributes
->cs
);
2958 *count
= attributes
->count
;
2959 LeaveCriticalSection(&attributes
->cs
);
2964 HRESULT
attributes_GetItemByIndex(struct attributes
*attributes
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
2968 EnterCriticalSection(&attributes
->cs
);
2970 if (index
< attributes
->count
)
2972 *key
= attributes
->attributes
[index
].key
;
2974 PropVariantCopy(value
, &attributes
->attributes
[index
].value
);
2979 LeaveCriticalSection(&attributes
->cs
);
2984 HRESULT
attributes_CopyAllItems(struct attributes
*attributes
, IMFAttributes
*dest
)
2989 EnterCriticalSection(&attributes
->cs
);
2991 IMFAttributes_LockStore(dest
);
2993 IMFAttributes_DeleteAllItems(dest
);
2995 for (i
= 0; i
< attributes
->count
; ++i
)
2997 hr
= IMFAttributes_SetItem(dest
, &attributes
->attributes
[i
].key
, &attributes
->attributes
[i
].value
);
3002 IMFAttributes_UnlockStore(dest
);
3004 LeaveCriticalSection(&attributes
->cs
);
3009 static HRESULT WINAPI
mfattributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
3011 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3013 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3015 return attributes_GetItem(attributes
, key
, value
);
3018 static HRESULT WINAPI
mfattributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
3020 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3022 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
3024 return attributes_GetItemType(attributes
, key
, type
);
3027 static HRESULT WINAPI
mfattributes_CompareItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
3029 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3031 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
3033 return attributes_CompareItem(attributes
, key
, value
, result
);
3036 static HRESULT WINAPI
mfattributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
3037 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
3039 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3041 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
3043 return attributes_Compare(attributes
, theirs
, match_type
, ret
);
3046 static HRESULT WINAPI
mfattributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
3048 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3050 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3052 return attributes_GetUINT32(attributes
, key
, value
);
3055 static HRESULT WINAPI
mfattributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
3057 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3059 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3061 return attributes_GetUINT64(attributes
, key
, value
);
3064 static HRESULT WINAPI
mfattributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
3066 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3068 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3070 return attributes_GetDouble(attributes
, key
, value
);
3073 static HRESULT WINAPI
mfattributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
3075 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3077 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
3079 return attributes_GetGUID(attributes
, key
, value
);
3082 static HRESULT WINAPI
mfattributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
3084 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3086 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
3088 return attributes_GetStringLength(attributes
, key
, length
);
3091 static HRESULT WINAPI
mfattributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
3092 UINT32 size
, UINT32
*length
)
3094 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3096 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
3098 return attributes_GetString(attributes
, key
, value
, size
, length
);
3101 static HRESULT WINAPI
mfattributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
3103 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3105 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
3107 return attributes_GetAllocatedString(attributes
, key
, value
, length
);
3110 static HRESULT WINAPI
mfattributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
3112 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3114 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
3116 return attributes_GetBlobSize(attributes
, key
, size
);
3119 static HRESULT WINAPI
mfattributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
3120 UINT32 bufsize
, UINT32
*blobsize
)
3122 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3124 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
3126 return attributes_GetBlob(attributes
, key
, buf
, bufsize
, blobsize
);
3129 static HRESULT WINAPI
mfattributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
3131 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3133 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
3135 return attributes_GetAllocatedBlob(attributes
, key
, buf
, size
);
3138 static HRESULT WINAPI
mfattributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **out
)
3140 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3142 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
3144 return attributes_GetUnknown(attributes
, key
, riid
, out
);
3147 static HRESULT WINAPI
mfattributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
3149 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3151 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
3153 return attributes_SetItem(attributes
, key
, value
);
3156 static HRESULT WINAPI
mfattributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
3158 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3160 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
3162 return attributes_DeleteItem(attributes
, key
);
3165 static HRESULT WINAPI
mfattributes_DeleteAllItems(IMFAttributes
*iface
)
3167 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3169 TRACE("%p.\n", iface
);
3171 return attributes_DeleteAllItems(attributes
);
3174 static HRESULT WINAPI
mfattributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
3176 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3178 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
3180 return attributes_SetUINT32(attributes
, key
, value
);
3183 static HRESULT WINAPI
mfattributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
3185 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3187 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
3189 return attributes_SetUINT64(attributes
, key
, value
);
3192 static HRESULT WINAPI
mfattributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
3194 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3196 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
3198 return attributes_SetDouble(attributes
, key
, value
);
3201 static HRESULT WINAPI
mfattributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
3203 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3205 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
3207 return attributes_SetGUID(attributes
, key
, value
);
3210 static HRESULT WINAPI
mfattributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
3212 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3214 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
3216 return attributes_SetString(attributes
, key
, value
);
3219 static HRESULT WINAPI
mfattributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
3221 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3223 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
3225 return attributes_SetBlob(attributes
, key
, buf
, size
);
3228 static HRESULT WINAPI
mfattributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
3230 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3232 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
3234 return attributes_SetUnknown(attributes
, key
, unknown
);
3237 static HRESULT WINAPI
mfattributes_LockStore(IMFAttributes
*iface
)
3239 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3241 TRACE("%p.\n", iface
);
3243 return attributes_LockStore(attributes
);
3246 static HRESULT WINAPI
mfattributes_UnlockStore(IMFAttributes
*iface
)
3248 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3250 TRACE("%p.\n", iface
);
3252 return attributes_UnlockStore(attributes
);
3255 static HRESULT WINAPI
mfattributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
3257 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3259 TRACE("%p, %p.\n", iface
, count
);
3261 return attributes_GetCount(attributes
, count
);
3264 static HRESULT WINAPI
mfattributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
3266 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3268 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
3270 return attributes_GetItemByIndex(attributes
, index
, key
, value
);
3273 static HRESULT WINAPI
mfattributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
3275 struct attributes
*attributes
= impl_from_IMFAttributes(iface
);
3277 TRACE("%p, %p.\n", iface
, dest
);
3279 return attributes_CopyAllItems(attributes
, dest
);
3282 static const IMFAttributesVtbl mfattributes_vtbl
=
3284 mfattributes_QueryInterface
,
3285 mfattributes_AddRef
,
3286 mfattributes_Release
,
3287 mfattributes_GetItem
,
3288 mfattributes_GetItemType
,
3289 mfattributes_CompareItem
,
3290 mfattributes_Compare
,
3291 mfattributes_GetUINT32
,
3292 mfattributes_GetUINT64
,
3293 mfattributes_GetDouble
,
3294 mfattributes_GetGUID
,
3295 mfattributes_GetStringLength
,
3296 mfattributes_GetString
,
3297 mfattributes_GetAllocatedString
,
3298 mfattributes_GetBlobSize
,
3299 mfattributes_GetBlob
,
3300 mfattributes_GetAllocatedBlob
,
3301 mfattributes_GetUnknown
,
3302 mfattributes_SetItem
,
3303 mfattributes_DeleteItem
,
3304 mfattributes_DeleteAllItems
,
3305 mfattributes_SetUINT32
,
3306 mfattributes_SetUINT64
,
3307 mfattributes_SetDouble
,
3308 mfattributes_SetGUID
,
3309 mfattributes_SetString
,
3310 mfattributes_SetBlob
,
3311 mfattributes_SetUnknown
,
3312 mfattributes_LockStore
,
3313 mfattributes_UnlockStore
,
3314 mfattributes_GetCount
,
3315 mfattributes_GetItemByIndex
,
3316 mfattributes_CopyAllItems
3319 HRESULT
init_attributes_object(struct attributes
*object
, UINT32 size
)
3321 object
->IMFAttributes_iface
.lpVtbl
= &mfattributes_vtbl
;
3323 InitializeCriticalSection(&object
->cs
);
3325 object
->attributes
= NULL
;
3327 object
->capacity
= 0;
3328 if (!mf_array_reserve((void **)&object
->attributes
, &object
->capacity
, size
,
3329 sizeof(*object
->attributes
)))
3331 DeleteCriticalSection(&object
->cs
);
3332 return E_OUTOFMEMORY
;
3338 void clear_attributes_object(struct attributes
*object
)
3342 for (i
= 0; i
< object
->count
; i
++)
3343 PropVariantClear(&object
->attributes
[i
].value
);
3344 free(object
->attributes
);
3346 DeleteCriticalSection(&object
->cs
);
3349 /***********************************************************************
3350 * MFCreateAttributes (mfplat.@)
3352 HRESULT WINAPI
MFCreateAttributes(IMFAttributes
**attributes
, UINT32 size
)
3354 struct attributes
*object
;
3357 TRACE("%p, %d\n", attributes
, size
);
3359 if (!(object
= calloc(1, sizeof(*object
))))
3360 return E_OUTOFMEMORY
;
3362 if (FAILED(hr
= init_attributes_object(object
, size
)))
3367 *attributes
= &object
->IMFAttributes_iface
;
3372 #define ATTRIBUTES_STORE_MAGIC 0x494d4641 /* IMFA */
3374 struct attributes_store_header
3380 struct attributes_store_item
3397 /***********************************************************************
3398 * MFGetAttributesAsBlobSize (mfplat.@)
3400 HRESULT WINAPI
MFGetAttributesAsBlobSize(IMFAttributes
*attributes
, UINT32
*size
)
3402 unsigned int i
, count
, length
;
3406 TRACE("%p, %p.\n", attributes
, size
);
3408 IMFAttributes_LockStore(attributes
);
3410 hr
= IMFAttributes_GetCount(attributes
, &count
);
3412 *size
= sizeof(struct attributes_store_header
);
3414 for (i
= 0; i
< count
; ++i
)
3416 MF_ATTRIBUTE_TYPE type
;
3418 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &key
, NULL
);
3422 *size
+= sizeof(struct attributes_store_item
);
3424 IMFAttributes_GetItemType(attributes
, &key
, &type
);
3428 case MF_ATTRIBUTE_GUID
:
3429 *size
+= sizeof(GUID
);
3431 case MF_ATTRIBUTE_STRING
:
3432 IMFAttributes_GetStringLength(attributes
, &key
, &length
);
3433 *size
+= (length
+ 1) * sizeof(WCHAR
);
3435 case MF_ATTRIBUTE_BLOB
:
3436 IMFAttributes_GetBlobSize(attributes
, &key
, &length
);
3439 case MF_ATTRIBUTE_UINT32
:
3440 case MF_ATTRIBUTE_UINT64
:
3441 case MF_ATTRIBUTE_DOUBLE
:
3442 case MF_ATTRIBUTE_IUNKNOWN
:
3448 IMFAttributes_UnlockStore(attributes
);
3453 struct attr_serialize_context
3460 static void attributes_serialize_write(struct attr_serialize_context
*context
, const void *value
, unsigned int size
)
3462 memcpy(context
->ptr
, value
, size
);
3463 context
->ptr
+= size
;
3466 static BOOL
attributes_serialize_write_item(struct attr_serialize_context
*context
, struct attributes_store_item
*item
,
3471 case MF_ATTRIBUTE_UINT32
:
3472 case MF_ATTRIBUTE_UINT64
:
3473 case MF_ATTRIBUTE_DOUBLE
:
3474 attributes_serialize_write(context
, item
, sizeof(*item
));
3476 case MF_ATTRIBUTE_GUID
:
3477 case MF_ATTRIBUTE_STRING
:
3478 case MF_ATTRIBUTE_BLOB
:
3479 item
->u
.subheader
.offset
= context
->size
- item
->u
.subheader
.size
;
3480 attributes_serialize_write(context
, item
, sizeof(*item
));
3481 memcpy(context
->buffer
+ item
->u
.subheader
.offset
, value
, item
->u
.subheader
.size
);
3482 context
->size
-= item
->u
.subheader
.size
;
3491 /***********************************************************************
3492 * MFGetAttributesAsBlob (mfplat.@)
3494 HRESULT WINAPI
MFGetAttributesAsBlob(IMFAttributes
*attributes
, UINT8
*buffer
, UINT size
)
3496 struct attributes_store_header header
;
3497 struct attr_serialize_context context
;
3498 unsigned int required_size
, i
;
3503 TRACE("%p, %p, %u.\n", attributes
, buffer
, size
);
3505 if (FAILED(hr
= MFGetAttributesAsBlobSize(attributes
, &required_size
)))
3508 if (required_size
> size
)
3509 return MF_E_BUFFERTOOSMALL
;
3511 context
.buffer
= buffer
;
3512 context
.ptr
= buffer
;
3513 context
.size
= required_size
;
3515 IMFAttributes_LockStore(attributes
);
3517 header
.magic
= ATTRIBUTES_STORE_MAGIC
;
3518 header
.count
= 0; /* Will be updated later */
3519 IMFAttributes_GetCount(attributes
, &count
);
3521 attributes_serialize_write(&context
, &header
, sizeof(header
));
3523 for (i
= 0; i
< count
; ++i
)
3525 struct attributes_store_item item
;
3526 const void *data
= NULL
;
3528 hr
= IMFAttributes_GetItemByIndex(attributes
, i
, &item
.key
, &value
);
3532 item
.type
= value
.vt
;
3536 case MF_ATTRIBUTE_UINT32
:
3537 case MF_ATTRIBUTE_UINT64
:
3538 item
.u
.i64
= value
.uhVal
.QuadPart
;
3540 case MF_ATTRIBUTE_DOUBLE
:
3541 item
.u
.f
= value
.dblVal
;
3543 case MF_ATTRIBUTE_GUID
:
3544 item
.u
.subheader
.size
= sizeof(*value
.puuid
);
3547 case MF_ATTRIBUTE_STRING
:
3548 item
.u
.subheader
.size
= (lstrlenW(value
.pwszVal
) + 1) * sizeof(WCHAR
);
3549 data
= value
.pwszVal
;
3551 case MF_ATTRIBUTE_BLOB
:
3552 item
.u
.subheader
.size
= value
.caub
.cElems
;
3553 data
= value
.caub
.pElems
;
3555 case MF_ATTRIBUTE_IUNKNOWN
:
3558 WARN("Unknown attribute type %#x.\n", value
.vt
);
3561 if (attributes_serialize_write_item(&context
, &item
, data
))
3564 PropVariantClear(&value
);
3567 memcpy(context
.buffer
, &header
, sizeof(header
));
3569 IMFAttributes_UnlockStore(attributes
);
3574 static HRESULT
attributes_deserialize_read(struct attr_serialize_context
*context
, void *value
, unsigned int size
)
3576 if (context
->size
< (context
->ptr
- context
->buffer
) + size
)
3577 return E_INVALIDARG
;
3579 memcpy(value
, context
->ptr
, size
);
3580 context
->ptr
+= size
;
3585 /***********************************************************************
3586 * MFInitAttributesFromBlob (mfplat.@)
3588 HRESULT WINAPI
MFInitAttributesFromBlob(IMFAttributes
*dest
, const UINT8
*buffer
, UINT size
)
3590 struct attr_serialize_context context
;
3591 struct attributes_store_header header
;
3592 struct attributes_store_item item
;
3593 IMFAttributes
*attributes
;
3597 TRACE("%p, %p, %u.\n", dest
, buffer
, size
);
3599 context
.buffer
= (UINT8
*)buffer
;
3600 context
.ptr
= (UINT8
*)buffer
;
3601 context
.size
= size
;
3603 /* Validate buffer structure. */
3604 if (FAILED(hr
= attributes_deserialize_read(&context
, &header
, sizeof(header
))))
3607 if (header
.magic
!= ATTRIBUTES_STORE_MAGIC
)
3608 return E_UNEXPECTED
;
3610 if (FAILED(hr
= MFCreateAttributes(&attributes
, header
.count
)))
3613 for (i
= 0; i
< header
.count
; ++i
)
3615 if (FAILED(hr
= attributes_deserialize_read(&context
, &item
, sizeof(item
))))
3622 case MF_ATTRIBUTE_UINT32
:
3623 hr
= IMFAttributes_SetUINT32(attributes
, &item
.key
, item
.u
.i32
);
3625 case MF_ATTRIBUTE_UINT64
:
3626 hr
= IMFAttributes_SetUINT64(attributes
, &item
.key
, item
.u
.i64
);
3628 case MF_ATTRIBUTE_DOUBLE
:
3629 hr
= IMFAttributes_SetDouble(attributes
, &item
.key
, item
.u
.f
);
3631 case MF_ATTRIBUTE_GUID
:
3632 if (item
.u
.subheader
.size
== sizeof(GUID
) &&
3633 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3635 hr
= IMFAttributes_SetGUID(attributes
, &item
.key
,
3636 (const GUID
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3639 case MF_ATTRIBUTE_STRING
:
3640 if (item
.u
.subheader
.size
>= sizeof(WCHAR
) &&
3641 item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3643 hr
= IMFAttributes_SetString(attributes
, &item
.key
,
3644 (const WCHAR
*)(context
.buffer
+ item
.u
.subheader
.offset
));
3647 case MF_ATTRIBUTE_BLOB
:
3648 if (item
.u
.subheader
.size
> 0 && item
.u
.subheader
.offset
+ item
.u
.subheader
.size
<= context
.size
)
3650 hr
= IMFAttributes_SetBlob(attributes
, &item
.key
, context
.buffer
+ item
.u
.subheader
.offset
,
3651 item
.u
.subheader
.size
);
3664 IMFAttributes_DeleteAllItems(dest
);
3665 hr
= IMFAttributes_CopyAllItems(attributes
, dest
);
3668 IMFAttributes_Release(attributes
);
3675 struct attributes attributes
;
3676 IMFByteStream IMFByteStream_iface
;
3677 IMFGetService IMFGetService_iface
;
3678 IRtwqAsyncCallback read_callback
;
3679 IRtwqAsyncCallback write_callback
;
3684 struct list pending
;
3685 CRITICAL_SECTION cs
;
3688 static inline struct bytestream
*impl_from_IMFByteStream(IMFByteStream
*iface
)
3690 return CONTAINING_RECORD(iface
, struct bytestream
, IMFByteStream_iface
);
3693 static struct bytestream
*impl_bytestream_from_IMFGetService(IMFGetService
*iface
)
3695 return CONTAINING_RECORD(iface
, struct bytestream
, IMFGetService_iface
);
3698 static struct bytestream
*impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3700 return CONTAINING_RECORD(iface
, struct bytestream
, read_callback
);
3703 static struct bytestream
*impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
3705 return CONTAINING_RECORD(iface
, struct bytestream
, write_callback
);
3708 enum async_stream_op_type
3710 ASYNC_STREAM_OP_READ
,
3711 ASYNC_STREAM_OP_WRITE
,
3714 struct async_stream_op
3716 IUnknown IUnknown_iface
;
3724 ULONG requested_length
;
3725 ULONG actual_length
;
3726 IMFAsyncResult
*caller
;
3728 enum async_stream_op_type type
;
3731 static struct async_stream_op
*impl_async_stream_op_from_IUnknown(IUnknown
*iface
)
3733 return CONTAINING_RECORD(iface
, struct async_stream_op
, IUnknown_iface
);
3736 static HRESULT WINAPI
async_stream_op_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
3738 if (IsEqualIID(riid
, &IID_IUnknown
))
3741 IUnknown_AddRef(iface
);
3745 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3747 return E_NOINTERFACE
;
3750 static ULONG WINAPI
async_stream_op_AddRef(IUnknown
*iface
)
3752 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3753 ULONG refcount
= InterlockedIncrement(&op
->refcount
);
3755 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3760 static ULONG WINAPI
async_stream_op_Release(IUnknown
*iface
)
3762 struct async_stream_op
*op
= impl_async_stream_op_from_IUnknown(iface
);
3763 ULONG refcount
= InterlockedDecrement(&op
->refcount
);
3765 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3770 IMFAsyncResult_Release(op
->caller
);
3777 static const IUnknownVtbl async_stream_op_vtbl
=
3779 async_stream_op_QueryInterface
,
3780 async_stream_op_AddRef
,
3781 async_stream_op_Release
,
3784 static HRESULT
bytestream_create_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3785 const BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
, IUnknown
*state
)
3787 struct async_stream_op
*op
;
3788 IRtwqAsyncResult
*request
;
3791 op
= malloc(sizeof(*op
));
3793 return E_OUTOFMEMORY
;
3795 op
->IUnknown_iface
.lpVtbl
= &async_stream_op_vtbl
;
3798 op
->position
= stream
->position
;
3799 op
->requested_length
= size
;
3801 if (FAILED(hr
= RtwqCreateAsyncResult((IUnknown
*)&stream
->IMFByteStream_iface
, (IRtwqAsyncCallback
*)callback
, state
,
3802 (IRtwqAsyncResult
**)&op
->caller
)))
3807 if (FAILED(hr
= RtwqCreateAsyncResult(&op
->IUnknown_iface
, type
== ASYNC_STREAM_OP_READ
? &stream
->read_callback
:
3808 &stream
->write_callback
, NULL
, &request
)))
3811 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, request
);
3812 IRtwqAsyncResult_Release(request
);
3815 IUnknown_Release(&op
->IUnknown_iface
);
3819 static HRESULT
bytestream_complete_io_request(struct bytestream
*stream
, enum async_stream_op_type type
,
3820 IMFAsyncResult
*result
, ULONG
*actual_length
)
3822 struct async_stream_op
*op
= NULL
, *cur
;
3825 EnterCriticalSection(&stream
->cs
);
3826 LIST_FOR_EACH_ENTRY(cur
, &stream
->pending
, struct async_stream_op
, entry
)
3828 if (cur
->caller
== result
&& cur
->type
== type
)
3831 list_remove(&cur
->entry
);
3835 LeaveCriticalSection(&stream
->cs
);
3838 return E_INVALIDARG
;
3840 if (SUCCEEDED(hr
= IMFAsyncResult_GetStatus(result
)))
3841 *actual_length
= op
->actual_length
;
3843 IUnknown_Release(&op
->IUnknown_iface
);
3848 static HRESULT WINAPI
bytestream_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
3850 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
3851 IsEqualIID(riid
, &IID_IUnknown
))
3854 IRtwqAsyncCallback_AddRef(iface
);
3858 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3860 return E_NOINTERFACE
;
3863 static ULONG WINAPI
bytestream_read_callback_AddRef(IRtwqAsyncCallback
*iface
)
3865 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3866 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3869 static ULONG WINAPI
bytestream_read_callback_Release(IRtwqAsyncCallback
*iface
)
3871 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
3872 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3875 static HRESULT WINAPI
bytestream_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
3880 static ULONG WINAPI
bytestream_write_callback_AddRef(IRtwqAsyncCallback
*iface
)
3882 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3883 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
3886 static ULONG WINAPI
bytestream_write_callback_Release(IRtwqAsyncCallback
*iface
)
3888 struct bytestream
*stream
= impl_from_write_callback_IRtwqAsyncCallback(iface
);
3889 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
3892 static HRESULT WINAPI
bytestream_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
3894 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3896 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
3898 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
3899 IsEqualIID(riid
, &IID_IUnknown
))
3901 *out
= &stream
->IMFByteStream_iface
;
3903 else if (IsEqualIID(riid
, &IID_IMFAttributes
))
3905 *out
= &stream
->attributes
.IMFAttributes_iface
;
3907 else if (stream
->IMFGetService_iface
.lpVtbl
&& IsEqualIID(riid
, &IID_IMFGetService
))
3909 *out
= &stream
->IMFGetService_iface
;
3913 WARN("Unsupported %s.\n", debugstr_guid(riid
));
3915 return E_NOINTERFACE
;
3918 IUnknown_AddRef((IUnknown
*)*out
);
3922 static ULONG WINAPI
bytestream_AddRef(IMFByteStream
*iface
)
3924 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3925 ULONG refcount
= InterlockedIncrement(&stream
->attributes
.ref
);
3927 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3932 static ULONG WINAPI
bytestream_Release(IMFByteStream
*iface
)
3934 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3935 ULONG refcount
= InterlockedDecrement(&stream
->attributes
.ref
);
3936 struct async_stream_op
*cur
, *cur2
;
3938 TRACE("%p, refcount %ld.\n", iface
, refcount
);
3942 clear_attributes_object(&stream
->attributes
);
3943 LIST_FOR_EACH_ENTRY_SAFE(cur
, cur2
, &stream
->pending
, struct async_stream_op
, entry
)
3945 list_remove(&cur
->entry
);
3946 IUnknown_Release(&cur
->IUnknown_iface
);
3948 DeleteCriticalSection(&stream
->cs
);
3950 IStream_Release(stream
->stream
);
3952 CloseHandle(stream
->hfile
);
3959 static HRESULT WINAPI
bytestream_stream_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3961 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3965 TRACE("%p, %p.\n", iface
, capabilities
);
3967 if (FAILED(hr
= IStream_Stat(stream
->stream
, &stat
, STATFLAG_NONAME
)))
3970 *capabilities
= MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_SEEKABLE
;
3971 if (stat
.grfMode
& (STGM_WRITE
| STGM_READWRITE
))
3972 *capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
3977 static HRESULT WINAPI
bytestream_file_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
3979 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3981 TRACE("%p, %p.\n", iface
, capabilities
);
3983 *capabilities
= stream
->capabilities
;
3988 static HRESULT WINAPI
bytestream_file_SetLength(IMFByteStream
*iface
, QWORD length
)
3990 FIXME("%p, %s\n", iface
, wine_dbgstr_longlong(length
));
3995 static HRESULT WINAPI
bytestream_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
3997 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
3999 TRACE("%p, %p.\n", iface
, position
);
4002 return E_INVALIDARG
;
4004 *position
= stream
->position
;
4009 static HRESULT WINAPI
bytestream_file_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4011 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4014 TRACE("%p, %p.\n", iface
, length
);
4017 return E_INVALIDARG
;
4019 if (GetFileSizeEx(stream
->hfile
, &li
))
4020 *length
= li
.QuadPart
;
4022 return HRESULT_FROM_WIN32(GetLastError());
4027 static HRESULT WINAPI
bytestream_file_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4029 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4030 LARGE_INTEGER position
, length
;
4033 TRACE("%p, %p.\n", iface
, ret
);
4035 EnterCriticalSection(&stream
->cs
);
4037 position
.QuadPart
= 0;
4038 if (SetFilePointerEx(stream
->hfile
, position
, &length
, FILE_END
))
4039 *ret
= stream
->position
>= length
.QuadPart
;
4041 hr
= HRESULT_FROM_WIN32(GetLastError());
4043 LeaveCriticalSection(&stream
->cs
);
4048 static HRESULT WINAPI
bytestream_file_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4050 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4051 LARGE_INTEGER position
;
4055 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, read_len
);
4057 EnterCriticalSection(&stream
->cs
);
4059 position
.QuadPart
= stream
->position
;
4060 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
4062 if ((ret
= ReadFile(stream
->hfile
, buffer
, size
, read_len
, NULL
)))
4063 stream
->position
+= *read_len
;
4067 hr
= HRESULT_FROM_WIN32(GetLastError());
4069 LeaveCriticalSection(&stream
->cs
);
4074 static HRESULT WINAPI
bytestream_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
, IMFAsyncCallback
*callback
,
4077 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4079 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4081 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_READ
, data
, size
, callback
, state
);
4084 static HRESULT WINAPI
bytestream_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4086 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4088 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4090 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_READ
, result
, byte_read
);
4093 static HRESULT WINAPI
bytestream_file_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
, ULONG
*written
)
4095 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4096 LARGE_INTEGER position
;
4100 TRACE("%p, %p, %lu, %p\n", iface
, data
, size
, written
);
4102 EnterCriticalSection(&stream
->cs
);
4104 position
.QuadPart
= stream
->position
;
4105 if ((ret
= SetFilePointerEx(stream
->hfile
, position
, NULL
, FILE_BEGIN
)))
4107 if ((ret
= WriteFile(stream
->hfile
, data
, size
, written
, NULL
)))
4108 stream
->position
+= *written
;
4112 hr
= HRESULT_FROM_WIN32(GetLastError());
4114 LeaveCriticalSection(&stream
->cs
);
4119 static HRESULT WINAPI
bytestream_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4120 IMFAsyncCallback
*callback
, IUnknown
*state
)
4122 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4124 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4126 return bytestream_create_io_request(stream
, ASYNC_STREAM_OP_WRITE
, data
, size
, callback
, state
);
4129 static HRESULT WINAPI
bytestream_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4131 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4133 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4135 return bytestream_complete_io_request(stream
, ASYNC_STREAM_OP_WRITE
, result
, written
);
4138 static HRESULT WINAPI
bytestream_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN origin
, LONGLONG offset
,
4139 DWORD flags
, QWORD
*current
)
4141 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4144 TRACE("%p, %u, %s, %#lx, %p.\n", iface
, origin
, wine_dbgstr_longlong(offset
), flags
, current
);
4146 EnterCriticalSection(&stream
->cs
);
4151 stream
->position
= offset
;
4154 stream
->position
+= offset
;
4157 WARN("Unknown origin mode %d.\n", origin
);
4161 *current
= stream
->position
;
4163 LeaveCriticalSection(&stream
->cs
);
4168 static HRESULT WINAPI
bytestream_file_Flush(IMFByteStream
*iface
)
4170 FIXME("%p\n", iface
);
4175 static HRESULT WINAPI
bytestream_file_Close(IMFByteStream
*iface
)
4177 FIXME("%p\n", iface
);
4182 static HRESULT WINAPI
bytestream_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4184 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4186 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4188 EnterCriticalSection(&stream
->cs
);
4189 stream
->position
= position
;
4190 LeaveCriticalSection(&stream
->cs
);
4195 static const IMFByteStreamVtbl bytestream_file_vtbl
=
4197 bytestream_QueryInterface
,
4200 bytestream_file_GetCapabilities
,
4201 bytestream_file_GetLength
,
4202 bytestream_file_SetLength
,
4203 bytestream_GetCurrentPosition
,
4204 bytestream_SetCurrentPosition
,
4205 bytestream_file_IsEndOfStream
,
4206 bytestream_file_Read
,
4207 bytestream_BeginRead
,
4209 bytestream_file_Write
,
4210 bytestream_BeginWrite
,
4211 bytestream_EndWrite
,
4213 bytestream_file_Flush
,
4214 bytestream_file_Close
4217 static HRESULT WINAPI
bytestream_stream_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4219 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4223 TRACE("%p, %p.\n", iface
, length
);
4225 if (FAILED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4228 *length
= statstg
.cbSize
.QuadPart
;
4233 static HRESULT WINAPI
bytestream_stream_SetLength(IMFByteStream
*iface
, QWORD length
)
4235 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4236 ULARGE_INTEGER size
;
4239 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4241 EnterCriticalSection(&stream
->cs
);
4243 size
.QuadPart
= length
;
4244 hr
= IStream_SetSize(stream
->stream
, size
);
4246 LeaveCriticalSection(&stream
->cs
);
4251 static HRESULT WINAPI
bytestream_stream_IsEndOfStream(IMFByteStream
*iface
, BOOL
*ret
)
4253 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4257 TRACE("%p, %p.\n", iface
, ret
);
4259 EnterCriticalSection(&stream
->cs
);
4261 if (SUCCEEDED(hr
= IStream_Stat(stream
->stream
, &statstg
, STATFLAG_NONAME
)))
4262 *ret
= stream
->position
>= statstg
.cbSize
.QuadPart
;
4264 LeaveCriticalSection(&stream
->cs
);
4269 static HRESULT WINAPI
bytestream_stream_Read(IMFByteStream
*iface
, BYTE
*buffer
, ULONG size
, ULONG
*read_len
)
4271 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4272 LARGE_INTEGER position
;
4275 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, read_len
);
4277 EnterCriticalSection(&stream
->cs
);
4279 position
.QuadPart
= stream
->position
;
4280 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4282 if (SUCCEEDED(hr
= IStream_Read(stream
->stream
, buffer
, size
, read_len
)))
4283 stream
->position
+= *read_len
;
4286 LeaveCriticalSection(&stream
->cs
);
4291 static HRESULT WINAPI
bytestream_stream_Write(IMFByteStream
*iface
, const BYTE
*buffer
, ULONG size
, ULONG
*written
)
4293 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4294 LARGE_INTEGER position
;
4297 TRACE("%p, %p, %lu, %p.\n", iface
, buffer
, size
, written
);
4299 EnterCriticalSection(&stream
->cs
);
4301 position
.QuadPart
= stream
->position
;
4302 if (SUCCEEDED(hr
= IStream_Seek(stream
->stream
, position
, STREAM_SEEK_SET
, NULL
)))
4304 if (SUCCEEDED(hr
= IStream_Write(stream
->stream
, buffer
, size
, written
)))
4305 stream
->position
+= *written
;
4308 LeaveCriticalSection(&stream
->cs
);
4313 static HRESULT WINAPI
bytestream_stream_Flush(IMFByteStream
*iface
)
4315 struct bytestream
*stream
= impl_from_IMFByteStream(iface
);
4317 TRACE("%p.\n", iface
);
4319 return IStream_Commit(stream
->stream
, STGC_DEFAULT
);
4322 static HRESULT WINAPI
bytestream_stream_Close(IMFByteStream
*iface
)
4324 TRACE("%p.\n", iface
);
4329 static const IMFByteStreamVtbl bytestream_stream_vtbl
=
4331 bytestream_QueryInterface
,
4334 bytestream_stream_GetCapabilities
,
4335 bytestream_stream_GetLength
,
4336 bytestream_stream_SetLength
,
4337 bytestream_GetCurrentPosition
,
4338 bytestream_SetCurrentPosition
,
4339 bytestream_stream_IsEndOfStream
,
4340 bytestream_stream_Read
,
4341 bytestream_BeginRead
,
4343 bytestream_stream_Write
,
4344 bytestream_BeginWrite
,
4345 bytestream_EndWrite
,
4347 bytestream_stream_Flush
,
4348 bytestream_stream_Close
,
4351 static inline struct bytestream
*impl_from_IMFByteStream_IMFAttributes(IMFAttributes
*iface
)
4353 return CONTAINING_RECORD(iface
, struct bytestream
, attributes
.IMFAttributes_iface
);
4356 static HRESULT WINAPI
bytestream_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **out
)
4358 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4359 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, out
);
4362 static ULONG WINAPI
bytestream_attributes_AddRef(IMFAttributes
*iface
)
4364 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4365 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4368 static ULONG WINAPI
bytestream_attributes_Release(IMFAttributes
*iface
)
4370 struct bytestream
*stream
= impl_from_IMFByteStream_IMFAttributes(iface
);
4371 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4374 static const IMFAttributesVtbl bytestream_attributes_vtbl
=
4376 bytestream_attributes_QueryInterface
,
4377 bytestream_attributes_AddRef
,
4378 bytestream_attributes_Release
,
4379 mfattributes_GetItem
,
4380 mfattributes_GetItemType
,
4381 mfattributes_CompareItem
,
4382 mfattributes_Compare
,
4383 mfattributes_GetUINT32
,
4384 mfattributes_GetUINT64
,
4385 mfattributes_GetDouble
,
4386 mfattributes_GetGUID
,
4387 mfattributes_GetStringLength
,
4388 mfattributes_GetString
,
4389 mfattributes_GetAllocatedString
,
4390 mfattributes_GetBlobSize
,
4391 mfattributes_GetBlob
,
4392 mfattributes_GetAllocatedBlob
,
4393 mfattributes_GetUnknown
,
4394 mfattributes_SetItem
,
4395 mfattributes_DeleteItem
,
4396 mfattributes_DeleteAllItems
,
4397 mfattributes_SetUINT32
,
4398 mfattributes_SetUINT64
,
4399 mfattributes_SetDouble
,
4400 mfattributes_SetGUID
,
4401 mfattributes_SetString
,
4402 mfattributes_SetBlob
,
4403 mfattributes_SetUnknown
,
4404 mfattributes_LockStore
,
4405 mfattributes_UnlockStore
,
4406 mfattributes_GetCount
,
4407 mfattributes_GetItemByIndex
,
4408 mfattributes_CopyAllItems
4411 static HRESULT WINAPI
bytestream_read_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4413 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4414 struct async_stream_op
*op
;
4418 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4421 op
= impl_async_stream_op_from_IUnknown(object
);
4423 EnterCriticalSection(&stream
->cs
);
4425 hr
= IMFByteStream_Read(&stream
->IMFByteStream_iface
, op
->u
.dest
, op
->requested_length
, &op
->actual_length
);
4426 if(FAILED(hr
)) TRACE("Read failed: %#lx\n", hr
);
4427 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4428 list_add_tail(&stream
->pending
, &op
->entry
);
4430 LeaveCriticalSection(&stream
->cs
);
4432 MFInvokeCallback(op
->caller
);
4437 static HRESULT WINAPI
bytestream_write_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
4439 struct bytestream
*stream
= impl_from_read_callback_IRtwqAsyncCallback(iface
);
4440 struct async_stream_op
*op
;
4444 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
4447 op
= impl_async_stream_op_from_IUnknown(object
);
4449 EnterCriticalSection(&stream
->cs
);
4451 hr
= IMFByteStream_Write(&stream
->IMFByteStream_iface
, op
->u
.src
, op
->requested_length
, &op
->actual_length
);
4452 if(FAILED(hr
)) TRACE("Write failed: %#lx\n", hr
);
4453 IMFAsyncResult_SetStatus(op
->caller
, hr
);
4454 list_add_tail(&stream
->pending
, &op
->entry
);
4456 LeaveCriticalSection(&stream
->cs
);
4458 MFInvokeCallback(op
->caller
);
4463 static const IRtwqAsyncCallbackVtbl bytestream_read_callback_vtbl
=
4465 bytestream_callback_QueryInterface
,
4466 bytestream_read_callback_AddRef
,
4467 bytestream_read_callback_Release
,
4468 bytestream_callback_GetParameters
,
4469 bytestream_read_callback_Invoke
,
4472 static const IRtwqAsyncCallbackVtbl bytestream_write_callback_vtbl
=
4474 bytestream_callback_QueryInterface
,
4475 bytestream_write_callback_AddRef
,
4476 bytestream_write_callback_Release
,
4477 bytestream_callback_GetParameters
,
4478 bytestream_write_callback_Invoke
,
4481 /***********************************************************************
4482 * MFCreateMFByteStreamOnStream (mfplat.@)
4484 HRESULT WINAPI
MFCreateMFByteStreamOnStream(IStream
*stream
, IMFByteStream
**bytestream
)
4486 struct bytestream
*object
;
4487 LARGE_INTEGER position
;
4491 TRACE("%p, %p.\n", stream
, bytestream
);
4493 if (!(object
= calloc(1, sizeof(*object
))))
4494 return E_OUTOFMEMORY
;
4496 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
4502 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_stream_vtbl
;
4503 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4504 object
->read_callback
.lpVtbl
= &bytestream_read_callback_vtbl
;
4505 object
->write_callback
.lpVtbl
= &bytestream_write_callback_vtbl
;
4506 InitializeCriticalSection(&object
->cs
);
4507 list_init(&object
->pending
);
4509 object
->stream
= stream
;
4510 IStream_AddRef(object
->stream
);
4511 position
.QuadPart
= 0;
4512 IStream_Seek(object
->stream
, position
, STREAM_SEEK_SET
, NULL
);
4514 if (SUCCEEDED(IStream_Stat(object
->stream
, &stat
, 0)))
4518 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
,
4520 CoTaskMemFree(stat
.pwcsName
);
4524 *bytestream
= &object
->IMFByteStream_iface
;
4529 static HRESULT WINAPI
bytestream_file_getservice_QueryInterface(IMFGetService
*iface
, REFIID riid
, void **obj
)
4531 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4532 return IMFByteStream_QueryInterface(&stream
->IMFByteStream_iface
, riid
, obj
);
4535 static ULONG WINAPI
bytestream_file_getservice_AddRef(IMFGetService
*iface
)
4537 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4538 return IMFByteStream_AddRef(&stream
->IMFByteStream_iface
);
4541 static ULONG WINAPI
bytestream_file_getservice_Release(IMFGetService
*iface
)
4543 struct bytestream
*stream
= impl_bytestream_from_IMFGetService(iface
);
4544 return IMFByteStream_Release(&stream
->IMFByteStream_iface
);
4547 static HRESULT WINAPI
bytestream_file_getservice_GetService(IMFGetService
*iface
, REFGUID service
,
4548 REFIID riid
, void **obj
)
4550 FIXME("%p, %s, %s, %p.\n", iface
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
4555 static const IMFGetServiceVtbl bytestream_file_getservice_vtbl
=
4557 bytestream_file_getservice_QueryInterface
,
4558 bytestream_file_getservice_AddRef
,
4559 bytestream_file_getservice_Release
,
4560 bytestream_file_getservice_GetService
,
4563 static HRESULT
create_file_bytestream(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4564 const WCHAR
*path
, BOOL is_tempfile
, IMFByteStream
**bytestream
)
4566 DWORD capabilities
= MFBYTESTREAM_IS_SEEKABLE
| MFBYTESTREAM_DOES_NOT_USE_NETWORK
;
4567 DWORD filecreation_disposition
= 0, fileaccessmode
= 0, fileattributes
= 0;
4568 DWORD filesharemode
= FILE_SHARE_READ
| FILE_SHARE_DELETE
;
4569 struct bytestream
*object
;
4576 case MF_ACCESSMODE_READ
:
4577 fileaccessmode
= GENERIC_READ
;
4578 capabilities
|= MFBYTESTREAM_IS_READABLE
;
4580 case MF_ACCESSMODE_WRITE
:
4581 fileaccessmode
= GENERIC_WRITE
;
4582 capabilities
|= MFBYTESTREAM_IS_WRITABLE
;
4584 case MF_ACCESSMODE_READWRITE
:
4585 fileaccessmode
= GENERIC_READ
| GENERIC_WRITE
;
4586 capabilities
|= (MFBYTESTREAM_IS_READABLE
| MFBYTESTREAM_IS_WRITABLE
);
4592 case MF_OPENMODE_FAIL_IF_NOT_EXIST
:
4593 filecreation_disposition
= OPEN_EXISTING
;
4595 case MF_OPENMODE_FAIL_IF_EXIST
:
4596 filecreation_disposition
= CREATE_NEW
;
4598 case MF_OPENMODE_RESET_IF_EXIST
:
4599 filecreation_disposition
= TRUNCATE_EXISTING
;
4601 case MF_OPENMODE_APPEND_IF_EXIST
:
4602 filecreation_disposition
= OPEN_ALWAYS
;
4603 fileaccessmode
|= FILE_APPEND_DATA
;
4605 case MF_OPENMODE_DELETE_IF_EXIST
:
4606 filecreation_disposition
= CREATE_ALWAYS
;
4610 if (flags
& MF_FILEFLAGS_NOBUFFERING
)
4611 fileattributes
|= FILE_FLAG_NO_BUFFERING
;
4613 fileattributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
4615 /* Open HANDLE to file */
4616 file
= CreateFileW(path
, fileaccessmode
, filesharemode
, NULL
, filecreation_disposition
, fileattributes
, 0);
4617 if (file
== INVALID_HANDLE_VALUE
)
4618 return HRESULT_FROM_WIN32(GetLastError());
4620 if (!(object
= calloc(1, sizeof(*object
))))
4623 return E_OUTOFMEMORY
;
4626 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 2)))
4632 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_file_vtbl
;
4633 object
->attributes
.IMFAttributes_iface
.lpVtbl
= &bytestream_attributes_vtbl
;
4634 object
->IMFGetService_iface
.lpVtbl
= &bytestream_file_getservice_vtbl
;
4635 object
->read_callback
.lpVtbl
= &bytestream_read_callback_vtbl
;
4636 object
->write_callback
.lpVtbl
= &bytestream_write_callback_vtbl
;
4637 InitializeCriticalSection(&object
->cs
);
4638 list_init(&object
->pending
);
4639 object
->capabilities
= capabilities
;
4640 object
->hfile
= file
;
4642 if (!is_tempfile
&& GetFileTime(file
, NULL
, NULL
, &writetime
))
4644 IMFAttributes_SetBlob(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_LAST_MODIFIED_TIME
,
4645 (const UINT8
*)&writetime
, sizeof(writetime
));
4648 IMFAttributes_SetString(&object
->attributes
.IMFAttributes_iface
, &MF_BYTESTREAM_ORIGIN_NAME
, path
);
4650 *bytestream
= &object
->IMFByteStream_iface
;
4655 /***********************************************************************
4656 * MFCreateFile (mfplat.@)
4658 HRESULT WINAPI
MFCreateFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4659 const WCHAR
*path
, IMFByteStream
**bytestream
)
4661 TRACE("%d, %d, %#x, %s, %p.\n", accessmode
, openmode
, flags
, debugstr_w(path
), bytestream
);
4663 return create_file_bytestream(accessmode
, openmode
, flags
, path
, FALSE
, bytestream
);
4666 /***********************************************************************
4667 * MFCreateTempFile (mfplat.@)
4669 HRESULT WINAPI
MFCreateTempFile(MF_FILE_ACCESSMODE accessmode
, MF_FILE_OPENMODE openmode
, MF_FILE_FLAGS flags
,
4670 IMFByteStream
**bytestream
)
4672 WCHAR name
[24], tmppath
[MAX_PATH
], *path
;
4677 TRACE("%d, %d, %#x, %p.\n", accessmode
, openmode
, flags
, bytestream
);
4679 BCryptGenRandom(NULL
, (UCHAR
*)&rnd
, sizeof(rnd
), BCRYPT_USE_SYSTEM_PREFERRED_RNG
);
4680 swprintf(name
, ARRAY_SIZE(name
), L
"MFP%llX.TMP", rnd
);
4681 GetTempPathW(ARRAY_SIZE(tmppath
), tmppath
);
4683 len
= wcslen(tmppath
) + wcslen(name
) + 2;
4684 if (!(path
= malloc(len
* sizeof(*path
))))
4685 return E_OUTOFMEMORY
;
4687 wcscpy(path
, tmppath
);
4688 PathCchAppend(path
, len
, name
);
4690 hr
= create_file_bytestream(accessmode
, openmode
, flags
, path
, TRUE
, bytestream
);
4697 struct bytestream_wrapper
4699 IMFByteStreamCacheControl IMFByteStreamCacheControl_iface
;
4700 IMFByteStreamBuffering IMFByteStreamBuffering_iface
;
4701 IMFMediaEventGenerator IMFMediaEventGenerator_iface
;
4702 IMFByteStreamTimeSeek IMFByteStreamTimeSeek_iface
;
4703 IMFSampleOutputStream IMFSampleOutputStream_iface
;
4704 IPropertyStore IPropertyStore_iface
;
4705 IMFByteStream IMFByteStream_iface
;
4706 IMFAttributes IMFAttributes_iface
;
4709 IMFByteStreamCacheControl
*cache_control
;
4710 IMFByteStreamBuffering
*stream_buffering
;
4711 IMFMediaEventGenerator
*event_generator
;
4712 IMFByteStreamTimeSeek
*time_seek
;
4713 IMFSampleOutputStream
*sample_output
;
4714 IPropertyStore
*propstore
;
4715 IMFByteStream
*stream
;
4716 IMFAttributes
*attributes
;
4720 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStream(IMFByteStream
*iface
)
4722 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStream_iface
);
4725 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamCacheControl(IMFByteStreamCacheControl
*iface
)
4727 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamCacheControl_iface
);
4730 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamBuffering(IMFByteStreamBuffering
*iface
)
4732 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamBuffering_iface
);
4735 static struct bytestream_wrapper
*impl_wrapper_from_IMFMediaEventGenerator(IMFMediaEventGenerator
*iface
)
4737 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFMediaEventGenerator_iface
);
4740 static struct bytestream_wrapper
*impl_wrapper_from_IMFByteStreamTimeSeek(IMFByteStreamTimeSeek
*iface
)
4742 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFByteStreamTimeSeek_iface
);
4745 static struct bytestream_wrapper
*impl_wrapper_from_IMFSampleOutputStream(IMFSampleOutputStream
*iface
)
4747 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFSampleOutputStream_iface
);
4750 static struct bytestream_wrapper
*impl_wrapper_from_IPropertyStore(IPropertyStore
*iface
)
4752 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IPropertyStore_iface
);
4755 static struct bytestream_wrapper
*impl_wrapper_from_IMFAttributes(IMFAttributes
*iface
)
4757 return CONTAINING_RECORD(iface
, struct bytestream_wrapper
, IMFAttributes_iface
);
4760 static HRESULT WINAPI
bytestream_wrapper_QueryInterface(IMFByteStream
*iface
, REFIID riid
, void **out
)
4762 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4764 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
4766 if (IsEqualIID(riid
, &IID_IMFByteStream
) ||
4767 IsEqualIID(riid
, &IID_IUnknown
))
4769 *out
= &wrapper
->IMFByteStream_iface
;
4771 else if (wrapper
->cache_control
&& IsEqualIID(riid
, &IID_IMFByteStreamCacheControl
))
4773 *out
= &wrapper
->IMFByteStreamCacheControl_iface
;
4775 else if (wrapper
->stream_buffering
&& IsEqualIID(riid
, &IID_IMFByteStreamBuffering
))
4777 *out
= &wrapper
->IMFByteStreamBuffering_iface
;
4779 else if (wrapper
->event_generator
&& IsEqualIID(riid
, &IID_IMFMediaEventGenerator
))
4781 *out
= &wrapper
->IMFMediaEventGenerator_iface
;
4783 else if (wrapper
->time_seek
&& IsEqualIID(riid
, &IID_IMFByteStreamTimeSeek
))
4785 *out
= &wrapper
->IMFByteStreamTimeSeek_iface
;
4787 else if (wrapper
->sample_output
&& IsEqualIID(riid
, &IID_IMFSampleOutputStream
))
4789 *out
= &wrapper
->IMFSampleOutputStream_iface
;
4791 else if (wrapper
->propstore
&& IsEqualIID(riid
, &IID_IPropertyStore
))
4793 *out
= &wrapper
->IPropertyStore_iface
;
4795 else if (wrapper
->attributes
&& IsEqualIID(riid
, &IID_IMFAttributes
))
4797 *out
= &wrapper
->IMFAttributes_iface
;
4801 WARN("Unsupported %s.\n", debugstr_guid(riid
));
4803 return E_NOINTERFACE
;
4806 IUnknown_AddRef((IUnknown
*)*out
);
4810 static ULONG WINAPI
bytestream_wrapper_AddRef(IMFByteStream
*iface
)
4812 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4813 ULONG refcount
= InterlockedIncrement(&wrapper
->refcount
);
4815 TRACE("%p, refcount %ld.\n", iface
, refcount
);
4820 static ULONG WINAPI
bytestream_wrapper_Release(IMFByteStream
*iface
)
4822 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4823 ULONG refcount
= InterlockedDecrement(&wrapper
->refcount
);
4825 TRACE("%p, refcount %ld.\n", iface
, refcount
);
4829 if (wrapper
->cache_control
)
4830 IMFByteStreamCacheControl_Release(wrapper
->cache_control
);
4831 if (wrapper
->stream_buffering
)
4832 IMFByteStreamBuffering_Release(wrapper
->stream_buffering
);
4833 if (wrapper
->event_generator
)
4834 IMFMediaEventGenerator_Release(wrapper
->event_generator
);
4835 if (wrapper
->time_seek
)
4836 IMFByteStreamTimeSeek_Release(wrapper
->time_seek
);
4837 if (wrapper
->sample_output
)
4838 IMFSampleOutputStream_Release(wrapper
->sample_output
);
4839 if (wrapper
->propstore
)
4840 IPropertyStore_Release(wrapper
->propstore
);
4841 if (wrapper
->attributes
)
4842 IMFAttributes_Release(wrapper
->attributes
);
4843 IMFByteStream_Release(wrapper
->stream
);
4850 static HRESULT WINAPI
bytestream_wrapper_GetCapabilities(IMFByteStream
*iface
, DWORD
*capabilities
)
4852 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4854 TRACE("%p, %p.\n", iface
, capabilities
);
4856 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4857 IMFByteStream_GetCapabilities(wrapper
->stream
, capabilities
);
4860 static HRESULT WINAPI
bytestream_wrapper_GetLength(IMFByteStream
*iface
, QWORD
*length
)
4862 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4864 TRACE("%p, %p.\n", iface
, length
);
4866 if (wrapper
->is_closed
)
4867 return MF_E_INVALIDREQUEST
;
4869 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4870 IMFByteStream_GetLength(wrapper
->stream
, length
);
4873 static HRESULT WINAPI
bytestream_wrapper_SetLength(IMFByteStream
*iface
, QWORD length
)
4875 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4877 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(length
));
4879 if (wrapper
->is_closed
)
4880 return MF_E_INVALIDREQUEST
;
4882 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4883 IMFByteStream_SetLength(wrapper
->stream
, length
);
4886 static HRESULT WINAPI
bytestream_wrapper_GetCurrentPosition(IMFByteStream
*iface
, QWORD
*position
)
4888 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4890 TRACE("%p, %p.\n", iface
, position
);
4892 if (wrapper
->is_closed
)
4893 return MF_E_INVALIDREQUEST
;
4895 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4896 IMFByteStream_GetCurrentPosition(wrapper
->stream
, position
);
4899 static HRESULT WINAPI
bytestream_wrapper_SetCurrentPosition(IMFByteStream
*iface
, QWORD position
)
4901 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4903 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
4905 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4906 IMFByteStream_SetCurrentPosition(wrapper
->stream
, position
);
4909 static HRESULT WINAPI
bytestream_wrapper_IsEndOfStream(IMFByteStream
*iface
, BOOL
*eos
)
4911 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4913 TRACE("%p, %p.\n", iface
, eos
);
4915 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4916 IMFByteStream_IsEndOfStream(wrapper
->stream
, eos
);
4919 static HRESULT WINAPI
bytestream_wrapper_Read(IMFByteStream
*iface
, BYTE
*data
, ULONG count
, ULONG
*byte_read
)
4921 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4923 TRACE("%p, %p, %lu, %p.\n", iface
, data
, count
, byte_read
);
4925 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4926 IMFByteStream_Read(wrapper
->stream
, data
, count
, byte_read
);
4929 static HRESULT WINAPI
bytestream_wrapper_BeginRead(IMFByteStream
*iface
, BYTE
*data
, ULONG size
,
4930 IMFAsyncCallback
*callback
, IUnknown
*state
)
4932 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4934 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4936 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4937 IMFByteStream_BeginRead(wrapper
->stream
, data
, size
, callback
, state
);
4940 static HRESULT WINAPI
bytestream_wrapper_EndRead(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*byte_read
)
4942 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4944 TRACE("%p, %p, %p.\n", iface
, result
, byte_read
);
4946 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4947 IMFByteStream_EndRead(wrapper
->stream
, result
, byte_read
);
4950 static HRESULT WINAPI
bytestream_wrapper_Write(IMFByteStream
*iface
, const BYTE
*data
, ULONG count
, ULONG
*written
)
4952 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4954 TRACE("%p, %p, %lu, %p.\n", iface
, data
, count
, written
);
4956 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4957 IMFByteStream_Write(wrapper
->stream
, data
, count
, written
);
4960 static HRESULT WINAPI
bytestream_wrapper_BeginWrite(IMFByteStream
*iface
, const BYTE
*data
, ULONG size
,
4961 IMFAsyncCallback
*callback
, IUnknown
*state
)
4963 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4965 TRACE("%p, %p, %lu, %p, %p.\n", iface
, data
, size
, callback
, state
);
4967 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4968 IMFByteStream_BeginWrite(wrapper
->stream
, data
, size
, callback
, state
);
4971 static HRESULT WINAPI
bytestream_wrapper_EndWrite(IMFByteStream
*iface
, IMFAsyncResult
*result
, ULONG
*written
)
4973 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4975 TRACE("%p, %p, %p.\n", iface
, result
, written
);
4977 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4978 IMFByteStream_EndWrite(wrapper
->stream
, result
, written
);
4981 static HRESULT WINAPI
bytestream_wrapper_Seek(IMFByteStream
*iface
, MFBYTESTREAM_SEEK_ORIGIN seek
, LONGLONG offset
,
4982 DWORD flags
, QWORD
*current
)
4984 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4986 TRACE("%p, %u, %s, %#lx, %p.\n", iface
, seek
, wine_dbgstr_longlong(offset
), flags
, current
);
4988 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
:
4989 IMFByteStream_Seek(wrapper
->stream
, seek
, offset
, flags
, current
);
4992 static HRESULT WINAPI
bytestream_wrapper_Flush(IMFByteStream
*iface
)
4994 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
4996 TRACE("%p\n", iface
);
4998 return wrapper
->is_closed
? MF_E_INVALIDREQUEST
: IMFByteStream_Flush(wrapper
->stream
);
5001 static HRESULT WINAPI
bytestream_wrapper_Close(IMFByteStream
*iface
)
5003 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStream(iface
);
5005 TRACE("%p\n", iface
);
5007 wrapper
->is_closed
= TRUE
;
5012 static const IMFByteStreamVtbl bytestream_wrapper_vtbl
=
5014 bytestream_wrapper_QueryInterface
,
5015 bytestream_wrapper_AddRef
,
5016 bytestream_wrapper_Release
,
5017 bytestream_wrapper_GetCapabilities
,
5018 bytestream_wrapper_GetLength
,
5019 bytestream_wrapper_SetLength
,
5020 bytestream_wrapper_GetCurrentPosition
,
5021 bytestream_wrapper_SetCurrentPosition
,
5022 bytestream_wrapper_IsEndOfStream
,
5023 bytestream_wrapper_Read
,
5024 bytestream_wrapper_BeginRead
,
5025 bytestream_wrapper_EndRead
,
5026 bytestream_wrapper_Write
,
5027 bytestream_wrapper_BeginWrite
,
5028 bytestream_wrapper_EndWrite
,
5029 bytestream_wrapper_Seek
,
5030 bytestream_wrapper_Flush
,
5031 bytestream_wrapper_Close
,
5034 static HRESULT WINAPI
bytestream_wrapper_cache_control_QueryInterface(IMFByteStreamCacheControl
*iface
,
5035 REFIID riid
, void **obj
)
5037 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5038 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5041 static ULONG WINAPI
bytestream_wrapper_cache_control_AddRef(IMFByteStreamCacheControl
*iface
)
5043 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5044 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5047 static ULONG WINAPI
bytestream_wrapper_cache_control_Release(IMFByteStreamCacheControl
*iface
)
5049 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5050 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5053 static HRESULT WINAPI
bytestream_wrapper_cache_control_StopBackgroundTransfer(IMFByteStreamCacheControl
*iface
)
5055 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamCacheControl(iface
);
5057 TRACE("%p.\n", iface
);
5059 return IMFByteStreamCacheControl_StopBackgroundTransfer(wrapper
->cache_control
);
5062 static const IMFByteStreamCacheControlVtbl bytestream_wrapper_cache_control_vtbl
=
5064 bytestream_wrapper_cache_control_QueryInterface
,
5065 bytestream_wrapper_cache_control_AddRef
,
5066 bytestream_wrapper_cache_control_Release
,
5067 bytestream_wrapper_cache_control_StopBackgroundTransfer
,
5070 static HRESULT WINAPI
bytestream_wrapper_buffering_QueryInterface(IMFByteStreamBuffering
*iface
,
5071 REFIID riid
, void **obj
)
5073 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5074 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5077 static ULONG WINAPI
bytestream_wrapper_buffering_AddRef(IMFByteStreamBuffering
*iface
)
5079 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5080 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5083 static ULONG WINAPI
bytestream_wrapper_buffering_Release(IMFByteStreamBuffering
*iface
)
5085 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5086 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5089 static HRESULT WINAPI
bytestream_wrapper_buffering_SetBufferingParams(IMFByteStreamBuffering
*iface
,
5090 MFBYTESTREAM_BUFFERING_PARAMS
*params
)
5092 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5094 TRACE("%p, %p.\n", iface
, params
);
5096 return IMFByteStreamBuffering_SetBufferingParams(wrapper
->stream_buffering
, params
);
5099 static HRESULT WINAPI
bytestream_wrapper_buffering_EnableBuffering(IMFByteStreamBuffering
*iface
,
5102 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5104 TRACE("%p, %d.\n", iface
, enable
);
5106 return IMFByteStreamBuffering_EnableBuffering(wrapper
->stream_buffering
, enable
);
5109 static HRESULT WINAPI
bytestream_wrapper_buffering_StopBuffering(IMFByteStreamBuffering
*iface
)
5111 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamBuffering(iface
);
5113 TRACE("%p.\n", iface
);
5115 return IMFByteStreamBuffering_StopBuffering(wrapper
->stream_buffering
);
5118 static const IMFByteStreamBufferingVtbl bytestream_wrapper_buffering_vtbl
=
5120 bytestream_wrapper_buffering_QueryInterface
,
5121 bytestream_wrapper_buffering_AddRef
,
5122 bytestream_wrapper_buffering_Release
,
5123 bytestream_wrapper_buffering_SetBufferingParams
,
5124 bytestream_wrapper_buffering_EnableBuffering
,
5125 bytestream_wrapper_buffering_StopBuffering
,
5128 static HRESULT WINAPI
bytestream_wrapper_timeseek_QueryInterface(IMFByteStreamTimeSeek
*iface
,
5129 REFIID riid
, void **obj
)
5131 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5132 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5135 static ULONG WINAPI
bytestream_wrapper_timeseek_AddRef(IMFByteStreamTimeSeek
*iface
)
5137 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5138 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5141 static ULONG WINAPI
bytestream_wrapper_timeseek_Release(IMFByteStreamTimeSeek
*iface
)
5143 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5144 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5147 static HRESULT WINAPI
bytestream_wrapper_timeseek_IsTimeSeekSupported(IMFByteStreamTimeSeek
*iface
, BOOL
*result
)
5149 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5151 TRACE("%p, %p.\n", iface
, result
);
5153 return IMFByteStreamTimeSeek_IsTimeSeekSupported(wrapper
->time_seek
, result
);
5156 static HRESULT WINAPI
bytestream_wrapper_timeseek_TimeSeek(IMFByteStreamTimeSeek
*iface
, QWORD position
)
5158 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5160 TRACE("%p, %s.\n", iface
, wine_dbgstr_longlong(position
));
5162 return IMFByteStreamTimeSeek_TimeSeek(wrapper
->time_seek
, position
);
5165 static HRESULT WINAPI
bytestream_wrapper_timeseek_GetTimeSeekResult(IMFByteStreamTimeSeek
*iface
, QWORD
*start_time
,
5166 QWORD
*stop_time
, QWORD
*duration
)
5168 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFByteStreamTimeSeek(iface
);
5170 TRACE("%p, %p, %p, %p.\n", iface
, start_time
, stop_time
, duration
);
5172 return IMFByteStreamTimeSeek_GetTimeSeekResult(wrapper
->time_seek
, start_time
, stop_time
, duration
);
5175 static const IMFByteStreamTimeSeekVtbl bytestream_wrapper_timeseek_vtbl
=
5177 bytestream_wrapper_timeseek_QueryInterface
,
5178 bytestream_wrapper_timeseek_AddRef
,
5179 bytestream_wrapper_timeseek_Release
,
5180 bytestream_wrapper_timeseek_IsTimeSeekSupported
,
5181 bytestream_wrapper_timeseek_TimeSeek
,
5182 bytestream_wrapper_timeseek_GetTimeSeekResult
,
5185 static HRESULT WINAPI
bytestream_wrapper_events_QueryInterface(IMFMediaEventGenerator
*iface
, REFIID riid
, void **obj
)
5187 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5188 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5191 static ULONG WINAPI
bytestream_wrapper_events_AddRef(IMFMediaEventGenerator
*iface
)
5193 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5194 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5197 static ULONG WINAPI
bytestream_wrapper_events_Release(IMFMediaEventGenerator
*iface
)
5199 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5200 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5203 static HRESULT WINAPI
bytestream_wrapper_events_GetEvent(IMFMediaEventGenerator
*iface
, DWORD flags
, IMFMediaEvent
**event
)
5205 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5207 TRACE("%p, %#lx, %p.\n", iface
, flags
, event
);
5209 return IMFMediaEventGenerator_GetEvent(wrapper
->event_generator
, flags
, event
);
5212 static HRESULT WINAPI
bytestream_wrapper_events_BeginGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
5214 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5216 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
5218 return IMFMediaEventGenerator_BeginGetEvent(wrapper
->event_generator
, callback
, state
);
5221 static HRESULT WINAPI
bytestream_wrapper_events_EndGetEvent(IMFMediaEventGenerator
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
5223 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5225 TRACE("%p, %p, %p.\n", iface
, result
, event
);
5227 return IMFMediaEventGenerator_EndGetEvent(wrapper
->event_generator
, result
, event
);
5230 static HRESULT WINAPI
bytestream_wrapper_events_QueueEvent(IMFMediaEventGenerator
*iface
, MediaEventType type
,
5231 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
5233 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFMediaEventGenerator(iface
);
5235 TRACE("%p, %ld, %s, %#lx, %s.\n", iface
, type
, debugstr_guid(ext_type
), hr
, debugstr_propvar(value
));
5237 return IMFMediaEventGenerator_QueueEvent(wrapper
->event_generator
, type
, ext_type
, hr
, value
);
5240 static const IMFMediaEventGeneratorVtbl bytestream_wrapper_events_vtbl
=
5242 bytestream_wrapper_events_QueryInterface
,
5243 bytestream_wrapper_events_AddRef
,
5244 bytestream_wrapper_events_Release
,
5245 bytestream_wrapper_events_GetEvent
,
5246 bytestream_wrapper_events_BeginGetEvent
,
5247 bytestream_wrapper_events_EndGetEvent
,
5248 bytestream_wrapper_events_QueueEvent
,
5251 static HRESULT WINAPI
bytestream_wrapper_sample_output_QueryInterface(IMFSampleOutputStream
*iface
, REFIID riid
, void **obj
)
5253 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5254 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5257 static ULONG WINAPI
bytestream_wrapper_sample_output_AddRef(IMFSampleOutputStream
*iface
)
5259 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5260 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5263 static ULONG WINAPI
bytestream_wrapper_sample_output_Release(IMFSampleOutputStream
*iface
)
5265 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5266 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5269 static HRESULT WINAPI
bytestream_wrapper_sample_output_BeginWriteSample(IMFSampleOutputStream
*iface
, IMFSample
*sample
,
5270 IMFAsyncCallback
*callback
, IUnknown
*state
)
5272 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5274 TRACE("%p, %p, %p, %p.\n", iface
, sample
, callback
, state
);
5276 return IMFSampleOutputStream_BeginWriteSample(wrapper
->sample_output
, sample
, callback
, state
);
5279 static HRESULT WINAPI
bytestream_wrapper_sample_output_EndWriteSample(IMFSampleOutputStream
*iface
, IMFAsyncResult
*result
)
5281 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5283 TRACE("%p, %p.\n", iface
, result
);
5285 return IMFSampleOutputStream_EndWriteSample(wrapper
->sample_output
, result
);
5288 static HRESULT WINAPI
bytestream_wrapper_sample_output_Close(IMFSampleOutputStream
*iface
)
5290 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFSampleOutputStream(iface
);
5292 TRACE("%p.\n", iface
);
5294 return IMFSampleOutputStream_Close(wrapper
->sample_output
);
5297 static const IMFSampleOutputStreamVtbl bytestream_wrapper_sample_output_vtbl
=
5299 bytestream_wrapper_sample_output_QueryInterface
,
5300 bytestream_wrapper_sample_output_AddRef
,
5301 bytestream_wrapper_sample_output_Release
,
5302 bytestream_wrapper_sample_output_BeginWriteSample
,
5303 bytestream_wrapper_sample_output_EndWriteSample
,
5304 bytestream_wrapper_sample_output_Close
,
5307 static HRESULT WINAPI
bytestream_wrapper_propstore_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
5309 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5310 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5313 static ULONG WINAPI
bytestream_wrapper_propstore_AddRef(IPropertyStore
*iface
)
5315 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5316 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5319 static ULONG WINAPI
bytestream_wrapper_propstore_Release(IPropertyStore
*iface
)
5321 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5322 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5325 static HRESULT WINAPI
bytestream_wrapper_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
5327 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5329 TRACE("%p, %p.\n", iface
, count
);
5331 return IPropertyStore_GetCount(wrapper
->propstore
, count
);
5334 static HRESULT WINAPI
bytestream_wrapper_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
5336 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5338 TRACE("%p, %lu, %p.\n", iface
, prop
, key
);
5340 return IPropertyStore_GetAt(wrapper
->propstore
, prop
, key
);
5343 static HRESULT WINAPI
bytestream_wrapper_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
5345 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5347 TRACE("%p, %p, %p.\n", iface
, key
, value
);
5349 return IPropertyStore_GetValue(wrapper
->propstore
, key
, value
);
5352 static HRESULT WINAPI
bytestream_wrapper_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
,
5353 const PROPVARIANT
*value
)
5355 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5357 TRACE("%p, %p, %s.\n", iface
, key
, debugstr_propvar(value
));
5359 return IPropertyStore_SetValue(wrapper
->propstore
, key
, value
);
5362 static HRESULT WINAPI
bytestream_wrapper_propstore_Commit(IPropertyStore
*iface
)
5364 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IPropertyStore(iface
);
5366 TRACE("%p.\n", iface
);
5368 return IPropertyStore_Commit(wrapper
->propstore
);
5371 static const IPropertyStoreVtbl bytestream_wrapper_propstore_vtbl
=
5373 bytestream_wrapper_propstore_QueryInterface
,
5374 bytestream_wrapper_propstore_AddRef
,
5375 bytestream_wrapper_propstore_Release
,
5376 bytestream_wrapper_propstore_GetCount
,
5377 bytestream_wrapper_propstore_GetAt
,
5378 bytestream_wrapper_propstore_GetValue
,
5379 bytestream_wrapper_propstore_SetValue
,
5380 bytestream_wrapper_propstore_Commit
,
5383 static HRESULT WINAPI
bytestream_wrapper_attributes_QueryInterface(IMFAttributes
*iface
, REFIID riid
, void **obj
)
5385 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5386 return IMFByteStream_QueryInterface(&wrapper
->IMFByteStream_iface
, riid
, obj
);
5389 static ULONG WINAPI
bytestream_wrapper_attributes_AddRef(IMFAttributes
*iface
)
5391 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5392 return IMFByteStream_AddRef(&wrapper
->IMFByteStream_iface
);
5395 static ULONG WINAPI
bytestream_wrapper_attributes_Release(IMFAttributes
*iface
)
5397 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5398 return IMFByteStream_Release(&wrapper
->IMFByteStream_iface
);
5401 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItem(IMFAttributes
*iface
, REFGUID key
, PROPVARIANT
*value
)
5403 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5405 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5407 return IMFAttributes_GetItem(wrapper
->attributes
, key
, value
);
5410 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemType(IMFAttributes
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
5412 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5414 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
5416 return IMFAttributes_GetItemType(wrapper
->attributes
, key
, type
);
5419 static HRESULT WINAPI
bytestream_wrapper_attributes_CompareItem(IMFAttributes
*iface
, REFGUID key
,
5420 REFPROPVARIANT value
, BOOL
*result
)
5422 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5424 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
5426 return IMFAttributes_CompareItem(wrapper
->attributes
, key
, value
, result
);
5429 static HRESULT WINAPI
bytestream_wrapper_attributes_Compare(IMFAttributes
*iface
, IMFAttributes
*theirs
,
5430 MF_ATTRIBUTES_MATCH_TYPE match_type
, BOOL
*ret
)
5432 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5434 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, match_type
, ret
);
5436 return IMFAttributes_Compare(wrapper
->attributes
, theirs
, match_type
, ret
);
5439 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32
*value
)
5441 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5443 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5445 return IMFAttributes_GetUINT32(wrapper
->attributes
, key
, value
);
5448 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64
*value
)
5450 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5452 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5454 return IMFAttributes_GetUINT64(wrapper
->attributes
, key
, value
);
5457 static HRESULT WINAPI
bytestream_wrapper_attributes_GetDouble(IMFAttributes
*iface
, REFGUID key
, double *value
)
5459 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5461 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5463 return IMFAttributes_GetDouble(wrapper
->attributes
, key
, value
);
5466 static HRESULT WINAPI
bytestream_wrapper_attributes_GetGUID(IMFAttributes
*iface
, REFGUID key
, GUID
*value
)
5468 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5470 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
5472 return IMFAttributes_GetGUID(wrapper
->attributes
, key
, value
);
5475 static HRESULT WINAPI
bytestream_wrapper_attributes_GetStringLength(IMFAttributes
*iface
, REFGUID key
, UINT32
*length
)
5477 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5479 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
5481 return IMFAttributes_GetStringLength(wrapper
->attributes
, key
, length
);
5484 static HRESULT WINAPI
bytestream_wrapper_attributes_GetString(IMFAttributes
*iface
, REFGUID key
, WCHAR
*value
,
5485 UINT32 size
, UINT32
*length
)
5487 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5489 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
5491 return IMFAttributes_GetString(wrapper
->attributes
, key
, value
, size
, length
);
5494 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedString(IMFAttributes
*iface
, REFGUID key
, WCHAR
**value
, UINT32
*length
)
5496 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5498 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
5500 return IMFAttributes_GetAllocatedString(wrapper
->attributes
, key
, value
, length
);
5503 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlobSize(IMFAttributes
*iface
, REFGUID key
, UINT32
*size
)
5505 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5507 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
5509 return IMFAttributes_GetBlobSize(wrapper
->attributes
, key
, size
);
5512 static HRESULT WINAPI
bytestream_wrapper_attributes_GetBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
*buf
,
5513 UINT32 bufsize
, UINT32
*blobsize
)
5515 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5517 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
5519 return IMFAttributes_GetBlob(wrapper
->attributes
, key
, buf
, bufsize
, blobsize
);
5522 static HRESULT WINAPI
bytestream_wrapper_attributes_GetAllocatedBlob(IMFAttributes
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
5524 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5526 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
5528 return IMFAttributes_GetAllocatedBlob(wrapper
->attributes
, key
, buf
, size
);
5531 static HRESULT WINAPI
bytestream_wrapper_attributes_GetUnknown(IMFAttributes
*iface
, REFGUID key
, REFIID riid
, void **obj
)
5533 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5535 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), obj
);
5537 return IMFAttributes_GetUnknown(wrapper
->attributes
, key
, riid
, obj
);
5540 static HRESULT WINAPI
bytestream_wrapper_attributes_SetItem(IMFAttributes
*iface
, REFGUID key
, REFPROPVARIANT value
)
5542 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5544 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
5546 return IMFAttributes_SetItem(wrapper
->attributes
, key
, value
);
5549 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteItem(IMFAttributes
*iface
, REFGUID key
)
5551 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5553 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
5555 return IMFAttributes_DeleteItem(wrapper
->attributes
, key
);
5558 static HRESULT WINAPI
bytestream_wrapper_attributes_DeleteAllItems(IMFAttributes
*iface
)
5560 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5562 TRACE("%p.\n", iface
);
5564 return IMFAttributes_DeleteAllItems(wrapper
->attributes
);
5567 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT32(IMFAttributes
*iface
, REFGUID key
, UINT32 value
)
5569 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5571 TRACE("%p, %s, %d.\n", iface
, debugstr_attr(key
), value
);
5573 return IMFAttributes_SetUINT32(wrapper
->attributes
, key
, value
);
5576 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUINT64(IMFAttributes
*iface
, REFGUID key
, UINT64 value
)
5578 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5580 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
5582 return IMFAttributes_SetUINT64(wrapper
->attributes
, key
, value
);
5585 static HRESULT WINAPI
bytestream_wrapper_attributes_SetDouble(IMFAttributes
*iface
, REFGUID key
, double value
)
5587 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5589 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
5591 return IMFAttributes_SetDouble(wrapper
->attributes
, key
, value
);
5594 static HRESULT WINAPI
bytestream_wrapper_attributes_SetGUID(IMFAttributes
*iface
, REFGUID key
, REFGUID value
)
5596 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5598 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
5600 return IMFAttributes_SetGUID(wrapper
->attributes
, key
, value
);
5603 static HRESULT WINAPI
bytestream_wrapper_attributes_SetString(IMFAttributes
*iface
, REFGUID key
, const WCHAR
*value
)
5605 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5607 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
5609 return IMFAttributes_SetString(wrapper
->attributes
, key
, value
);
5612 static HRESULT WINAPI
bytestream_wrapper_attributes_SetBlob(IMFAttributes
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
5614 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5616 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
5618 return IMFAttributes_SetBlob(wrapper
->attributes
, key
, buf
, size
);
5621 static HRESULT WINAPI
bytestream_wrapper_attributes_SetUnknown(IMFAttributes
*iface
, REFGUID key
, IUnknown
*unknown
)
5623 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5625 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
5627 return IMFAttributes_SetUnknown(wrapper
->attributes
, key
, unknown
);
5630 static HRESULT WINAPI
bytestream_wrapper_attributes_LockStore(IMFAttributes
*iface
)
5632 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5634 TRACE("%p.\n", iface
);
5636 return IMFAttributes_LockStore(wrapper
->attributes
);
5639 static HRESULT WINAPI
bytestream_wrapper_attributes_UnlockStore(IMFAttributes
*iface
)
5641 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5643 TRACE("%p.\n", iface
);
5645 return IMFAttributes_UnlockStore(wrapper
->attributes
);
5648 static HRESULT WINAPI
bytestream_wrapper_attributes_GetCount(IMFAttributes
*iface
, UINT32
*count
)
5650 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5652 TRACE("%p, %p.\n", iface
, count
);
5654 return IMFAttributes_GetCount(wrapper
->attributes
, count
);
5657 static HRESULT WINAPI
bytestream_wrapper_attributes_GetItemByIndex(IMFAttributes
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
5659 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5661 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
5663 return IMFAttributes_GetItemByIndex(wrapper
->attributes
, index
, key
, value
);
5666 static HRESULT WINAPI
bytestream_wrapper_attributes_CopyAllItems(IMFAttributes
*iface
, IMFAttributes
*dest
)
5668 struct bytestream_wrapper
*wrapper
= impl_wrapper_from_IMFAttributes(iface
);
5670 TRACE("%p, %p.\n", iface
, dest
);
5672 return IMFAttributes_CopyAllItems(wrapper
->attributes
, dest
);
5675 static const IMFAttributesVtbl bytestream_wrapper_attributes_vtbl
=
5677 bytestream_wrapper_attributes_QueryInterface
,
5678 bytestream_wrapper_attributes_AddRef
,
5679 bytestream_wrapper_attributes_Release
,
5680 bytestream_wrapper_attributes_GetItem
,
5681 bytestream_wrapper_attributes_GetItemType
,
5682 bytestream_wrapper_attributes_CompareItem
,
5683 bytestream_wrapper_attributes_Compare
,
5684 bytestream_wrapper_attributes_GetUINT32
,
5685 bytestream_wrapper_attributes_GetUINT64
,
5686 bytestream_wrapper_attributes_GetDouble
,
5687 bytestream_wrapper_attributes_GetGUID
,
5688 bytestream_wrapper_attributes_GetStringLength
,
5689 bytestream_wrapper_attributes_GetString
,
5690 bytestream_wrapper_attributes_GetAllocatedString
,
5691 bytestream_wrapper_attributes_GetBlobSize
,
5692 bytestream_wrapper_attributes_GetBlob
,
5693 bytestream_wrapper_attributes_GetAllocatedBlob
,
5694 bytestream_wrapper_attributes_GetUnknown
,
5695 bytestream_wrapper_attributes_SetItem
,
5696 bytestream_wrapper_attributes_DeleteItem
,
5697 bytestream_wrapper_attributes_DeleteAllItems
,
5698 bytestream_wrapper_attributes_SetUINT32
,
5699 bytestream_wrapper_attributes_SetUINT64
,
5700 bytestream_wrapper_attributes_SetDouble
,
5701 bytestream_wrapper_attributes_SetGUID
,
5702 bytestream_wrapper_attributes_SetString
,
5703 bytestream_wrapper_attributes_SetBlob
,
5704 bytestream_wrapper_attributes_SetUnknown
,
5705 bytestream_wrapper_attributes_LockStore
,
5706 bytestream_wrapper_attributes_UnlockStore
,
5707 bytestream_wrapper_attributes_GetCount
,
5708 bytestream_wrapper_attributes_GetItemByIndex
,
5709 bytestream_wrapper_attributes_CopyAllItems
5712 /***********************************************************************
5713 * MFCreateMFByteStreamWrapper (mfplat.@)
5715 HRESULT WINAPI
MFCreateMFByteStreamWrapper(IMFByteStream
*stream
, IMFByteStream
**wrapper
)
5717 struct bytestream_wrapper
*object
;
5719 TRACE("%p, %p.\n", stream
, wrapper
);
5721 if (!(object
= calloc(1, sizeof(*object
))))
5722 return E_OUTOFMEMORY
;
5724 object
->IMFByteStreamCacheControl_iface
.lpVtbl
= &bytestream_wrapper_cache_control_vtbl
;
5725 object
->IMFByteStreamBuffering_iface
.lpVtbl
= &bytestream_wrapper_buffering_vtbl
;
5726 object
->IMFMediaEventGenerator_iface
.lpVtbl
= &bytestream_wrapper_events_vtbl
;
5727 object
->IMFByteStreamTimeSeek_iface
.lpVtbl
= &bytestream_wrapper_timeseek_vtbl
;
5728 object
->IMFSampleOutputStream_iface
.lpVtbl
= &bytestream_wrapper_sample_output_vtbl
;
5729 object
->IMFByteStream_iface
.lpVtbl
= &bytestream_wrapper_vtbl
;
5730 object
->IPropertyStore_iface
.lpVtbl
= &bytestream_wrapper_propstore_vtbl
;
5731 object
->IMFAttributes_iface
.lpVtbl
= &bytestream_wrapper_attributes_vtbl
;
5733 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamCacheControl
, (void **)&object
->cache_control
);
5734 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamBuffering
, (void **)&object
->stream_buffering
);
5735 IMFByteStream_QueryInterface(stream
, &IID_IMFMediaEventGenerator
, (void **)&object
->event_generator
);
5736 IMFByteStream_QueryInterface(stream
, &IID_IMFByteStreamTimeSeek
, (void **)&object
->time_seek
);
5737 IMFByteStream_QueryInterface(stream
, &IID_IMFSampleOutputStream
, (void **)&object
->sample_output
);
5738 IMFByteStream_QueryInterface(stream
, &IID_IPropertyStore
, (void **)&object
->propstore
);
5739 IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&object
->attributes
);
5741 object
->stream
= stream
;
5742 IMFByteStream_AddRef(object
->stream
);
5744 object
->refcount
= 1;
5746 *wrapper
= &object
->IMFByteStream_iface
;
5751 static HRESULT WINAPI
MFPluginControl_QueryInterface(IMFPluginControl
*iface
, REFIID riid
, void **ppv
)
5753 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
5754 TRACE("(IID_IUnknown %p)\n", ppv
);
5756 }else if(IsEqualGUID(riid
, &IID_IMFPluginControl
)) {
5757 TRACE("(IID_IMFPluginControl %p)\n", ppv
);
5760 FIXME("(%s %p)\n", debugstr_guid(riid
), ppv
);
5762 return E_NOINTERFACE
;
5765 IUnknown_AddRef((IUnknown
*)*ppv
);
5769 static ULONG WINAPI
MFPluginControl_AddRef(IMFPluginControl
*iface
)
5775 static ULONG WINAPI
MFPluginControl_Release(IMFPluginControl
*iface
)
5781 static HRESULT WINAPI
MFPluginControl_GetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5782 const WCHAR
*selector
, CLSID
*clsid
)
5784 FIXME("(%ld %s %p)\n", plugin_type
, debugstr_w(selector
), clsid
);
5788 static HRESULT WINAPI
MFPluginControl_GetPreferredClsidByIndex(IMFPluginControl
*iface
, DWORD plugin_type
,
5789 DWORD index
, WCHAR
**selector
, CLSID
*clsid
)
5791 FIXME("(%ld %ld %p %p)\n", plugin_type
, index
, selector
, clsid
);
5795 static HRESULT WINAPI
MFPluginControl_SetPreferredClsid(IMFPluginControl
*iface
, DWORD plugin_type
,
5796 const WCHAR
*selector
, const CLSID
*clsid
)
5798 FIXME("(%ld %s %s)\n", plugin_type
, debugstr_w(selector
), debugstr_guid(clsid
));
5802 static HRESULT WINAPI
MFPluginControl_IsDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
)
5804 FIXME("(%ld %s)\n", plugin_type
, debugstr_guid(clsid
));
5808 static HRESULT WINAPI
MFPluginControl_GetDisabledByIndex(IMFPluginControl
*iface
, DWORD plugin_type
, DWORD index
, CLSID
*clsid
)
5810 FIXME("(%ld %ld %p)\n", plugin_type
, index
, clsid
);
5814 static HRESULT WINAPI
MFPluginControl_SetDisabled(IMFPluginControl
*iface
, DWORD plugin_type
, REFCLSID clsid
, BOOL disabled
)
5816 FIXME("(%ld %s %x)\n", plugin_type
, debugstr_guid(clsid
), disabled
);
5820 static const IMFPluginControlVtbl MFPluginControlVtbl
= {
5821 MFPluginControl_QueryInterface
,
5822 MFPluginControl_AddRef
,
5823 MFPluginControl_Release
,
5824 MFPluginControl_GetPreferredClsid
,
5825 MFPluginControl_GetPreferredClsidByIndex
,
5826 MFPluginControl_SetPreferredClsid
,
5827 MFPluginControl_IsDisabled
,
5828 MFPluginControl_GetDisabledByIndex
,
5829 MFPluginControl_SetDisabled
5832 static IMFPluginControl plugin_control
= { &MFPluginControlVtbl
};
5834 /***********************************************************************
5835 * MFGetPluginControl (mfplat.@)
5837 HRESULT WINAPI
MFGetPluginControl(IMFPluginControl
**ret
)
5839 TRACE("(%p)\n", ret
);
5841 *ret
= &plugin_control
;
5845 enum resolved_object_origin
5847 OBJECT_FROM_BYTESTREAM
,
5851 struct resolver_queued_result
5855 MF_OBJECT_TYPE obj_type
;
5857 IRtwqAsyncResult
*inner_result
;
5858 enum resolved_object_origin origin
;
5861 struct resolver_cancel_object
5863 IUnknown IUnknown_iface
;
5868 IMFByteStreamHandler
*stream_handler
;
5869 IMFSchemeHandler
*scheme_handler
;
5871 IUnknown
*cancel_cookie
;
5872 enum resolved_object_origin origin
;
5875 struct source_resolver
5877 IMFSourceResolver IMFSourceResolver_iface
;
5879 IRtwqAsyncCallback stream_callback
;
5880 IRtwqAsyncCallback url_callback
;
5881 CRITICAL_SECTION cs
;
5882 struct list pending
;
5885 static struct source_resolver
*impl_from_IMFSourceResolver(IMFSourceResolver
*iface
)
5887 return CONTAINING_RECORD(iface
, struct source_resolver
, IMFSourceResolver_iface
);
5890 static struct source_resolver
*impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5892 return CONTAINING_RECORD(iface
, struct source_resolver
, stream_callback
);
5895 static struct source_resolver
*impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
5897 return CONTAINING_RECORD(iface
, struct source_resolver
, url_callback
);
5900 static HRESULT
resolver_handler_end_create(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
5901 IRtwqAsyncResult
*result
)
5903 IRtwqAsyncResult
*inner_result
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
5904 RTWQASYNCRESULT
*data
= (RTWQASYNCRESULT
*)inner_result
;
5905 struct resolver_queued_result
*queued_result
;
5909 IMFByteStreamHandler
*stream_handler
;
5910 IMFSchemeHandler
*scheme_handler
;
5913 if (!(queued_result
= calloc(1, sizeof(*queued_result
))))
5914 return E_OUTOFMEMORY
;
5916 queued_result
->origin
= origin
;
5918 IRtwqAsyncResult_GetObject(inner_result
, &handler
.handler
);
5922 case OBJECT_FROM_BYTESTREAM
:
5923 queued_result
->hr
= IMFByteStreamHandler_EndCreateObject(handler
.stream_handler
, (IMFAsyncResult
*)result
,
5924 &queued_result
->obj_type
, &queued_result
->object
);
5926 case OBJECT_FROM_URL
:
5927 queued_result
->hr
= IMFSchemeHandler_EndCreateObject(handler
.scheme_handler
, (IMFAsyncResult
*)result
,
5928 &queued_result
->obj_type
, &queued_result
->object
);
5931 queued_result
->hr
= E_FAIL
;
5934 IUnknown_Release(handler
.handler
);
5938 queued_result
->inner_result
= inner_result
;
5939 IRtwqAsyncResult_AddRef(queued_result
->inner_result
);
5942 /* Push resolved object type and created object, so we don't have to guess on End*() call. */
5943 EnterCriticalSection(&resolver
->cs
);
5944 list_add_tail(&resolver
->pending
, &queued_result
->entry
);
5945 LeaveCriticalSection(&resolver
->cs
);
5948 SetEvent(data
->hEvent
);
5951 IUnknown
*caller_state
= IRtwqAsyncResult_GetStateNoAddRef(inner_result
);
5952 IRtwqAsyncResult
*caller_result
;
5954 if (SUCCEEDED(RtwqCreateAsyncResult(queued_result
->object
, data
->pCallback
, caller_state
, &caller_result
)))
5956 RtwqInvokeCallback(caller_result
);
5957 IRtwqAsyncResult_Release(caller_result
);
5964 static struct resolver_cancel_object
*impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
5966 return CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
);
5969 static HRESULT WINAPI
resolver_cancel_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
5971 if (IsEqualIID(riid
, &IID_IUnknown
))
5974 IUnknown_AddRef(iface
);
5979 return E_NOINTERFACE
;
5982 static ULONG WINAPI
resolver_cancel_object_AddRef(IUnknown
*iface
)
5984 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5985 return InterlockedIncrement(&object
->refcount
);
5988 static ULONG WINAPI
resolver_cancel_object_Release(IUnknown
*iface
)
5990 struct resolver_cancel_object
*object
= impl_cancel_obj_from_IUnknown(iface
);
5991 ULONG refcount
= InterlockedDecrement(&object
->refcount
);
5995 if (object
->cancel_cookie
)
5996 IUnknown_Release(object
->cancel_cookie
);
5997 IUnknown_Release(object
->u
.handler
);
6004 static const IUnknownVtbl resolver_cancel_object_vtbl
=
6006 resolver_cancel_object_QueryInterface
,
6007 resolver_cancel_object_AddRef
,
6008 resolver_cancel_object_Release
,
6011 static struct resolver_cancel_object
*unsafe_impl_cancel_obj_from_IUnknown(IUnknown
*iface
)
6016 return (iface
->lpVtbl
== &resolver_cancel_object_vtbl
) ?
6017 CONTAINING_RECORD(iface
, struct resolver_cancel_object
, IUnknown_iface
) : NULL
;
6020 static HRESULT
resolver_create_cancel_object(IUnknown
*handler
, enum resolved_object_origin origin
,
6021 IUnknown
*cancel_cookie
, IUnknown
**cancel_object
)
6023 struct resolver_cancel_object
*object
;
6025 if (!(object
= calloc(1, sizeof(*object
))))
6026 return E_OUTOFMEMORY
;
6028 object
->IUnknown_iface
.lpVtbl
= &resolver_cancel_object_vtbl
;
6029 object
->refcount
= 1;
6030 object
->u
.handler
= handler
;
6031 IUnknown_AddRef(object
->u
.handler
);
6032 object
->cancel_cookie
= cancel_cookie
;
6033 IUnknown_AddRef(object
->cancel_cookie
);
6034 object
->origin
= origin
;
6036 *cancel_object
= &object
->IUnknown_iface
;
6041 static HRESULT WINAPI
source_resolver_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
6043 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
6044 IsEqualIID(riid
, &IID_IUnknown
))
6047 IRtwqAsyncCallback_AddRef(iface
);
6052 return E_NOINTERFACE
;
6055 static ULONG WINAPI
source_resolver_callback_stream_AddRef(IRtwqAsyncCallback
*iface
)
6057 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6058 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
6061 static ULONG WINAPI
source_resolver_callback_stream_Release(IRtwqAsyncCallback
*iface
)
6063 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6064 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
6067 static HRESULT WINAPI
source_resolver_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
6072 static HRESULT WINAPI
source_resolver_callback_stream_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
6074 struct source_resolver
*resolver
= impl_from_stream_IRtwqAsyncCallback(iface
);
6076 return resolver_handler_end_create(resolver
, OBJECT_FROM_BYTESTREAM
, result
);
6079 static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl
=
6081 source_resolver_callback_QueryInterface
,
6082 source_resolver_callback_stream_AddRef
,
6083 source_resolver_callback_stream_Release
,
6084 source_resolver_callback_GetParameters
,
6085 source_resolver_callback_stream_Invoke
,
6088 static ULONG WINAPI
source_resolver_callback_url_AddRef(IRtwqAsyncCallback
*iface
)
6090 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6091 return IMFSourceResolver_AddRef(&resolver
->IMFSourceResolver_iface
);
6094 static ULONG WINAPI
source_resolver_callback_url_Release(IRtwqAsyncCallback
*iface
)
6096 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6097 return IMFSourceResolver_Release(&resolver
->IMFSourceResolver_iface
);
6100 static HRESULT WINAPI
source_resolver_callback_url_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
6102 struct source_resolver
*resolver
= impl_from_url_IRtwqAsyncCallback(iface
);
6104 return resolver_handler_end_create(resolver
, OBJECT_FROM_URL
, result
);
6107 static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl
=
6109 source_resolver_callback_QueryInterface
,
6110 source_resolver_callback_url_AddRef
,
6111 source_resolver_callback_url_Release
,
6112 source_resolver_callback_GetParameters
,
6113 source_resolver_callback_url_Invoke
,
6116 static HRESULT
resolver_create_registered_handler(HKEY hkey
, REFIID riid
, void **handler
)
6118 DWORD name_length
, type
;
6119 HRESULT hr
= E_FAIL
;
6124 name_length
= ARRAY_SIZE(clsidW
);
6125 while (!RegEnumValueW(hkey
, j
++, clsidW
, &name_length
, NULL
, &type
, NULL
, NULL
))
6129 if (SUCCEEDED(CLSIDFromString(clsidW
, &clsid
)))
6131 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, handler
);
6137 name_length
= ARRAY_SIZE(clsidW
);
6143 static HRESULT
resolver_create_bytestream_handler(IMFByteStream
*stream
, DWORD flags
, const WCHAR
*mime
,
6144 const WCHAR
*extension
, IMFByteStreamHandler
**handler
)
6146 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6147 HRESULT hr
= E_FAIL
;
6152 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6154 struct local_handler
*local_handler
;
6156 EnterCriticalSection(&local_handlers_section
);
6158 LIST_FOR_EACH_ENTRY(local_handler
, &local_bytestream_handlers
, struct local_handler
, entry
)
6160 if ((mime
&& !lstrcmpiW(mime
, local_handler
->u
.bytestream
.mime
))
6161 || (extension
&& !lstrcmpiW(extension
, local_handler
->u
.bytestream
.extension
)))
6163 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFByteStreamHandler
,
6169 LeaveCriticalSection(&local_handlers_section
);
6175 for (i
= 0, hr
= E_FAIL
; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6177 const WCHAR
*namesW
[2] = { mime
, extension
};
6178 HKEY hkey
, hkey_handler
;
6180 if (RegOpenKeyW(hkey_roots
[i
], L
"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers", &hkey
))
6183 for (j
= 0; j
< ARRAY_SIZE(namesW
); ++j
)
6188 if (!RegOpenKeyW(hkey
, namesW
[j
], &hkey_handler
))
6190 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFByteStreamHandler
, (void **)handler
);
6191 RegCloseKey(hkey_handler
);
6207 static HRESULT
resolver_get_bytestream_url_hint(IMFByteStream
*stream
, WCHAR
const **url
)
6209 static const unsigned char asfmagic
[] = {0x30,0x26,0xb2,0x75,0x8e,0x66,0xcf,0x11,0xa6,0xd9,0x00,0xaa,0x00,0x62,0xce,0x6c};
6210 static const unsigned char wavmagic
[] = { 'R', 'I', 'F', 'F',0x00,0x00,0x00,0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' '};
6211 static const unsigned char wavmask
[] = {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
6212 static const unsigned char isommagic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'i', 's', 'o', 'm',0x00,0x00,0x00,0x00};
6213 static const unsigned char mp4_magic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'M', 'S', 'N', 'V',0x00,0x00,0x00,0x00};
6214 static const unsigned char mp42magic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'm', 'p', '4', '2',0x00,0x00,0x00,0x00};
6215 static const unsigned char mp4vmagic
[] = {0x00,0x00,0x00,0x00, 'f', 't', 'y', 'p', 'M', '4', 'V', ' ',0x00,0x00,0x00,0x00};
6216 static const unsigned char mp4mask
[] = {0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00};
6217 static const struct stream_content_url_hint
6219 const unsigned char *magic
;
6221 const unsigned char *mask
;
6225 { asfmagic
, L
".asf" },
6226 { wavmagic
, L
".wav", wavmask
},
6227 { isommagic
, L
".mp4", mp4mask
},
6228 { mp42magic
, L
".mp4", mp4mask
},
6229 { mp4_magic
, L
".mp4", mp4mask
},
6230 { mp4vmagic
, L
".m4v", mp4mask
},
6232 unsigned char buffer
[4 * sizeof(unsigned int)], pattern
[4 * sizeof(unsigned int)];
6233 IMFAttributes
*attributes
;
6234 DWORD length
= 0, caps
= 0;
6241 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
6243 UINT32 string_length
= 0;
6244 IMFAttributes_GetStringLength(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &string_length
);
6245 IMFAttributes_Release(attributes
);
6251 if (FAILED(hr
= IMFByteStream_GetCapabilities(stream
, &caps
)))
6254 if (!(caps
& MFBYTESTREAM_IS_SEEKABLE
))
6255 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6257 if (FAILED(hr
= IMFByteStream_GetCurrentPosition(stream
, &position
)))
6260 hr
= IMFByteStream_Read(stream
, buffer
, sizeof(buffer
), &length
);
6261 IMFByteStream_SetCurrentPosition(stream
, position
);
6265 if (length
< sizeof(buffer
))
6268 for (i
= 0; i
< ARRAY_SIZE(url_hints
); ++i
)
6270 memcpy(pattern
, buffer
, sizeof(buffer
));
6271 if (url_hints
[i
].mask
)
6273 unsigned int *mask
= (unsigned int *)url_hints
[i
].mask
;
6274 unsigned int *data
= (unsigned int *)pattern
;
6276 for (j
= 0; j
< sizeof(buffer
) / sizeof(unsigned int); ++j
)
6280 if (!memcmp(pattern
, url_hints
[i
].magic
, sizeof(pattern
)))
6282 *url
= url_hints
[i
].url
;
6288 TRACE("Content type guessed as %s from %s.\n", debugstr_w(*url
), debugstr_an((char *)buffer
, length
));
6290 WARN("Unrecognized content type %s.\n", debugstr_an((char *)buffer
, length
));
6295 static HRESULT
resolver_create_gstreamer_handler(IMFByteStreamHandler
**handler
)
6297 static const GUID CLSID_GStreamerByteStreamHandler
= {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
6298 return CoCreateInstance(&CLSID_GStreamerByteStreamHandler
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFByteStreamHandler
, (void **)handler
);
6301 static HRESULT
resolver_get_bytestream_handler(IMFByteStream
*stream
, const WCHAR
*url
, DWORD flags
,
6302 IMFByteStreamHandler
**handler
)
6304 WCHAR
*mimeW
= NULL
, *urlW
= NULL
;
6305 IMFAttributes
*attributes
;
6306 const WCHAR
*url_ext
;
6307 HRESULT hr
= E_FAIL
;
6313 if (SUCCEEDED(IMFByteStream_QueryInterface(stream
, &IID_IMFAttributes
, (void **)&attributes
)))
6315 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_CONTENT_TYPE
, &mimeW
, &length
);
6318 IMFAttributes_GetAllocatedString(attributes
, &MF_BYTESTREAM_ORIGIN_NAME
, &urlW
, &length
);
6321 IMFAttributes_Release(attributes
);
6325 url_ext
= url
? wcsrchr(url
, '.') : NULL
;
6327 /* If content type was provided by the caller, it's tried first. Otherwise an attempt to deduce
6328 content type from the content itself is made.
6330 TODO: wine specific fallback to predefined handler could be replaced by normally registering
6331 this handler for all possible types.
6334 if (url_ext
|| mimeW
)
6336 hr
= resolver_create_bytestream_handler(stream
, flags
, mimeW
, url_ext
, handler
);
6339 hr
= resolver_create_gstreamer_handler(handler
);
6342 CoTaskMemFree(mimeW
);
6343 CoTaskMemFree(urlW
);
6348 if (!(flags
& MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE
))
6349 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6351 if (FAILED(hr
= resolver_get_bytestream_url_hint(stream
, &url_ext
)))
6354 hr
= resolver_create_bytestream_handler(stream
, flags
, NULL
, url_ext
, handler
);
6357 hr
= resolver_create_gstreamer_handler(handler
);
6362 static HRESULT
resolver_create_scheme_handler(const WCHAR
*scheme
, DWORD flags
, IMFSchemeHandler
**handler
)
6364 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
6365 HRESULT hr
= MF_E_UNSUPPORTED_SCHEME
;
6368 TRACE("%s, %#lx, %p.\n", debugstr_w(scheme
), flags
, handler
);
6372 if (!(flags
& MF_RESOLUTION_DISABLE_LOCAL_PLUGINS
))
6374 struct local_handler
*local_handler
;
6376 EnterCriticalSection(&local_handlers_section
);
6378 LIST_FOR_EACH_ENTRY(local_handler
, &local_scheme_handlers
, struct local_handler
, entry
)
6380 if (!lstrcmpiW(scheme
, local_handler
->u
.scheme
))
6382 if (SUCCEEDED(hr
= IMFActivate_ActivateObject(local_handler
->activate
, &IID_IMFSchemeHandler
,
6388 LeaveCriticalSection(&local_handlers_section
);
6394 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
6396 HKEY hkey
, hkey_handler
;
6398 hr
= MF_E_UNSUPPORTED_SCHEME
;
6400 if (RegOpenKeyW(hkey_roots
[i
], L
"Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers", &hkey
))
6403 if (!RegOpenKeyW(hkey
, scheme
, &hkey_handler
))
6405 hr
= resolver_create_registered_handler(hkey_handler
, &IID_IMFSchemeHandler
, (void **)handler
);
6406 RegCloseKey(hkey_handler
);
6418 static HRESULT
resolver_get_scheme_handler(const WCHAR
*url
, DWORD flags
, IMFSchemeHandler
**handler
)
6420 static const WCHAR fileschemeW
[] = L
"file:";
6421 const WCHAR
*ptr
= url
;
6426 /* RFC 3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
6429 WCHAR ch
= towlower(*ptr
);
6431 if (*ptr
== '*' && ptr
== url
)
6436 else if (!(*ptr
>= '0' && *ptr
<= '9') &&
6437 !(ch
>= 'a' && ch
<= 'z') &&
6438 *ptr
!= '+' && *ptr
!= '-' && *ptr
!= '.')
6446 /* Schemes must end with a ':', if not found try "file:" */
6447 if (ptr
== url
|| *ptr
!= ':')
6450 len
= ARRAY_SIZE(fileschemeW
) - 1;
6453 len
= ptr
- url
+ 1;
6455 scheme
= malloc((len
+ 1) * sizeof(WCHAR
));
6457 return E_OUTOFMEMORY
;
6459 memcpy(scheme
, url
, len
* sizeof(WCHAR
));
6462 hr
= resolver_create_scheme_handler(scheme
, flags
, handler
);
6463 if (FAILED(hr
) && url
!= fileschemeW
)
6464 hr
= resolver_create_scheme_handler(fileschemeW
, flags
, handler
);
6471 static HRESULT
resolver_end_create_object(struct source_resolver
*resolver
, enum resolved_object_origin origin
,
6472 IRtwqAsyncResult
*result
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**out
)
6474 struct resolver_queued_result
*queued_result
= NULL
, *iter
;
6478 if (FAILED(hr
= IRtwqAsyncResult_GetObject(result
, &object
)))
6481 EnterCriticalSection(&resolver
->cs
);
6483 LIST_FOR_EACH_ENTRY(iter
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6485 if (iter
->inner_result
== result
|| (iter
->object
== object
&& iter
->origin
== origin
))
6487 list_remove(&iter
->entry
);
6488 queued_result
= iter
;
6493 LeaveCriticalSection(&resolver
->cs
);
6495 IUnknown_Release(object
);
6499 *out
= queued_result
->object
;
6500 *obj_type
= queued_result
->obj_type
;
6501 hr
= queued_result
->hr
;
6502 if (queued_result
->inner_result
)
6503 IRtwqAsyncResult_Release(queued_result
->inner_result
);
6504 free(queued_result
);
6512 static HRESULT WINAPI
source_resolver_QueryInterface(IMFSourceResolver
*iface
, REFIID riid
, void **obj
)
6514 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6516 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
6518 if (IsEqualIID(riid
, &IID_IMFSourceResolver
) ||
6519 IsEqualIID(riid
, &IID_IUnknown
))
6521 *obj
= &resolver
->IMFSourceResolver_iface
;
6526 FIXME("unsupported interface %s\n", debugstr_guid(riid
));
6527 return E_NOINTERFACE
;
6530 IUnknown_AddRef((IUnknown
*)*obj
);
6534 static ULONG WINAPI
source_resolver_AddRef(IMFSourceResolver
*iface
)
6536 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6537 ULONG refcount
= InterlockedIncrement(&resolver
->refcount
);
6539 TRACE("%p, refcount %ld.\n", iface
, refcount
);
6544 static ULONG WINAPI
source_resolver_Release(IMFSourceResolver
*iface
)
6546 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6547 ULONG refcount
= InterlockedDecrement(&resolver
->refcount
);
6548 struct resolver_queued_result
*result
, *result2
;
6550 TRACE("%p, refcount %ld.\n", iface
, refcount
);
6554 LIST_FOR_EACH_ENTRY_SAFE(result
, result2
, &resolver
->pending
, struct resolver_queued_result
, entry
)
6557 IUnknown_Release(result
->object
);
6558 list_remove(&result
->entry
);
6561 DeleteCriticalSection(&resolver
->cs
);
6568 static HRESULT WINAPI
source_resolver_CreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6569 DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6571 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6572 IMFSchemeHandler
*handler
;
6573 IRtwqAsyncResult
*result
;
6574 RTWQASYNCRESULT
*data
;
6577 TRACE("%p, %s, %#lx, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6579 if (!url
|| !obj_type
|| !object
)
6582 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6585 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6586 IMFSchemeHandler_Release(handler
);
6590 data
= (RTWQASYNCRESULT
*)result
;
6591 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6593 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, NULL
, (IMFAsyncCallback
*)&resolver
->url_callback
,
6594 (IUnknown
*)result
);
6597 IRtwqAsyncResult_Release(result
);
6601 WaitForSingleObject(data
->hEvent
, INFINITE
);
6603 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_URL
, result
, obj_type
, object
);
6604 IRtwqAsyncResult_Release(result
);
6609 static HRESULT WINAPI
source_resolver_CreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6610 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6612 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6613 IMFByteStreamHandler
*handler
;
6614 IRtwqAsyncResult
*result
;
6615 RTWQASYNCRESULT
*data
;
6618 TRACE("%p, %p, %s, %#lx, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, obj_type
, object
);
6620 if (!stream
|| !obj_type
|| !object
)
6623 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6624 return MF_E_UNSUPPORTED_BYTESTREAM_TYPE
;
6626 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, NULL
, NULL
, &result
);
6627 IMFByteStreamHandler_Release(handler
);
6631 data
= (RTWQASYNCRESULT
*)result
;
6632 data
->hEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6634 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
, NULL
,
6635 (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6638 IRtwqAsyncResult_Release(result
);
6642 WaitForSingleObject(data
->hEvent
, INFINITE
);
6644 hr
= resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, result
, obj_type
, object
);
6645 IRtwqAsyncResult_Release(result
);
6650 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromURL(IMFSourceResolver
*iface
, const WCHAR
*url
,
6651 DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
6653 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6654 IMFSchemeHandler
*handler
;
6655 IUnknown
*inner_cookie
= NULL
;
6656 IRtwqAsyncResult
*result
;
6659 TRACE("%p, %s, %#lx, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
6661 if (FAILED(hr
= resolver_get_scheme_handler(url
, flags
, &handler
)))
6665 *cancel_cookie
= NULL
;
6667 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6668 IMFSchemeHandler_Release(handler
);
6672 hr
= IMFSchemeHandler_BeginCreateObject(handler
, url
, flags
, props
, cancel_cookie
? &inner_cookie
: NULL
,
6673 (IMFAsyncCallback
*)&resolver
->url_callback
, (IUnknown
*)result
);
6675 if (SUCCEEDED(hr
) && inner_cookie
)
6676 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_URL
, inner_cookie
, cancel_cookie
);
6678 IRtwqAsyncResult_Release(result
);
6683 static HRESULT WINAPI
source_resolver_EndCreateObjectFromURL(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6684 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6686 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6688 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6690 return resolver_end_create_object(resolver
, OBJECT_FROM_URL
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6693 static HRESULT WINAPI
source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFByteStream
*stream
,
6694 const WCHAR
*url
, DWORD flags
, IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
,
6697 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6698 IMFByteStreamHandler
*handler
;
6699 IUnknown
*inner_cookie
= NULL
;
6700 IRtwqAsyncResult
*result
;
6703 TRACE("%p, %p, %s, %#lx, %p, %p, %p, %p.\n", iface
, stream
, debugstr_w(url
), flags
, props
, cancel_cookie
,
6706 if (FAILED(hr
= resolver_get_bytestream_handler(stream
, url
, flags
, &handler
)))
6710 *cancel_cookie
= NULL
;
6712 hr
= RtwqCreateAsyncResult((IUnknown
*)handler
, (IRtwqAsyncCallback
*)callback
, state
, &result
);
6713 IMFByteStreamHandler_Release(handler
);
6717 hr
= IMFByteStreamHandler_BeginCreateObject(handler
, stream
, url
, flags
, props
,
6718 cancel_cookie
? &inner_cookie
: NULL
, (IMFAsyncCallback
*)&resolver
->stream_callback
, (IUnknown
*)result
);
6720 /* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */
6721 if (SUCCEEDED(hr
) && inner_cookie
)
6722 resolver_create_cancel_object((IUnknown
*)handler
, OBJECT_FROM_BYTESTREAM
, inner_cookie
, cancel_cookie
);
6724 IRtwqAsyncResult_Release(result
);
6729 static HRESULT WINAPI
source_resolver_EndCreateObjectFromByteStream(IMFSourceResolver
*iface
, IMFAsyncResult
*result
,
6730 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
6732 struct source_resolver
*resolver
= impl_from_IMFSourceResolver(iface
);
6734 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
6736 return resolver_end_create_object(resolver
, OBJECT_FROM_BYTESTREAM
, (IRtwqAsyncResult
*)result
, obj_type
, object
);
6739 static HRESULT WINAPI
source_resolver_CancelObjectCreation(IMFSourceResolver
*iface
, IUnknown
*cancel_cookie
)
6741 struct resolver_cancel_object
*object
;
6744 TRACE("%p, %p.\n", iface
, cancel_cookie
);
6746 if (!(object
= unsafe_impl_cancel_obj_from_IUnknown(cancel_cookie
)))
6747 return E_UNEXPECTED
;
6749 switch (object
->origin
)
6751 case OBJECT_FROM_BYTESTREAM
:
6752 hr
= IMFByteStreamHandler_CancelObjectCreation(object
->u
.stream_handler
, object
->cancel_cookie
);
6754 case OBJECT_FROM_URL
:
6755 hr
= IMFSchemeHandler_CancelObjectCreation(object
->u
.scheme_handler
, object
->cancel_cookie
);
6764 static const IMFSourceResolverVtbl mfsourceresolvervtbl
=
6766 source_resolver_QueryInterface
,
6767 source_resolver_AddRef
,
6768 source_resolver_Release
,
6769 source_resolver_CreateObjectFromURL
,
6770 source_resolver_CreateObjectFromByteStream
,
6771 source_resolver_BeginCreateObjectFromURL
,
6772 source_resolver_EndCreateObjectFromURL
,
6773 source_resolver_BeginCreateObjectFromByteStream
,
6774 source_resolver_EndCreateObjectFromByteStream
,
6775 source_resolver_CancelObjectCreation
,
6778 /***********************************************************************
6779 * MFCreateSourceResolver (mfplat.@)
6781 HRESULT WINAPI
MFCreateSourceResolver(IMFSourceResolver
**resolver
)
6783 struct source_resolver
*object
;
6785 TRACE("%p\n", resolver
);
6790 if (!(object
= calloc(1, sizeof(*object
))))
6791 return E_OUTOFMEMORY
;
6793 object
->IMFSourceResolver_iface
.lpVtbl
= &mfsourceresolvervtbl
;
6794 object
->stream_callback
.lpVtbl
= &source_resolver_callback_stream_vtbl
;
6795 object
->url_callback
.lpVtbl
= &source_resolver_callback_url_vtbl
;
6796 object
->refcount
= 1;
6797 list_init(&object
->pending
);
6798 InitializeCriticalSection(&object
->cs
);
6800 *resolver
= &object
->IMFSourceResolver_iface
;
6807 struct attributes attributes
;
6808 IMFMediaEvent IMFMediaEvent_iface
;
6810 MediaEventType type
;
6816 static inline struct media_event
*impl_from_IMFMediaEvent(IMFMediaEvent
*iface
)
6818 return CONTAINING_RECORD(iface
, struct media_event
, IMFMediaEvent_iface
);
6821 static HRESULT WINAPI
mfmediaevent_QueryInterface(IMFMediaEvent
*iface
, REFIID riid
, void **out
)
6823 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6825 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
6827 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
6828 IsEqualGUID(riid
, &IID_IMFAttributes
) ||
6829 IsEqualGUID(riid
, &IID_IMFMediaEvent
))
6831 *out
= &event
->IMFMediaEvent_iface
;
6835 FIXME("%s, %p.\n", debugstr_guid(riid
), out
);
6837 return E_NOINTERFACE
;
6840 IUnknown_AddRef((IUnknown
*)*out
);
6844 static ULONG WINAPI
mfmediaevent_AddRef(IMFMediaEvent
*iface
)
6846 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6847 ULONG refcount
= InterlockedIncrement(&event
->attributes
.ref
);
6849 TRACE("%p, refcount %lu.\n", iface
, refcount
);
6854 static ULONG WINAPI
mfmediaevent_Release(IMFMediaEvent
*iface
)
6856 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6857 ULONG refcount
= InterlockedDecrement(&event
->attributes
.ref
);
6859 TRACE("%p, refcount %lu.\n", iface
, refcount
);
6863 clear_attributes_object(&event
->attributes
);
6864 PropVariantClear(&event
->value
);
6871 static HRESULT WINAPI
mfmediaevent_GetItem(IMFMediaEvent
*iface
, REFGUID key
, PROPVARIANT
*value
)
6873 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6875 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6877 return attributes_GetItem(&event
->attributes
, key
, value
);
6880 static HRESULT WINAPI
mfmediaevent_GetItemType(IMFMediaEvent
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
6882 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6884 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), type
);
6886 return attributes_GetItemType(&event
->attributes
, key
, type
);
6889 static HRESULT WINAPI
mfmediaevent_CompareItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
6891 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6893 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
), result
);
6895 return attributes_CompareItem(&event
->attributes
, key
, value
, result
);
6898 static HRESULT WINAPI
mfmediaevent_Compare(IMFMediaEvent
*iface
, IMFAttributes
*attrs
, MF_ATTRIBUTES_MATCH_TYPE type
,
6901 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6903 TRACE("%p, %p, %d, %p.\n", iface
, attrs
, type
, result
);
6905 return attributes_Compare(&event
->attributes
, attrs
, type
, result
);
6908 static HRESULT WINAPI
mfmediaevent_GetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*value
)
6910 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6912 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6914 return attributes_GetUINT32(&event
->attributes
, key
, value
);
6917 static HRESULT WINAPI
mfmediaevent_GetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64
*value
)
6919 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6921 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6923 return attributes_GetUINT64(&event
->attributes
, key
, value
);
6926 static HRESULT WINAPI
mfmediaevent_GetDouble(IMFMediaEvent
*iface
, REFGUID key
, double *value
)
6928 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6930 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6932 return attributes_GetDouble(&event
->attributes
, key
, value
);
6935 static HRESULT WINAPI
mfmediaevent_GetGUID(IMFMediaEvent
*iface
, REFGUID key
, GUID
*value
)
6937 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6939 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), value
);
6941 return attributes_GetGUID(&event
->attributes
, key
, value
);
6944 static HRESULT WINAPI
mfmediaevent_GetStringLength(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*length
)
6946 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6948 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), length
);
6950 return attributes_GetStringLength(&event
->attributes
, key
, length
);
6953 static HRESULT WINAPI
mfmediaevent_GetString(IMFMediaEvent
*iface
, REFGUID key
, WCHAR
*value
,
6954 UINT32 size
, UINT32
*length
)
6956 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6958 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), value
, size
, length
);
6960 return attributes_GetString(&event
->attributes
, key
, value
, size
, length
);
6963 static HRESULT WINAPI
mfmediaevent_GetAllocatedString(IMFMediaEvent
*iface
, REFGUID key
,
6964 WCHAR
**value
, UINT32
*length
)
6966 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6968 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), value
, length
);
6970 return attributes_GetAllocatedString(&event
->attributes
, key
, value
, length
);
6973 static HRESULT WINAPI
mfmediaevent_GetBlobSize(IMFMediaEvent
*iface
, REFGUID key
, UINT32
*size
)
6975 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6977 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), size
);
6979 return attributes_GetBlobSize(&event
->attributes
, key
, size
);
6982 static HRESULT WINAPI
mfmediaevent_GetBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
*buf
,
6983 UINT32 bufsize
, UINT32
*blobsize
)
6985 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6987 TRACE("%p, %s, %p, %u, %p.\n", iface
, debugstr_attr(key
), buf
, bufsize
, blobsize
);
6989 return attributes_GetBlob(&event
->attributes
, key
, buf
, bufsize
, blobsize
);
6992 static HRESULT WINAPI
mfmediaevent_GetAllocatedBlob(IMFMediaEvent
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
6994 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
6996 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_attr(key
), buf
, size
);
6998 return attributes_GetAllocatedBlob(&event
->attributes
, key
, buf
, size
);
7001 static HRESULT WINAPI
mfmediaevent_GetUnknown(IMFMediaEvent
*iface
, REFGUID key
, REFIID riid
, void **out
)
7003 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7005 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_attr(key
), debugstr_guid(riid
), out
);
7007 return attributes_GetUnknown(&event
->attributes
, key
, riid
, out
);
7010 static HRESULT WINAPI
mfmediaevent_SetItem(IMFMediaEvent
*iface
, REFGUID key
, REFPROPVARIANT value
)
7012 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7014 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_propvar(value
));
7016 return attributes_SetItem(&event
->attributes
, key
, value
);
7019 static HRESULT WINAPI
mfmediaevent_DeleteItem(IMFMediaEvent
*iface
, REFGUID key
)
7021 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7023 TRACE("%p, %s.\n", iface
, debugstr_attr(key
));
7025 return attributes_DeleteItem(&event
->attributes
, key
);
7028 static HRESULT WINAPI
mfmediaevent_DeleteAllItems(IMFMediaEvent
*iface
)
7030 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7032 TRACE("%p.\n", iface
);
7034 return attributes_DeleteAllItems(&event
->attributes
);
7037 static HRESULT WINAPI
mfmediaevent_SetUINT32(IMFMediaEvent
*iface
, REFGUID key
, UINT32 value
)
7039 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7041 TRACE("%p, %s, %u.\n", iface
, debugstr_attr(key
), value
);
7043 return attributes_SetUINT32(&event
->attributes
, key
, value
);
7046 static HRESULT WINAPI
mfmediaevent_SetUINT64(IMFMediaEvent
*iface
, REFGUID key
, UINT64 value
)
7048 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7050 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), wine_dbgstr_longlong(value
));
7052 return attributes_SetUINT64(&event
->attributes
, key
, value
);
7055 static HRESULT WINAPI
mfmediaevent_SetDouble(IMFMediaEvent
*iface
, REFGUID key
, double value
)
7057 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7059 TRACE("%p, %s, %f.\n", iface
, debugstr_attr(key
), value
);
7061 return attributes_SetDouble(&event
->attributes
, key
, value
);
7064 static HRESULT WINAPI
mfmediaevent_SetGUID(IMFMediaEvent
*iface
, REFGUID key
, REFGUID value
)
7066 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7068 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_mf_guid(value
));
7070 return attributes_SetGUID(&event
->attributes
, key
, value
);
7073 static HRESULT WINAPI
mfmediaevent_SetString(IMFMediaEvent
*iface
, REFGUID key
, const WCHAR
*value
)
7075 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7077 TRACE("%p, %s, %s.\n", iface
, debugstr_attr(key
), debugstr_w(value
));
7079 return attributes_SetString(&event
->attributes
, key
, value
);
7082 static HRESULT WINAPI
mfmediaevent_SetBlob(IMFMediaEvent
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
7084 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7086 TRACE("%p, %s, %p, %u.\n", iface
, debugstr_attr(key
), buf
, size
);
7088 return attributes_SetBlob(&event
->attributes
, key
, buf
, size
);
7091 static HRESULT WINAPI
mfmediaevent_SetUnknown(IMFMediaEvent
*iface
, REFGUID key
, IUnknown
*unknown
)
7093 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7095 TRACE("%p, %s, %p.\n", iface
, debugstr_attr(key
), unknown
);
7097 return attributes_SetUnknown(&event
->attributes
, key
, unknown
);
7100 static HRESULT WINAPI
mfmediaevent_LockStore(IMFMediaEvent
*iface
)
7102 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7104 TRACE("%p.\n", iface
);
7106 return attributes_LockStore(&event
->attributes
);
7109 static HRESULT WINAPI
mfmediaevent_UnlockStore(IMFMediaEvent
*iface
)
7111 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7113 TRACE("%p.\n", iface
);
7115 return attributes_UnlockStore(&event
->attributes
);
7118 static HRESULT WINAPI
mfmediaevent_GetCount(IMFMediaEvent
*iface
, UINT32
*count
)
7120 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7122 TRACE("%p, %p.\n", iface
, count
);
7124 return attributes_GetCount(&event
->attributes
, count
);
7127 static HRESULT WINAPI
mfmediaevent_GetItemByIndex(IMFMediaEvent
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
7129 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7131 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
7133 return attributes_GetItemByIndex(&event
->attributes
, index
, key
, value
);
7136 static HRESULT WINAPI
mfmediaevent_CopyAllItems(IMFMediaEvent
*iface
, IMFAttributes
*dest
)
7138 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7140 TRACE("%p, %p.\n", iface
, dest
);
7142 return attributes_CopyAllItems(&event
->attributes
, dest
);
7145 static HRESULT WINAPI
mfmediaevent_GetType(IMFMediaEvent
*iface
, MediaEventType
*type
)
7147 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7149 TRACE("%p, %p.\n", iface
, type
);
7151 *type
= event
->type
;
7156 static HRESULT WINAPI
mfmediaevent_GetExtendedType(IMFMediaEvent
*iface
, GUID
*extended_type
)
7158 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7160 TRACE("%p, %p.\n", iface
, extended_type
);
7162 *extended_type
= event
->extended_type
;
7167 static HRESULT WINAPI
mfmediaevent_GetStatus(IMFMediaEvent
*iface
, HRESULT
*status
)
7169 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7171 TRACE("%p, %p.\n", iface
, status
);
7173 *status
= event
->status
;
7178 static HRESULT WINAPI
mfmediaevent_GetValue(IMFMediaEvent
*iface
, PROPVARIANT
*value
)
7180 struct media_event
*event
= impl_from_IMFMediaEvent(iface
);
7182 TRACE("%p, %p.\n", iface
, value
);
7184 PropVariantCopy(value
, &event
->value
);
7189 static const IMFMediaEventVtbl mfmediaevent_vtbl
=
7191 mfmediaevent_QueryInterface
,
7192 mfmediaevent_AddRef
,
7193 mfmediaevent_Release
,
7194 mfmediaevent_GetItem
,
7195 mfmediaevent_GetItemType
,
7196 mfmediaevent_CompareItem
,
7197 mfmediaevent_Compare
,
7198 mfmediaevent_GetUINT32
,
7199 mfmediaevent_GetUINT64
,
7200 mfmediaevent_GetDouble
,
7201 mfmediaevent_GetGUID
,
7202 mfmediaevent_GetStringLength
,
7203 mfmediaevent_GetString
,
7204 mfmediaevent_GetAllocatedString
,
7205 mfmediaevent_GetBlobSize
,
7206 mfmediaevent_GetBlob
,
7207 mfmediaevent_GetAllocatedBlob
,
7208 mfmediaevent_GetUnknown
,
7209 mfmediaevent_SetItem
,
7210 mfmediaevent_DeleteItem
,
7211 mfmediaevent_DeleteAllItems
,
7212 mfmediaevent_SetUINT32
,
7213 mfmediaevent_SetUINT64
,
7214 mfmediaevent_SetDouble
,
7215 mfmediaevent_SetGUID
,
7216 mfmediaevent_SetString
,
7217 mfmediaevent_SetBlob
,
7218 mfmediaevent_SetUnknown
,
7219 mfmediaevent_LockStore
,
7220 mfmediaevent_UnlockStore
,
7221 mfmediaevent_GetCount
,
7222 mfmediaevent_GetItemByIndex
,
7223 mfmediaevent_CopyAllItems
,
7224 mfmediaevent_GetType
,
7225 mfmediaevent_GetExtendedType
,
7226 mfmediaevent_GetStatus
,
7227 mfmediaevent_GetValue
,
7230 /***********************************************************************
7231 * MFCreateMediaEvent (mfplat.@)
7233 HRESULT WINAPI
MFCreateMediaEvent(MediaEventType type
, REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
,
7234 IMFMediaEvent
**event
)
7236 struct media_event
*object
;
7239 TRACE("%s, %s, %#lx, %s, %p.\n", debugstr_eventid(type
), debugstr_guid(extended_type
), status
,
7240 debugstr_propvar(value
), event
);
7242 object
= malloc(sizeof(*object
));
7244 return E_OUTOFMEMORY
;
7246 if (FAILED(hr
= init_attributes_object(&object
->attributes
, 0)))
7251 object
->IMFMediaEvent_iface
.lpVtbl
= &mfmediaevent_vtbl
;
7253 object
->type
= type
;
7254 object
->extended_type
= *extended_type
;
7255 object
->status
= status
;
7257 PropVariantInit(&object
->value
);
7259 PropVariantCopy(&object
->value
, value
);
7261 *event
= &object
->IMFMediaEvent_iface
;
7263 TRACE("Created event %p.\n", *event
);
7270 IMFMediaEventQueue IMFMediaEventQueue_iface
;
7273 CRITICAL_SECTION cs
;
7274 CONDITION_VARIABLE update_event
;
7278 IRtwqAsyncResult
*subscriber
;
7284 IMFMediaEvent
*event
;
7287 static inline struct event_queue
*impl_from_IMFMediaEventQueue(IMFMediaEventQueue
*iface
)
7289 return CONTAINING_RECORD(iface
, struct event_queue
, IMFMediaEventQueue_iface
);
7292 static IMFMediaEvent
*queue_pop_event(struct event_queue
*queue
)
7294 struct list
*head
= list_head(&queue
->events
);
7295 struct queued_event
*queued_event
;
7296 IMFMediaEvent
*event
;
7301 queued_event
= LIST_ENTRY(head
, struct queued_event
, entry
);
7302 event
= queued_event
->event
;
7303 list_remove(&queued_event
->entry
);
7308 static void event_queue_clear_subscriber(struct event_queue
*queue
)
7310 if (queue
->subscriber
)
7311 IRtwqAsyncResult_Release(queue
->subscriber
);
7312 queue
->subscriber
= NULL
;
7315 static void event_queue_cleanup(struct event_queue
*queue
)
7317 IMFMediaEvent
*event
;
7319 while ((event
= queue_pop_event(queue
)))
7320 IMFMediaEvent_Release(event
);
7321 event_queue_clear_subscriber(queue
);
7324 static HRESULT WINAPI
eventqueue_QueryInterface(IMFMediaEventQueue
*iface
, REFIID riid
, void **out
)
7326 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7328 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7330 if (IsEqualIID(riid
, &IID_IMFMediaEventQueue
) ||
7331 IsEqualIID(riid
, &IID_IUnknown
))
7333 *out
= &queue
->IMFMediaEventQueue_iface
;
7334 IMFMediaEventQueue_AddRef(iface
);
7338 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7340 return E_NOINTERFACE
;
7343 static ULONG WINAPI
eventqueue_AddRef(IMFMediaEventQueue
*iface
)
7345 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7346 ULONG refcount
= InterlockedIncrement(&queue
->refcount
);
7348 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7353 static ULONG WINAPI
eventqueue_Release(IMFMediaEventQueue
*iface
)
7355 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7356 ULONG refcount
= InterlockedDecrement(&queue
->refcount
);
7358 TRACE("%p, refcount %lu.\n", queue
, refcount
);
7362 event_queue_cleanup(queue
);
7363 DeleteCriticalSection(&queue
->cs
);
7370 static HRESULT WINAPI
eventqueue_GetEvent(IMFMediaEventQueue
*iface
, DWORD flags
, IMFMediaEvent
**event
)
7372 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7375 TRACE("%p, %p.\n", iface
, event
);
7377 EnterCriticalSection(&queue
->cs
);
7379 if (queue
->is_shut_down
)
7381 else if (queue
->subscriber
)
7382 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7385 if (flags
& MF_EVENT_FLAG_NO_WAIT
)
7387 if (!(*event
= queue_pop_event(queue
)))
7388 hr
= MF_E_NO_EVENTS_AVAILABLE
;
7392 while (list_empty(&queue
->events
) && !queue
->is_shut_down
)
7394 SleepConditionVariableCS(&queue
->update_event
, &queue
->cs
, INFINITE
);
7396 *event
= queue_pop_event(queue
);
7397 if (queue
->is_shut_down
)
7402 LeaveCriticalSection(&queue
->cs
);
7407 static void queue_notify_subscriber(struct event_queue
*queue
)
7409 if (list_empty(&queue
->events
) || !queue
->subscriber
|| queue
->notified
)
7412 queue
->notified
= TRUE
;
7413 RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD
, 0, queue
->subscriber
);
7416 static HRESULT WINAPI
eventqueue_BeginGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
7418 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7419 RTWQASYNCRESULT
*result_data
;
7422 TRACE("%p, %p, %p.\n", iface
, callback
, state
);
7425 return E_INVALIDARG
;
7427 EnterCriticalSection(&queue
->cs
);
7429 if (queue
->is_shut_down
)
7431 else if ((result_data
= (RTWQASYNCRESULT
*)queue
->subscriber
))
7433 if (result_data
->pCallback
== (IRtwqAsyncCallback
*)callback
)
7434 hr
= IRtwqAsyncResult_GetStateNoAddRef(queue
->subscriber
) == state
?
7435 MF_S_MULTIPLE_BEGIN
: MF_E_MULTIPLE_BEGIN
;
7437 hr
= MF_E_MULTIPLE_SUBSCRIBERS
;
7441 hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &queue
->subscriber
);
7443 queue_notify_subscriber(queue
);
7446 LeaveCriticalSection(&queue
->cs
);
7451 static HRESULT WINAPI
eventqueue_EndGetEvent(IMFMediaEventQueue
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
7453 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7454 HRESULT hr
= E_FAIL
;
7456 TRACE("%p, %p, %p.\n", iface
, result
, event
);
7458 EnterCriticalSection(&queue
->cs
);
7460 if (queue
->is_shut_down
)
7462 else if (queue
->subscriber
== (IRtwqAsyncResult
*)result
)
7464 *event
= queue_pop_event(queue
);
7465 event_queue_clear_subscriber(queue
);
7466 queue
->notified
= FALSE
;
7467 hr
= *event
? S_OK
: E_FAIL
;
7470 LeaveCriticalSection(&queue
->cs
);
7475 static HRESULT
eventqueue_queue_event(struct event_queue
*queue
, IMFMediaEvent
*event
)
7477 struct queued_event
*queued_event
;
7480 queued_event
= malloc(sizeof(*queued_event
));
7482 return E_OUTOFMEMORY
;
7484 queued_event
->event
= event
;
7486 EnterCriticalSection(&queue
->cs
);
7488 if (queue
->is_shut_down
)
7492 IMFMediaEvent_AddRef(queued_event
->event
);
7493 list_add_tail(&queue
->events
, &queued_event
->entry
);
7494 queue_notify_subscriber(queue
);
7497 LeaveCriticalSection(&queue
->cs
);
7502 WakeAllConditionVariable(&queue
->update_event
);
7507 static HRESULT WINAPI
eventqueue_QueueEvent(IMFMediaEventQueue
*iface
, IMFMediaEvent
*event
)
7509 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7511 TRACE("%p, %p.\n", iface
, event
);
7513 return eventqueue_queue_event(queue
, event
);
7516 static HRESULT WINAPI
eventqueue_QueueEventParamVar(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7517 REFGUID extended_type
, HRESULT status
, const PROPVARIANT
*value
)
7519 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7520 IMFMediaEvent
*event
;
7523 TRACE("%p, %s, %s, %#lx, %s\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
,
7524 debugstr_propvar(value
));
7526 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, value
, &event
)))
7529 hr
= eventqueue_queue_event(queue
, event
);
7530 IMFMediaEvent_Release(event
);
7534 static HRESULT WINAPI
eventqueue_QueueEventParamUnk(IMFMediaEventQueue
*iface
, MediaEventType event_type
,
7535 REFGUID extended_type
, HRESULT status
, IUnknown
*unk
)
7537 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7538 IMFMediaEvent
*event
;
7542 TRACE("%p, %s, %s, %#lx, %p.\n", iface
, debugstr_eventid(event_type
), debugstr_guid(extended_type
), status
, unk
);
7544 value
.vt
= VT_UNKNOWN
;
7545 value
.punkVal
= unk
;
7547 if (FAILED(hr
= MFCreateMediaEvent(event_type
, extended_type
, status
, &value
, &event
)))
7550 hr
= eventqueue_queue_event(queue
, event
);
7551 IMFMediaEvent_Release(event
);
7555 static HRESULT WINAPI
eventqueue_Shutdown(IMFMediaEventQueue
*iface
)
7557 struct event_queue
*queue
= impl_from_IMFMediaEventQueue(iface
);
7559 TRACE("%p\n", queue
);
7561 EnterCriticalSection(&queue
->cs
);
7563 if (!queue
->is_shut_down
)
7565 event_queue_cleanup(queue
);
7566 queue
->is_shut_down
= TRUE
;
7569 LeaveCriticalSection(&queue
->cs
);
7571 WakeAllConditionVariable(&queue
->update_event
);
7576 static const IMFMediaEventQueueVtbl eventqueuevtbl
=
7578 eventqueue_QueryInterface
,
7581 eventqueue_GetEvent
,
7582 eventqueue_BeginGetEvent
,
7583 eventqueue_EndGetEvent
,
7584 eventqueue_QueueEvent
,
7585 eventqueue_QueueEventParamVar
,
7586 eventqueue_QueueEventParamUnk
,
7590 /***********************************************************************
7591 * MFCreateEventQueue (mfplat.@)
7593 HRESULT WINAPI
MFCreateEventQueue(IMFMediaEventQueue
**queue
)
7595 struct event_queue
*object
;
7597 TRACE("%p\n", queue
);
7599 if (!(object
= calloc(1, sizeof(*object
))))
7600 return E_OUTOFMEMORY
;
7602 object
->IMFMediaEventQueue_iface
.lpVtbl
= &eventqueuevtbl
;
7603 object
->refcount
= 1;
7604 list_init(&object
->events
);
7605 InitializeCriticalSection(&object
->cs
);
7606 InitializeConditionVariable(&object
->update_event
);
7608 *queue
= &object
->IMFMediaEventQueue_iface
;
7615 IMFCollection IMFCollection_iface
;
7617 IUnknown
**elements
;
7622 static struct collection
*impl_from_IMFCollection(IMFCollection
*iface
)
7624 return CONTAINING_RECORD(iface
, struct collection
, IMFCollection_iface
);
7627 static void collection_clear(struct collection
*collection
)
7631 for (i
= 0; i
< collection
->count
; ++i
)
7633 if (collection
->elements
[i
])
7634 IUnknown_Release(collection
->elements
[i
]);
7637 free(collection
->elements
);
7638 collection
->elements
= NULL
;
7639 collection
->count
= 0;
7640 collection
->capacity
= 0;
7643 static HRESULT WINAPI
collection_QueryInterface(IMFCollection
*iface
, REFIID riid
, void **out
)
7645 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), out
);
7647 if (IsEqualIID(riid
, &IID_IMFCollection
) ||
7648 IsEqualIID(riid
, &IID_IUnknown
))
7651 IMFCollection_AddRef(iface
);
7655 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
7657 return E_NOINTERFACE
;
7660 static ULONG WINAPI
collection_AddRef(IMFCollection
*iface
)
7662 struct collection
*collection
= impl_from_IMFCollection(iface
);
7663 ULONG refcount
= InterlockedIncrement(&collection
->refcount
);
7665 TRACE("%p, %ld.\n", collection
, refcount
);
7670 static ULONG WINAPI
collection_Release(IMFCollection
*iface
)
7672 struct collection
*collection
= impl_from_IMFCollection(iface
);
7673 ULONG refcount
= InterlockedDecrement(&collection
->refcount
);
7675 TRACE("%p, %ld.\n", collection
, refcount
);
7679 collection_clear(collection
);
7680 free(collection
->elements
);
7687 static HRESULT WINAPI
collection_GetElementCount(IMFCollection
*iface
, DWORD
*count
)
7689 struct collection
*collection
= impl_from_IMFCollection(iface
);
7691 TRACE("%p, %p.\n", iface
, count
);
7696 *count
= collection
->count
;
7701 static HRESULT WINAPI
collection_GetElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7703 struct collection
*collection
= impl_from_IMFCollection(iface
);
7705 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7710 if (idx
>= collection
->count
)
7711 return E_INVALIDARG
;
7713 *element
= collection
->elements
[idx
];
7715 IUnknown_AddRef(*element
);
7717 return *element
? S_OK
: E_UNEXPECTED
;
7720 static HRESULT WINAPI
collection_AddElement(IMFCollection
*iface
, IUnknown
*element
)
7722 struct collection
*collection
= impl_from_IMFCollection(iface
);
7724 TRACE("%p, %p.\n", iface
, element
);
7726 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, collection
->count
+ 1,
7727 sizeof(*collection
->elements
)))
7728 return E_OUTOFMEMORY
;
7730 collection
->elements
[collection
->count
++] = element
;
7732 IUnknown_AddRef(element
);
7737 static HRESULT WINAPI
collection_RemoveElement(IMFCollection
*iface
, DWORD idx
, IUnknown
**element
)
7739 struct collection
*collection
= impl_from_IMFCollection(iface
);
7742 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7747 if (idx
>= collection
->count
)
7748 return E_INVALIDARG
;
7750 *element
= collection
->elements
[idx
];
7752 count
= collection
->count
- idx
- 1;
7754 memmove(&collection
->elements
[idx
], &collection
->elements
[idx
+ 1], count
* sizeof(*collection
->elements
));
7755 collection
->count
--;
7760 static HRESULT WINAPI
collection_InsertElementAt(IMFCollection
*iface
, DWORD idx
, IUnknown
*element
)
7762 struct collection
*collection
= impl_from_IMFCollection(iface
);
7765 TRACE("%p, %lu, %p.\n", iface
, idx
, element
);
7767 if (!mf_array_reserve((void **)&collection
->elements
, &collection
->capacity
, idx
+ 1,
7768 sizeof(*collection
->elements
)))
7769 return E_OUTOFMEMORY
;
7771 if (idx
< collection
->count
)
7773 memmove(&collection
->elements
[idx
+ 1], &collection
->elements
[idx
],
7774 (collection
->count
- idx
) * sizeof(*collection
->elements
));
7775 collection
->count
++;
7779 for (i
= collection
->count
; i
< idx
; ++i
)
7780 collection
->elements
[i
] = NULL
;
7781 collection
->count
= idx
+ 1;
7784 collection
->elements
[idx
] = element
;
7785 if (collection
->elements
[idx
])
7786 IUnknown_AddRef(collection
->elements
[idx
]);
7791 static HRESULT WINAPI
collection_RemoveAllElements(IMFCollection
*iface
)
7793 struct collection
*collection
= impl_from_IMFCollection(iface
);
7795 TRACE("%p.\n", iface
);
7797 collection_clear(collection
);
7802 static const IMFCollectionVtbl mfcollectionvtbl
=
7804 collection_QueryInterface
,
7807 collection_GetElementCount
,
7808 collection_GetElement
,
7809 collection_AddElement
,
7810 collection_RemoveElement
,
7811 collection_InsertElementAt
,
7812 collection_RemoveAllElements
,
7815 /***********************************************************************
7816 * MFCreateCollection (mfplat.@)
7818 HRESULT WINAPI
MFCreateCollection(IMFCollection
**collection
)
7820 struct collection
*object
;
7822 TRACE("%p\n", collection
);
7827 if (!(object
= calloc(1, sizeof(*object
))))
7828 return E_OUTOFMEMORY
;
7830 object
->IMFCollection_iface
.lpVtbl
= &mfcollectionvtbl
;
7831 object
->refcount
= 1;
7833 *collection
= &object
->IMFCollection_iface
;
7838 /***********************************************************************
7839 * MFHeapAlloc (mfplat.@)
7841 void *WINAPI
MFHeapAlloc(SIZE_T size
, ULONG flags
, char *file
, int line
, EAllocationType type
)
7843 TRACE("%Iu, %#lx, %s, %d, %#x.\n", size
, flags
, debugstr_a(file
), line
, type
);
7844 return HeapAlloc(GetProcessHeap(), flags
, size
);
7847 /***********************************************************************
7848 * MFHeapFree (mfplat.@)
7850 void WINAPI
MFHeapFree(void *p
)
7853 HeapFree(GetProcessHeap(), 0, p
);
7856 /***********************************************************************
7857 * MFCreateMFByteStreamOnStreamEx (mfplat.@)
7859 HRESULT WINAPI
MFCreateMFByteStreamOnStreamEx(IUnknown
*stream
, IMFByteStream
**bytestream
)
7861 FIXME("(%p, %p): stub\n", stream
, bytestream
);
7866 static HRESULT WINAPI
system_clock_QueryInterface(IMFClock
*iface
, REFIID riid
, void **obj
)
7868 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7870 if (IsEqualIID(riid
, &IID_IMFClock
) ||
7871 IsEqualIID(riid
, &IID_IUnknown
))
7874 IMFClock_AddRef(iface
);
7878 WARN("Unsupported %s.\n", debugstr_guid(riid
));
7880 return E_NOINTERFACE
;
7883 static ULONG WINAPI
system_clock_AddRef(IMFClock
*iface
)
7885 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7886 ULONG refcount
= InterlockedIncrement(&clock
->refcount
);
7888 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7893 static ULONG WINAPI
system_clock_Release(IMFClock
*iface
)
7895 struct system_clock
*clock
= impl_from_IMFClock(iface
);
7896 ULONG refcount
= InterlockedDecrement(&clock
->refcount
);
7898 TRACE("%p, refcount %lu.\n", iface
, refcount
);
7906 static HRESULT WINAPI
system_clock_GetClockCharacteristics(IMFClock
*iface
, DWORD
*flags
)
7908 TRACE("%p, %p.\n", iface
, flags
);
7910 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING
|
7911 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
7916 static HRESULT WINAPI
system_clock_GetCorrelatedTime(IMFClock
*iface
, DWORD reserved
, LONGLONG
*clock_time
,
7917 MFTIME
*system_time
)
7919 TRACE("%p, %#lx, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
7921 *clock_time
= *system_time
= MFGetSystemTime();
7926 static HRESULT WINAPI
system_clock_GetContinuityKey(IMFClock
*iface
, DWORD
*key
)
7928 TRACE("%p, %p.\n", iface
, key
);
7935 static HRESULT WINAPI
system_clock_GetState(IMFClock
*iface
, DWORD reserved
, MFCLOCK_STATE
*state
)
7937 TRACE("%p, %#lx, %p.\n", iface
, reserved
, state
);
7939 *state
= MFCLOCK_STATE_RUNNING
;
7944 static HRESULT WINAPI
system_clock_GetProperties(IMFClock
*iface
, MFCLOCK_PROPERTIES
*props
)
7946 TRACE("%p, %p.\n", iface
, props
);
7951 memset(props
, 0, sizeof(*props
));
7952 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
7953 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
7954 props
->dwClockJitter
= 1;
7959 static const IMFClockVtbl system_clock_vtbl
=
7961 system_clock_QueryInterface
,
7962 system_clock_AddRef
,
7963 system_clock_Release
,
7964 system_clock_GetClockCharacteristics
,
7965 system_clock_GetCorrelatedTime
,
7966 system_clock_GetContinuityKey
,
7967 system_clock_GetState
,
7968 system_clock_GetProperties
,
7971 static HRESULT
create_system_clock(IMFClock
**clock
)
7973 struct system_clock
*object
;
7975 if (!(object
= malloc(sizeof(*object
))))
7976 return E_OUTOFMEMORY
;
7978 object
->IMFClock_iface
.lpVtbl
= &system_clock_vtbl
;
7979 object
->refcount
= 1;
7981 *clock
= &object
->IMFClock_iface
;
7986 static HRESULT WINAPI
system_time_source_QueryInterface(IMFPresentationTimeSource
*iface
, REFIID riid
, void **obj
)
7988 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
7990 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
7992 if (IsEqualIID(riid
, &IID_IMFPresentationTimeSource
) ||
7993 IsEqualIID(riid
, &IID_IUnknown
))
7995 *obj
= &source
->IMFPresentationTimeSource_iface
;
7997 else if (IsEqualIID(riid
, &IID_IMFClockStateSink
))
7999 *obj
= &source
->IMFClockStateSink_iface
;
8003 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8005 return E_NOINTERFACE
;
8008 IUnknown_AddRef((IUnknown
*)*obj
);
8012 static ULONG WINAPI
system_time_source_AddRef(IMFPresentationTimeSource
*iface
)
8014 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8015 ULONG refcount
= InterlockedIncrement(&source
->refcount
);
8017 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8022 static ULONG WINAPI
system_time_source_Release(IMFPresentationTimeSource
*iface
)
8024 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8025 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
8027 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8032 IMFClock_Release(source
->clock
);
8033 DeleteCriticalSection(&source
->cs
);
8040 static HRESULT WINAPI
system_time_source_GetClockCharacteristics(IMFPresentationTimeSource
*iface
, DWORD
*flags
)
8042 TRACE("%p, %p.\n", iface
, flags
);
8044 *flags
= MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
;
8049 static HRESULT WINAPI
system_time_source_GetCorrelatedTime(IMFPresentationTimeSource
*iface
, DWORD reserved
,
8050 LONGLONG
*clock_time
, MFTIME
*system_time
)
8052 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8055 TRACE("%p, %#lx, %p, %p.\n", iface
, reserved
, clock_time
, system_time
);
8057 EnterCriticalSection(&source
->cs
);
8058 if (SUCCEEDED(hr
= IMFClock_GetCorrelatedTime(source
->clock
, 0, clock_time
, system_time
)))
8060 if (source
->state
== MFCLOCK_STATE_RUNNING
)
8061 system_time_source_update_clock_time(source
, *system_time
);
8062 *clock_time
= source
->start_offset
+ source
->clock_time
;
8064 LeaveCriticalSection(&source
->cs
);
8069 static HRESULT WINAPI
system_time_source_GetContinuityKey(IMFPresentationTimeSource
*iface
, DWORD
*key
)
8071 TRACE("%p, %p.\n", iface
, key
);
8078 static HRESULT WINAPI
system_time_source_GetState(IMFPresentationTimeSource
*iface
, DWORD reserved
,
8079 MFCLOCK_STATE
*state
)
8081 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8083 TRACE("%p, %#lx, %p.\n", iface
, reserved
, state
);
8085 EnterCriticalSection(&source
->cs
);
8086 *state
= source
->state
;
8087 LeaveCriticalSection(&source
->cs
);
8092 static HRESULT WINAPI
system_time_source_GetProperties(IMFPresentationTimeSource
*iface
, MFCLOCK_PROPERTIES
*props
)
8094 TRACE("%p, %p.\n", iface
, props
);
8099 memset(props
, 0, sizeof(*props
));
8100 props
->qwClockFrequency
= MFCLOCK_FREQUENCY_HNS
;
8101 props
->dwClockTolerance
= MFCLOCK_TOLERANCE_UNKNOWN
;
8102 props
->dwClockJitter
= 1;
8107 static HRESULT WINAPI
system_time_source_GetUnderlyingClock(IMFPresentationTimeSource
*iface
, IMFClock
**clock
)
8109 struct system_time_source
*source
= impl_from_IMFPresentationTimeSource(iface
);
8111 TRACE("%p, %p.\n", iface
, clock
);
8113 *clock
= source
->clock
;
8114 IMFClock_AddRef(*clock
);
8119 static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl
=
8121 system_time_source_QueryInterface
,
8122 system_time_source_AddRef
,
8123 system_time_source_Release
,
8124 system_time_source_GetClockCharacteristics
,
8125 system_time_source_GetCorrelatedTime
,
8126 system_time_source_GetContinuityKey
,
8127 system_time_source_GetState
,
8128 system_time_source_GetProperties
,
8129 system_time_source_GetUnderlyingClock
,
8132 static HRESULT WINAPI
system_time_source_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **out
)
8134 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8135 return IMFPresentationTimeSource_QueryInterface(&source
->IMFPresentationTimeSource_iface
, riid
, out
);
8138 static ULONG WINAPI
system_time_source_sink_AddRef(IMFClockStateSink
*iface
)
8140 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8141 return IMFPresentationTimeSource_AddRef(&source
->IMFPresentationTimeSource_iface
);
8144 static ULONG WINAPI
system_time_source_sink_Release(IMFClockStateSink
*iface
)
8146 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8147 return IMFPresentationTimeSource_Release(&source
->IMFPresentationTimeSource_iface
);
8152 CLOCK_CMD_START
= 0,
8159 static HRESULT
system_time_source_change_state(struct system_time_source
*source
, enum clock_command command
)
8161 static const BYTE state_change_is_allowed
[MFCLOCK_STATE_PAUSED
+1][CLOCK_CMD_MAX
] =
8163 /* INVALID */ { 1, 0, 1, 0 },
8164 /* RUNNING */ { 1, 1, 1, 0 },
8165 /* STOPPED */ { 1, 1, 0, 0 },
8166 /* PAUSED */ { 1, 1, 0, 1 },
8168 static const MFCLOCK_STATE states
[CLOCK_CMD_MAX
] =
8170 /* CLOCK_CMD_START */ MFCLOCK_STATE_RUNNING
,
8171 /* CLOCK_CMD_STOP */ MFCLOCK_STATE_STOPPED
,
8172 /* CLOCK_CMD_PAUSE */ MFCLOCK_STATE_PAUSED
,
8173 /* CLOCK_CMD_RESTART */ MFCLOCK_STATE_RUNNING
,
8176 /* Special case that go against usual state change vs return value behavior. */
8177 if (source
->state
== MFCLOCK_STATE_INVALID
&& command
== CLOCK_CMD_STOP
)
8180 if (!state_change_is_allowed
[source
->state
][command
])
8181 return MF_E_INVALIDREQUEST
;
8183 source
->state
= states
[command
];
8188 static HRESULT WINAPI
system_time_source_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
,
8189 LONGLONG start_offset
)
8191 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8192 MFCLOCK_STATE state
;
8195 TRACE("%p, %s, %s.\n", iface
, debugstr_time(system_time
), debugstr_time(start_offset
));
8197 EnterCriticalSection(&source
->cs
);
8198 state
= source
->state
;
8199 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_START
)))
8201 if (start_offset
== PRESENTATION_CURRENT_POSITION
)
8203 if (state
!= MFCLOCK_STATE_RUNNING
)
8205 source
->start_offset
-= system_time
;
8206 source
->system_time
= 0;
8211 source
->start_offset
= start_offset
;
8212 source
->system_time
= system_time
;
8213 source
->clock_time
= 0;
8216 LeaveCriticalSection(&source
->cs
);
8221 static HRESULT WINAPI
system_time_source_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
8223 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8226 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8228 EnterCriticalSection(&source
->cs
);
8229 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_STOP
)))
8231 source
->start_offset
= source
->system_time
= source
->clock_time
= 0;
8233 LeaveCriticalSection(&source
->cs
);
8238 static HRESULT WINAPI
system_time_source_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
8240 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8243 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8245 EnterCriticalSection(&source
->cs
);
8246 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_PAUSE
)))
8248 system_time_source_update_clock_time(source
, system_time
);
8250 LeaveCriticalSection(&source
->cs
);
8255 static HRESULT WINAPI
system_time_source_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
8257 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8260 TRACE("%p, %s.\n", iface
, debugstr_time(system_time
));
8262 EnterCriticalSection(&source
->cs
);
8263 if (SUCCEEDED(hr
= system_time_source_change_state(source
, CLOCK_CMD_RESTART
)))
8265 source
->system_time
= system_time
;
8267 LeaveCriticalSection(&source
->cs
);
8272 static HRESULT WINAPI
system_time_source_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
8274 struct system_time_source
*source
= impl_from_IMFClockStateSink(iface
);
8277 TRACE("%p, %s, %f.\n", iface
, debugstr_time(system_time
), rate
);
8280 return MF_E_UNSUPPORTED_RATE
;
8282 modf(rate
, &intpart
);
8284 EnterCriticalSection(&source
->cs
);
8285 source
->rate
= rate
;
8286 source
->i_rate
= rate
== intpart
? rate
: 0;
8287 LeaveCriticalSection(&source
->cs
);
8292 static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl
=
8294 system_time_source_sink_QueryInterface
,
8295 system_time_source_sink_AddRef
,
8296 system_time_source_sink_Release
,
8297 system_time_source_sink_OnClockStart
,
8298 system_time_source_sink_OnClockStop
,
8299 system_time_source_sink_OnClockPause
,
8300 system_time_source_sink_OnClockRestart
,
8301 system_time_source_sink_OnClockSetRate
,
8304 /***********************************************************************
8305 * MFCreateSystemTimeSource (mfplat.@)
8307 HRESULT WINAPI
MFCreateSystemTimeSource(IMFPresentationTimeSource
**time_source
)
8309 struct system_time_source
*object
;
8312 TRACE("%p.\n", time_source
);
8314 object
= calloc(1, sizeof(*object
));
8316 return E_OUTOFMEMORY
;
8318 object
->IMFPresentationTimeSource_iface
.lpVtbl
= &systemtimesourcevtbl
;
8319 object
->IMFClockStateSink_iface
.lpVtbl
= &systemtimesourcesinkvtbl
;
8320 object
->refcount
= 1;
8321 object
->rate
= 1.0f
;
8323 InitializeCriticalSection(&object
->cs
);
8325 if (FAILED(hr
= create_system_clock(&object
->clock
)))
8327 IMFPresentationTimeSource_Release(&object
->IMFPresentationTimeSource_iface
);
8331 *time_source
= &object
->IMFPresentationTimeSource_iface
;
8336 struct async_create_file
8338 IRtwqAsyncCallback IRtwqAsyncCallback_iface
;
8340 MF_FILE_ACCESSMODE access_mode
;
8341 MF_FILE_OPENMODE open_mode
;
8342 MF_FILE_FLAGS flags
;
8346 struct async_create_file_result
8349 IRtwqAsyncResult
*result
;
8350 IMFByteStream
*stream
;
8353 static struct list async_create_file_results
= LIST_INIT(async_create_file_results
);
8354 static CRITICAL_SECTION async_create_file_cs
= { NULL
, -1, 0, 0, 0, 0 };
8356 static struct async_create_file
*impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback
*iface
)
8358 return CONTAINING_RECORD(iface
, struct async_create_file
, IRtwqAsyncCallback_iface
);
8361 static HRESULT WINAPI
async_create_file_callback_QueryInterface(IRtwqAsyncCallback
*iface
, REFIID riid
, void **obj
)
8363 if (IsEqualIID(riid
, &IID_IRtwqAsyncCallback
) ||
8364 IsEqualIID(riid
, &IID_IUnknown
))
8367 IRtwqAsyncCallback_AddRef(iface
);
8372 return E_NOINTERFACE
;
8375 static ULONG WINAPI
async_create_file_callback_AddRef(IRtwqAsyncCallback
*iface
)
8377 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8378 ULONG refcount
= InterlockedIncrement(&async
->refcount
);
8380 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8385 static ULONG WINAPI
async_create_file_callback_Release(IRtwqAsyncCallback
*iface
)
8387 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8388 ULONG refcount
= InterlockedDecrement(&async
->refcount
);
8390 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8401 static HRESULT WINAPI
async_create_file_callback_GetParameters(IRtwqAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
8406 static HRESULT WINAPI
async_create_file_callback_Invoke(IRtwqAsyncCallback
*iface
, IRtwqAsyncResult
*result
)
8408 struct async_create_file
*async
= impl_from_create_file_IRtwqAsyncCallback(iface
);
8409 IRtwqAsyncResult
*caller
;
8410 IMFByteStream
*stream
;
8413 caller
= (IRtwqAsyncResult
*)IRtwqAsyncResult_GetStateNoAddRef(result
);
8415 hr
= MFCreateFile(async
->access_mode
, async
->open_mode
, async
->flags
, async
->path
, &stream
);
8418 struct async_create_file_result
*result_item
;
8420 result_item
= malloc(sizeof(*result_item
));
8423 result_item
->result
= caller
;
8424 IRtwqAsyncResult_AddRef(caller
);
8425 result_item
->stream
= stream
;
8426 IMFByteStream_AddRef(stream
);
8428 EnterCriticalSection(&async_create_file_cs
);
8429 list_add_tail(&async_create_file_results
, &result_item
->entry
);
8430 LeaveCriticalSection(&async_create_file_cs
);
8433 IMFByteStream_Release(stream
);
8436 IRtwqAsyncResult_SetStatus(caller
, hr
);
8438 RtwqInvokeCallback(caller
);
8443 static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl
=
8445 async_create_file_callback_QueryInterface
,
8446 async_create_file_callback_AddRef
,
8447 async_create_file_callback_Release
,
8448 async_create_file_callback_GetParameters
,
8449 async_create_file_callback_Invoke
,
8452 /***********************************************************************
8453 * MFBeginCreateFile (mfplat.@)
8455 HRESULT WINAPI
MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode
, MF_FILE_OPENMODE open_mode
, MF_FILE_FLAGS flags
,
8456 const WCHAR
*path
, IMFAsyncCallback
*callback
, IUnknown
*state
, IUnknown
**cancel_cookie
)
8458 struct async_create_file
*async
= NULL
;
8459 IRtwqAsyncResult
*caller
, *item
= NULL
;
8462 TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode
, open_mode
, flags
, debugstr_w(path
), callback
, state
,
8466 *cancel_cookie
= NULL
;
8468 if (FAILED(hr
= RtwqCreateAsyncResult(NULL
, (IRtwqAsyncCallback
*)callback
, state
, &caller
)))
8471 if (!(async
= malloc(sizeof(*async
))))
8477 async
->IRtwqAsyncCallback_iface
.lpVtbl
= &async_create_file_callback_vtbl
;
8478 async
->refcount
= 1;
8479 async
->access_mode
= access_mode
;
8480 async
->open_mode
= open_mode
;
8481 async
->flags
= flags
;
8482 if (!(async
->path
= wcsdup(path
)))
8488 hr
= RtwqCreateAsyncResult(NULL
, &async
->IRtwqAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
8494 *cancel_cookie
= (IUnknown
*)caller
;
8495 IUnknown_AddRef(*cancel_cookie
);
8498 hr
= RtwqInvokeCallback(item
);
8502 IRtwqAsyncCallback_Release(&async
->IRtwqAsyncCallback_iface
);
8504 IRtwqAsyncResult_Release(item
);
8506 IRtwqAsyncResult_Release(caller
);
8511 static HRESULT
async_create_file_pull_result(IUnknown
*unk
, IMFByteStream
**stream
)
8513 struct async_create_file_result
*item
;
8514 HRESULT hr
= MF_E_UNEXPECTED
;
8515 IRtwqAsyncResult
*result
;
8519 if (FAILED(IUnknown_QueryInterface(unk
, &IID_IRtwqAsyncResult
, (void **)&result
)))
8522 EnterCriticalSection(&async_create_file_cs
);
8524 LIST_FOR_EACH_ENTRY(item
, &async_create_file_results
, struct async_create_file_result
, entry
)
8526 if (result
== item
->result
)
8528 *stream
= item
->stream
;
8529 IRtwqAsyncResult_Release(item
->result
);
8530 list_remove(&item
->entry
);
8536 LeaveCriticalSection(&async_create_file_cs
);
8539 hr
= IRtwqAsyncResult_GetStatus(result
);
8541 IRtwqAsyncResult_Release(result
);
8546 /***********************************************************************
8547 * MFEndCreateFile (mfplat.@)
8549 HRESULT WINAPI
MFEndCreateFile(IMFAsyncResult
*result
, IMFByteStream
**stream
)
8551 TRACE("%p, %p.\n", result
, stream
);
8553 return async_create_file_pull_result((IUnknown
*)result
, stream
);
8556 /***********************************************************************
8557 * MFCancelCreateFile (mfplat.@)
8559 HRESULT WINAPI
MFCancelCreateFile(IUnknown
*cancel_cookie
)
8561 IMFByteStream
*stream
= NULL
;
8564 TRACE("%p.\n", cancel_cookie
);
8566 hr
= async_create_file_pull_result(cancel_cookie
, &stream
);
8569 IMFByteStream_Release(stream
);
8574 /***********************************************************************
8575 * MFRegisterLocalSchemeHandler (mfplat.@)
8577 HRESULT WINAPI
MFRegisterLocalSchemeHandler(const WCHAR
*scheme
, IMFActivate
*activate
)
8579 struct local_handler
*handler
;
8581 TRACE("%s, %p.\n", debugstr_w(scheme
), activate
);
8583 if (!scheme
|| !activate
)
8584 return E_INVALIDARG
;
8586 if (!(handler
= malloc(sizeof(*handler
))))
8587 return E_OUTOFMEMORY
;
8589 if (!(handler
->u
.scheme
= wcsdup(scheme
)))
8592 return E_OUTOFMEMORY
;
8594 handler
->activate
= activate
;
8595 IMFActivate_AddRef(handler
->activate
);
8597 EnterCriticalSection(&local_handlers_section
);
8598 list_add_head(&local_scheme_handlers
, &handler
->entry
);
8599 LeaveCriticalSection(&local_handlers_section
);
8604 /***********************************************************************
8605 * MFRegisterLocalByteStreamHandler (mfplat.@)
8607 HRESULT WINAPI
MFRegisterLocalByteStreamHandler(const WCHAR
*extension
, const WCHAR
*mime
, IMFActivate
*activate
)
8609 struct local_handler
*handler
;
8611 TRACE("%s, %s, %p.\n", debugstr_w(extension
), debugstr_w(mime
), activate
);
8613 if ((!extension
&& !mime
) || !activate
)
8614 return E_INVALIDARG
;
8616 if (!(handler
= calloc(1, sizeof(*handler
))))
8617 return E_OUTOFMEMORY
;
8619 if (extension
&& !(handler
->u
.bytestream
.extension
= wcsdup(extension
)))
8621 if (mime
&& !(handler
->u
.bytestream
.mime
= wcsdup(mime
)))
8624 EnterCriticalSection(&local_handlers_section
);
8625 list_add_head(&local_bytestream_handlers
, &handler
->entry
);
8626 LeaveCriticalSection(&local_handlers_section
);
8631 free(handler
->u
.bytestream
.extension
);
8632 free(handler
->u
.bytestream
.mime
);
8635 return E_OUTOFMEMORY
;
8638 struct property_store
8640 IPropertyStore IPropertyStore_iface
;
8642 CRITICAL_SECTION cs
;
8643 size_t count
, capacity
;
8651 static struct property_store
*impl_from_IPropertyStore(IPropertyStore
*iface
)
8653 return CONTAINING_RECORD(iface
, struct property_store
, IPropertyStore_iface
);
8656 static HRESULT WINAPI
property_store_QueryInterface(IPropertyStore
*iface
, REFIID riid
, void **obj
)
8658 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8660 if (IsEqualIID(riid
, &IID_IPropertyStore
) || IsEqualIID(riid
, &IID_IUnknown
))
8663 IPropertyStore_AddRef(iface
);
8668 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
8669 return E_NOINTERFACE
;
8672 static ULONG WINAPI
property_store_AddRef(IPropertyStore
*iface
)
8674 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8675 ULONG refcount
= InterlockedIncrement(&store
->refcount
);
8677 TRACE("%p, refcount %ld.\n", iface
, refcount
);
8682 static ULONG WINAPI
property_store_Release(IPropertyStore
*iface
)
8684 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8685 ULONG refcount
= InterlockedDecrement(&store
->refcount
);
8687 TRACE("%p, refcount %ld.\n", iface
, refcount
);
8691 DeleteCriticalSection(&store
->cs
);
8692 free(store
->values
);
8699 static HRESULT WINAPI
property_store_GetCount(IPropertyStore
*iface
, DWORD
*count
)
8701 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8703 TRACE("%p, %p.\n", iface
, count
);
8706 return E_INVALIDARG
;
8708 EnterCriticalSection(&store
->cs
);
8709 *count
= store
->count
;
8710 LeaveCriticalSection(&store
->cs
);
8714 static HRESULT WINAPI
property_store_GetAt(IPropertyStore
*iface
, DWORD index
, PROPERTYKEY
*key
)
8716 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8718 TRACE("%p, %lu, %p.\n", iface
, index
, key
);
8720 EnterCriticalSection(&store
->cs
);
8722 if (index
>= store
->count
)
8724 LeaveCriticalSection(&store
->cs
);
8725 return E_INVALIDARG
;
8728 *key
= store
->values
[index
].key
;
8730 LeaveCriticalSection(&store
->cs
);
8734 static HRESULT WINAPI
property_store_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
8736 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8739 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8742 return E_INVALIDARG
;
8747 EnterCriticalSection(&store
->cs
);
8749 for (i
= 0; i
< store
->count
; ++i
)
8751 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8753 PropVariantCopy(value
, &store
->values
[i
].value
);
8754 LeaveCriticalSection(&store
->cs
);
8759 LeaveCriticalSection(&store
->cs
);
8763 static HRESULT WINAPI
property_store_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
8765 struct property_store
*store
= impl_from_IPropertyStore(iface
);
8768 TRACE("%p, %p, %p.\n", iface
, key
, value
);
8770 EnterCriticalSection(&store
->cs
);
8772 for (i
= 0; i
< store
->count
; ++i
)
8774 if (!memcmp(key
, &store
->values
[i
].key
, sizeof(PROPERTYKEY
)))
8776 PropVariantCopy(&store
->values
[i
].value
, value
);
8777 LeaveCriticalSection(&store
->cs
);
8782 if (!mf_array_reserve((void **)&store
->values
, &store
->capacity
, store
->count
+ 1, sizeof(*store
->values
)))
8784 LeaveCriticalSection(&store
->cs
);
8785 return E_OUTOFMEMORY
;
8788 store
->values
[store
->count
].key
= *key
;
8789 PropVariantCopy(&store
->values
[store
->count
].value
, value
);
8792 LeaveCriticalSection(&store
->cs
);
8796 static HRESULT WINAPI
property_store_Commit(IPropertyStore
*iface
)
8798 TRACE("%p.\n", iface
);
8803 static const IPropertyStoreVtbl property_store_vtbl
=
8805 property_store_QueryInterface
,
8806 property_store_AddRef
,
8807 property_store_Release
,
8808 property_store_GetCount
,
8809 property_store_GetAt
,
8810 property_store_GetValue
,
8811 property_store_SetValue
,
8812 property_store_Commit
,
8815 /***********************************************************************
8816 * CreatePropertyStore (mfplat.@)
8818 HRESULT WINAPI
CreatePropertyStore(IPropertyStore
**store
)
8820 struct property_store
*object
;
8822 TRACE("%p.\n", store
);
8825 return E_INVALIDARG
;
8827 if (!(object
= calloc(1, sizeof(*object
))))
8828 return E_OUTOFMEMORY
;
8830 object
->IPropertyStore_iface
.lpVtbl
= &property_store_vtbl
;
8831 object
->refcount
= 1;
8832 InitializeCriticalSection(&object
->cs
);
8834 TRACE("Created store %p.\n", object
);
8835 *store
= &object
->IPropertyStore_iface
;
8840 struct shared_dxgi_manager
8842 IMFDXGIDeviceManager
*manager
;
8847 static struct shared_dxgi_manager shared_dm
;
8848 static CRITICAL_SECTION shared_dm_cs
= { NULL
, -1, 0, 0, 0, 0 };
8850 enum dxgi_device_handle_flags
8852 DXGI_DEVICE_HANDLE_FLAG_OPEN
= 0x1,
8853 DXGI_DEVICE_HANDLE_FLAG_INVALID
= 0x2,
8854 DXGI_DEVICE_HANDLE_FLAG_LOCKED
= 0x4,
8857 struct dxgi_device_manager
8859 IMFDXGIDeviceManager IMFDXGIDeviceManager_iface
;
8864 unsigned int *handles
;
8869 unsigned int locking_tid
;
8871 CRITICAL_SECTION cs
;
8872 CONDITION_VARIABLE lock
;
8875 static struct dxgi_device_manager
*impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager
*iface
)
8877 return CONTAINING_RECORD(iface
, struct dxgi_device_manager
, IMFDXGIDeviceManager_iface
);
8880 static HRESULT
dxgi_device_manager_get_handle_index(struct dxgi_device_manager
*manager
, HANDLE hdevice
, size_t *idx
)
8882 if (!hdevice
|| hdevice
> ULongToHandle(manager
->count
))
8884 *idx
= (ULONG_PTR
)hdevice
- 1;
8888 static HRESULT WINAPI
dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager
*iface
, REFIID riid
, void **obj
)
8890 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
8892 if (IsEqualIID(riid
, &IID_IMFDXGIDeviceManager
) ||
8893 IsEqualGUID(riid
, &IID_IUnknown
))
8896 IMFDXGIDeviceManager_AddRef(iface
);
8900 WARN("Unsupported %s.\n", debugstr_guid(riid
));
8902 return E_NOINTERFACE
;
8905 static ULONG WINAPI
dxgi_device_manager_AddRef(IMFDXGIDeviceManager
*iface
)
8907 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8908 ULONG refcount
= InterlockedIncrement(&manager
->refcount
);
8910 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8915 static ULONG WINAPI
dxgi_device_manager_Release(IMFDXGIDeviceManager
*iface
)
8917 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8918 ULONG refcount
= InterlockedDecrement(&manager
->refcount
);
8920 TRACE("%p, refcount %lu.\n", iface
, refcount
);
8924 if (manager
->device
)
8925 IUnknown_Release(manager
->device
);
8926 DeleteCriticalSection(&manager
->cs
);
8927 free(manager
->handles
);
8934 static void dxgi_device_manager_lock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8936 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
)
8939 manager
->handles
[idx
] |= DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8943 static void dxgi_device_manager_unlock_handle(struct dxgi_device_manager
*manager
, size_t idx
)
8945 if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
))
8948 manager
->handles
[idx
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
8949 if (!--manager
->locks
)
8950 manager
->locking_tid
= 0;
8953 static HRESULT WINAPI
dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
8955 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8959 TRACE("%p, %p.\n", iface
, hdevice
);
8961 EnterCriticalSection(&manager
->cs
);
8963 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8965 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
8967 dxgi_device_manager_unlock_handle(manager
, idx
);
8968 manager
->handles
[idx
] = 0;
8969 if (idx
== manager
->count
- 1)
8976 LeaveCriticalSection(&manager
->cs
);
8978 WakeAllConditionVariable(&manager
->lock
);
8983 static HRESULT WINAPI
dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
8984 REFIID riid
, void **service
)
8986 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
8990 TRACE("%p, %p, %s, %p.\n", iface
, hdevice
, debugstr_guid(riid
), service
);
8992 EnterCriticalSection(&manager
->cs
);
8994 if (!manager
->device
)
8995 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
8996 else if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
8998 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
8999 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9000 else if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
)
9001 hr
= IUnknown_QueryInterface(manager
->device
, riid
, service
);
9006 LeaveCriticalSection(&manager
->cs
);
9011 static HRESULT WINAPI
dxgi_device_manager_LockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
9012 REFIID riid
, void **obj
, BOOL block
)
9014 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9018 TRACE("%p, %p, %s, %p, %d.\n", iface
, hdevice
, wine_dbgstr_guid(riid
), obj
, block
);
9020 EnterCriticalSection(&manager
->cs
);
9022 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9024 if (!manager
->device
)
9026 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
9028 else if (manager
->locking_tid
== GetCurrentThreadId())
9030 if (SUCCEEDED(hr
= IUnknown_QueryInterface(manager
->device
, riid
, obj
)))
9031 dxgi_device_manager_lock_handle(manager
, idx
);
9033 else if (manager
->locking_tid
&& !block
)
9035 hr
= MF_E_DXGI_VIDEO_DEVICE_LOCKED
;
9039 while (manager
->locking_tid
)
9041 SleepConditionVariableCS(&manager
->lock
, &manager
->cs
, INFINITE
);
9044 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9046 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
9047 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9048 else if (SUCCEEDED(hr
= IUnknown_QueryInterface(manager
->device
, riid
, obj
)))
9050 manager
->locking_tid
= GetCurrentThreadId();
9051 dxgi_device_manager_lock_handle(manager
, idx
);
9057 LeaveCriticalSection(&manager
->cs
);
9062 static HRESULT WINAPI
dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager
*iface
, HANDLE
*hdevice
)
9064 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9068 TRACE("%p, %p.\n", iface
, hdevice
);
9072 EnterCriticalSection(&manager
->cs
);
9074 if (!manager
->device
)
9075 hr
= MF_E_DXGI_DEVICE_NOT_INITIALIZED
;
9078 for (i
= 0; i
< manager
->count
; ++i
)
9080 if (!(manager
->handles
[i
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
9082 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_OPEN
;
9083 *hdevice
= ULongToHandle(i
+ 1);
9088 if (mf_array_reserve((void **)&manager
->handles
, &manager
->capacity
, manager
->count
+ 1,
9089 sizeof(*manager
->handles
)))
9091 *hdevice
= ULongToHandle(manager
->count
+ 1);
9092 manager
->handles
[manager
->count
++] = DXGI_DEVICE_HANDLE_FLAG_OPEN
;
9098 LeaveCriticalSection(&manager
->cs
);
9103 static HRESULT WINAPI
dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager
*iface
, IUnknown
*device
, UINT token
)
9105 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9106 IUnknown
*d3d_device
;
9109 TRACE("%p, %p, %u.\n", iface
, device
, token
);
9111 if (!device
|| token
!= manager
->token
)
9112 return E_INVALIDARG
;
9114 if (FAILED(IUnknown_QueryInterface(device
, &IID_ID3D11Device
, (void **)&d3d_device
)))
9116 if (FAILED(IUnknown_QueryInterface(device
, &IID_ID3D12Device
, (void **)&d3d_device
)))
9118 WARN("Unsupported device interface.\n");
9119 return E_INVALIDARG
;
9123 EnterCriticalSection(&manager
->cs
);
9125 if (manager
->device
)
9127 for (i
= 0; i
< manager
->count
; ++i
)
9129 manager
->handles
[i
] |= DXGI_DEVICE_HANDLE_FLAG_INVALID
;
9130 manager
->handles
[i
] &= ~DXGI_DEVICE_HANDLE_FLAG_LOCKED
;
9132 manager
->locking_tid
= 0;
9134 IUnknown_Release(manager
->device
);
9136 manager
->device
= d3d_device
;
9138 LeaveCriticalSection(&manager
->cs
);
9140 WakeAllConditionVariable(&manager
->lock
);
9145 static HRESULT WINAPI
dxgi_device_manager_TestDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
)
9147 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9151 TRACE("%p, %p.\n", iface
, hdevice
);
9153 EnterCriticalSection(&manager
->cs
);
9155 if (SUCCEEDED(hr
= dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9157 if (manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_INVALID
)
9158 hr
= MF_E_DXGI_NEW_VIDEO_DEVICE
;
9159 else if (!(manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_OPEN
))
9163 LeaveCriticalSection(&manager
->cs
);
9168 static HRESULT WINAPI
dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager
*iface
, HANDLE hdevice
,
9171 struct dxgi_device_manager
*manager
= impl_from_IMFDXGIDeviceManager(iface
);
9172 HRESULT hr
= E_FAIL
;
9175 TRACE("%p, %p, %d.\n", iface
, hdevice
, savestate
);
9177 EnterCriticalSection(&manager
->cs
);
9179 if (SUCCEEDED(dxgi_device_manager_get_handle_index(manager
, hdevice
, &idx
)))
9181 hr
= manager
->handles
[idx
] & DXGI_DEVICE_HANDLE_FLAG_LOCKED
? S_OK
: E_INVALIDARG
;
9183 dxgi_device_manager_unlock_handle(manager
, idx
);
9186 LeaveCriticalSection(&manager
->cs
);
9188 WakeAllConditionVariable(&manager
->lock
);
9193 static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl
=
9195 dxgi_device_manager_QueryInterface
,
9196 dxgi_device_manager_AddRef
,
9197 dxgi_device_manager_Release
,
9198 dxgi_device_manager_CloseDeviceHandle
,
9199 dxgi_device_manager_GetVideoService
,
9200 dxgi_device_manager_LockDevice
,
9201 dxgi_device_manager_OpenDeviceHandle
,
9202 dxgi_device_manager_ResetDevice
,
9203 dxgi_device_manager_TestDevice
,
9204 dxgi_device_manager_UnlockDevice
,
9207 /***********************************************************************
9208 * MFCreateDXGIDeviceManager (mfplat.@)
9210 HRESULT WINAPI
MFCreateDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
9212 struct dxgi_device_manager
*object
;
9214 TRACE("%p, %p.\n", token
, manager
);
9216 if (!token
|| !manager
)
9219 if (!(object
= calloc(1, sizeof(*object
))))
9220 return E_OUTOFMEMORY
;
9222 object
->IMFDXGIDeviceManager_iface
.lpVtbl
= &dxgi_device_manager_vtbl
;
9223 object
->refcount
= 1;
9224 object
->token
= GetTickCount();
9225 InitializeCriticalSection(&object
->cs
);
9226 InitializeConditionVariable(&object
->lock
);
9228 TRACE("Created device manager: %p, token: %u.\n", object
, object
->token
);
9230 *token
= object
->token
;
9231 *manager
= &object
->IMFDXGIDeviceManager_iface
;
9236 /***********************************************************************
9237 * MFLockDXGIDeviceManager (mfplat.@)
9239 HRESULT WINAPI
MFLockDXGIDeviceManager(UINT
*token
, IMFDXGIDeviceManager
**manager
)
9243 TRACE("%p, %p.\n", token
, manager
);
9245 EnterCriticalSection(&shared_dm_cs
);
9247 if (!shared_dm
.manager
)
9248 hr
= MFCreateDXGIDeviceManager(&shared_dm
.token
, &shared_dm
.manager
);
9252 *manager
= shared_dm
.manager
;
9253 IMFDXGIDeviceManager_AddRef(*manager
);
9256 if (token
) *token
= shared_dm
.token
;
9259 LeaveCriticalSection(&shared_dm_cs
);
9264 /***********************************************************************
9265 * MFUnlockDXGIDeviceManager (mfplat.@)
9267 HRESULT WINAPI
MFUnlockDXGIDeviceManager(void)
9271 EnterCriticalSection(&shared_dm_cs
);
9273 if (shared_dm
.manager
)
9275 IMFDXGIDeviceManager_Release(shared_dm
.manager
);
9276 if (!--shared_dm
.locks
)
9278 shared_dm
.manager
= NULL
;
9279 shared_dm
.token
= 0;
9283 LeaveCriticalSection(&shared_dm_cs
);
9290 * MFllMulDiv implementation is derived from gstreamer utility functions code (gstutils.c),
9291 * released under LGPL2. Full authors list follows.
9292 * ===================================================================================
9293 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
9294 * 2000 Wim Taymans <wtay@chello.be>
9295 * 2002 Thomas Vander Stichele <thomas@apestaart.org>
9296 * 2004 Wim Taymans <wim@fluendo.com>
9297 * 2015 Jan Schmidt <jan@centricular.com>
9298 * ===================================================================================
9301 static void llmult128(ULARGE_INTEGER
*c1
, ULARGE_INTEGER
*c0
, LONGLONG val
, LONGLONG num
)
9303 ULARGE_INTEGER a1
, b0
, v
, n
;
9305 v
.QuadPart
= llabs(val
);
9306 n
.QuadPart
= llabs(num
);
9308 /* do 128 bits multiply
9316 * -------------------
9319 * "a0" is optimized away, result is stored directly in c0. "b1" is
9320 * optimized away, result is stored directly in c1.
9322 c0
->QuadPart
= (ULONGLONG
)v
.LowPart
* n
.LowPart
;
9323 a1
.QuadPart
= (ULONGLONG
)v
.LowPart
* n
.HighPart
;
9324 b0
.QuadPart
= (ULONGLONG
)v
.HighPart
* n
.LowPart
;
9326 /* add the high word of a0 to the low words of a1 and b0 using c1 as
9327 * scratch space to capture the carry. the low word of the result becomes
9328 * the final high word of c0 */
9329 c1
->QuadPart
= (ULONGLONG
)c0
->HighPart
+ a1
.LowPart
+ b0
.LowPart
;
9330 c0
->HighPart
= c1
->LowPart
;
9332 /* add the carry from the result above (found in the high word of c1) and
9333 * the high words of a1 and b0 to b1, the result is c1. */
9334 c1
->QuadPart
= (ULONGLONG
)v
.HighPart
* n
.HighPart
+ c1
->HighPart
+ a1
.HighPart
+ b0
.HighPart
;
9337 static ULONGLONG
lldiv128(ULARGE_INTEGER c1
, ULARGE_INTEGER c0
, LONGLONG denom
)
9339 ULARGE_INTEGER q1
, q0
, rhat
;
9340 ULARGE_INTEGER v
, cmp1
, cmp2
;
9343 v
.QuadPart
= llabs(denom
);
9345 /* 64bit numerator */
9346 if (c1
.QuadPart
== 0)
9347 return c0
.QuadPart
/ v
.QuadPart
;
9349 /* 96bit numerator, 32bit denominator */
9350 if (v
.HighPart
== 0 && c1
.HighPart
== 0)
9352 ULONGLONG low
= c0
.LowPart
, high
= c0
.HighPart
+ ((ULONGLONG
)c1
.LowPart
<< 32);
9353 low
+= (high
% v
.LowPart
) << 32;
9354 return ((high
/ v
.LowPart
) << 32) + (low
/ v
.LowPart
);
9357 /* 128bit numerator, 32bit denominator */
9358 if (v
.HighPart
== 0)
9361 /* count number of leading zeroes */
9362 BitScanReverse(&s
, v
.HighPart
);
9367 /* normalize divisor and dividend */
9369 c1
.QuadPart
= (c1
.QuadPart
<< s
) | (c0
.HighPart
>> (32 - s
));
9373 q1
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9374 rhat
.QuadPart
= c1
.QuadPart
- q1
.QuadPart
* v
.HighPart
;
9376 cmp1
.HighPart
= rhat
.LowPart
;
9377 cmp1
.LowPart
= c0
.HighPart
;
9378 cmp2
.QuadPart
= q1
.QuadPart
* v
.LowPart
;
9380 while (q1
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9383 rhat
.QuadPart
+= v
.HighPart
;
9386 cmp1
.HighPart
= rhat
.LowPart
;
9387 cmp2
.QuadPart
-= v
.LowPart
;
9389 c1
.HighPart
= c1
.LowPart
;
9390 c1
.LowPart
= c0
.HighPart
;
9391 c1
.QuadPart
-= q1
.QuadPart
* v
.QuadPart
;
9392 q0
.QuadPart
= c1
.QuadPart
/ v
.HighPart
;
9393 rhat
.QuadPart
= c1
.QuadPart
- q0
.QuadPart
* v
.HighPart
;
9395 cmp1
.HighPart
= rhat
.LowPart
;
9396 cmp1
.LowPart
= c0
.LowPart
;
9397 cmp2
.QuadPart
= q0
.QuadPart
* v
.LowPart
;
9399 while (q0
.HighPart
|| cmp2
.QuadPart
> cmp1
.QuadPart
)
9402 rhat
.QuadPart
+= v
.HighPart
;
9405 cmp1
.HighPart
= rhat
.LowPart
;
9406 cmp2
.QuadPart
-= v
.LowPart
;
9408 q0
.HighPart
+= q1
.LowPart
;
9413 /***********************************************************************
9414 * MFllMulDiv (mfplat.@)
9416 LONGLONG WINAPI
MFllMulDiv(LONGLONG val
, LONGLONG num
, LONGLONG denom
, LONGLONG factor
)
9418 #define LLOVERFLOW (sign ? I64_MIN : I64_MAX)
9419 unsigned int sign
, factor_sign
, denom_sign
;
9420 ULARGE_INTEGER c1
, c0
;
9423 TRACE("%s, %s, %s, %s.\n", wine_dbgstr_longlong(val
), wine_dbgstr_longlong(num
),
9424 wine_dbgstr_longlong(denom
), wine_dbgstr_longlong(factor
));
9426 /* compute 128-bit numerator product */
9427 llmult128(&c1
, &c0
, val
, num
);
9429 sign
= (val
< 0) ^ (num
< 0);
9430 factor_sign
= factor
< 0;
9431 denom_sign
= denom
< 0;
9433 factor
= llabs(factor
);
9434 if (sign
== factor_sign
)
9436 if (UI64_MAX
- c0
.QuadPart
< factor
)
9438 if (c1
.QuadPart
== UI64_MAX
) return LLOVERFLOW
;
9441 c0
.QuadPart
+= factor
;
9445 if (c0
.QuadPart
>= factor
)
9446 c0
.QuadPart
-= factor
;
9454 c0
.QuadPart
= factor
- c0
.QuadPart
;
9458 if (c1
.QuadPart
>= denom
) return LLOVERFLOW
;
9460 /* compute quotient, fits in 64 bits */
9461 ret
= lldiv128(c1
, c0
, denom
);
9463 if (ret
>= I64_MAX
) return LLOVERFLOW
;
9464 return sign
? -(LONGLONG
)ret
: ret
;
9468 /***********************************************************************
9469 * MFCreatePathFromURL (mfplat.@)
9471 HRESULT WINAPI
MFCreatePathFromURL(const WCHAR
*url
, WCHAR
**ret_path
)
9473 WCHAR path
[MAX_PATH
];
9477 TRACE("%s, %p.\n", debugstr_w(url
), ret_path
);
9479 if (!url
|| !ret_path
)
9482 length
= ARRAY_SIZE(path
);
9483 if (FAILED(hr
= PathCreateFromUrlW(url
, path
, &length
, 0)))
9486 if (!(*ret_path
= CoTaskMemAlloc((length
+ 1) * sizeof(*path
))))
9487 return E_OUTOFMEMORY
;
9489 memcpy(*ret_path
, path
, (length
+ 1) * sizeof(*path
));