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 *upstream_node;
|
||||||
IMFTopologyNode *sink;
|
IMFTopologyNode *sink;
|
||||||
IMFMediaTypeHandler *sink_handler;
|
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);
|
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 = *context;
|
||||||
sink_ctx.upstream_node = node;
|
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)))
|
connect_to_sink, &sink_ctx)))
|
||||||
{
|
{
|
||||||
hr = IMFTopology_AddNode(context->context->output_topology, node);
|
hr = IMFTopology_AddNode(context->context->output_topology, node);
|
||||||
|
@ -2225,13 +2228,62 @@ static HRESULT topology_loader_get_mft_categories(IMFMediaTypeHandler *handler,
|
||||||
return S_OK;
|
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,
|
static HRESULT topology_loader_connect_source_to_sink(struct topoloader_context *context, IMFTopologyNode *source,
|
||||||
unsigned int output_index, IMFTopologyNode *sink, unsigned int input_index)
|
unsigned int output_index, IMFTopologyNode *sink, unsigned int input_index)
|
||||||
{
|
{
|
||||||
IMFMediaTypeHandler *source_handler = NULL, *sink_handler = NULL;
|
IMFMediaTypeHandler *source_handler = NULL, *sink_handler = NULL;
|
||||||
struct connect_context convert_ctx, sink_ctx;
|
struct connect_context convert_ctx, sink_ctx;
|
||||||
MF_CONNECT_METHOD source_method, sink_method;
|
MF_CONNECT_METHOD source_method, sink_method;
|
||||||
GUID decode_cat, convert_cat;
|
unsigned int enumerate_source_types = 0;
|
||||||
IMFMediaType *media_type;
|
IMFMediaType *media_type;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -2248,36 +2300,47 @@ static HRESULT topology_loader_connect_source_to_sink(struct topoloader_context
|
||||||
if (FAILED(IMFTopologyNode_GetUINT32(sink, &MF_TOPONODE_CONNECT_METHOD, &sink_method)))
|
if (FAILED(IMFTopologyNode_GetUINT32(sink, &MF_TOPONODE_CONNECT_METHOD, &sink_method)))
|
||||||
sink_method = MF_CONNECT_ALLOW_DECODER;
|
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.context = context;
|
||||||
sink_ctx.upstream_node = source;
|
sink_ctx.upstream_node = source;
|
||||||
sink_ctx.sink = sink;
|
sink_ctx.sink = sink;
|
||||||
sink_ctx.sink_handler = sink_handler;
|
sink_ctx.sink_handler = sink_handler;
|
||||||
|
sink_ctx.output_index = output_index;
|
||||||
|
sink_ctx.input_index = input_index;
|
||||||
|
|
||||||
convert_ctx = sink_ctx;
|
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;
|
||||||
|
|
||||||
|
IMFTopology_GetUINT32(context->output_topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enumerate_source_types);
|
||||||
|
|
||||||
|
if (enumerate_source_types)
|
||||||
|
{
|
||||||
|
if (source_method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)
|
||||||
|
{
|
||||||
|
hr = topology_loader_foreach_source_type(sink_handler, source_handler, MF_CONNECT_ALLOW_DECODER,
|
||||||
|
&sink_ctx, &convert_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(source_handler, &media_type)))
|
if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(source_handler, &media_type)))
|
||||||
{
|
{
|
||||||
/* Direct connection. */
|
hr = topology_loader_connect(sink_handler, sink_method, &sink_ctx, &convert_ctx, media_type);
|
||||||
if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(sink_handler, media_type, NULL))
|
|
||||||
&& SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(sink_handler, media_type)))
|
|
||||||
{
|
|
||||||
hr = IMFTopologyNode_ConnectOutput(source, output_index, sink, input_index);
|
|
||||||
}
|
|
||||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_CONVERTER)
|
|
||||||
{
|
|
||||||
hr = topology_loader_enumerate_output_types(&convert_cat, media_type, connect_to_sink, &sink_ctx);
|
|
||||||
}
|
|
||||||
if (FAILED(hr) && sink_method & MF_CONNECT_ALLOW_DECODER)
|
|
||||||
{
|
|
||||||
hr = topology_loader_enumerate_output_types(&decode_cat, media_type, connect_to_converter, &convert_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
IMFMediaType_Release(media_type);
|
IMFMediaType_Release(media_type);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (source_handler)
|
if (source_handler)
|
||||||
|
|
Loading…
Reference in New Issue