mf/topoloader: Add copier transform automatically for D3D-aware outputs.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
deda3f8172
commit
79776e4540
|
@ -561,6 +561,14 @@ static const IMFTransformVtbl sample_copier_transform_vtbl =
|
|||
sample_copier_transform_ProcessOutput,
|
||||
};
|
||||
|
||||
BOOL mf_is_sample_copier_transform(IUnknown *transform)
|
||||
{
|
||||
return transform->lpVtbl == (IUnknownVtbl *)&sample_copier_transform_vtbl;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MFCreateSampleCopierMFT (mf.@)
|
||||
*/
|
||||
HRESULT WINAPI MFCreateSampleCopierMFT(IMFTransform **transform)
|
||||
{
|
||||
struct sample_copier *object;
|
||||
|
|
|
@ -79,3 +79,5 @@ static inline const char *debugstr_time(LONGLONG time)
|
|||
|
||||
return wine_dbg_sprintf("%s", rev);
|
||||
}
|
||||
|
||||
extern BOOL mf_is_sample_copier_transform(IUnknown *transform) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -2213,7 +2213,6 @@ static void test_topology_loader_evr(void)
|
|||
|
||||
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
todo_wine
|
||||
ok(node_count == 3, "Unexpected node count %u.\n", node_count);
|
||||
|
||||
for (i = 0; i < node_count; ++i)
|
||||
|
|
|
@ -2364,6 +2364,119 @@ static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context,
|
|||
return hr;
|
||||
}
|
||||
|
||||
static BOOL topology_loader_is_node_d3d_aware(IMFTopologyNode *node)
|
||||
{
|
||||
IMFAttributes *attributes;
|
||||
unsigned int d3d_aware = 0;
|
||||
IUnknown *object = NULL;
|
||||
|
||||
if (FAILED(IMFTopologyNode_GetObject(node, &object)))
|
||||
return FALSE;
|
||||
|
||||
if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFAttributes, (void **)&attributes)))
|
||||
{
|
||||
IMFAttributes_GetUINT32(attributes, &MF_SA_D3D_AWARE, &d3d_aware);
|
||||
IMFAttributes_Release(attributes);
|
||||
}
|
||||
|
||||
if (!d3d_aware)
|
||||
d3d_aware = mf_is_sample_copier_transform(object);
|
||||
|
||||
IUnknown_Release(object);
|
||||
|
||||
return !!d3d_aware;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_create_copier(IMFTopologyNode *upstream_node, unsigned int upstream_output,
|
||||
IMFTopologyNode *downstream_node, unsigned int downstream_input, IMFTransform **copier)
|
||||
{
|
||||
IMFMediaType *input_type = NULL, *output_type = NULL;
|
||||
IMFTransform *transform;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = MFCreateSampleCopierMFT(&transform)))
|
||||
return hr;
|
||||
|
||||
if (FAILED(hr = MFGetTopoNodeCurrentType(upstream_node, upstream_output, TRUE, &input_type)))
|
||||
WARN("Failed to get upstream media type hr %#x.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && FAILED(hr = MFGetTopoNodeCurrentType(downstream_node, downstream_input, FALSE, &output_type)))
|
||||
WARN("Failed to get downstream media type hr %#x.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && FAILED(hr = IMFTransform_SetInputType(transform, 0, input_type, 0)))
|
||||
WARN("Input type wasn't accepted, hr %#x.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && FAILED(hr = IMFTransform_SetOutputType(transform, 0, output_type, 0)))
|
||||
WARN("Output type wasn't accepted, hr %#x.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*copier = transform;
|
||||
IMFTransform_AddRef(*copier);
|
||||
}
|
||||
|
||||
if (input_type)
|
||||
IMFMediaType_Release(input_type);
|
||||
if (output_type)
|
||||
IMFMediaType_Release(output_type);
|
||||
|
||||
IMFTransform_Release(transform);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_connect_copier(struct topoloader_context *context, IMFTopologyNode *upstream_node,
|
||||
unsigned int upstream_output, IMFTopologyNode *downstream_node, unsigned int downstream_input, IMFTransform *copier)
|
||||
{
|
||||
IMFTopologyNode *copier_node;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &copier_node)))
|
||||
return hr;
|
||||
|
||||
IMFTopologyNode_SetObject(copier_node, (IUnknown *)copier);
|
||||
IMFTopology_AddNode(context->output_topology, copier_node);
|
||||
IMFTopologyNode_ConnectOutput(upstream_node, upstream_output, copier_node, 0);
|
||||
IMFTopologyNode_ConnectOutput(copier_node, 0, downstream_node, downstream_input);
|
||||
|
||||
IMFTopologyNode_Release(copier_node);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Right now this should be used for output nodes only. */
|
||||
static HRESULT topology_loader_connect_d3d_aware_input(struct topoloader_context *context,
|
||||
IMFTopologyNode *node)
|
||||
{
|
||||
IMFTopologyNode *upstream_node;
|
||||
unsigned int upstream_output;
|
||||
IMFStreamSink *stream_sink;
|
||||
IMFTransform *copier = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
IMFTopologyNode_GetObject(node, (IUnknown **)&stream_sink);
|
||||
|
||||
if (topology_loader_is_node_d3d_aware(node))
|
||||
{
|
||||
if (SUCCEEDED(IMFTopologyNode_GetInput(node, 0, &upstream_node, &upstream_output)))
|
||||
{
|
||||
if (!topology_loader_is_node_d3d_aware(upstream_node))
|
||||
{
|
||||
if (SUCCEEDED(hr = topology_loader_create_copier(upstream_node, upstream_output, node, 0, &copier)))
|
||||
{
|
||||
hr = topology_loader_connect_copier(context, upstream_node, upstream_output, node, 0, copier);
|
||||
IMFTransform_Release(copier);
|
||||
}
|
||||
}
|
||||
IMFTopologyNode_Release(upstream_node);
|
||||
}
|
||||
}
|
||||
|
||||
IMFStreamSink_Release(stream_sink);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void topology_loader_resolve_complete(struct topoloader_context *context)
|
||||
{
|
||||
MF_TOPOLOGY_TYPE node_type;
|
||||
|
@ -2383,6 +2496,8 @@ static void topology_loader_resolve_complete(struct topoloader_context *context)
|
|||
/* Set MF_TOPONODE_STREAMID for all outputs. */
|
||||
if (FAILED(IMFTopologyNode_GetItem(node, &MF_TOPONODE_STREAMID, NULL)))
|
||||
IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_STREAMID, 0);
|
||||
|
||||
topology_loader_connect_d3d_aware_input(context, node);
|
||||
}
|
||||
else if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue