mf/topology: Implement MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES connection method.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0abc002a3e
commit
33ea3fc806
|
@ -2010,7 +2010,10 @@ struct connect_context
|
|||
IMFTopologyNode *upstream_node;
|
||||
IMFTopologyNode *sink;
|
||||
IMFMediaTypeHandler *sink_handler;
|
||||
const GUID *converter_category;
|
||||
unsigned int output_index;
|
||||
unsigned int input_index;
|
||||
GUID converter_category;
|
||||
GUID decoder_category;
|
||||
};
|
||||
|
||||
typedef HRESULT (*p_connect_func)(struct transform_output_type *output_type, struct connect_context *context);
|
||||
|
@ -2142,7 +2145,7 @@ static HRESULT connect_to_converter(struct transform_output_type *output_type, s
|
|||
sink_ctx = *context;
|
||||
sink_ctx.upstream_node = node;
|
||||
|
||||
if (SUCCEEDED(hr = topology_loader_enumerate_output_types(context->converter_category, output_type->type,
|
||||
if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&context->converter_category, output_type->type,
|
||||
connect_to_sink, &sink_ctx)))
|
||||
{
|
||||
hr = IMFTopology_AddNode(context->context->output_topology, node);
|
||||
|
@ -2225,13 +2228,62 @@ static HRESULT topology_loader_get_mft_categories(IMFMediaTypeHandler *handler,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_connect(IMFMediaTypeHandler *sink_handler, unsigned int sink_method,
|
||||
struct connect_context *sink_ctx, struct connect_context *convert_ctx, IMFMediaType *media_type)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(sink_handler, media_type, NULL))
|
||||
&& SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(sink_handler, media_type)))
|
||||
{
|
||||
hr = IMFTopologyNode_ConnectOutput(sink_ctx->upstream_node, sink_ctx->output_index, sink_ctx->sink, sink_ctx->input_index);
|
||||
}
|
||||
|
||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_CONVERTER)
|
||||
{
|
||||
hr = topology_loader_enumerate_output_types(&convert_ctx->converter_category, media_type, connect_to_sink, sink_ctx);
|
||||
}
|
||||
|
||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_DECODER)
|
||||
{
|
||||
hr = topology_loader_enumerate_output_types(&convert_ctx->decoder_category, media_type,
|
||||
connect_to_converter, convert_ctx);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_foreach_source_type(IMFMediaTypeHandler *sink_handler, IMFMediaTypeHandler *source_handler,
|
||||
unsigned int sink_method, struct connect_context *sink_ctx, struct connect_context *convert_ctx)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
IMFMediaType *media_type;
|
||||
HRESULT hr;
|
||||
|
||||
while (SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(source_handler, index++, &media_type)))
|
||||
{
|
||||
hr = topology_loader_connect(sink_handler, sink_method, sink_ctx, convert_ctx, media_type);
|
||||
if (SUCCEEDED(hr)) break;
|
||||
IMFMediaType_Release(media_type);
|
||||
media_type = NULL;
|
||||
}
|
||||
|
||||
if (media_type)
|
||||
{
|
||||
hr = IMFMediaTypeHandler_SetCurrentMediaType(source_handler, media_type);
|
||||
IMFMediaType_Release(media_type);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_connect_source_to_sink(struct topoloader_context *context, IMFTopologyNode *source,
|
||||
unsigned int output_index, IMFTopologyNode *sink, unsigned int input_index)
|
||||
{
|
||||
IMFMediaTypeHandler *source_handler = NULL, *sink_handler = NULL;
|
||||
struct connect_context convert_ctx, sink_ctx;
|
||||
MF_CONNECT_METHOD source_method, sink_method;
|
||||
GUID decode_cat, convert_cat;
|
||||
unsigned int enumerate_source_types = 0;
|
||||
IMFMediaType *media_type;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -2248,35 +2300,46 @@ static HRESULT topology_loader_connect_source_to_sink(struct topoloader_context
|
|||
if (FAILED(IMFTopologyNode_GetUINT32(sink, &MF_TOPONODE_CONNECT_METHOD, &sink_method)))
|
||||
sink_method = MF_CONNECT_ALLOW_DECODER;
|
||||
|
||||
if (FAILED(hr = topology_loader_get_mft_categories(source_handler, &decode_cat, &convert_cat)))
|
||||
goto done;
|
||||
|
||||
sink_ctx.context = context;
|
||||
sink_ctx.upstream_node = source;
|
||||
sink_ctx.sink = sink;
|
||||
sink_ctx.sink_handler = sink_handler;
|
||||
sink_ctx.output_index = output_index;
|
||||
sink_ctx.input_index = input_index;
|
||||
|
||||
convert_ctx = sink_ctx;
|
||||
convert_ctx.converter_category = &convert_cat;
|
||||
if (FAILED(hr = topology_loader_get_mft_categories(source_handler, &convert_ctx.decoder_category,
|
||||
&convert_ctx.converter_category)))
|
||||
goto done;
|
||||
|
||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(source_handler, &media_type)))
|
||||
IMFTopology_GetUINT32(context->output_topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enumerate_source_types);
|
||||
|
||||
if (enumerate_source_types)
|
||||
{
|
||||
/* Direct connection. */
|
||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(sink_handler, media_type, NULL))
|
||||
&& SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(sink_handler, media_type)))
|
||||
if (source_method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)
|
||||
{
|
||||
hr = IMFTopologyNode_ConnectOutput(source, output_index, sink, input_index);
|
||||
hr = topology_loader_foreach_source_type(sink_handler, source_handler, MF_CONNECT_ALLOW_DECODER,
|
||||
&sink_ctx, &convert_ctx);
|
||||
}
|
||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_CONVERTER)
|
||||
else
|
||||
{
|
||||
hr = topology_loader_enumerate_output_types(&convert_cat, media_type, connect_to_sink, &sink_ctx);
|
||||
hr = topology_loader_foreach_source_type(sink_handler, source_handler, MF_CONNECT_DIRECT,
|
||||
&sink_ctx, &convert_ctx);
|
||||
if (FAILED(hr))
|
||||
hr = topology_loader_foreach_source_type(sink_handler, source_handler, MF_CONNECT_ALLOW_CONVERTER,
|
||||
&sink_ctx, &convert_ctx);
|
||||
if (FAILED(hr))
|
||||
hr = topology_loader_foreach_source_type(sink_handler, source_handler, MF_CONNECT_ALLOW_DECODER,
|
||||
&sink_ctx, &convert_ctx);
|
||||
}
|
||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_DECODER)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(source_handler, &media_type)))
|
||||
{
|
||||
hr = topology_loader_enumerate_output_types(&decode_cat, media_type, connect_to_converter, &convert_ctx);
|
||||
hr = topology_loader_connect(sink_handler, sink_method, &sink_ctx, &convert_ctx, media_type);
|
||||
IMFMediaType_Release(media_type);
|
||||
}
|
||||
|
||||
IMFMediaType_Release(media_type);
|
||||
}
|
||||
|
||||
done:
|
||||
|
|
Loading…
Reference in New Issue