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,
|
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)
|
HRESULT WINAPI MFCreateSampleCopierMFT(IMFTransform **transform)
|
||||||
{
|
{
|
||||||
struct sample_copier *object;
|
struct sample_copier *object;
|
||||||
|
|
|
@ -79,3 +79,5 @@ static inline const char *debugstr_time(LONGLONG time)
|
||||||
|
|
||||||
return wine_dbg_sprintf("%s", rev);
|
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);
|
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
|
||||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||||
todo_wine
|
|
||||||
ok(node_count == 3, "Unexpected node count %u.\n", node_count);
|
ok(node_count == 3, "Unexpected node count %u.\n", node_count);
|
||||||
|
|
||||||
for (i = 0; i < node_count; ++i)
|
for (i = 0; i < node_count; ++i)
|
||||||
|
|
|
@ -2364,6 +2364,119 @@ static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context,
|
||||||
return hr;
|
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)
|
static void topology_loader_resolve_complete(struct topoloader_context *context)
|
||||||
{
|
{
|
||||||
MF_TOPOLOGY_TYPE node_type;
|
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. */
|
/* Set MF_TOPONODE_STREAMID for all outputs. */
|
||||||
if (FAILED(IMFTopologyNode_GetItem(node, &MF_TOPONODE_STREAMID, NULL)))
|
if (FAILED(IMFTopologyNode_GetItem(node, &MF_TOPONODE_STREAMID, NULL)))
|
||||||
IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_STREAMID, 0);
|
IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_STREAMID, 0);
|
||||||
|
|
||||||
|
topology_loader_connect_d3d_aware_input(context, node);
|
||||||
}
|
}
|
||||||
else if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
else if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue