mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Rebase against 727168a9e116a43f851df2673a9169ad280a9ec8.
Includes an updated mfplat patchset.
This commit is contained in:
parent
5eb920dd83
commit
e002d94a8b
@ -1,4 +1,4 @@
|
||||
From ef218059ebea8a860dea6b12a7b28984c51d2777 Mon Sep 17 00:00:00 2001
|
||||
From eaab7eaeb7533445473bc19d947c34bdc360566e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 2 Oct 2020 11:29:24 -0500
|
||||
Subject: [PATCH] bcrypt: Allow multiple backends to coexist.
|
||||
@ -27,11 +27,11 @@ index 24803fb2d7c..46a20d473dd 100644
|
||||
|
||||
RC_SRCS = version.rc
|
||||
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
|
||||
index 463672db470..90551868cf0 100644
|
||||
index e1777ed130b..86b1e3d28c3 100644
|
||||
--- a/dlls/bcrypt/bcrypt_internal.h
|
||||
+++ b/dlls/bcrypt/bcrypt_internal.h
|
||||
@@ -215,4 +215,7 @@ struct key_funcs
|
||||
NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG );
|
||||
@@ -217,4 +217,7 @@ struct key_funcs
|
||||
NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG );
|
||||
};
|
||||
|
||||
+struct key_funcs *gnutls_lib_init(DWORD reason);
|
||||
@ -39,10 +39,10 @@ index 463672db470..90551868cf0 100644
|
||||
+
|
||||
#endif /* __BCRYPT_INTERNAL_H */
|
||||
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
|
||||
index 5ed51e8704c..7a1eada329c 100644
|
||||
index 162ac9ea732..a7fd8428dec 100644
|
||||
--- a/dlls/bcrypt/gnutls.c
|
||||
+++ b/dlls/bcrypt/gnutls.c
|
||||
@@ -347,9 +347,12 @@ fail:
|
||||
@@ -358,9 +358,12 @@ fail:
|
||||
|
||||
static void gnutls_uninitialize(void)
|
||||
{
|
||||
@ -58,8 +58,8 @@ index 5ed51e8704c..7a1eada329c 100644
|
||||
}
|
||||
|
||||
struct buffer
|
||||
@@ -1848,19 +1851,28 @@ static const struct key_funcs key_funcs =
|
||||
key_import_ecc
|
||||
@@ -1906,19 +1909,28 @@ static const struct key_funcs key_funcs =
|
||||
key_import_rsa
|
||||
};
|
||||
|
||||
-NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
||||
@ -95,11 +95,11 @@ index 5ed51e8704c..7a1eada329c 100644
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c
|
||||
index d8bba46ad5c..8df5ca8645f 100644
|
||||
index 57edc3e262b..55dca5dde34 100644
|
||||
--- a/dlls/bcrypt/macos.c
|
||||
+++ b/dlls/bcrypt/macos.c
|
||||
@@ -287,11 +287,21 @@ static const struct key_funcs key_funcs =
|
||||
key_import_ecc
|
||||
@@ -294,11 +294,21 @@ static const struct key_funcs key_funcs =
|
||||
key_import_rsa
|
||||
};
|
||||
|
||||
-NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
||||
@ -325,5 +325,5 @@ index 00000000000..a158ec1630a
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 6f2d3fa75e7fd783816d52af0ca9b3c16f2a947e Mon Sep 17 00:00:00 2001
|
||||
From 6a38df1250c4bab1fab1a72e06fc347586a7c535 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 2 Oct 2020 12:11:49 -0500
|
||||
Subject: [PATCH] bcrypt: Implement BCryptSecretAgreement with libgcrypt.
|
||||
@ -18,7 +18,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
create mode 100644 dlls/bcrypt/gcrypt.c
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 372785ee0fd..68fff9bf6d8 100644
|
||||
index 029dcd45187..a18e271dd4c 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -45,6 +45,7 @@ AC_ARG_WITH(faudio, AS_HELP_STRING([--without-faudio],[do not use FAudio (XAu
|
||||
@ -29,7 +29,7 @@ index 372785ee0fd..68fff9bf6d8 100644
|
||||
AC_ARG_WITH(gettext, AS_HELP_STRING([--without-gettext],[do not use gettext]))
|
||||
AC_ARG_WITH(gettextpo, AS_HELP_STRING([--with-gettextpo],[use the GetTextPO library to rebuild po files]),
|
||||
[if test "x$withval" = "xno"; then ac_cv_header_gettext_po_h=no; fi])
|
||||
@@ -2000,6 +2001,19 @@ WINE_NOTICE_WITH(vkd3d,[test "x$ac_cv_lib_soname_vkd3d" = "x"],
|
||||
@@ -1988,6 +1989,19 @@ WINE_NOTICE_WITH(vkd3d,[test "x$ac_cv_lib_soname_vkd3d" = "x"],
|
||||
[vkd3d ${notice_platform}development files not found (or too old), Direct3D 12 won't be supported.])
|
||||
test "x$ac_cv_lib_soname_vkd3d" != "x" || enable_d3d12=${enable_d3d12:-no}
|
||||
|
||||
@ -62,10 +62,10 @@ index 46a20d473dd..4a3016784af 100644
|
||||
macos.c \
|
||||
md2.c \
|
||||
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
|
||||
index 90551868cf0..03254f72d92 100644
|
||||
index 86b1e3d28c3..5d969b13dc3 100644
|
||||
--- a/dlls/bcrypt/bcrypt_internal.h
|
||||
+++ b/dlls/bcrypt/bcrypt_internal.h
|
||||
@@ -191,6 +191,8 @@ struct key
|
||||
@@ -192,6 +192,8 @@ struct key
|
||||
struct secret
|
||||
{
|
||||
struct object hdr;
|
||||
@ -74,10 +74,10 @@ index 90551868cf0..03254f72d92 100644
|
||||
};
|
||||
|
||||
struct key_funcs
|
||||
@@ -213,9 +215,11 @@ struct key_funcs
|
||||
NTSTATUS (CDECL *key_export_ecc)( struct key *, UCHAR *, ULONG, ULONG * );
|
||||
@@ -215,9 +217,11 @@ struct key_funcs
|
||||
NTSTATUS (CDECL *key_import_dsa_capi)( struct key *, UCHAR *, ULONG );
|
||||
NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG );
|
||||
NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG );
|
||||
+ NTSTATUS (CDECL *key_compute_secret_ecc)( unsigned char *privkey_in, struct key *pubkey_in, struct secret *secret );
|
||||
};
|
||||
|
||||
@ -87,10 +87,10 @@ index 90551868cf0..03254f72d92 100644
|
||||
|
||||
#endif /* __BCRYPT_INTERNAL_H */
|
||||
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
|
||||
index 85d06f6001e..0f023d02076 100644
|
||||
index 591c01c710c..f2c344f3275 100644
|
||||
--- a/dlls/bcrypt/bcrypt_main.c
|
||||
+++ b/dlls/bcrypt/bcrypt_main.c
|
||||
@@ -1828,9 +1828,12 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H
|
||||
@@ -1914,9 +1914,12 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H
|
||||
{
|
||||
struct key *privkey = privatekey;
|
||||
struct key *pubkey = publickey;
|
||||
@ -104,7 +104,7 @@ index 85d06f6001e..0f023d02076 100644
|
||||
|
||||
if (!privkey || privkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||
if (!pubkey || pubkey->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE;
|
||||
@@ -1839,18 +1842,39 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H
|
||||
@@ -1925,18 +1928,39 @@ NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE privatekey, BCRYPT_KEY_H
|
||||
if (!(secret = heap_alloc_zero( sizeof(*secret) ))) return STATUS_NO_MEMORY;
|
||||
secret->hdr.magic = MAGIC_SECRET;
|
||||
|
||||
@ -146,7 +146,7 @@ index 85d06f6001e..0f023d02076 100644
|
||||
heap_free( secret );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1860,12 +1884,33 @@ NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCrypt
|
||||
@@ -1946,12 +1970,33 @@ NTSTATUS WINAPI BCryptDeriveKey(BCRYPT_SECRET_HANDLE handle, LPCWSTR kdf, BCrypt
|
||||
{
|
||||
struct secret *secret = handle;
|
||||
|
||||
@ -479,38 +479,38 @@ index 00000000000..00849358c68
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
|
||||
index 7a1eada329c..4505a8d965c 100644
|
||||
index a7fd8428dec..575aaa21309 100644
|
||||
--- a/dlls/bcrypt/gnutls.c
|
||||
+++ b/dlls/bcrypt/gnutls.c
|
||||
@@ -1848,7 +1848,8 @@ static const struct key_funcs key_funcs =
|
||||
key_export_dsa_capi,
|
||||
@@ -1906,7 +1906,8 @@ static const struct key_funcs key_funcs =
|
||||
key_export_ecc,
|
||||
key_import_dsa_capi,
|
||||
- key_import_ecc
|
||||
+ key_import_ecc,
|
||||
key_import_ecc,
|
||||
- key_import_rsa
|
||||
+ key_import_rsa,
|
||||
+ NULL
|
||||
};
|
||||
|
||||
struct key_funcs * gnutls_lib_init( DWORD reason )
|
||||
diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c
|
||||
index 8df5ca8645f..e44436a73fb 100644
|
||||
index 55dca5dde34..fd7aeae9ec2 100644
|
||||
--- a/dlls/bcrypt/macos.c
|
||||
+++ b/dlls/bcrypt/macos.c
|
||||
@@ -284,7 +284,8 @@ static const struct key_funcs key_funcs =
|
||||
key_export_dsa_capi,
|
||||
@@ -291,7 +291,8 @@ static const struct key_funcs key_funcs =
|
||||
key_export_ecc,
|
||||
key_import_dsa_capi,
|
||||
- key_import_ecc
|
||||
+ key_import_ecc,
|
||||
key_import_ecc,
|
||||
- key_import_rsa
|
||||
+ key_import_rsa,
|
||||
+ NULL
|
||||
};
|
||||
|
||||
struct key_funcs * macos_lib_init( DWORD reason )
|
||||
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
|
||||
index 0ae4b5dad53..559f49ec78c 100644
|
||||
index 456727d04a9..6be406dee21 100644
|
||||
--- a/dlls/bcrypt/tests/bcrypt.c
|
||||
+++ b/dlls/bcrypt/tests/bcrypt.c
|
||||
@@ -2102,7 +2102,7 @@ static void test_ECDH(void)
|
||||
@@ -2163,7 +2163,7 @@ static void test_ECDH(void)
|
||||
goto raw_secret_end;
|
||||
}
|
||||
|
||||
@ -520,7 +520,7 @@ index 0ae4b5dad53..559f49ec78c 100644
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
diff --git a/dlls/bcrypt/unixlib.c b/dlls/bcrypt/unixlib.c
|
||||
index c122df63f0b..fabb0ea40aa 100644
|
||||
index a158ec1630a..a01e2ad02ed 100644
|
||||
--- a/dlls/bcrypt/unixlib.c
|
||||
+++ b/dlls/bcrypt/unixlib.c
|
||||
@@ -129,6 +129,12 @@ static void CDECL key_asymmetric_destroy( struct key *key )
|
||||
@ -564,7 +564,7 @@ index c122df63f0b..fabb0ea40aa 100644
|
||||
|
||||
RESOLVE_FUNC(set_property)
|
||||
RESOLVE_FUNC(symmetric_init)
|
||||
@@ -181,6 +191,7 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p
|
||||
@@ -182,6 +192,7 @@ NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *p
|
||||
RESOLVE_FUNC(export_ecc)
|
||||
RESOLVE_FUNC(import_dsa_capi)
|
||||
RESOLVE_FUNC(import_ecc)
|
||||
@ -573,5 +573,5 @@ index c122df63f0b..fabb0ea40aa 100644
|
||||
#undef RESOLVE_FUNC
|
||||
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
From 600fb937ace942db4325c268d71f799f7c058286 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 13:48:23 -0600
|
||||
Subject: [PATCH] winegstreamer: Implement ::SetInputType for audio conversion
|
||||
transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 77 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 75 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 9499920347f..8bfd28b1ef2 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
+#include <gst/gst.h>
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
@@ -36,6 +37,8 @@ struct audio_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
+ IMFMediaType *input_type;
|
||||
+ CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
|
||||
@@ -79,6 +82,8 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
+ transform->cs.DebugInfo->Spare[0] = 0;
|
||||
+ DeleteCriticalSection(&transform->cs);
|
||||
heap_free(transform);
|
||||
}
|
||||
|
||||
@@ -270,9 +275,74 @@ fail:
|
||||
|
||||
static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ GstCaps *input_caps;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ GUID major_type, subtype;
|
||||
+ DWORD unused;
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(input_caps = caps_from_mf_media_type(type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ gst_caps_unref(input_caps);
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->input_type)
|
||||
+ hr = MFCreateMediaType(&converter->input_type);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->input_type);
|
||||
+ converter->input_type = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (converter->input_type)
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->input_type);
|
||||
+ converter->input_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
@@ -395,6 +465,9 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
+ InitializeCriticalSection(&object->cs);
|
||||
+ object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
|
||||
+
|
||||
*ret = &object->IMFTransform_iface;
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,106 @@
|
||||
From 661099668f972a9bb0a9194c2691ab034e1ebe9e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 2 Dec 2020 14:36:17 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::SetOutputType for audio conversion
|
||||
transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 73 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 71 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 8bfd28b1ef2..7fb0dee99f6 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -38,6 +38,7 @@ struct audio_converter
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
IMFMediaType *input_type;
|
||||
+ IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
@@ -347,9 +348,77 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
|
||||
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ GUID major_type, subtype;
|
||||
+ GstCaps *output_caps;
|
||||
+ DWORD unused;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (!converter->input_type)
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ /* validate the type */
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(output_caps = caps_from_mf_media_type(type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ gst_caps_unref(output_caps);
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->output_type)
|
||||
+ hr = MFCreateMediaType(&converter->output_type);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->output_type);
|
||||
+ converter->output_type = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (converter->output_type)
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->output_type);
|
||||
+ converter->output_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From db7e26f933c7f275c13c3c9d42066b9524cc703c Mon Sep 17 00:00:00 2001
|
||||
From 0c493f7590ba2d7b90cf44c389378aacae8f6fe0 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 14:31:00 -0600
|
||||
Subject: [PATCH] winegstreamer: Implement ::Process(Input/Output) for audio
|
||||
@ -6,107 +6,119 @@ Subject: [PATCH] winegstreamer: Implement ::Process(Input/Output) for audio
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 202 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/audioconvert.c | 175 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 75 +++++++++++
|
||||
3 files changed, 273 insertions(+), 5 deletions(-)
|
||||
dlls/winegstreamer/mfplat.c | 69 ++++++++++++
|
||||
3 files changed, 239 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 04227d168ae..deb5ceb2f7c 100644
|
||||
index 7fb0dee99f6..631c57d6d55 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -24,7 +24,8 @@ struct audio_converter
|
||||
@@ -40,6 +40,8 @@ struct audio_converter
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
- BOOL valid_state;
|
||||
+ BOOL valid_state, inflight;
|
||||
+ BOOL inflight;
|
||||
+ GstElement *container, *appsrc, *audioconvert, *resampler, *appsink;
|
||||
};
|
||||
|
||||
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
|
||||
@@ -69,6 +70,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
if (!refcount)
|
||||
@@ -85,6 +87,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
{
|
||||
transform->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&transform->cs);
|
||||
+ gst_object_unref(transform->container);
|
||||
heap_free(transform);
|
||||
}
|
||||
|
||||
@@ -261,22 +263,54 @@ static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface
|
||||
static void audio_converter_update_pipeline_state(struct audio_converter *converter)
|
||||
{
|
||||
GstCaps *input_caps, *output_caps;
|
||||
+ GstStructure *input_structure, *output_structure;
|
||||
+ guint64 channels_in, channels_out, channel_mask = 0;
|
||||
@@ -311,7 +314,8 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
if (!(input_caps = caps_from_mf_media_type(type)))
|
||||
return MF_E_INVALIDTYPE;
|
||||
|
||||
if (!(converter->valid_state = converter->input_type && converter->output_type))
|
||||
+ {
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
return;
|
||||
+ }
|
||||
|
||||
if (!(input_caps = caps_from_mf_media_type(converter->input_type)))
|
||||
{
|
||||
converter->valid_state = FALSE;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
return;
|
||||
- gst_caps_unref(input_caps);
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ gst_caps_unref(input_caps);
|
||||
}
|
||||
if (!(output_caps = caps_from_mf_media_type(converter->output_type)))
|
||||
|
||||
if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
@@ -320,6 +324,7 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
EnterCriticalSection(&converter->cs);
|
||||
|
||||
hr = S_OK;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
|
||||
if (type)
|
||||
{
|
||||
converter->valid_state = FALSE;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
@@ -329,6 +334,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
|
||||
|
||||
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
|
||||
+ gst_caps_unref(input_caps);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* audioconvert needs a valid channel-mask */
|
||||
+ input_structure = gst_caps_get_structure(input_caps, 0);
|
||||
+ output_structure = gst_caps_get_structure(output_caps, 0);
|
||||
+
|
||||
+ if (!gst_structure_get(input_structure, "channels", G_TYPE_INT, &channels_in, NULL) ||
|
||||
+ !gst_structure_get(output_structure, "channels", G_TYPE_INT, &channels_out, NULL))
|
||||
+ {
|
||||
+ converter->valid_state = FALSE;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
gst_caps_unref(input_caps);
|
||||
+ gst_caps_unref(output_caps);
|
||||
return;
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IMFMediaType_Release(converter->input_type);
|
||||
@@ -341,6 +349,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
converter->input_type = NULL;
|
||||
}
|
||||
|
||||
+ gst_structure_get(input_structure, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL);
|
||||
+ if (channel_mask == 0)
|
||||
+ gst_caps_set_simple(input_caps, "channel-mask", GST_TYPE_BITMASK, (guint64) (1 << channels_in) - 1, NULL);
|
||||
+ if (converter->input_type && converter->output_type)
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+
|
||||
+ gst_structure_get(output_structure, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL);
|
||||
+ if (channel_mask == 0)
|
||||
+ gst_caps_set_simple(output_caps, "channel-mask", GST_TYPE_BITMASK, (guint64) (1 << channels_out) - 1, NULL);
|
||||
+
|
||||
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
|
||||
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
|
||||
+
|
||||
if (TRACE_ON(mfplat))
|
||||
LeaveCriticalSection(&converter->cs);
|
||||
|
||||
return hr;
|
||||
@@ -386,7 +397,8 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
if (!(output_caps = caps_from_mf_media_type(type)))
|
||||
return MF_E_INVALIDTYPE;
|
||||
|
||||
- gst_caps_unref(output_caps);
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ gst_caps_unref(output_caps);
|
||||
}
|
||||
|
||||
if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
@@ -395,6 +407,7 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
EnterCriticalSection(&converter->cs);
|
||||
|
||||
hr = S_OK;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
|
||||
if (type)
|
||||
{
|
||||
gchar *input_caps_str, *output_caps_str;
|
||||
@@ -293,6 +327,7 @@ static void audio_converter_update_pipeline_state(struct audio_converter *conver
|
||||
@@ -404,6 +417,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
|
||||
|
||||
gst_caps_unref(input_caps);
|
||||
gst_caps_unref(output_caps);
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
|
||||
+ gst_caps_unref(output_caps);
|
||||
+
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IMFMediaType_Release(converter->output_type);
|
||||
@@ -416,6 +432,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
converter->output_type = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -496,17 +531,114 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
|
||||
+ if (converter->input_type && converter->output_type)
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+
|
||||
LeaveCriticalSection(&converter->cs);
|
||||
|
||||
return hr;
|
||||
@@ -479,17 +498,102 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
|
||||
|
||||
static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ GstBuffer *gst_buffer;
|
||||
+ HRESULT hr = S_OK;
|
||||
+ int ret;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+
|
||||
+ if (flags)
|
||||
@ -117,183 +129,163 @@ index 04227d168ae..deb5ceb2f7c 100644
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!converter->valid_state)
|
||||
+ if (!converter->input_type || !converter->output_type)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ goto done;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ }
|
||||
+
|
||||
+ if (converter->inflight)
|
||||
+ {
|
||||
+ hr = MF_E_NOTACCEPTING;
|
||||
+ goto done;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_NOTACCEPTING;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret);
|
||||
+ gst_buffer_unref(gst_buffer);
|
||||
+ if (ret != GST_FLOW_OK)
|
||||
+ {
|
||||
+ ERR("Couldn't push buffer ret = %d\n", ret);
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ ERR("Couldn't push buffer ret = %d (%s)\n", ret, gst_flow_get_name(ret));
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ converter->inflight = TRUE;
|
||||
+
|
||||
+ done:
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
|
||||
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
{
|
||||
- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL;
|
||||
+ GstSample *sample;
|
||||
+ HRESULT hr = S_OK;
|
||||
+ unsigned int i;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+
|
||||
+ if (flags)
|
||||
+ WARN("Unsupported flags %#x\n", flags);
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ {
|
||||
+ MFT_OUTPUT_DATA_BUFFER *out_buffer = &samples[i];
|
||||
+
|
||||
+ if (out_buffer->dwStreamID != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (relevant_buffer)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ relevant_buffer = out_buffer;
|
||||
+ }
|
||||
+
|
||||
+ if (!relevant_buffer)
|
||||
+ if (!count)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ if (count != 1)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (samples[0].dwStreamID != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!converter->valid_state)
|
||||
+ if (!converter->input_type || !converter->output_type)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ goto done;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ }
|
||||
+
|
||||
+ if (!converter->inflight)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_NEED_MORE_INPUT;
|
||||
+ goto done;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
|
||||
+ }
|
||||
+
|
||||
+ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
|
||||
+
|
||||
+ converter->inflight = FALSE;
|
||||
+
|
||||
+ relevant_buffer->pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
|
||||
+ samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
|
||||
+ gst_sample_unref(sample);
|
||||
+ relevant_buffer->dwStatus = S_OK;
|
||||
+ relevant_buffer->pEvents = NULL;
|
||||
+ samples[0].dwStatus = S_OK;
|
||||
+ samples[0].pEvents = NULL;
|
||||
+ *status = 0;
|
||||
+
|
||||
+ done:
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static const IMFTransformVtbl audio_converter_vtbl =
|
||||
@@ -542,6 +674,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
|
||||
HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
{
|
||||
struct audio_converter *object;
|
||||
+ HRESULT hr;
|
||||
|
||||
TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
|
||||
@@ -553,6 +686,65 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
|
||||
@@ -537,6 +641,65 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
InitializeCriticalSection(&object->cs);
|
||||
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
|
||||
|
||||
+ object->container = gst_bin_new(NULL);
|
||||
+
|
||||
+ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create appsrc");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ ERR("Failed to create appsrc, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->appsrc);
|
||||
+
|
||||
+ if (!(object->audioconvert = gst_element_factory_make("audioconvert", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create converter\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ ERR("Failed to create audioconvert, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->audioconvert);
|
||||
+
|
||||
+ if (!(object->resampler = gst_element_factory_make("audioresample", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create resampler\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ ERR("Failed to create audioresample, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->resampler);
|
||||
+
|
||||
+ if (!(object->appsink = gst_element_factory_make("appsink", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create appsink\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ ERR("Failed to create appsink, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->appsink);
|
||||
+
|
||||
+ if (!(gst_element_link(object->appsrc, object->audioconvert)))
|
||||
+ if (!gst_element_link(object->appsrc, object->audioconvert))
|
||||
+ {
|
||||
+ ERR("Failed to link appsrc to audioconvert\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_element_link(object->audioconvert, object->resampler)))
|
||||
+ if (!gst_element_link(object->audioconvert, object->resampler))
|
||||
+ {
|
||||
+ ERR("Failed to link audioconvert to resampler\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_element_link(object->resampler, object->appsink)))
|
||||
+ if (!gst_element_link(object->resampler, object->appsink))
|
||||
+ {
|
||||
+ ERR("Failed to link resampler to appsink\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
*ret = &object->IMFTransform_iface;
|
||||
return S_OK;
|
||||
+failed:
|
||||
+
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return hr;
|
||||
}
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 7889c996204..7f96c06dfaf 100644
|
||||
index 9518f721504..14b6a011ac2 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -81,6 +81,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
|
||||
@@ -82,6 +82,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
|
||||
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
|
||||
IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
|
||||
@ -302,10 +294,10 @@ index 7889c996204..7f96c06dfaf 100644
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 909fb8b3572..7fdf722ec2e 100644
|
||||
index f300988fc5c..883084b2d89 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -877,3 +877,78 @@ done:
|
||||
@@ -865,3 +865,72 @@ done:
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -333,7 +325,7 @@ index 909fb8b3572..7fdf722ec2e 100644
|
||||
+
|
||||
+ for (i = 0; i < buffer_count; i++)
|
||||
+ {
|
||||
+ DWORD buffer_max_size, buffer_size;
|
||||
+ DWORD buffer_size;
|
||||
+ GstMapInfo map_info;
|
||||
+ GstMemory *memory;
|
||||
+ BYTE *buf_data;
|
||||
@ -341,9 +333,6 @@ index 909fb8b3572..7fdf722ec2e 100644
|
||||
+ if (FAILED(hr = IMFSample_GetBufferByIndex(mf_sample, i, &mf_buffer)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_GetMaxLength(mf_buffer, &buffer_max_size)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_GetCurrentLength(mf_buffer, &buffer_size)))
|
||||
+ goto fail;
|
||||
+
|
||||
@ -364,9 +353,6 @@ index 909fb8b3572..7fdf722ec2e 100644
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(mf_buffer, buffer_size)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ gst_memory_unmap(memory, &map_info);
|
||||
+
|
||||
+ gst_buffer_append_memory(out, memory);
|
@ -1,4 +1,4 @@
|
||||
From 0a944954888cbe4ea094a7e97c9f19db2aa358d6 Mon Sep 17 00:00:00 2001
|
||||
From 13e0d5671caaeae69bde747e547a5bd4524dd2ff Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 14:32:27 -0600
|
||||
Subject: [PATCH] winegstreamer: Implement ::Get(Input/Output)StreamInfo for
|
||||
@ -6,23 +6,21 @@ Subject: [PATCH] winegstreamer: Implement ::Get(Input/Output)StreamInfo for
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 29 +++++++++++++++++++++++++----
|
||||
1 file changed, 25 insertions(+), 4 deletions(-)
|
||||
dlls/winegstreamer/audioconvert.c | 23 +++++++++++++++++++----
|
||||
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index deb5ceb2f7c..cb7d4a15bf8 100644
|
||||
index 631c57d6d55..d204d9582ba 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -106,16 +106,37 @@ static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD in
|
||||
@@ -123,16 +123,31 @@ static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD in
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
{
|
||||
- FIXME("%p %u %p.\n", iface, id, info);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ TRACE("%p %u %p.\n", iface, id, info);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p %u %p\n", converter, id, info);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
@ -30,26 +28,22 @@ index deb5ceb2f7c..cb7d4a15bf8 100644
|
||||
+ info->cbMaxLookahead = 0;
|
||||
+ info->cbAlignment = 0;
|
||||
+ info->hnsMaxLatency = 0;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
{
|
||||
- FIXME("%p %u %p.\n", iface, id, info);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ MFT_OUTPUT_STREAM_INFO stream_info = {};
|
||||
+ TRACE("%p %u %p.\n", iface, id, info);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p %u %p\n", converter, id, info);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ stream_info.dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
|
||||
+ stream_info.cbSize = 0;
|
||||
+ stream_info.cbAlignment = 0;
|
||||
+
|
||||
+ *info = stream_info;
|
||||
+ info->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
|
||||
+ info->cbSize = 0;
|
||||
+ info->cbAlignment = 0;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
From a84dafe62e44de78320b121fb45dae042e6b3099 Mon Sep 17 00:00:00 2001
|
||||
From 91a772eb1cb4ec9e86b4ab007743a99a8bd75265 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 14:34:56 -0600
|
||||
Subject: [PATCH] winegstreamer: Implement Get*Attributes functions for audio
|
||||
@ -6,14 +6,14 @@ Subject: [PATCH] winegstreamer: Implement Get*Attributes functions for audio
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 30 ++++++++++++++++++++++++++----
|
||||
1 file changed, 26 insertions(+), 4 deletions(-)
|
||||
dlls/winegstreamer/audioconvert.c | 37 +++++++++++++++++++++++++++----
|
||||
1 file changed, 33 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index cb7d4a15bf8..7d19b561dd1 100644
|
||||
index d204d9582ba..556aba44fc9 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -21,6 +21,8 @@ struct audio_converter
|
||||
@@ -37,6 +37,8 @@ struct audio_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
@ -22,9 +22,9 @@ index cb7d4a15bf8..7d19b561dd1 100644
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
@@ -70,6 +72,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
if (!refcount)
|
||||
@@ -87,6 +89,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
{
|
||||
transform->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&transform->cs);
|
||||
+ if (transform->attributes)
|
||||
+ IMFAttributes_Release(transform->attributes);
|
||||
@ -33,49 +33,63 @@ index cb7d4a15bf8..7d19b561dd1 100644
|
||||
gst_object_unref(transform->container);
|
||||
heap_free(transform);
|
||||
}
|
||||
@@ -141,9 +147,14 @@ static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, D
|
||||
@@ -152,9 +158,14 @@ static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, D
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
{
|
||||
- FIXME("%p, %p.\n", iface, attributes);
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %p.\n", iface, attributes);
|
||||
+
|
||||
+ *attributes = transform->attributes;
|
||||
+ *attributes = converter->attributes;
|
||||
+ IMFAttributes_AddRef(*attributes);
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
@@ -157,9 +168,14 @@ static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *ifa
|
||||
@@ -168,9 +179,14 @@ static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *ifa
|
||||
static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
IMFAttributes **attributes)
|
||||
{
|
||||
- FIXME("%p, %u, %p.\n", iface, id, attributes);
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ *attributes = transform->output_attributes;
|
||||
+ *attributes = converter->output_attributes;
|
||||
+ IMFAttributes_AddRef(*attributes);
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
|
||||
@@ -707,6 +723,12 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
@@ -644,6 +660,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
|
||||
HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
{
|
||||
struct audio_converter *object;
|
||||
+ HRESULT hr;
|
||||
|
||||
TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
|
||||
@@ -656,6 +673,18 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
InitializeCriticalSection(&object->cs);
|
||||
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
|
||||
|
||||
+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
|
||||
+ goto failed;
|
||||
+ {
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
|
||||
+ goto failed;
|
||||
+ {
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
object->container = gst_bin_new(NULL);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,19 @@
|
||||
From e95595f362fd016cfbba18a88837660efcc75b85 Mon Sep 17 00:00:00 2001
|
||||
From 617386fb620e7751e926046f5cf785ebde436aa4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Nov 2020 15:25:48 -0500
|
||||
Subject: [PATCH] Implement Get(Input/Output)CurrentType functions for audio
|
||||
converter transform.
|
||||
Subject: [PATCH] winegstreamer: Implement Get(Input/Output)CurrentType
|
||||
functions for audio converter transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 52 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 48 insertions(+), 4 deletions(-)
|
||||
dlls/winegstreamer/audioconvert.c | 56 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 52 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 7d19b561dd1..5e714fed638 100644
|
||||
index 556aba44fc9..e709c43ed5c 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -519,16 +519,60 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
@@ -473,16 +473,64 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
{
|
||||
@ -42,6 +42,8 @@ index 7d19b561dd1..5e714fed638 100644
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ *type = ret;
|
||||
+ else
|
||||
+ IMFMediaType_Release(ret);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
@ -73,6 +75,8 @@ index 7d19b561dd1..5e714fed638 100644
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ *type = ret;
|
||||
+ else
|
||||
+ IMFMediaType_Release(ret);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
From 83cca2566e290fa035cc3efcfafaeefc55022b67 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 13:48:23 -0600
|
||||
Subject: [PATCH] winegstreamer: Implement ::Set(Input/Output)Type for audio
|
||||
conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 190 +++++++++++++++++++++++++++++-
|
||||
1 file changed, 185 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 91fa556cb88..04227d168ae 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "config.h"
|
||||
+#include <gst/gst.h>
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
@@ -20,6 +21,10 @@ struct audio_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
+ IMFMediaType *input_type;
|
||||
+ IMFMediaType *output_type;
|
||||
+ CRITICAL_SECTION cs;
|
||||
+ BOOL valid_state;
|
||||
};
|
||||
|
||||
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
|
||||
@@ -63,6 +68,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
+ DeleteCriticalSection(&transform->cs);
|
||||
heap_free(transform);
|
||||
}
|
||||
|
||||
@@ -252,18 +258,191 @@ static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface
|
||||
return hr;
|
||||
}
|
||||
|
||||
+static void audio_converter_update_pipeline_state(struct audio_converter *converter)
|
||||
+{
|
||||
+ GstCaps *input_caps, *output_caps;
|
||||
+
|
||||
+ if (!(converter->valid_state = converter->input_type && converter->output_type))
|
||||
+ return;
|
||||
+
|
||||
+ if (!(input_caps = caps_from_mf_media_type(converter->input_type)))
|
||||
+ {
|
||||
+ converter->valid_state = FALSE;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!(output_caps = caps_from_mf_media_type(converter->output_type)))
|
||||
+ {
|
||||
+ converter->valid_state = FALSE;
|
||||
+ gst_caps_unref(input_caps);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (TRACE_ON(mfplat))
|
||||
+ {
|
||||
+ gchar *input_caps_str, *output_caps_str;
|
||||
+
|
||||
+ input_caps_str = gst_caps_to_string(input_caps);
|
||||
+ output_caps_str = gst_caps_to_string(output_caps);
|
||||
+
|
||||
+ TRACE("Audio converter MFT configured to transform caps %s to caps %s\n",
|
||||
+ debugstr_a(input_caps_str), debugstr_a(output_caps_str));
|
||||
+
|
||||
+ g_free(input_caps_str);
|
||||
+ g_free(output_caps_str);
|
||||
+ }
|
||||
+
|
||||
+ gst_caps_unref(input_caps);
|
||||
+ gst_caps_unref(output_caps);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ unsigned int i;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ GUID major_type, subtype;
|
||||
+ BOOL found = FALSE;
|
||||
+ DWORD unused;
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
|
||||
+ {
|
||||
+ if (IsEqualGUID(&subtype, raw_types[i]))
|
||||
+ {
|
||||
+ found = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!found)
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->input_type)
|
||||
+ if (FAILED(hr = MFCreateMediaType(&converter->input_type)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type)))
|
||||
+ goto done;
|
||||
+ }
|
||||
+ else if (converter->input_type)
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->input_type);
|
||||
+ converter->input_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ done:
|
||||
+ if (hr == S_OK)
|
||||
+ audio_converter_update_pipeline_state(converter);
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ GUID major_type, subtype;
|
||||
+ unsigned int i;
|
||||
+ DWORD unused;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (!converter->input_type)
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ /* validate the type */
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
|
||||
+ {
|
||||
+ if (IsEqualGUID(&subtype, raw_types[i]))
|
||||
+ break;
|
||||
+ if (i == ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->output_type)
|
||||
+ if (FAILED(hr = MFCreateMediaType(&converter->output_type)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type)))
|
||||
+ goto done;
|
||||
+ }
|
||||
+ else if (converter->output_type)
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->output_type);
|
||||
+ converter->output_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ done:
|
||||
+ if (hr == S_OK)
|
||||
+ audio_converter_update_pipeline_state(converter);
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
@@ -363,7 +542,6 @@ static const IMFTransformVtbl audio_converter_vtbl =
|
||||
HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
{
|
||||
struct audio_converter *object;
|
||||
- HRESULT hr;
|
||||
|
||||
TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
|
||||
@@ -373,6 +551,8 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
+ InitializeCriticalSection(&object->cs);
|
||||
+
|
||||
*ret = &object->IMFTransform_iface;
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,386 @@
|
||||
From b5316e74275511a63372473cb6bb10b8f2f8d2e1 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 1 Dec 2020 13:16:27 -0500
|
||||
Subject: [PATCH] winegstreamer: Introduce color conversion transform.
|
||||
|
||||
Serves as a wrapper of videoconvert, and roughly fills the roll of Windows' CColorConverterDMO.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/Makefile.in | 1 +
|
||||
dlls/winegstreamer/colorconvert.c | 302 +++++++++++++++++++
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 3 +
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
|
||||
5 files changed, 313 insertions(+)
|
||||
create mode 100644 dlls/winegstreamer/colorconvert.c
|
||||
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index 0b3229160b9..5395d6fd501 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -7,6 +7,7 @@ PARENTSRC = ../strmbase
|
||||
|
||||
C_SRCS = \
|
||||
audioconvert.c \
|
||||
+ colorconvert.c \
|
||||
filter.c \
|
||||
gst_cbs.c \
|
||||
gstdemux.c \
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
new file mode 100644
|
||||
index 00000000000..8d0823fc0dc
|
||||
--- /dev/null
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -0,0 +1,302 @@
|
||||
+/* GStreamer Color Converter
|
||||
+ *
|
||||
+ * Copyright 2020 Derek Lesho
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include "gst_private.h"
|
||||
+
|
||||
+#include "mfapi.h"
|
||||
+#include "mferror.h"
|
||||
+#include "mfidl.h"
|
||||
+
|
||||
+#include "wine/debug.h"
|
||||
+#include "wine/heap.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||
+
|
||||
+struct color_converter
|
||||
+{
|
||||
+ IMFTransform IMFTransform_iface;
|
||||
+ LONG refcount;
|
||||
+};
|
||||
+
|
||||
+static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct color_converter, IMFTransform_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
|
||||
+{
|
||||
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
|
||||
+ IsEqualIID(riid, &IID_IUnknown))
|
||||
+ {
|
||||
+ *obj = iface;
|
||||
+ IMFTransform_AddRef(iface);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
|
||||
+ *obj = NULL;
|
||||
+ return E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI color_converter_AddRef(IMFTransform *iface)
|
||||
+{
|
||||
+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedIncrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI color_converter_Release(IMFTransform *iface)
|
||||
+{
|
||||
+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedDecrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ {
|
||||
+ heap_free(transform);
|
||||
+ }
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
|
||||
+ DWORD *output_minimum, DWORD *output_maximum)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
|
||||
+
|
||||
+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p.\n", iface, inputs, outputs);
|
||||
+
|
||||
+ *inputs = *outputs = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
|
||||
+ DWORD output_size, DWORD *outputs)
|
||||
+{
|
||||
+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ FIXME("%p %u %p.\n", iface, id, info);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ FIXME("%p %u %p.\n", iface, id, info);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %p.\n", iface, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
|
||||
+{
|
||||
+ TRACE("%p, %u.\n", iface, id);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %p.\n", iface, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
|
||||
+{
|
||||
+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, id, event);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||
+{
|
||||
+ FIXME("%p, %u %lu.\n", iface, message, param);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
|
||||
+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
+{
|
||||
+ FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static const IMFTransformVtbl color_converter_vtbl =
|
||||
+{
|
||||
+ color_converter_QueryInterface,
|
||||
+ color_converter_AddRef,
|
||||
+ color_converter_Release,
|
||||
+ color_converter_GetStreamLimits,
|
||||
+ color_converter_GetStreamCount,
|
||||
+ color_converter_GetStreamIDs,
|
||||
+ color_converter_GetInputStreamInfo,
|
||||
+ color_converter_GetOutputStreamInfo,
|
||||
+ color_converter_GetAttributes,
|
||||
+ color_converter_GetInputStreamAttributes,
|
||||
+ color_converter_GetOutputStreamAttributes,
|
||||
+ color_converter_DeleteInputStream,
|
||||
+ color_converter_AddInputStreams,
|
||||
+ color_converter_GetInputAvailableType,
|
||||
+ color_converter_GetOutputAvailableType,
|
||||
+ color_converter_SetInputType,
|
||||
+ color_converter_SetOutputType,
|
||||
+ color_converter_GetInputCurrentType,
|
||||
+ color_converter_GetOutputCurrentType,
|
||||
+ color_converter_GetInputStatus,
|
||||
+ color_converter_GetOutputStatus,
|
||||
+ color_converter_SetOutputBounds,
|
||||
+ color_converter_ProcessEvent,
|
||||
+ color_converter_ProcessMessage,
|
||||
+ color_converter_ProcessInput,
|
||||
+ color_converter_ProcessOutput,
|
||||
+};
|
||||
+
|
||||
+HRESULT color_converter_create(REFIID riid, void **ret)
|
||||
+{
|
||||
+ struct color_converter *object;
|
||||
+
|
||||
+ TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
+
|
||||
+ if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ object->IMFTransform_iface.lpVtbl = &color_converter_vtbl;
|
||||
+ object->refcount = 1;
|
||||
+
|
||||
+ *ret = &object->IMFTransform_iface;
|
||||
+ return S_OK;
|
||||
+}
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 14b6a011ac2..075e0ce1f0f 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -87,5 +87,6 @@ GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
|
||||
+HRESULT color_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __GST_PRIVATE_INCLUDED__ */
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 883084b2d89..288b79997cd 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -407,6 +407,8 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a
|
||||
|
||||
static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
|
||||
|
||||
+static GUID CLSID_WINEColorConverter = {0x2be8b27f,0xcd60,0x4b8a,{0x95,0xae,0xd1,0x74,0xcc,0x5c,0xba,0xa7}};
|
||||
+
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -417,6 +419,7 @@ class_objects[] =
|
||||
{ &CLSID_VideoProcessorMFT, &video_processor_create },
|
||||
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
|
||||
{ &CLSID_WINEAudioConverter, &audio_converter_create },
|
||||
+ { &CLSID_WINEColorConverter, &color_converter_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index cf1fc69f38a..47c10a09cf0 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {}
|
||||
uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
|
||||
]
|
||||
coclass WINEAudioConverter { }
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
+ uuid(2be8b27f-cd60-4b8a-95ae-d174cc5cbaa7)
|
||||
+]
|
||||
+coclass WINEColorConverter { }
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,71 @@
|
||||
From 18799e737ff065a62ea1c92c9a684940053d9dfb Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 12:45:48 -0500
|
||||
Subject: [PATCH] winegstreamer: Register the color conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 34 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 288b79997cd..1b19c43d991 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -455,6 +455,26 @@ static const GUID *audio_converter_supported_types[] =
|
||||
&MFAudioFormat_Float,
|
||||
};
|
||||
|
||||
+static WCHAR color_converterW[] = {'C','o','l','o','r',' ','C','o','n','v','e','r','t','e','r',0};
|
||||
+const GUID *color_converter_supported_types[] =
|
||||
+{
|
||||
+ &MFVideoFormat_RGB24,
|
||||
+ &MFVideoFormat_RGB32,
|
||||
+ &MFVideoFormat_RGB555,
|
||||
+ &MFVideoFormat_RGB8,
|
||||
+ &MFVideoFormat_AYUV,
|
||||
+ &MFVideoFormat_I420,
|
||||
+ &MFVideoFormat_IYUV,
|
||||
+ &MFVideoFormat_NV11,
|
||||
+ &MFVideoFormat_NV12,
|
||||
+ &MFVideoFormat_UYVY,
|
||||
+ &MFVideoFormat_v216,
|
||||
+ &MFVideoFormat_v410,
|
||||
+ &MFVideoFormat_YUY2,
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+};
|
||||
+
|
||||
static const struct mft
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -482,13 +502,25 @@ mfts[] =
|
||||
audio_converter_supported_types,
|
||||
NULL
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_WINEColorConverter,
|
||||
+ &MFT_CATEGORY_VIDEO_EFFECT,
|
||||
+ color_converterW,
|
||||
+ MFT_ENUM_FLAG_SYNCMFT,
|
||||
+ &MFMediaType_Video,
|
||||
+ ARRAY_SIZE(color_converter_supported_types),
|
||||
+ color_converter_supported_types,
|
||||
+ ARRAY_SIZE(color_converter_supported_types),
|
||||
+ color_converter_supported_types,
|
||||
+ NULL
|
||||
+ },
|
||||
};
|
||||
|
||||
HRESULT mfplat_DllRegisterServer(void)
|
||||
{
|
||||
unsigned int i, j;
|
||||
HRESULT hr;
|
||||
- MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
|
||||
+ MFT_REGISTER_TYPE_INFO input_types[15], output_types[15];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mfts); i++)
|
||||
{
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,81 @@
|
||||
From 15b54cf08d296483e6d4c211eeae50db62f70804 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 12:55:14 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::GetInputAvailableType for color
|
||||
conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 48 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 46 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index 8d0823fc0dc..9a1d2880234 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -30,6 +30,24 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||
|
||||
+static const GUID *raw_types[] = {
|
||||
+ &MFVideoFormat_RGB24,
|
||||
+ &MFVideoFormat_RGB32,
|
||||
+ &MFVideoFormat_RGB555,
|
||||
+ &MFVideoFormat_RGB8,
|
||||
+ &MFVideoFormat_AYUV,
|
||||
+ &MFVideoFormat_I420,
|
||||
+ &MFVideoFormat_IYUV,
|
||||
+ &MFVideoFormat_NV11,
|
||||
+ &MFVideoFormat_NV12,
|
||||
+ &MFVideoFormat_UYVY,
|
||||
+ &MFVideoFormat_v216,
|
||||
+ &MFVideoFormat_v410,
|
||||
+ &MFVideoFormat_YUY2,
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+};
|
||||
+
|
||||
struct color_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
@@ -164,9 +182,35 @@ static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD
|
||||
static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
IMFMediaType **type)
|
||||
{
|
||||
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+ IMFMediaType *ret;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (index >= ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&ret)))
|
||||
+ return hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index])))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ *type = ret;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,123 @@
|
||||
From 096a5070ac3ce917e6c8ae010e8e80c8ffbde3c4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 14:34:07 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::SetInputType for color conversion
|
||||
transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 76 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 74 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index 9a1d2880234..5dd48188147 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -52,6 +52,8 @@ struct color_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
+ IMFMediaType *input_type;
|
||||
+ CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
|
||||
@@ -95,6 +97,8 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface)
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
+ transform->cs.DebugInfo->Spare[0] = 0;
|
||||
+ DeleteCriticalSection(&transform->cs);
|
||||
heap_free(transform);
|
||||
}
|
||||
|
||||
@@ -223,9 +227,74 @@ static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface
|
||||
|
||||
static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ GstCaps *input_caps;
|
||||
+ unsigned int i;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ GUID major_type, subtype;
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Video)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
|
||||
+ {
|
||||
+ if (IsEqualGUID(&subtype, raw_types[i]))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(input_caps = caps_from_mf_media_type(type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ gst_caps_unref(input_caps);
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->input_type)
|
||||
+ hr = MFCreateMediaType(&converter->input_type);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->input_type);
|
||||
+ converter->input_type = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->input_type);
|
||||
+ converter->input_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
@@ -341,6 +410,9 @@ HRESULT color_converter_create(REFIID riid, void **ret)
|
||||
object->IMFTransform_iface.lpVtbl = &color_converter_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
+ InitializeCriticalSection(&object->cs);
|
||||
+ object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock");
|
||||
+
|
||||
*ret = &object->IMFTransform_iface;
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,77 @@
|
||||
From 64cfb2a80d7ebc22b12d8b6c1e41cf7a74e15d88 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 14:45:32 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::GetOutputAvailableType for color
|
||||
conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 48 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 46 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index 5dd48188147..b80232e195b 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -217,12 +217,56 @@ static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
+static void copy_attr(IMFMediaType *target, IMFMediaType *source, const GUID *key)
|
||||
+{
|
||||
+ PROPVARIANT val;
|
||||
+
|
||||
+ if (SUCCEEDED(IMFAttributes_GetItem((IMFAttributes *)source, key, &val)))
|
||||
+ {
|
||||
+ IMFAttributes_SetItem((IMFAttributes* )target, key, &val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
IMFMediaType **type)
|
||||
{
|
||||
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+ IMFMediaType *output_type;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (index >= ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&output_type)))
|
||||
+ return hr;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!(converter->input_type))
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *)output_type);
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, raw_types[index])))
|
||||
+ {
|
||||
+ IMFMediaType_Release(output_type);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ *type = output_type;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,103 @@
|
||||
From f1714a949175290e9f01bd32fde1dacecfed7946 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 14:55:41 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::SetOutputType for color conversion
|
||||
transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 70 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 68 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index b80232e195b..e7e84690738 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -53,6 +53,7 @@ struct color_converter
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
IMFMediaType *input_type;
|
||||
+ IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
@@ -343,9 +344,74 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
|
||||
static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+ GstCaps *output_caps;
|
||||
+ unsigned int i;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ GUID major_type, subtype;
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Video)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
|
||||
+ {
|
||||
+ if (IsEqualGUID(&subtype, raw_types[i]))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(output_caps = caps_from_mf_media_type(type)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ gst_caps_unref(output_caps);
|
||||
+ }
|
||||
+
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ if (type)
|
||||
+ {
|
||||
+ if (!converter->output_type)
|
||||
+ hr = MFCreateMediaType(&converter->output_type);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->output_type);
|
||||
+ converter->output_type = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ IMFMediaType_Release(converter->output_type);
|
||||
+ converter->output_type = NULL;
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,267 @@
|
||||
From c94cfbf0ec1c10452c2cf1496f32eeefe5794cea Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 15:22:20 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::Process(Input/Output) for color
|
||||
conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 159 +++++++++++++++++++++++++++++-
|
||||
1 file changed, 154 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index e7e84690738..b77f3358c52 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -55,6 +55,8 @@ struct color_converter
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
+ BOOL inflight;
|
||||
+ GstElement *container, *appsrc, *videoconvert, *appsink;
|
||||
};
|
||||
|
||||
static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
|
||||
@@ -100,6 +102,7 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface)
|
||||
{
|
||||
transform->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&transform->cs);
|
||||
+ gst_object_unref(transform->container);
|
||||
heap_free(transform);
|
||||
}
|
||||
|
||||
@@ -307,7 +310,8 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
if (!(input_caps = caps_from_mf_media_type(type)))
|
||||
return MF_E_INVALIDTYPE;
|
||||
|
||||
- gst_caps_unref(input_caps);
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ gst_caps_unref(input_caps);
|
||||
}
|
||||
|
||||
if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
@@ -316,6 +320,7 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
EnterCriticalSection(&converter->cs);
|
||||
|
||||
hr = S_OK;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
|
||||
if (type)
|
||||
{
|
||||
@@ -325,6 +330,9 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
|
||||
|
||||
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
|
||||
+ gst_caps_unref(input_caps);
|
||||
+
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IMFMediaType_Release(converter->input_type);
|
||||
@@ -337,6 +345,9 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
|
||||
converter->input_type = NULL;
|
||||
}
|
||||
|
||||
+ if (converter->input_type && converter->output_type)
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+
|
||||
LeaveCriticalSection(&converter->cs);
|
||||
|
||||
return hr;
|
||||
@@ -379,7 +390,8 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
if (!(output_caps = caps_from_mf_media_type(type)))
|
||||
return MF_E_INVALIDTYPE;
|
||||
|
||||
- gst_caps_unref(output_caps);
|
||||
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
+ gst_caps_unref(output_caps);
|
||||
}
|
||||
|
||||
if (flags & MFT_SET_TYPE_TEST_ONLY)
|
||||
@@ -388,6 +400,7 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
EnterCriticalSection(&converter->cs);
|
||||
|
||||
hr = S_OK;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
|
||||
if (type)
|
||||
{
|
||||
@@ -397,6 +410,9 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
|
||||
|
||||
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
|
||||
+ gst_caps_unref(output_caps);
|
||||
+
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IMFMediaType_Release(converter->output_type);
|
||||
@@ -409,6 +425,9 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
|
||||
converter->output_type = NULL;
|
||||
}
|
||||
|
||||
+ if (converter->input_type && converter->output_type)
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+
|
||||
LeaveCriticalSection(&converter->cs);
|
||||
|
||||
return hr;
|
||||
@@ -465,15 +484,102 @@ static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_ME
|
||||
|
||||
static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
{
|
||||
- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+ GstBuffer *gst_buffer;
|
||||
+ int ret;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+
|
||||
+ if (flags)
|
||||
+ WARN("Unsupported flags %#x\n", flags);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!converter->input_type || !converter->output_type)
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ }
|
||||
+
|
||||
+ if (converter->inflight)
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_NOTACCEPTING;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret);
|
||||
+ gst_buffer_unref(gst_buffer);
|
||||
+ if (ret != GST_FLOW_OK)
|
||||
+ {
|
||||
+ ERR("Couldn't push buffer ret = %d (%s)\n", ret, gst_flow_get_name(ret));
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ converter->inflight = TRUE;
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
|
||||
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
|
||||
{
|
||||
- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+ GstSample *sample;
|
||||
+
|
||||
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+
|
||||
+ if (flags)
|
||||
+ WARN("Unsupported flags %#x\n", flags);
|
||||
+
|
||||
+ if (!count)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ if (count != 1)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (samples[0].dwStreamID != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!converter->input_type || !converter->output_type)
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ }
|
||||
+
|
||||
+ if (!converter->inflight)
|
||||
+ {
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
|
||||
+ }
|
||||
+
|
||||
+ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
|
||||
+
|
||||
+ converter->inflight = FALSE;
|
||||
+
|
||||
+ samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
|
||||
+ gst_sample_unref(sample);
|
||||
+ samples[0].dwStatus = S_OK;
|
||||
+ samples[0].pEvents = NULL;
|
||||
+ *status = 0;
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return S_OK;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
@@ -523,6 +629,49 @@ HRESULT color_converter_create(REFIID riid, void **ret)
|
||||
InitializeCriticalSection(&object->cs);
|
||||
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock");
|
||||
|
||||
+ object->container = gst_bin_new(NULL);
|
||||
+
|
||||
+ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create appsrc, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->appsrc);
|
||||
+
|
||||
+ if (!(object->videoconvert = gst_element_factory_make("videoconvert", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create videoconvert, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->videoconvert);
|
||||
+
|
||||
+ if (!(object->appsink = gst_element_factory_make("appsink", NULL)))
|
||||
+ {
|
||||
+ ERR("Failed to create appsink, are %u-bit Gstreamer \"base\" plugins installed?\n",
|
||||
+ 8 * (int)sizeof(void *));
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->appsink);
|
||||
+
|
||||
+ if (!gst_element_link(object->appsrc, object->videoconvert))
|
||||
+ {
|
||||
+ ERR("Failed to link appsrc to videoconvert\n");
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if (!gst_element_link(object->videoconvert, object->appsink))
|
||||
+ {
|
||||
+ ERR("Failed to link videoconvert to appsink\n");
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
*ret = &object->IMFTransform_iface;
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,37 @@
|
||||
From d68df1b4131caa500cea5c4241be3c55b2728d4c Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 16:02:20 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::ProcessMessage for color
|
||||
conversion MFT.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index b77f3358c52..c07ef22acc3 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -477,9 +477,16 @@ static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id
|
||||
|
||||
static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||
{
|
||||
- FIXME("%p, %u %lu.\n", iface, message, param);
|
||||
+ TRACE("%p, %u %lu.\n", iface, message, param);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ switch(message)
|
||||
+ {
|
||||
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
|
||||
+ return S_OK;
|
||||
+ default:
|
||||
+ FIXME("Unhandled message type %x.\n", message);
|
||||
+ return E_NOTIMPL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,54 @@
|
||||
From e8eef3f90da399a077f5853e2a399c7e27a6418e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 3 Dec 2020 15:28:42 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement ::Get(Input/Output)StreamInfo for
|
||||
color conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/colorconvert.c | 23 +++++++++++++++++++----
|
||||
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
|
||||
index c07ef22acc3..43b8dddeee7 100644
|
||||
--- a/dlls/winegstreamer/colorconvert.c
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -138,16 +138,31 @@ static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD in
|
||||
|
||||
static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
{
|
||||
- FIXME("%p %u %p.\n", iface, id, info);
|
||||
+ TRACE("%p %u %p.\n", iface, id, info);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF;
|
||||
+ info->cbMaxLookahead = 0;
|
||||
+ info->cbAlignment = 0;
|
||||
+ info->hnsMaxLatency = 0;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
{
|
||||
- FIXME("%p %u %p.\n", iface, id, info);
|
||||
+ TRACE("%p %u %p.\n", iface, id, info);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ info->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
|
||||
+ info->cbSize = 0;
|
||||
+ info->cbAlignment = 0;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
--
|
||||
2.29.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user