[PATCH 4/5] winegstreamer: Implement ::GetInputAvailableType for decode transform.

Derek Lesho dlesho at codeweavers.com
Wed Mar 10 13:33:41 CST 2021


Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
 dlls/winegstreamer/decode_transform.c | 60 +++++++++++++++++++++++++--
 dlls/winegstreamer/gst_private.h      |  6 ++-
 dlls/winegstreamer/mfplat.c           |  7 +++-
 3 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
index f5d4763bde4..55a0c1c6c9b 100644
--- a/dlls/winegstreamer/decode_transform.c
+++ b/dlls/winegstreamer/decode_transform.c
@@ -29,10 +29,33 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 
+const GUID *h264_input_types[] = {&MFVideoFormat_H264};
+/* NV12 comes first https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order . thanks to @vitorhnn */
+const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12};
+
+static struct decoder_desc
+{
+    const GUID *major_type;
+    const GUID **input_types;
+    unsigned int input_types_count;
+    const GUID **output_types;
+    unsigned int output_types_count;
+} decoder_descs[] =
+{
+    { /* DECODER_TYPE_H264 */
+        &MFMediaType_Video,
+        h264_input_types,
+        ARRAY_SIZE(h264_input_types),
+        h264_output_types,
+        ARRAY_SIZE(h264_output_types),
+    },
+};
+
 struct mf_decoder
 {
     IMFTransform IMFTransform_iface;
     LONG refcount;
+    enum decoder_type type;
 };
 
 static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface)
@@ -163,9 +186,36 @@ static HRESULT WINAPI mf_decoder_AddInputStreams(IMFTransform *iface, DWORD stre
 static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
         IMFMediaType **type)
 {
-    FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+    struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+    IMFMediaType *input_type;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("%p, %u, %u, %p\n", decoder, id, index, type);
+
+    if (id != 0)
+        return MF_E_INVALIDSTREAMNUMBER;
+
+    if (index >= decoder_descs[decoder->type].input_types_count)
+        return MF_E_NO_MORE_TYPES;
+
+    if (FAILED(hr = MFCreateMediaType(&input_type)))
+        return hr;
+
+    if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type)))
+    {
+        IMFMediaType_Release(input_type);
+        return hr;
+    }
+
+    if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_SUBTYPE, decoder_descs[decoder->type].input_types[index])))
+    {
+        IMFMediaType_Release(input_type);
+        return hr;
+    }
+
+    *type = input_type;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
@@ -284,11 +334,11 @@ static const IMFTransformVtbl mf_decoder_vtbl =
     mf_decoder_ProcessOutput,
 };
 
-HRESULT decode_transform_create(REFIID riid, void **obj)
+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type)
 {
     struct mf_decoder *object;
 
-    TRACE("%s, %p.\n", debugstr_guid(riid), obj);
+    TRACE("%s, %p %u.\n", debugstr_guid(riid), obj, type);
 
     if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
@@ -296,6 +346,8 @@ HRESULT decode_transform_create(REFIID riid, void **obj)
     object->IMFTransform_iface.lpVtbl = &mf_decoder_vtbl;
     object->refcount = 1;
 
+    object->type = type;
+
     *obj = &object->IMFTransform_iface;
     return S_OK;
 }
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index c97c874fd68..54aba7a09ae 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -216,6 +216,10 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
 
 HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
 
-HRESULT decode_transform_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+enum decoder_type
+{
+    DECODER_TYPE_H264,
+};
+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
 
 #endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index cb862375276..65c55e4835d 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -402,6 +402,11 @@ 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 HRESULT h264_decoder_create(REFIID riid, void **ret)
+{
+    return decode_transform_create(riid, ret, DECODER_TYPE_H264);
+}
+
 static const struct class_object
 {
     const GUID *clsid;
@@ -412,7 +417,7 @@ class_objects[] =
     { &CLSID_VideoProcessorMFT, &video_processor_create },
     { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
     { &CLSID_WINEAudioConverter, &audio_converter_create },
-    { &CLSID_CMSH264DecoderMFT, &decode_transform_create },
+    { &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
 };
 
 HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
-- 
2.30.1




More information about the wine-devel mailing list