mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Updated mfplat-streaming-support patchset
This commit is contained in:
parent
2a073f334b
commit
47fea9ffa2
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
||||
From 485aa86f6b509c71e657c726df99c770ca2146bc Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 20 Nov 2020 12:50:16 -0600
|
||||
Subject: [PATCH] mf/topoloader: Move node connection responsibility to
|
||||
connection function.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/topology.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 8032e438b73..a09f6ef0ef4 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -2022,8 +2022,6 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context
|
||||
if (FAILED(IMFTopology_GetNodeByID(context->output_topology, id, &node)))
|
||||
topology_loader_clone_node(context, downstream_node, &node, context->marker + 1);
|
||||
|
||||
- IMFTopologyNode_ConnectOutput(upstream_node, output_index, node, input_index);
|
||||
-
|
||||
IMFTopologyNode_GetNodeType(upstream_node, &u_type);
|
||||
IMFTopologyNode_GetNodeType(downstream_node, &d_type);
|
||||
|
||||
@@ -2033,7 +2031,7 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
- return connectors[u_type][d_type](context, upstream_node, output_index, downstream_node, input_index);
|
||||
+ return connectors[u_type][d_type](context, upstream_node, output_index, node, input_index);
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context, unsigned int *layer_size)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,300 @@
|
||||
From c57374bb3b8a81524fff529b33e272234b03bb4c Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 20 Nov 2020 12:52:31 -0600
|
||||
Subject: [PATCH] mf/topoloader: Implement source node to sink node branch
|
||||
resolver.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/topology.c | 268 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 266 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index a09f6ef0ef4..4756a30895b 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1992,15 +1992,279 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM
|
||||
return hr;
|
||||
}
|
||||
|
||||
+struct available_output_type
|
||||
+{
|
||||
+ IMFMediaType *type;
|
||||
+ IMFTransform *transform;
|
||||
+};
|
||||
+
|
||||
+static HRESULT topology_loader_enumerate_output_types(GUID *category, IMFMediaType *input_type, HRESULT (*new_type)(struct available_output_type *, void *), void *context)
|
||||
+{
|
||||
+ MFT_REGISTER_TYPE_INFO mft_typeinfo;
|
||||
+ GUID major_type, subtype;
|
||||
+ IMFActivate **activates;
|
||||
+ UINT32 num_activates;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_GetMajorType(input_type, &major_type)))
|
||||
+ return hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_GetGUID(input_type, &MF_MT_SUBTYPE, &subtype)))
|
||||
+ return hr;
|
||||
+
|
||||
+ mft_typeinfo.guidMajorType = major_type;
|
||||
+ mft_typeinfo.guidSubtype = subtype;
|
||||
+
|
||||
+ if (FAILED(hr = MFTEnumEx(*category, MFT_ENUM_FLAG_ALL, &mft_typeinfo, NULL, &activates, &num_activates)))
|
||||
+ return hr;
|
||||
+
|
||||
+ hr = E_FAIL;
|
||||
+
|
||||
+ for (unsigned int i = 0; i < num_activates; i++)
|
||||
+ {
|
||||
+ IMFTransform *mft;
|
||||
+
|
||||
+ if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void**) &mft)))
|
||||
+ {
|
||||
+ IMFActivate_Release(activates[i]);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (SUCCEEDED(hr = IMFTransform_SetInputType(mft, 0, input_type, 0)))
|
||||
+ {
|
||||
+ struct available_output_type avail = {.transform = mft};
|
||||
+ unsigned int output_count = 0;
|
||||
+
|
||||
+ while (SUCCEEDED(IMFTransform_GetOutputAvailableType(mft, 0, output_count++, &avail.type)))
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = new_type(&avail, context)))
|
||||
+ {
|
||||
+ IMFActivate_Release(activates[i]);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ IMFActivate_ShutdownObject(activates[i]);
|
||||
+ IMFActivate_Release(activates[i]);
|
||||
+ }
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+struct connect_to_sink_context
|
||||
+{
|
||||
+ struct topoloader_context *context;
|
||||
+ IMFTopologyNode *src, *sink;
|
||||
+ IMFMediaTypeHandler *sink_mth;
|
||||
+};
|
||||
+
|
||||
+HRESULT connect_to_sink(struct available_output_type *type, void *context)
|
||||
+{
|
||||
+ IMFTopologyNode *node;
|
||||
+ struct connect_to_sink_context *ctx = context;
|
||||
+
|
||||
+ if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(ctx->sink_mth, type->type, NULL)))
|
||||
+ {
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
|
||||
+ IMFTopologyNode_SetObject(node, (IUnknown *) type->transform);
|
||||
+ IMFTopologyNode_ConnectOutput(ctx->src, 0, node, 0);
|
||||
+ IMFTopologyNode_ConnectOutput(node, 0, ctx->sink, 0);
|
||||
+
|
||||
+ IMFTopology_AddNode(ctx->context->output_topology, node);
|
||||
+ IMFTopologyNode_Release(node);
|
||||
+
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(ctx->sink_mth, type->type);
|
||||
+ IMFTransform_SetOutputType(type->transform, 0, type->type, 0);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ return MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION;
|
||||
+}
|
||||
+
|
||||
+struct connect_to_converter_context
|
||||
+{
|
||||
+ struct connect_to_sink_context sink_ctx;
|
||||
+ GUID *converter_category;
|
||||
+};
|
||||
+
|
||||
+HRESULT connect_to_converter(struct available_output_type *type, void *context)
|
||||
+{
|
||||
+ struct connect_to_converter_context *ctx = context;
|
||||
+ struct connect_to_sink_context sink_ctx;
|
||||
+ IMFTopologyNode *node;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (SUCCEEDED(connect_to_sink(type, &ctx->sink_ctx)))
|
||||
+ return S_OK;
|
||||
+
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
|
||||
+ IMFTopologyNode_SetObject(node, (IUnknown *) type->transform);
|
||||
+
|
||||
+ sink_ctx = ctx->sink_ctx;
|
||||
+ sink_ctx.src = node;
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(ctx->converter_category, type->type, connect_to_sink, &sink_ctx)))
|
||||
+ {
|
||||
+ IMFTopologyNode_ConnectOutput(ctx->sink_ctx.src, 0, node, 0);
|
||||
+
|
||||
+ IMFTopology_AddNode(ctx->sink_ctx.context->output_topology, node);
|
||||
+
|
||||
+ IMFTransform_SetOutputType(type->transform, 0, type->type, 0);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ IMFTopologyNode_Release(node);
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
typedef HRESULT (*p_topology_loader_connect_func)(struct topoloader_context *context, IMFTopologyNode *upstream_node,
|
||||
unsigned int output_index, IMFTopologyNode *downstream_node, unsigned int input_index);
|
||||
|
||||
static HRESULT topology_loader_connect_source_node(struct topoloader_context *context, IMFTopologyNode *upstream_node,
|
||||
unsigned int output_index, IMFTopologyNode *downstream_node, unsigned int input_index)
|
||||
{
|
||||
- FIXME("Unimplemented.\n");
|
||||
+ UINT32 enum_src_types, src_method = 0, sink_method = MF_CONNECT_ALLOW_DECODER;
|
||||
+ IMFMediaTypeHandler *src_mth = NULL, *sink_mth = NULL;
|
||||
+ struct connect_to_converter_context convert_ctx;
|
||||
+ unsigned int i, k, i_, k_, src_type_count;
|
||||
+ GUID major_type, decode_cat, convert_cat;
|
||||
+ struct connect_to_sink_context sink_ctx;
|
||||
+ IMFStreamDescriptor *desc = NULL;
|
||||
+ IMFStreamSink *stream_sink;
|
||||
+ IMFMediaType *media_type;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("attempting to connect %p:%u to %p:%u\n", upstream_node, output_index, downstream_node, input_index);
|
||||
+
|
||||
+ IMFTopologyNode_GetUnknown(upstream_node, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&desc);
|
||||
+
|
||||
+ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(desc, &src_mth)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeCount(src_mth, &src_type_count)))
|
||||
+ goto done;
|
||||
+
|
||||
+ IMFTopologyNode_GetObject(downstream_node, (IUnknown **)&stream_sink);
|
||||
+
|
||||
+ if (FAILED(hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &sink_mth)))
|
||||
+ {
|
||||
+ IMFStreamSink_Release(stream_sink);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ IMFStreamSink_Release(stream_sink);
|
||||
+
|
||||
+ IMFTopologyNode_GetUINT32(upstream_node, &MF_TOPONODE_CONNECT_METHOD, &src_method);
|
||||
+ IMFTopologyNode_GetUINT32(downstream_node, &MF_TOPONODE_CONNECT_METHOD, &sink_method);
|
||||
+ IMFTopology_GetUINT32(context->input_topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enum_src_types);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMajorType(src_mth, &major_type)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
+ {
|
||||
+ decode_cat = MFT_CATEGORY_AUDIO_DECODER;
|
||||
+ convert_cat = MFT_CATEGORY_AUDIO_EFFECT;
|
||||
+ }
|
||||
+ else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
+ {
|
||||
+ decode_cat = MFT_CATEGORY_VIDEO_DECODER;
|
||||
+ convert_cat = MFT_CATEGORY_VIDEO_EFFECT;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ hr = MF_E_INVALIDTYPE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ sink_ctx.context = context;
|
||||
+ sink_ctx.src = upstream_node;
|
||||
+ sink_ctx.sink = downstream_node;
|
||||
+ sink_ctx.sink_mth = sink_mth;
|
||||
+
|
||||
+ convert_ctx.sink_ctx = sink_ctx;
|
||||
+ convert_ctx.converter_category = &convert_cat;
|
||||
+
|
||||
+ i_ = (enum_src_types && src_method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES) ? src_type_count : 1;
|
||||
+ k_ = (enum_src_types && !(src_method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)) ? src_type_count : 1;
|
||||
+ for(i = 0; i < i_; i++)
|
||||
+ {
|
||||
+ /* MF_CONNECT_DIRECT */
|
||||
+ for (k = 0; k < k_; k++)
|
||||
+ {
|
||||
+ if (enum_src_types)
|
||||
+ {
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(src_mth, i * k, &media_type))) goto done;
|
||||
+ }
|
||||
+ else
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(src_mth, &media_type))) goto done;
|
||||
+
|
||||
+ if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(sink_mth, media_type, NULL)))
|
||||
+ {
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(src_mth, media_type);
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(sink_mth, media_type);
|
||||
+ IMFTopologyNode_ConnectOutput(upstream_node, output_index, downstream_node, input_index);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ }
|
||||
+
|
||||
+ for (k = 0; k < k_; k++)
|
||||
+ {
|
||||
+ if (enum_src_types)
|
||||
+ {
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(src_mth, i * k, &media_type))) goto done;
|
||||
+ }
|
||||
+ else
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(src_mth, &media_type))) goto done;
|
||||
+
|
||||
+ if (sink_method & MF_CONNECT_ALLOW_CONVERTER)
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&convert_cat, media_type, connect_to_sink, &sink_ctx)))
|
||||
+ {
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(src_mth, media_type);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ }
|
||||
+
|
||||
+ for (k = 0; k < k_; k++)
|
||||
+ {
|
||||
+ if (enum_src_types)
|
||||
+ {
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(src_mth, i * k, &media_type))) goto done;
|
||||
+ }
|
||||
+ else
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(src_mth, &media_type))) goto done;
|
||||
+
|
||||
+ if (sink_method & MF_CONNECT_ALLOW_DECODER)
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&decode_cat, media_type, connect_to_converter, &convert_ctx)))
|
||||
+ {
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(src_mth, media_type);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ }
|
||||
+ }
|
||||
+ hr = MF_E_INVALIDMEDIATYPE;
|
||||
+
|
||||
+ done:
|
||||
+ if (desc)
|
||||
+ IMFStreamDescriptor_Release(desc);
|
||||
+ if (src_mth)
|
||||
+ IMFMediaTypeHandler_Release(src_mth);
|
||||
+ if (sink_mth)
|
||||
+ IMFMediaTypeHandler_Release(sink_mth);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_resolve_branch(struct topoloader_context *context, IMFTopologyNode *upstream_node,
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From d60f2f4d4e5e4eb790e5d065afb554a008506d4f Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 20 Nov 2020 12:53:20 -0600
|
||||
Subject: [PATCH] mf/topoloader: Unstub IMFTopologyLoader::Load.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/topology.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 4756a30895b..99f3c12f190 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -2430,11 +2430,9 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
break;
|
||||
}
|
||||
|
||||
- /* For now return original topology. */
|
||||
-
|
||||
*ret_topology = output_topology;
|
||||
|
||||
- return IMFTopology_CloneFrom(output_topology, input_topology);
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static const IMFTopoLoaderVtbl topologyloadervtbl =
|
||||
--
|
||||
2.29.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,256 @@
|
||||
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,389 @@
|
||||
From db7e26f933c7f275c13c3c9d42066b9524cc703c 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
|
||||
conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 202 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 75 +++++++++++
|
||||
3 files changed, 273 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 04227d168ae..deb5ceb2f7c 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -24,7 +24,8 @@ struct audio_converter
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
- BOOL valid_state;
|
||||
+ BOOL valid_state, 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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
if (!(output_caps = caps_from_mf_media_type(converter->output_type)))
|
||||
{
|
||||
converter->valid_state = FALSE;
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
+ 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;
|
||||
}
|
||||
|
||||
+ 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);
|
||||
+
|
||||
+ 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))
|
||||
{
|
||||
gchar *input_caps_str, *output_caps_str;
|
||||
@@ -293,6 +327,7 @@ static void audio_converter_update_pipeline_state(struct audio_converter *conver
|
||||
|
||||
gst_caps_unref(input_caps);
|
||||
gst_caps_unref(output_caps);
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -496,17 +531,114 @@ 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;
|
||||
+ 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->valid_state)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (converter->inflight)
|
||||
+ {
|
||||
+ hr = MF_E_NOTACCEPTING;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ converter->inflight = TRUE;
|
||||
+
|
||||
+ done:
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
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;
|
||||
+ 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)
|
||||
+ return S_OK;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (!converter->valid_state)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!converter->inflight)
|
||||
+ {
|
||||
+ hr = MF_E_TRANSFORM_NEED_MORE_INPUT;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ 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));
|
||||
+ gst_sample_unref(sample);
|
||||
+ relevant_buffer->dwStatus = S_OK;
|
||||
+ relevant_buffer->pEvents = NULL;
|
||||
+ *status = 0;
|
||||
+
|
||||
+ done:
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
InitializeCriticalSection(&object->cs);
|
||||
|
||||
+ 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;
|
||||
+ }
|
||||
+ 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;
|
||||
+ }
|
||||
+ 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;
|
||||
+ }
|
||||
+ 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;
|
||||
+ }
|
||||
+ gst_bin_add(GST_BIN(object->container), object->appsink);
|
||||
+
|
||||
+ if (!(gst_element_link(object->appsrc, object->audioconvert)))
|
||||
+ {
|
||||
+ ERR("Failed to link appsrc to audioconvert\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_element_link(object->audioconvert, object->resampler)))
|
||||
+ {
|
||||
+ ERR("Failed to link audioconvert to resampler\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ if (!(gst_element_link(object->resampler, object->appsink)))
|
||||
+ {
|
||||
+ ERR("Failed to link resampler to appsink\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
*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
|
||||
--- 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
|
||||
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;
|
||||
+GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
|
||||
|
||||
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
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -877,3 +877,78 @@ done:
|
||||
|
||||
return out;
|
||||
}
|
||||
+
|
||||
+GstBuffer* gst_buffer_from_mf_sample(IMFSample *mf_sample)
|
||||
+{
|
||||
+ GstBuffer *out = gst_buffer_new();
|
||||
+ IMFMediaBuffer *mf_buffer = NULL;
|
||||
+ LONGLONG duration, time;
|
||||
+ DWORD buffer_count;
|
||||
+ unsigned int i;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetSampleTime(mf_sample, &time)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ GST_BUFFER_DURATION(out) = duration;
|
||||
+ GST_BUFFER_PTS(out) = time * 100;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ for (i = 0; i < buffer_count; i++)
|
||||
+ {
|
||||
+ DWORD buffer_max_size, buffer_size;
|
||||
+ GstMapInfo map_info;
|
||||
+ GstMemory *memory;
|
||||
+ BYTE *buf_data;
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ memory = gst_allocator_alloc(NULL, buffer_size, NULL);
|
||||
+ gst_memory_resize(memory, 0, buffer_size);
|
||||
+
|
||||
+ if (!(gst_memory_map(memory, &map_info, GST_MAP_WRITE)))
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ memcpy(map_info.data, buf_data, buffer_size);
|
||||
+
|
||||
+ 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);
|
||||
+
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ mf_buffer = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return out;
|
||||
+
|
||||
+fail:
|
||||
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
|
||||
+ if (mf_buffer)
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ gst_buffer_unref(out);
|
||||
+ return NULL;
|
||||
+}
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 0a944954888cbe4ea094a7e97c9f19db2aa358d6 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
|
||||
audio conversion transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 29 +++++++++++++++++++++++++----
|
||||
1 file changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index deb5ceb2f7c..cb7d4a15bf8 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
|
||||
|
||||
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);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p %u %p\n", converter, id, info);
|
||||
+
|
||||
+ 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 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 = {};
|
||||
|
||||
- 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;
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,85 @@
|
||||
From a84dafe62e44de78320b121fb45dae042e6b3099 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
|
||||
converter transform.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 30 ++++++++++++++++++++++++++----
|
||||
1 file changed, 26 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index cb7d4a15bf8..7d19b561dd1 100644
|
||||
--- a/dlls/winegstreamer/audioconvert.c
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -21,6 +21,8 @@ struct audio_converter
|
||||
{
|
||||
IMFTransform IMFTransform_iface;
|
||||
LONG refcount;
|
||||
+ IMFAttributes *attributes;
|
||||
+ IMFAttributes *output_attributes;
|
||||
IMFMediaType *input_type;
|
||||
IMFMediaType *output_type;
|
||||
CRITICAL_SECTION cs;
|
||||
@@ -70,6 +72,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
if (!refcount)
|
||||
{
|
||||
DeleteCriticalSection(&transform->cs);
|
||||
+ if (transform->attributes)
|
||||
+ IMFAttributes_Release(transform->attributes);
|
||||
+ if (transform->output_attributes)
|
||||
+ IMFAttributes_Release(transform->output_attributes);
|
||||
gst_object_unref(transform->container);
|
||||
heap_free(transform);
|
||||
}
|
||||
@@ -141,9 +147,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);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %p.\n", iface, attributes);
|
||||
+
|
||||
+ *attributes = transform->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
|
||||
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);
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ *attributes = transform->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)
|
||||
|
||||
InitializeCriticalSection(&object->cs);
|
||||
|
||||
+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
|
||||
+ goto failed;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
|
||||
+ goto failed;
|
||||
+
|
||||
object->container = gst_bin_new(NULL);
|
||||
|
||||
if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
|
||||
--
|
||||
2.29.2
|
||||
|
@ -0,0 +1,83 @@
|
||||
From e95595f362fd016cfbba18a88837660efcc75b85 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.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/audioconvert.c | 52 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 48 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
index 7d19b561dd1..5e714fed638 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
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
{
|
||||
- FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ IMFMediaType *ret;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p.\n", converter, id, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&ret)))
|
||||
+ return hr;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (converter->input_type)
|
||||
+ hr = IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *)ret);
|
||||
+ else
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ *type = ret;
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
{
|
||||
- FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ IMFMediaType *ret;
|
||||
+ HRESULT hr;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ TRACE("%p, %u, %p.\n", converter, id, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&ret)))
|
||||
+ return hr;
|
||||
+
|
||||
+ EnterCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (converter->output_type)
|
||||
+ hr = IMFMediaType_CopyAllItems(converter->output_type, (IMFAttributes *)ret);
|
||||
+ else
|
||||
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+
|
||||
+ LeaveCriticalSection(&converter->cs);
|
||||
+
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ *type = ret;
|
||||
+
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,36 +1,36 @@
|
||||
From 5200b2daf7544fac24238aa4c9a1c4a4e0891640 Mon Sep 17 00:00:00 2001
|
||||
From 421665f7dc9a8f305b63ac13a994fb2198e71714 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 1 May 2020 13:20:49 -0500
|
||||
Subject: [PATCH 26/45] winegstreamer: Implement Color Converter MFT.
|
||||
Subject: [PATCH] winegstreamer: Implement Color Converter MFT.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/Makefile.in | 1 +
|
||||
dlls/winegstreamer/colorconvert.c | 704 +++++++++++++++++++
|
||||
dlls/winegstreamer/gst_private.h | 2 +
|
||||
dlls/winegstreamer/colorconvert.c | 706 +++++++++++++++++++
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 36 +
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
|
||||
5 files changed, 749 insertions(+)
|
||||
5 files changed, 750 insertions(+)
|
||||
create mode 100644 dlls/winegstreamer/colorconvert.c
|
||||
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index e2af4085827..a266b0a95e4 100644
|
||||
index 0b3229160b9..5395d6fd501 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||
PARENTSRC = ../strmbase ../mf
|
||||
@@ -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..f01373907ee
|
||||
index 00000000000..da2189d85e4
|
||||
--- /dev/null
|
||||
+++ b/dlls/winegstreamer/colorconvert.c
|
||||
@@ -0,0 +1,704 @@
|
||||
@@ -0,0 +1,706 @@
|
||||
+#include "config.h"
|
||||
+#include <gst/gst.h>
|
||||
+
|
||||
@ -305,6 +305,8 @@ index 00000000000..f01373907ee
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_MAJOR_TYPE);
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_FRAME_SIZE);
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_FRAME_RATE);
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_COMPRESSED);
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_ALL_SAMPLES_INDEPENDENT);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, raw_types[index])))
|
||||
+ {
|
||||
@ -735,46 +737,51 @@ index 00000000000..f01373907ee
|
||||
+ IMFTransform_Release(&object->IMFTransform_iface);
|
||||
+ return hr;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index cebd8d5282f..eb467ffeeea 100644
|
||||
index 7f96c06dfaf..1fa13560e8a 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -94,4 +94,6 @@ enum decoder_type
|
||||
HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
|
||||
@@ -86,5 +86,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 b699c1dc8ec..0b177198e5e 100644
|
||||
index 7fdf722ec2e..e5255937387 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -420,6 +420,9 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret)
|
||||
{
|
||||
return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV);
|
||||
}
|
||||
+
|
||||
@@ -407,6 +407,8 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a
|
||||
|
||||
static GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
|
||||
|
||||
+static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}};
|
||||
+
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -432,6 +435,7 @@ class_objects[] =
|
||||
{ &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
|
||||
{ &CLSID_CMSAACDecMFT, &aac_decoder_create },
|
||||
{ &CLSID_CWMVDecMediaObject, &wmv_decoder_create },
|
||||
@@ -417,6 +419,7 @@ class_objects[] =
|
||||
{ &CLSID_VideoProcessorMFT, &video_processor_create },
|
||||
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
|
||||
{ &CLSID_WINEAudioConverter, &audio_converter_create },
|
||||
+ { &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -460,6 +464,26 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -445,6 +448,7 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
+static WCHAR color_converterW[] = {'C','o','l','o','r',' ','C','o','n','v','e','r','t','e','r',0};
|
||||
+
|
||||
static WCHAR audio_converterW[] = {'A','u','d','i','o',' ','C','o','n','v','e','r','t','e','r',0};
|
||||
const GUID *audio_converter_supported_types[] =
|
||||
{
|
||||
@@ -452,6 +456,26 @@ 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,
|
||||
@ -793,13 +800,14 @@ index b699c1dc8ec..0b177198e5e 100644
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+ &MFVideoFormat_YVYU,
|
||||
+};
|
||||
|
||||
static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0};
|
||||
const GUID *h264_decoder_input_types[] =
|
||||
@@ -525,6 +549,18 @@ static const struct mft
|
||||
}
|
||||
mfts[] =
|
||||
+
|
||||
static const struct mft
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -479,6 +503,18 @@ mfts[] =
|
||||
audio_converter_supported_types,
|
||||
NULL
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_CColorConvertDMO,
|
||||
+ &MFT_CATEGORY_VIDEO_EFFECT,
|
||||
@ -812,17 +820,17 @@ index b699c1dc8ec..0b177198e5e 100644
|
||||
+ color_converter_supported_types,
|
||||
+ NULL
|
||||
+ },
|
||||
{
|
||||
&CLSID_CMSH264DecoderMFT,
|
||||
&MFT_CATEGORY_VIDEO_DECODER,
|
||||
};
|
||||
|
||||
HRESULT mfplat_DllRegisterServer(void)
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index f9b0158fa6a..1556b6cff9f 100644
|
||||
index cf1fc69f38a..9788fd45d36 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -79,3 +79,9 @@ coclass CMSAACDecMFT { }
|
||||
uuid(82d353df-90bd-4382-8bc2-3f6192b76e34)
|
||||
@@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {}
|
||||
uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
|
||||
]
|
||||
coclass CLSID_CWMVDecMediaObject {}
|
||||
coclass WINEAudioConverter { }
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
@ -830,5 +838,5 @@ index f9b0158fa6a..1556b6cff9f 100644
|
||||
+]
|
||||
+coclass CColorConvertDMO { }
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 21b3adc827428ea014e2d02ef955efeffd965999 Mon Sep 17 00:00:00 2001
|
||||
From 364f264ab7d77047fe9082cdeab885fe0461c68f Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 14 Oct 2020 11:07:05 -0500
|
||||
Subject: [PATCH 04/45] mf: Unconditionally deliver NULL (EOS) samples.
|
||||
Subject: [PATCH] mf/session: Unconditionally deliver NULL (EOS) samples.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index a1b54b7080e..7c82aa42a4b 100644
|
||||
index 1a7439a13c3..07e29cd013f 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2599,11 +2599,12 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
@@ -2858,11 +2858,12 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
LIST_FOR_EACH_ENTRY_SAFE(sample_entry, sample_entry2, &topo_node->u.transform.outputs[i].samples,
|
||||
struct sample, entry)
|
||||
{
|
||||
@ -28,5 +28,5 @@ index a1b54b7080e..7c82aa42a4b 100644
|
||||
transform_release_sample(sample_entry);
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 651f85c986806d5ae08f9e471fdca3139e57da1e Mon Sep 17 00:00:00 2001
|
||||
From c6cfead684074a72b5f55a2f5f4070a743b09862 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 2 Apr 2020 15:42:18 -0500
|
||||
Subject: [PATCH] mf: Ask for more samples from upstream node when upon
|
||||
MF_E_TRANSFORM_NEED_MORE_INPUT
|
||||
Subject: [PATCH] mf/session: Request more samples when a transform needs them.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/session.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index 75bc669f8fd..42f28702ddd 100644
|
||||
index 07e29cd013f..5a08a2eb6c6 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2534,6 +2534,8 @@ static HRESULT transform_node_pull_samples(const struct media_session *session,
|
||||
@@ -2759,6 +2759,8 @@ static HRESULT transform_node_pull_samples(const struct media_session *session,
|
||||
return hr;
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ index 75bc669f8fd..42f28702ddd 100644
|
||||
static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input,
|
||||
IMFSample *sample)
|
||||
{
|
||||
@@ -2609,7 +2611,14 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
@@ -2834,7 +2836,14 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
WARN("Drain command failed for transform, hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
@ -38,5 +38,5 @@ index 75bc669f8fd..42f28702ddd 100644
|
||||
/* Remaining unprocessed input has been discarded, now queue markers for every output. */
|
||||
if (drain)
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 17153f26c5b725631a72e28a3330dfaf010d8ed7 Mon Sep 17 00:00:00 2001
|
||||
From c6563305821336faffd5089cf9ee365bcbaf1f05 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 7 May 2020 13:09:47 -0500
|
||||
Subject: [PATCH 31/45] winegstreamer: Implement IMFMediaSource::Stop.
|
||||
Subject: [PATCH] winegstreamer: Implement IMFMediaSource::Stop.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 30 ++++++++++++++++++++++++++++--
|
||||
1 file changed, 28 insertions(+), 2 deletions(-)
|
||||
dlls/winegstreamer/media_source.c | 29 +++++++++++++++++++++++++++--
|
||||
1 file changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 9a6b2b8242c..20417bca8f6 100644
|
||||
index 5c502cf3ed5..7d677e39feb 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -65,6 +65,7 @@ struct media_stream
|
||||
@@ -64,6 +64,7 @@ struct media_stream
|
||||
enum source_async_op
|
||||
{
|
||||
SOURCE_ASYNC_START,
|
||||
@ -20,13 +20,12 @@ index 9a6b2b8242c..20417bca8f6 100644
|
||||
SOURCE_ASYNC_REQUEST_SAMPLE,
|
||||
};
|
||||
|
||||
@@ -356,6 +357,23 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
|
||||
@@ -343,6 +344,22 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
|
||||
gst_element_set_state(source->container, GST_STATE_PLAYING);
|
||||
}
|
||||
|
||||
+static void stop_pipeline(struct media_source *source)
|
||||
+{
|
||||
+ /* TODO: seek to beginning */
|
||||
+ gst_element_set_state(source->container, GST_STATE_PAUSED);
|
||||
+
|
||||
+ for (unsigned int i = 0; i < source->stream_count; i++)
|
||||
@ -44,7 +43,7 @@ index 9a6b2b8242c..20417bca8f6 100644
|
||||
static void dispatch_end_of_presentation(struct media_source *source)
|
||||
{
|
||||
PROPVARIANT empty = {.vt = VT_EMPTY};
|
||||
@@ -430,6 +448,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA
|
||||
@@ -417,6 +434,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA
|
||||
case SOURCE_ASYNC_START:
|
||||
start_pipeline(source, command);
|
||||
break;
|
||||
@ -54,7 +53,7 @@ index 9a6b2b8242c..20417bca8f6 100644
|
||||
case SOURCE_ASYNC_REQUEST_SAMPLE:
|
||||
wait_on_sample(command->u.request_sample.stream, command->u.request_sample.token);
|
||||
break;
|
||||
@@ -1201,13 +1222,18 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD
|
||||
@@ -1087,13 +1107,18 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD
|
||||
static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface)
|
||||
{
|
||||
struct media_source *source = impl_from_IMFMediaSource(iface);
|
||||
@ -76,5 +75,5 @@ index 9a6b2b8242c..20417bca8f6 100644
|
||||
|
||||
static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface)
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -0,0 +1,24 @@
|
||||
From ae56ea765474f1881070e72fa029b3a5229a97db Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Nov 2020 12:29:50 -0500
|
||||
Subject: [PATCH] Set MF_MT_ALL_SAMPLES_INDEPENDENT on raw video types.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index e5255937387..4e0a9c10f9d 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -610,6 +610,7 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
unsigned int i;
|
||||
|
||||
IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, FALSE);
|
||||
+ IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
|
||||
|
||||
/* First try FOURCC */
|
||||
if ((fourcc_subtype.Data1 = gst_video_format_to_fourcc(video_info.finfo->format)))
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,17 +1,17 @@
|
||||
From 064abcfc3ae7b8704ed5b31f4dd8b1c23127f4b3 Mon Sep 17 00:00:00 2001
|
||||
From 446501feb60dbff0305449647b316ab99ecbb995 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 15 Oct 2020 12:18:10 -0500
|
||||
Subject: [PATCH 45/45] HACK: Flush decoder when changing times.
|
||||
Subject: [PATCH] HACK: Flush decoder when changing times.
|
||||
|
||||
---
|
||||
dlls/mf/session.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index 6fce432da72..856daebf6b4 100644
|
||||
index ae10548b304..b29cacf8a77 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2094,7 +2094,10 @@ static void session_set_presentation_clock(struct media_session *session)
|
||||
@@ -2331,7 +2331,10 @@ static void session_set_presentation_clock(struct media_session *session)
|
||||
LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry)
|
||||
{
|
||||
if (node->type == MF_TOPOLOGY_TRANSFORM_NODE)
|
||||
@ -23,5 +23,5 @@ index 6fce432da72..856daebf6b4 100644
|
||||
|
||||
if (!(session->presentation.flags & SESSION_FLAG_PRESENTATION_CLOCK_SET))
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,108 +0,0 @@
|
||||
From e92f897fc9590659e579ee2d5cf366b5eeb617f4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 10:43:27 -0500
|
||||
Subject: [PATCH 18/45] Introduce IMFSample -> GstBuffer converter.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 74 ++++++++++++++++++++++++++++++++
|
||||
2 files changed, 75 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 75fc7dc90a8..321143396d6 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -82,6 +82,7 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) DECLSPEC_HIDDEN;
|
||||
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;
|
||||
+GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 15c38254bf5..7b7300d5e8e 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1323,3 +1323,77 @@ done:
|
||||
|
||||
return out;
|
||||
}
|
||||
+
|
||||
+GstBuffer* gst_buffer_from_mf_sample(IMFSample *mf_sample)
|
||||
+{
|
||||
+ GstBuffer *out = gst_buffer_new();
|
||||
+ IMFMediaBuffer *mf_buffer = NULL;
|
||||
+ LONGLONG duration, time;
|
||||
+ DWORD buffer_count;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetSampleTime(mf_sample, &time)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ GST_BUFFER_DURATION(out) = duration;
|
||||
+ GST_BUFFER_PTS(out) = time * 100;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ for (unsigned int i = 0; i < buffer_count; i++)
|
||||
+ {
|
||||
+ DWORD buffer_max_size, buffer_size;
|
||||
+ GstMapInfo map_info;
|
||||
+ GstMemory *memory;
|
||||
+ BYTE *buf_data;
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ memory = gst_allocator_alloc(NULL, buffer_size, NULL);
|
||||
+ gst_memory_resize(memory, 0, buffer_size);
|
||||
+
|
||||
+ if (!(gst_memory_map(memory, &map_info, GST_MAP_WRITE)))
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ memcpy(map_info.data, buf_data, buffer_size);
|
||||
+
|
||||
+ 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);
|
||||
+
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ mf_buffer = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return out;
|
||||
+
|
||||
+fail:
|
||||
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
|
||||
+ if (mf_buffer)
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ gst_buffer_unref(out);
|
||||
+ return NULL;
|
||||
+}
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From ab1e5e5535fc22d14e64d8f6b0f42188440f6884 Mon Sep 17 00:00:00 2001
|
||||
From 1506f79c2e68478112ee52709a19a4a298ebc399 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 2 Nov 2020 09:56:54 -0600
|
||||
Subject: [PATCH] winegstreamer: Add IMFSeekInfo::GetNearestKeyFrames stub.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 111 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 5c502cf3ed5..f08ab77746e 100644
|
||||
index 7d677e39feb..18d9f016aa0 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -91,6 +91,8 @@ struct source_async_command
|
||||
@@ -92,6 +92,8 @@ struct source_async_command
|
||||
struct media_source
|
||||
{
|
||||
IMFMediaSource IMFMediaSource_iface;
|
||||
@ -21,7 +21,7 @@ index 5c502cf3ed5..f08ab77746e 100644
|
||||
IMFAsyncCallback async_commands_callback;
|
||||
LONG ref;
|
||||
DWORD async_commands_queue;
|
||||
@@ -123,6 +125,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac
|
||||
@@ -124,6 +126,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac
|
||||
return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ index 5c502cf3ed5..f08ab77746e 100644
|
||||
static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct media_source, async_commands_callback);
|
||||
@@ -956,6 +968,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID
|
||||
@@ -976,6 +988,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID
|
||||
{
|
||||
*out = &source->IMFMediaSource_iface;
|
||||
}
|
||||
@ -49,7 +49,7 @@ index 5c502cf3ed5..f08ab77746e 100644
|
||||
else
|
||||
{
|
||||
FIXME("(%s, %p)\n", debugstr_guid(riid), out);
|
||||
@@ -1185,6 +1201,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
@@ -1210,6 +1226,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
media_source_Shutdown,
|
||||
};
|
||||
|
||||
@ -149,7 +149,7 @@ index 5c502cf3ed5..f08ab77746e 100644
|
||||
static void stream_added(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct media_source *source = user;
|
||||
@@ -1256,6 +1365,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1281,6 +1390,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl;
|
@ -1,4 +1,4 @@
|
||||
From 1aa3dc5dc91f16a896a88c6fd1537b2e537415a6 Mon Sep 17 00:00:00 2001
|
||||
From 938b5aed7b1f752ee15a17a7bd501ba9945df7e2 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 6 Nov 2020 10:06:23 -0600
|
||||
Subject: [PATCH] winegstreamer: Fixup raw audio caps to be compatible with
|
||||
@ -12,7 +12,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
3 files changed, 64 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 28e424439d8..75fc7dc90a8 100644
|
||||
index 1fa13560e8a..6a6da817d58 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -78,6 +78,7 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN;
|
||||
@ -24,10 +24,10 @@ index 28e424439d8..75fc7dc90a8 100644
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
|
||||
IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index cdde75b9892..e0e1b410613 100644
|
||||
index 18d9f016aa0..83891153bc0 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -869,15 +869,20 @@ fail:
|
||||
@@ -889,15 +889,20 @@ fail:
|
||||
|
||||
static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
{
|
||||
@ -50,10 +50,10 @@ index cdde75b9892..e0e1b410613 100644
|
||||
|
||||
if (!strcmp(major_type, "video/x-raw"))
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 3d224a5accc..7a877c2a416 100644
|
||||
index 4e0a9c10f9d..dd8b1a2a542 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -602,6 +602,63 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -716,6 +716,63 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
return media_type;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 0913eb045e183f568c9e3962cd09e3624a7893b9 Mon Sep 17 00:00:00 2001
|
||||
From c7474cf94097b935da7b135c9f911e048b97f47f Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 2 Nov 2020 10:18:27 -0600
|
||||
Subject: [PATCH] winegstreamer: Set MF_PD_MIME_TYPE on source's presentation
|
||||
@ -10,18 +10,18 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index a60cdbc8800..81c5c197072 100644
|
||||
index 83891153bc0..ba6bddc0af5 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1351,6 +1351,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1375,6 +1375,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
GST_STATIC_PAD_TEMPLATE("mf_src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
|
||||
|
||||
IMFStreamDescriptor **descriptors = NULL;
|
||||
struct media_source *object;
|
||||
+ IMFAttributes *byte_stream_attributes;
|
||||
struct media_source *object;
|
||||
gint64 total_pres_time = 0;
|
||||
DWORD bytestream_caps;
|
||||
unsigned int i;
|
||||
@@ -1493,6 +1494,18 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1518,6 +1519,18 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
if (object->stream_count)
|
||||
IMFPresentationDescriptor_SetUINT64(object->pres_desc, &MF_PD_DURATION, total_pres_time / 100);
|
||||
|
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