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
@ -0,0 +1,749 @@
|
||||
From 546e1369ea175aac841ff621cb441e6d1d87e1f2 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Nov 2020 15:23:18 -0500
|
||||
Subject: [PATCH] mf/topoloader: Add partial topology resolution tests.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/tests/Makefile.in | 2 -
|
||||
dlls/mf/tests/mf.c | 601 +++++++++++++++++++++++++++++++-------
|
||||
dlls/mf/tests/resource.rc | 22 --
|
||||
3 files changed, 499 insertions(+), 126 deletions(-)
|
||||
delete mode 100644 dlls/mf/tests/resource.rc
|
||||
|
||||
diff --git a/dlls/mf/tests/Makefile.in b/dlls/mf/tests/Makefile.in
|
||||
index 5eb9ee4d4e3..614eb4fbc9e 100644
|
||||
--- a/dlls/mf/tests/Makefile.in
|
||||
+++ b/dlls/mf/tests/Makefile.in
|
||||
@@ -3,5 +3,3 @@ IMPORTS = mf mfplat mfuuid ole32 user32
|
||||
|
||||
C_SRCS = \
|
||||
mf.c
|
||||
-
|
||||
-RC_SRCS = resource.rc
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index fda80974724..092735466be 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -44,6 +44,7 @@ DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00,
|
||||
#include "mmdeviceapi.h"
|
||||
#include "audioclient.h"
|
||||
#include "evr.h"
|
||||
+#include "propvarutil.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
@@ -97,34 +98,6 @@ static HWND create_window(void)
|
||||
0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
-static WCHAR *load_resource(const WCHAR *name)
|
||||
-{
|
||||
- static WCHAR pathW[MAX_PATH];
|
||||
- DWORD written;
|
||||
- HANDLE file;
|
||||
- HRSRC res;
|
||||
- void *ptr;
|
||||
-
|
||||
- GetTempPathW(ARRAY_SIZE(pathW), pathW);
|
||||
- lstrcatW(pathW, name);
|
||||
-
|
||||
- file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
|
||||
- NULL, CREATE_ALWAYS, 0, 0);
|
||||
- ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
|
||||
- wine_dbgstr_w(pathW), GetLastError());
|
||||
-
|
||||
- res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
|
||||
- ok(res != 0, "couldn't find resource\n");
|
||||
- ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
|
||||
- WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
|
||||
- &written, NULL);
|
||||
- ok(written == SizeofResource(GetModuleHandleA(NULL), res),
|
||||
- "couldn't write resource\n" );
|
||||
- CloseHandle(file);
|
||||
-
|
||||
- return pathW;
|
||||
-}
|
||||
-
|
||||
static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
@@ -1447,26 +1420,316 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl =
|
||||
test_grabber_callback_OnShutdown,
|
||||
};
|
||||
|
||||
+struct test_source
|
||||
+{
|
||||
+ IMFMediaSource IMFMediaSource_iface;
|
||||
+ LONG refcount;
|
||||
+};
|
||||
+
|
||||
+static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct test_source, IMFMediaSource_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out)
|
||||
+{
|
||||
+ if (IsEqualIID(riid, &IID_IMFMediaSource)
|
||||
+ || IsEqualIID(riid, &IID_IMFMediaEventGenerator)
|
||||
+ || IsEqualIID(riid, &IID_IUnknown))
|
||||
+ {
|
||||
+ *out = iface;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *out = NULL;
|
||||
+ return E_NOINTERFACE;
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaSource_AddRef(iface);
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI test_source_AddRef(IMFMediaSource *iface)
|
||||
+{
|
||||
+ struct test_source *source = impl_from_IMFMediaSource(iface);
|
||||
+ return InterlockedIncrement(&source->refcount);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI test_source_Release(IMFMediaSource *iface)
|
||||
+{
|
||||
+ struct test_source *source = impl_from_IMFMediaSource(iface);
|
||||
+ ULONG refcount = InterlockedDecrement(&source->refcount);
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ HeapFree(GetProcessHeap(), 0, source);
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type,
|
||||
+ HRESULT hr, const PROPVARIANT *value)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format,
|
||||
+ const PROPVARIANT *start_position)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_Stop(IMFMediaSource *iface)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_Pause(IMFMediaSource *iface)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI test_source_Shutdown(IMFMediaSource *iface)
|
||||
+{
|
||||
+ ok(0, "Unexpected call.\n");
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static const IMFMediaSourceVtbl test_source_vtbl =
|
||||
+{
|
||||
+ test_source_QueryInterface,
|
||||
+ test_source_AddRef,
|
||||
+ test_source_Release,
|
||||
+ test_source_GetEvent,
|
||||
+ test_source_BeginGetEvent,
|
||||
+ test_source_EndGetEvent,
|
||||
+ test_source_QueueEvent,
|
||||
+ test_source_GetCharacteristics,
|
||||
+ test_source_CreatePresentationDescriptor,
|
||||
+ test_source_Start,
|
||||
+ test_source_Stop,
|
||||
+ test_source_Pause,
|
||||
+ test_source_Shutdown,
|
||||
+};
|
||||
+
|
||||
+static IMFMediaSource *create_test_source(void)
|
||||
+{
|
||||
+ struct test_source *source;
|
||||
+
|
||||
+ source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*source));
|
||||
+ source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl;
|
||||
+ source->refcount = 1;
|
||||
+
|
||||
+ return &source->IMFMediaSource_iface;
|
||||
+}
|
||||
+
|
||||
static void test_topology_loader(void)
|
||||
{
|
||||
+ static const struct resolution_test
|
||||
+ {
|
||||
+ union
|
||||
+ {
|
||||
+ WAVEFORMATEX input_type;
|
||||
+ MPEGLAYER3WAVEFORMAT mp3_input_type;
|
||||
+ };
|
||||
+ WAVEFORMATEX output_type;
|
||||
+ MF_CONNECT_METHOD method;
|
||||
+ HRESULT expected_result;
|
||||
+ BOOL expect_decoder, expect_converter, wine_todo;
|
||||
+ }
|
||||
+ resolution_tests[] =
|
||||
+ {
|
||||
+ {
|
||||
+ .input_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_DIRECT,
|
||||
+ .expected_result = S_OK,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = FALSE,
|
||||
+ },
|
||||
+ {
|
||||
+ .input_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 48000,
|
||||
+ .nAvgBytesPerSec = 48000, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_DIRECT,
|
||||
+ .expected_result = MF_E_INVALIDMEDIATYPE,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = FALSE,
|
||||
+ },
|
||||
+ {
|
||||
+ .input_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 48000,
|
||||
+ .nAvgBytesPerSec = 48000, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_ALLOW_CONVERTER,
|
||||
+ .expected_result = S_OK,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = TRUE,
|
||||
+ .wine_todo = TRUE,
|
||||
+ },
|
||||
+ /* Test MF_TOPONODE_CONNECT_METHOD:
|
||||
+ - 0x1 (MF_CONNECT_ALLOW_CONVERTER) allows converters
|
||||
+ - 0x3 (MF_CONNECT_ALLOW_DECODER) allows converters and decoders
|
||||
+ - 0x2 allows neither */
|
||||
+ {
|
||||
+ .mp3_input_type = {
|
||||
+ {
|
||||
+ .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES,
|
||||
+ },
|
||||
+ .wID = MPEGLAYER3_ID_MPEG,
|
||||
+ .fdwFlags = 0,
|
||||
+ .nBlockSize = 417,
|
||||
+ .nFramesPerBlock = 0,
|
||||
+ .nCodecDelay = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_DIRECT,
|
||||
+ .expected_result = MF_E_INVALIDMEDIATYPE,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = TRUE,
|
||||
+ },
|
||||
+ {
|
||||
+ .mp3_input_type = {
|
||||
+ {
|
||||
+ .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES,
|
||||
+ },
|
||||
+ .wID = MPEGLAYER3_ID_MPEG,
|
||||
+ .fdwFlags = 0,
|
||||
+ .nBlockSize = 417,
|
||||
+ .nFramesPerBlock = 0,
|
||||
+ .nCodecDelay = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_ALLOW_CONVERTER,
|
||||
+ .expected_result = MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = TRUE,
|
||||
+ },
|
||||
+ {
|
||||
+ .mp3_input_type = {
|
||||
+ {
|
||||
+ .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES,
|
||||
+ },
|
||||
+ .wID = MPEGLAYER3_ID_MPEG,
|
||||
+ .fdwFlags = 0,
|
||||
+ .nBlockSize = 417,
|
||||
+ .nFramesPerBlock = 0,
|
||||
+ .nCodecDelay = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = 2,
|
||||
+ .expected_result = MF_E_INVALIDMEDIATYPE,
|
||||
+ .expect_decoder = FALSE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = TRUE,
|
||||
+ },
|
||||
+ {
|
||||
+ .mp3_input_type = {
|
||||
+ {
|
||||
+ .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES,
|
||||
+ },
|
||||
+ .wID = MPEGLAYER3_ID_MPEG,
|
||||
+ .fdwFlags = 0,
|
||||
+ .nBlockSize = 417,
|
||||
+ .nFramesPerBlock = 0,
|
||||
+ .nCodecDelay = 0,
|
||||
+ },
|
||||
+ .output_type = {
|
||||
+ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100,
|
||||
+ .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0,
|
||||
+ },
|
||||
+ .method = MF_CONNECT_ALLOW_DECODER,
|
||||
+ .expected_result = S_OK,
|
||||
+ .expect_decoder = TRUE,
|
||||
+ .expect_converter = FALSE,
|
||||
+ .wine_todo = TRUE,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl };
|
||||
+ IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node;
|
||||
IMFTopology *topology, *topology2, *full_topology;
|
||||
- IMFTopologyNode *src_node, *sink_node;
|
||||
+ unsigned int count, value, index;
|
||||
IMFPresentationDescriptor *pd;
|
||||
- IMFSourceResolver *resolver;
|
||||
IMFActivate *sink_activate;
|
||||
IMFStreamSink *stream_sink;
|
||||
- unsigned int count, value;
|
||||
+ MF_TOPOLOGY_TYPE node_type;
|
||||
IMFMediaType *media_type;
|
||||
IMFStreamDescriptor *sd;
|
||||
- MF_OBJECT_TYPE obj_type;
|
||||
+ IMFTransform *transform;
|
||||
IMFMediaSource *source;
|
||||
IMFTopoLoader *loader;
|
||||
- IMFByteStream *stream;
|
||||
- IMFAttributes *attr;
|
||||
+ IUnknown *node_object;
|
||||
+ BOOL compare_result;
|
||||
IMFMediaSink *sink;
|
||||
- WCHAR *filename;
|
||||
- BOOL selected;
|
||||
+ WORD node_count;
|
||||
+ unsigned int i;
|
||||
+ TOPOID node_id;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
|
||||
@@ -1487,44 +1750,41 @@ static void test_topology_loader(void)
|
||||
todo_wine
|
||||
ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
- hr = MFCreateSourceResolver(&resolver);
|
||||
- ok(hr == S_OK, "Failed to create source resolver, hr %#x.\n", hr);
|
||||
+ /* Add source node. */
|
||||
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
|
||||
+ ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
|
||||
|
||||
- filename = load_resource(L"test.wav");
|
||||
+ /* when a decoder is involved, windows requires this attribute to be present */
|
||||
+ source = create_test_source();
|
||||
|
||||
- hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
|
||||
- ok(hr == S_OK, "Failed to create file stream, hr %#x.\n", hr);
|
||||
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
|
||||
+ ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
|
||||
|
||||
- IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attr);
|
||||
- IMFAttributes_SetString(attr, &MF_BYTESTREAM_CONTENT_TYPE, L"audio/wav");
|
||||
- IMFAttributes_Release(attr);
|
||||
+ IMFMediaSource_Release(source);
|
||||
|
||||
- hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
|
||||
- &obj_type, (IUnknown **)&source);
|
||||
- ok(hr == S_OK || broken(FAILED(hr)) /* Vista */, "Failed to create source, hr %#x.\n", hr);
|
||||
- if (FAILED(hr))
|
||||
- return;
|
||||
+ hr = MFCreateMediaType(&media_type);
|
||||
+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
|
||||
- ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
|
||||
- if (FAILED(hr))
|
||||
- return;
|
||||
+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
|
||||
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||
+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
|
||||
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
|
||||
- ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
|
||||
+ hr = MFCreateStreamDescriptor(0, 1, &media_type, &sd);
|
||||
+ ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n");
|
||||
|
||||
- /* Add source node. */
|
||||
- hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
|
||||
- ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
|
||||
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
|
||||
+ ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
|
||||
- ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
|
||||
+ hr = MFCreatePresentationDescriptor(1, &sd, &pd);
|
||||
+ ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n");
|
||||
|
||||
hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
|
||||
ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
|
||||
- ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
|
||||
+ IMFPresentationDescriptor_Release(pd);
|
||||
+ IMFStreamDescriptor_Release(sd);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
|
||||
hr = IMFTopology_AddNode(topology, src_node);
|
||||
ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
|
||||
@@ -1534,7 +1794,9 @@ todo_wine
|
||||
todo_wine
|
||||
ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
- /* Add grabber sink. */
|
||||
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
|
||||
+ ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr);
|
||||
+
|
||||
hr = MFCreateMediaType(&media_type);
|
||||
ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
|
||||
|
||||
@@ -1546,13 +1808,11 @@ todo_wine
|
||||
hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate);
|
||||
ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
|
||||
|
||||
- IMFMediaType_Release(media_type);
|
||||
-
|
||||
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
|
||||
- ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr);
|
||||
-
|
||||
hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate);
|
||||
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+
|
||||
hr = IMFTopology_AddNode(topology, sink_node);
|
||||
ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
|
||||
|
||||
@@ -1567,55 +1827,192 @@ todo_wine
|
||||
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
|
||||
- ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
|
||||
+ for (i = 0; i < ARRAY_SIZE(resolution_tests); i++)
|
||||
+ {
|
||||
+ IMFMediaType *input_type, *output_type;
|
||||
+ IMFMediaTypeHandler *mth;
|
||||
|
||||
- hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
|
||||
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
+ /* TODO: remove once MFInitMediaTypeFromWaveFormatEx gains support for non-zero cbSize */
|
||||
+ if(resolution_tests[i].wine_todo && !strcmp(winetest_platform, "wine"))
|
||||
+ {
|
||||
+ todo_wine ok(0, "Skipping test %u on wine.\n", i);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink);
|
||||
- ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
|
||||
+ hr = MFCreateMediaType(&input_type);
|
||||
+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
|
||||
|
||||
- IMFStreamSink_Release(stream_sink);
|
||||
+ hr = MFInitMediaTypeFromWaveFormatEx(input_type, &resolution_tests[i].input_type, sizeof(WAVEFORMATEX) + resolution_tests[i].input_type.cbSize);
|
||||
+ ok(hr == S_OK, "MFInitMediaTypeFromWaveFormatEx failed, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopology_GetCount(topology, &count);
|
||||
- ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
- ok(count == 0, "Unexpected count %u.\n", count);
|
||||
+ hr = MFCreateMediaType(&output_type);
|
||||
+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
- ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
|
||||
- ok(full_topology != topology, "Unexpected instance.\n");
|
||||
+ hr = MFInitMediaTypeFromWaveFormatEx(output_type, &resolution_tests[i].output_type, sizeof(WAVEFORMATEX) + resolution_tests[i].output_type.cbSize);
|
||||
+ ok(hr == S_OK, "MFInitMediaTypeFromWaveFormatEx failed, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopology_GetCount(topology, &count);
|
||||
- ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
- ok(count == 0, "Unexpected count %u.\n", count);
|
||||
+ hr = MFCreateStreamDescriptor(0, 1, &input_type, &sd);
|
||||
+ ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFTopology_GetCount(full_topology, &count);
|
||||
- ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
+ hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth);
|
||||
+ ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, input_type);
|
||||
+ ok(hr == S_OK, "Failed to set current media type, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFMediaTypeHandler_Release(mth);
|
||||
+
|
||||
+ hr = MFCreatePresentationDescriptor(1, &sd, &pd);
|
||||
+ ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
|
||||
+ ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFPresentationDescriptor_Release(pd);
|
||||
+
|
||||
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
|
||||
+ ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFStreamDescriptor_Release(sd);
|
||||
+
|
||||
+ hr = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate);
|
||||
+ ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
|
||||
+ ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
|
||||
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFMediaSink_Release(sink);
|
||||
+
|
||||
+ hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink);
|
||||
+ ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
|
||||
+
|
||||
+ IMFStreamSink_Release(stream_sink);
|
||||
+
|
||||
+ hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, resolution_tests[i].method);
|
||||
+ ok(hr == S_OK, "Failed to set connect method, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFTopology_GetCount(topology, &count);
|
||||
+ ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
+ ok(count == 0, "Unexpected count %u.\n", count);
|
||||
+
|
||||
+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
+todo_wine_if(resolution_tests[i].wine_todo)
|
||||
+ ok(hr == resolution_tests[i].expected_result, "Unexpected hr %#x on test %u.\n", hr, i);
|
||||
+ ok(full_topology != topology, "Unexpected instance.\n");
|
||||
+
|
||||
+ if (resolution_tests[i].expected_result == S_OK && hr == S_OK)
|
||||
+ {
|
||||
+ hr = IMFTopology_GetCount(full_topology, &count);
|
||||
+ ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
todo_wine
|
||||
- ok(count == 1, "Unexpected count %u.\n", count);
|
||||
+ ok(count == 1, "Unexpected count %u.\n", count);
|
||||
|
||||
- hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL);
|
||||
+ hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL);
|
||||
todo_wine {
|
||||
- ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr);
|
||||
- ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid));
|
||||
+ ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr);
|
||||
+ ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid));
|
||||
}
|
||||
- value = 0xdeadbeef;
|
||||
- hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
|
||||
+ value = 0xdeadbeef;
|
||||
+ hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
|
||||
todo_wine {
|
||||
- ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
|
||||
- ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
|
||||
+ ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
|
||||
+ ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
|
||||
}
|
||||
- hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
|
||||
- ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
|
||||
- ok(full_topology != topology2, "Unexpected instance.\n");
|
||||
|
||||
- IMFTopology_Release(topology2);
|
||||
- IMFTopology_Release(full_topology);
|
||||
+ hr = IMFTopology_GetNodeCount(full_topology, &node_count);
|
||||
+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
|
||||
+ ok(node_count == 2 + resolution_tests[i].expect_decoder + resolution_tests[i].expect_converter, "Unexpected node count %u.\n", node_count);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetTopoNodeID(src_node, &node_id);
|
||||
+ ok(hr == S_OK, "Failed to get source node id, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFTopology_GetNodeByID(full_topology, node_id, &src_node2);
|
||||
+ ok(hr == S_OK, "Failed to get source in resolved topology, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetTopoNodeID(sink_node, &node_id);
|
||||
+ ok(hr == S_OK, "Failed to get sink node id, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFTopology_GetNodeByID(full_topology, node_id, &sink_node2);
|
||||
+ ok(hr == S_OK, "Failed to get sink in resolved topology, hr %#x.\n", hr);
|
||||
+
|
||||
+ if (resolution_tests[i].expect_decoder || resolution_tests[i].expect_converter)
|
||||
+ {
|
||||
+ hr = IMFTopologyNode_GetOutput(src_node2, 0, &mft_node, &index);
|
||||
+ ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr);
|
||||
+ ok(index == 0, "Unexpected stream index %u.\n", index);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetNodeType(mft_node, &node_type);
|
||||
+ ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr);
|
||||
+ ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u, expected MF_TOPOLOGY_TRANSFORM_NODE.\n", node_type);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetObject(mft_node, &node_object);
|
||||
+ ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void**) &transform);
|
||||
+ ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr);
|
||||
+ IUnknown_Release(node_object);
|
||||
+
|
||||
+ hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
|
||||
+ ok(hr == S_OK, "Failed to get transform input type, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFMediaType_Compare(media_type, (IMFAttributes *)input_type, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &compare_result);
|
||||
+ ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr);
|
||||
+ ok(compare_result, "Input type of first transform doesn't match source node type.\n");
|
||||
+
|
||||
+ IMFTopologyNode_Release(mft_node);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ IMFTransform_Release(transform);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetInput(sink_node2, 0, &mft_node, &index);
|
||||
+ ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr);
|
||||
+ ok(index == 0, "Unexpected stream index %u.\n", index);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetNodeType(mft_node, &node_type);
|
||||
+ ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr);
|
||||
+ ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u, expected MF_TOPOLOGY_TRANSFORM_NODE.\n", node_type);
|
||||
+
|
||||
+ hr = IMFTopologyNode_GetObject(mft_node, &node_object);
|
||||
+ ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void**) &transform);
|
||||
+ ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr);
|
||||
+ IUnknown_Release(node_object);
|
||||
+
|
||||
+ hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
|
||||
+ ok(hr == S_OK, "Failed to get transform output type, hr %#x.\n", hr);
|
||||
+
|
||||
+ hr = IMFMediaType_Compare(media_type, (IMFAttributes *)output_type, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &compare_result);
|
||||
+ ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr);
|
||||
+ ok(compare_result, "Output type of last transform doesn't match sink node type.\n");
|
||||
+
|
||||
+ IMFTopologyNode_Release(mft_node);
|
||||
+ IMFMediaType_Release(media_type);
|
||||
+ IMFTransform_Release(transform);
|
||||
+ }
|
||||
+
|
||||
+ IMFTopologyNode_Release(sink_node2);
|
||||
+
|
||||
+ hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
|
||||
+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
|
||||
+ ok(full_topology != topology2, "Unexpected instance.\n");
|
||||
+
|
||||
+ IMFTopology_Release(topology2);
|
||||
+ IMFTopology_Release(full_topology);
|
||||
+ }
|
||||
+
|
||||
+ hr = IMFTopology_GetCount(topology, &count);
|
||||
+ ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
+ ok(count == 0, "Unexpected count %u.\n", count);
|
||||
+
|
||||
+ IMFActivate_ShutdownObject(sink_activate);
|
||||
+ IMFActivate_Release(sink_activate);
|
||||
+ IMFMediaType_Release(input_type);
|
||||
+ IMFMediaType_Release(output_type);
|
||||
+ }
|
||||
|
||||
- IMFMediaSource_Release(source);
|
||||
- IMFSourceResolver_Release(resolver);
|
||||
- IMFByteStream_Release(stream);
|
||||
IMFTopoLoader_Release(loader);
|
||||
|
||||
hr = MFShutdown();
|
||||
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc
|
||||
deleted file mode 100644
|
||||
index f54212a8c8f..00000000000
|
||||
--- a/dlls/mf/tests/resource.rc
|
||||
+++ /dev/null
|
||||
@@ -1,22 +0,0 @@
|
||||
-/*
|
||||
- * Copyright 2019 Nikolay Sivov for CodeWeavers
|
||||
- *
|
||||
- * This library is free software; you can redistribute it and/or
|
||||
- * modify it under the terms of the GNU Lesser General Public
|
||||
- * License as published by the Free Software Foundation; either
|
||||
- * version 2.1 of the License, or (at your option) any later version.
|
||||
- *
|
||||
- * This library is distributed in the hope that it will be useful,
|
||||
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- * Lesser General Public License for more details.
|
||||
- *
|
||||
- * You should have received a copy of the GNU Lesser General Public
|
||||
- * License along with this library; if not, write to the Free Software
|
||||
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
- */
|
||||
-
|
||||
-#include "windef.h"
|
||||
-
|
||||
-/* @makedep: test.wav */
|
||||
-test.wav RCDATA test.wav
|
||||
--
|
||||
2.29.2
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,543 @@
|
||||
From fa85a328dc4d091777bdc3f8d388c6e70fbd6ed3 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 18 Nov 2020 11:26:29 -0600
|
||||
Subject: [PATCH] winegstreamer: Introduce audio conversion transform.
|
||||
|
||||
Serves as a wrapper of audioconvert, and roughly fills the roll of Windows' CLSID_CResamplerMediaObject to convert audio to the format accepted by the streaming audio renderer.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/Makefile.in | 1 +
|
||||
dlls/winegstreamer/audioconvert.c | 378 +++++++++++++++++++
|
||||
dlls/winegstreamer/gst_private.h | 2 +
|
||||
dlls/winegstreamer/mfplat.c | 77 ++++
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
|
||||
5 files changed, 464 insertions(+)
|
||||
create mode 100644 dlls/winegstreamer/audioconvert.c
|
||||
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index e578d194f7f..0b3229160b9 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||
PARENTSRC = ../strmbase
|
||||
|
||||
C_SRCS = \
|
||||
+ audioconvert.c \
|
||||
filter.c \
|
||||
gst_cbs.c \
|
||||
gstdemux.c \
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
new file mode 100644
|
||||
index 00000000000..91fa556cb88
|
||||
--- /dev/null
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -0,0 +1,378 @@
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include "gst_private.h"
|
||||
+
|
||||
+#include "mfapi.h"
|
||||
+#include "mferror.h"
|
||||
+#include "mfidl.h"
|
||||
+
|
||||
+#include "wine/debug.h"
|
||||
+#include "wine/heap.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||
+
|
||||
+static const GUID *raw_types[] = {
|
||||
+ &MFAudioFormat_PCM,
|
||||
+ &MFAudioFormat_Float,
|
||||
+};
|
||||
+
|
||||
+struct audio_converter
|
||||
+{
|
||||
+ IMFTransform IMFTransform_iface;
|
||||
+ LONG refcount;
|
||||
+};
|
||||
+
|
||||
+static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct audio_converter, IMFTransform_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
|
||||
+{
|
||||
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
|
||||
+ IsEqualIID(riid, &IID_IUnknown))
|
||||
+ {
|
||||
+ *obj = iface;
|
||||
+ IMFTransform_AddRef(iface);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
|
||||
+ *obj = NULL;
|
||||
+ return E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI audio_converter_AddRef(IMFTransform *iface)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedIncrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedDecrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ {
|
||||
+ heap_free(transform);
|
||||
+ }
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
|
||||
+ DWORD *output_minimum, DWORD *output_maximum)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
|
||||
+
|
||||
+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p.\n", iface, inputs, outputs);
|
||||
+
|
||||
+ *inputs = *outputs = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
|
||||
+ DWORD output_size, DWORD *outputs)
|
||||
+{
|
||||
+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ FIXME("%p %u %p.\n", iface, id, info);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ FIXME("%p %u %p.\n", iface, id, info);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %p.\n", iface, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
|
||||
+{
|
||||
+ TRACE("%p, %u.\n", iface, id);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ IMFMediaType *ret;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (index >= ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&ret)))
|
||||
+ return hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio)))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index])))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ *type = ret;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ IMFMediaType *output_type;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ static const DWORD rates[] = {44100, 48000};
|
||||
+ static const DWORD channel_cnts[] = {1, 2, 6};
|
||||
+ static const DWORD sizes[] = {16, 24, 32};
|
||||
+ const GUID *subtype;
|
||||
+ DWORD rate, channels, bps;
|
||||
+
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (index >= (2/*rates*/ * 3/*layouts*/ * 3/*bps PCM*/) + (2 * 3))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&output_type)))
|
||||
+ return hr;
|
||||
+
|
||||
+ if (index < 2 * 3 * 3)
|
||||
+ {
|
||||
+ subtype = &MFAudioFormat_PCM;
|
||||
+ rate = rates[index % 2];
|
||||
+ channels = channel_cnts[(index / 2) % 3];
|
||||
+ bps = sizes[(index / (2*3)) % 3];
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ index -= (2 * 3 * 3);
|
||||
+ subtype = &MFAudioFormat_Float;
|
||||
+ bps = 32;
|
||||
+ rate = rates[index % 2];
|
||||
+ channels = channel_cnts[(index / 2) % 3];
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, subtype)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_NUM_CHANNELS, channels)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, bps)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, channels * bps / 8)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, rate * channels * bps / 8)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_CHANNEL_MASK,
|
||||
+ channels == 1 ? SPEAKER_FRONT_CENTER :
|
||||
+ channels == 2 ? SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT :
|
||||
+ /*channels == 6*/ 0x3F)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ *type = output_type;
|
||||
+
|
||||
+ return S_OK;
|
||||
+ fail:
|
||||
+ IMFMediaType_Release(output_type);
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %p.\n", iface, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
|
||||
+{
|
||||
+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, id, event);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||
+{
|
||||
+ FIXME("%p, %u.\n", iface, message);
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+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);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static const IMFTransformVtbl audio_converter_vtbl =
|
||||
+{
|
||||
+ audio_converter_QueryInterface,
|
||||
+ audio_converter_AddRef,
|
||||
+ audio_converter_Release,
|
||||
+ audio_converter_GetStreamLimits,
|
||||
+ audio_converter_GetStreamCount,
|
||||
+ audio_converter_GetStreamIDs,
|
||||
+ audio_converter_GetInputStreamInfo,
|
||||
+ audio_converter_GetOutputStreamInfo,
|
||||
+ audio_converter_GetAttributes,
|
||||
+ audio_converter_GetInputStreamAttributes,
|
||||
+ audio_converter_GetOutputStreamAttributes,
|
||||
+ audio_converter_DeleteInputStream,
|
||||
+ audio_converter_AddInputStreams,
|
||||
+ audio_converter_GetInputAvailableType,
|
||||
+ audio_converter_GetOutputAvailableType,
|
||||
+ audio_converter_SetInputType,
|
||||
+ audio_converter_SetOutputType,
|
||||
+ audio_converter_GetInputCurrentType,
|
||||
+ audio_converter_GetOutputCurrentType,
|
||||
+ audio_converter_GetInputStatus,
|
||||
+ audio_converter_GetOutputStatus,
|
||||
+ audio_converter_SetOutputBounds,
|
||||
+ audio_converter_ProcessEvent,
|
||||
+ audio_converter_ProcessMessage,
|
||||
+ audio_converter_ProcessInput,
|
||||
+ audio_converter_ProcessOutput,
|
||||
+};
|
||||
+
|
||||
+HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
+{
|
||||
+ struct audio_converter *object;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
+
|
||||
+ if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
|
||||
+ object->refcount = 1;
|
||||
+
|
||||
+ *ret = &object->IMFTransform_iface;
|
||||
+ return S_OK;
|
||||
+}
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 28e424439d8..7889c996204 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -84,4 +84,6 @@ IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
+HRESULT audio_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 3d224a5accc..909fb8b3572 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -405,6 +405,8 @@ failed:
|
||||
|
||||
static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
|
||||
|
||||
+static GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
|
||||
+
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -414,6 +416,7 @@ class_objects[] =
|
||||
{
|
||||
{ &CLSID_VideoProcessorMFT, &video_processor_create },
|
||||
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
|
||||
+ { &CLSID_WINEAudioConverter, &audio_converter_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -442,6 +445,80 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
+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[] =
|
||||
+{
|
||||
+ &MFAudioFormat_PCM,
|
||||
+ &MFAudioFormat_Float,
|
||||
+};
|
||||
+
|
||||
+static const struct mft
|
||||
+{
|
||||
+ const GUID *clsid;
|
||||
+ const GUID *category;
|
||||
+ LPWSTR name;
|
||||
+ const UINT32 flags;
|
||||
+ const GUID *major_type;
|
||||
+ const UINT32 input_types_count;
|
||||
+ const GUID **input_types;
|
||||
+ const UINT32 output_types_count;
|
||||
+ const GUID **output_types;
|
||||
+ IMFAttributes *attributes;
|
||||
+}
|
||||
+mfts[] =
|
||||
+{
|
||||
+ {
|
||||
+ &CLSID_WINEAudioConverter,
|
||||
+ &MFT_CATEGORY_AUDIO_EFFECT,
|
||||
+ audio_converterW,
|
||||
+ MFT_ENUM_FLAG_SYNCMFT,
|
||||
+ &MFMediaType_Audio,
|
||||
+ ARRAY_SIZE(audio_converter_supported_types),
|
||||
+ audio_converter_supported_types,
|
||||
+ ARRAY_SIZE(audio_converter_supported_types),
|
||||
+ audio_converter_supported_types,
|
||||
+ NULL
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+HRESULT mfplat_DllRegisterServer(void)
|
||||
+{
|
||||
+ unsigned int i, j;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mfts); i++)
|
||||
+ {
|
||||
+ const struct mft *cur = &mfts[i];
|
||||
+
|
||||
+ MFT_REGISTER_TYPE_INFO *input_types, *output_types;
|
||||
+ input_types = heap_alloc(cur->input_types_count * sizeof(input_types[0]));
|
||||
+ output_types = heap_alloc(cur->output_types_count * sizeof(output_types[0]));
|
||||
+ for (j = 0; j < cur->input_types_count; j++)
|
||||
+ {
|
||||
+ input_types[j].guidMajorType = *(cur->major_type);
|
||||
+ input_types[j].guidSubtype = *(cur->input_types[j]);
|
||||
+ }
|
||||
+ for (j = 0; j < cur->output_types_count; j++)
|
||||
+ {
|
||||
+ output_types[j].guidMajorType = *(cur->major_type);
|
||||
+ output_types[j].guidSubtype = *(cur->output_types[j]);
|
||||
+ }
|
||||
+
|
||||
+ hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count,
|
||||
+ input_types, cur->output_types_count, output_types, cur->attributes);
|
||||
+
|
||||
+ heap_free(input_types);
|
||||
+ heap_free(output_types);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ FIXME("Failed to register MFT, hr %#x\n", hr);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
static const struct
|
||||
{
|
||||
const GUID *subtype;
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index 1dc4ba9a10b..cf1fc69f38a 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -61,3 +61,9 @@ coclass VideoProcessorMFT {}
|
||||
uuid(317df618-5e5a-468a-9f15-d827a9a08162)
|
||||
]
|
||||
coclass GStreamerByteStreamHandler {}
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
+ uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
|
||||
+]
|
||||
+coclass WINEAudioConverter { }
|
||||
--
|
||||
2.29.2
|
||||
|
@ -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);
|
||||
|
@ -1,8 +1,8 @@
|
||||
From 2f4b30a65e449223c524453509ea0be5d11f8b9e Mon Sep 17 00:00:00 2001
|
||||
From ff4f51df0a12f39b0afd72ab0425684d54531876 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 15 Sep 2020 14:25:26 -0500
|
||||
Subject: [PATCH 05/45] winegstreamer: Insert parser into pipeline to rectify
|
||||
type differences.
|
||||
Subject: [PATCH] winegstreamer: Insert parser into pipeline to rectify type
|
||||
differences.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 92 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 36f995cc6ef..ea299c124dd 100644
|
||||
index ba6bddc0af5..941d7c27473 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -769,8 +769,17 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
@@ -789,8 +789,17 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
media_stream_RequestSample
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@ index 36f995cc6ef..ea299c124dd 100644
|
||||
static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
{
|
||||
GstCaps *source_caps = gst_pad_query_caps(stream->their_src, NULL);
|
||||
@@ -810,7 +819,68 @@ static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
@@ -830,7 +839,68 @@ static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -103,7 +103,7 @@ index 36f995cc6ef..ea299c124dd 100644
|
||||
}
|
||||
|
||||
if (gst_pad_link(stream->their_src, stream->my_sink) != GST_PAD_LINK_OK)
|
||||
@@ -1299,6 +1369,23 @@ static const IMFSeekInfoVtbl IMFSeekInfo_vtbl =
|
||||
@@ -1324,6 +1394,23 @@ static const IMFSeekInfoVtbl IMFSeekInfo_vtbl =
|
||||
source_seek_info_GetNearestKeyFrames,
|
||||
};
|
||||
|
||||
@ -127,7 +127,7 @@ index 36f995cc6ef..ea299c124dd 100644
|
||||
static void stream_added(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct media_source *source = user;
|
||||
@@ -1418,6 +1505,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1443,6 +1530,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
|
||||
gst_bin_add(GST_BIN(object->container), object->decodebin);
|
||||
|
||||
@ -137,5 +137,5 @@ index 36f995cc6ef..ea299c124dd 100644
|
||||
g_signal_connect(object->decodebin, "pad-removed", G_CALLBACK(mf_src_stream_removed_wrapper), object);
|
||||
g_signal_connect(object->decodebin, "no-more-pads", G_CALLBACK(mf_src_no_more_pads_wrapper), object);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From b4501cee4e60bc89c926de676db5945be58cf44a Mon Sep 17 00:00:00 2001
|
||||
From ad124c30b95bac3cdfeb4e0c8fd5607dcb23a375 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:00:26 -0500
|
||||
Subject: [PATCH 06/45] winegstreamer: Translate H.264 caps to attributes.
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 75 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7a877c2a416..f543c774b1d 100644
|
||||
index dd8b1a2a542..d853c46ec58 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -20,7 +20,7 @@ index 7a877c2a416..f543c774b1d 100644
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
@@ -521,6 +522,74 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -635,6 +636,74 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,7 @@ index 7a877c2a416..f543c774b1d 100644
|
||||
else
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
@@ -646,6 +715,12 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
@@ -760,6 +829,12 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,5 +109,5 @@ index 7a877c2a416..f543c774b1d 100644
|
||||
if ((media_type = mf_media_type_from_caps(ret)))
|
||||
IMFMediaType_Release(media_type);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 30499cfad9d6eee935b00e6efff8fec72a60dc99 Mon Sep 17 00:00:00 2001
|
||||
From 5e15609b9f1e4e70e11257464999ba9c62bf998a Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:01:20 -0500
|
||||
Subject: [PATCH 07/45] winegstreamer: Translate WMV caps to attributes.
|
||||
Subject: [PATCH] winegstreamer: Translate WMV caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index f543c774b1d..eb88d6ed6a2 100644
|
||||
index d853c46ec58..4b0b9cba300 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -457,6 +457,24 @@ uncompressed_video_formats[] =
|
||||
@@ -570,6 +570,24 @@ uncompressed_video_formats[] =
|
||||
{&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15},
|
||||
};
|
||||
|
||||
@ -37,7 +37,7 @@ index f543c774b1d..eb88d6ed6a2 100644
|
||||
/* returns NULL if doesn't match exactly */
|
||||
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
{
|
||||
@@ -590,6 +608,39 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -704,6 +722,39 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,5 +78,5 @@ index f543c774b1d..eb88d6ed6a2 100644
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 266a53b56c1f6e7b2704a2aced3cf0aac4d3c616 Mon Sep 17 00:00:00 2001
|
||||
From 05be1cc0fef98b3936c3a61ed5e2878cdde3bd20 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:02:27 -0500
|
||||
Subject: [PATCH 08/45] winegstreamer: Translate AAC caps to attributes.
|
||||
Subject: [PATCH] winegstreamer: Translate AAC caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 108 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index eb88d6ed6a2..6958806dc4f 100644
|
||||
index 4b0b9cba300..8a8e2d076c5 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -457,6 +457,15 @@ uncompressed_video_formats[] =
|
||||
@@ -570,6 +570,15 @@ uncompressed_video_formats[] =
|
||||
{&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15},
|
||||
};
|
||||
|
||||
@ -28,7 +28,7 @@ index eb88d6ed6a2..6958806dc4f 100644
|
||||
static void codec_data_to_user_data(GstStructure *structure, IMFMediaType *type)
|
||||
{
|
||||
const GValue *codec_data;
|
||||
@@ -706,6 +715,105 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -820,6 +829,105 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
|
||||
IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, depth);
|
||||
}
|
||||
@ -135,5 +135,5 @@ index eb88d6ed6a2..6958806dc4f 100644
|
||||
{
|
||||
FIXME("Unrecognized audio format %s\n", mime_type);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,8 +1,7 @@
|
||||
From 260e005c6b7b7998961d123f457f32568770fc11 Mon Sep 17 00:00:00 2001
|
||||
From 0ad065da0f4f991d1475ccecae63bcd82165b0c9 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 13:36:19 -0500
|
||||
Subject: [PATCH 09/45] winegstreamer: Translate MPEG-4 Section-2 caps to
|
||||
attributes.
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -10,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 6958806dc4f..96943f77a70 100644
|
||||
index 8a8e2d076c5..1ed1c70e7e6 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -650,6 +650,22 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -764,6 +764,22 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
|
||||
codec_data_to_user_data(info, media_type);
|
||||
}
|
||||
@ -37,5 +36,5 @@ index 6958806dc4f..96943f77a70 100644
|
||||
{
|
||||
FIXME("Unrecognized video format %s\n", mime_type);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From bcbc7087c297e0f739608b2b3538db4e40cb9b1d Mon Sep 17 00:00:00 2001
|
||||
From 098b390f1d6f3fa2f481de0e5e45847084cbab8c Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:41 -0500
|
||||
Subject: [PATCH 10/45] winegstreamer: Translate WMA caps to attributes.
|
||||
Subject: [PATCH] winegstreamer: Translate WMA caps to attributes.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 96943f77a70..28e0163cdf2 100644
|
||||
index 1ed1c70e7e6..18f9c42ca8b 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -830,6 +830,30 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
@@ -944,6 +944,30 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
FIXME("Unhandled mpegversion %d\n", mpeg_version);
|
||||
}
|
||||
}
|
||||
@ -44,5 +44,5 @@ index 96943f77a70..28e0163cdf2 100644
|
||||
{
|
||||
FIXME("Unrecognized audio format %s\n", mime_type);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,28 +0,0 @@
|
||||
From f131ace70768330c0558a71af255d9577b8fe9bd Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 1 May 2020 22:36:02 -0500
|
||||
Subject: [PATCH 27/45] HACK: Set BPS to 16 for output template.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/mf_decode.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 05c99365e32..64138f8cd94 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -322,6 +322,11 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO
|
||||
return hr;
|
||||
}
|
||||
|
||||
+ if (IsEqualGUID(decoder_descs[decoder->type].output_types[index], &MFAudioFormat_PCM))
|
||||
+ {
|
||||
+ IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
|
||||
+ }
|
||||
+
|
||||
*type = output_type;
|
||||
|
||||
return S_OK;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From aa5bec9bd28415efeb564a620391319653e92135 Mon Sep 17 00:00:00 2001
|
||||
From 8882fbbd49aaf97f7a45db8a03a6c6b362c59e66 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:18:40 -0500
|
||||
Subject: [PATCH 11/45] winegstreamer: Translate H.264 attributes to caps.
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 71 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 28e0163cdf2..25ff06b16a1 100644
|
||||
index 18f9c42ca8b..17ef78667d8 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -948,10 +948,6 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1062,10 +1062,6 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
UINT64 frame_rate = 0, frame_size = 0;
|
||||
DWORD width, height;
|
||||
@ -23,7 +23,7 @@ index 28e0163cdf2..25ff06b16a1 100644
|
||||
|
||||
if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return NULL;
|
||||
@@ -960,28 +956,84 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1074,28 +1070,84 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
output = gst_caps_new_empty_simple("video/x-raw");
|
||||
|
||||
@ -124,5 +124,5 @@ index 28e0163cdf2..25ff06b16a1 100644
|
||||
if (frame_size)
|
||||
{
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 15d2a62517079def88c968af852f04dc3ae815de Mon Sep 17 00:00:00 2001
|
||||
From 77a54feb2c4a025102cf0a96b71d47ebfd388daa Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:20:17 -0500
|
||||
Subject: [PATCH 12/45] winegstreamer: Translate WMV attributes to caps.
|
||||
Subject: [PATCH] winegstreamer: Translate WMV attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 25ff06b16a1..402693c424e 100644
|
||||
index 17ef78667d8..d7d6a46d73a 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -933,6 +933,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
@@ -1047,6 +1047,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ index 25ff06b16a1..402693c424e 100644
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
GUID major_type;
|
||||
@@ -1004,6 +1019,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1118,6 +1133,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
}
|
||||
}
|
||||
@ -78,5 +78,5 @@ index 25ff06b16a1..402693c424e 100644
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 7efecdc8387632f3fc1790a7ddc01a2dfd79369b Mon Sep 17 00:00:00 2001
|
||||
From 6cc3427929ad7e824afa65d3ca3e10c1fa2b81a4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 21 Apr 2020 10:31:02 -0500
|
||||
Subject: [PATCH 13/45] winegstreamer: Translate AAC attributes to caps.
|
||||
Subject: [PATCH] winegstreamer: Translate AAC attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 66 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 402693c424e..1f085e9b4b4 100644
|
||||
index d7d6a46d73a..a2e9ba3a5f7 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1135,6 +1135,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1249,6 +1249,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -86,5 +86,5 @@ index 402693c424e..1f085e9b4b4 100644
|
||||
{
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,8 +1,7 @@
|
||||
From a69723134dcf8069a7cdafbaa10dee6a37676571 Mon Sep 17 00:00:00 2001
|
||||
From b6d752722d031d298ea6e5465994a7fa8220c646 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 11 May 2020 16:03:09 -0500
|
||||
Subject: [PATCH 14/45] winegstreamer: Translate MPEG-4 Section-2 attributes to
|
||||
caps.
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -10,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 1f085e9b4b4..443adab0a8f 100644
|
||||
index a2e9ba3a5f7..51faa95fcc9 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1055,6 +1055,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1169,6 +1169,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
user_data_to_codec_data(type, output);
|
||||
}
|
||||
@ -29,5 +28,5 @@ index 1f085e9b4b4..443adab0a8f 100644
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 3e3c934208f0eb186919e82894d6f5a68882d460 Mon Sep 17 00:00:00 2001
|
||||
From 236f4ec9c0e01ef0b166bd3ab1e06b411ef43ffc Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:59 -0500
|
||||
Subject: [PATCH 15/45] winegstreamer: Translate WMA attributes to caps.
|
||||
Subject: [PATCH] winegstreamer: Translate WMA attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 443adab0a8f..15c38254bf5 100644
|
||||
index 51faa95fcc9..65d2d2efd64 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1209,6 +1209,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1323,6 +1323,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
CoTaskMemFree(user_data);
|
||||
}
|
||||
}
|
||||
@ -35,5 +35,5 @@ index 443adab0a8f..15c38254bf5 100644
|
||||
{
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 999d7a93536ecd9d3daa66adff2ed5d2ce375386 Mon Sep 17 00:00:00 2001
|
||||
From d2e9ca17ba7f224ba465358aa3502678b0ed7025 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 29 Jan 2020 15:37:39 -0600
|
||||
Subject: [PATCH 16/45] tools: Add support for multiple parent directories.
|
||||
Subject: [PATCH] tools: Add support for multiple parent directories.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
2 files changed, 46 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/tools/make_makefiles b/tools/make_makefiles
|
||||
index a92987c2ab5..6bc1b47ca5d 100755
|
||||
index 2d3c14cb2ec..cb4a808244d 100755
|
||||
--- a/tools/make_makefiles
|
||||
+++ b/tools/make_makefiles
|
||||
@@ -230,14 +230,14 @@ sub parse_makefile($)
|
||||
@@ -229,14 +229,14 @@ sub parse_makefile($)
|
||||
{
|
||||
die "Configure substitution is not allowed in $file" unless $file eq "Makefile";
|
||||
}
|
||||
@ -30,7 +30,7 @@ index a92987c2ab5..6bc1b47ca5d 100755
|
||||
{
|
||||
my $var = $1;
|
||||
my @list = split(/\s+/, $2);
|
||||
@@ -292,19 +292,27 @@ sub get_makedep_flags($)
|
||||
@@ -291,19 +291,27 @@ sub get_makedep_flags($)
|
||||
return %flags;
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ index a92987c2ab5..6bc1b47ca5d 100755
|
||||
}
|
||||
|
||||
# preserve shared source files that are listed in the existing makefile
|
||||
@@ -409,13 +417,16 @@ sub assign_sources_to_makefiles(@)
|
||||
@@ -404,13 +412,16 @@ sub assign_sources_to_makefiles(@)
|
||||
foreach my $file (@makefiles)
|
||||
{
|
||||
my $make = $makefiles{$file};
|
||||
@ -91,7 +91,7 @@ index a92987c2ab5..6bc1b47ca5d 100755
|
||||
}
|
||||
|
||||
diff --git a/tools/makedep.c b/tools/makedep.c
|
||||
index 90a21ef825c..029a07b753c 100644
|
||||
index cee64fd61bf..bf22af33572 100644
|
||||
--- a/tools/makedep.c
|
||||
+++ b/tools/makedep.c
|
||||
@@ -184,11 +184,11 @@ struct makefile
|
||||
@ -133,7 +133,7 @@ index 90a21ef825c..029a07b753c 100644
|
||||
}
|
||||
|
||||
if (ret) *filename = src_path;
|
||||
@@ -4124,13 +4131,13 @@ static void load_sources( struct makefile *make )
|
||||
@@ -4145,13 +4152,13 @@ static void load_sources( struct makefile *make )
|
||||
strarray_set_value( &make->vars, "top_srcdir", root_src_dir_path( "" ));
|
||||
strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" ));
|
||||
|
||||
@ -148,7 +148,7 @@ index 90a21ef825c..029a07b753c 100644
|
||||
make->programs = get_expanded_make_var_array( make, "PROGRAMS" );
|
||||
make->scripts = get_expanded_make_var_array( make, "SCRIPTS" );
|
||||
make->imports = get_expanded_make_var_array( make, "IMPORTS" );
|
||||
@@ -4175,8 +4182,11 @@ static void load_sources( struct makefile *make )
|
||||
@@ -4196,8 +4203,11 @@ static void load_sources( struct makefile *make )
|
||||
strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" )));
|
||||
if (make->src_dir)
|
||||
strarray_add( &make->include_args, strmake( "-I%s", make->src_dir ));
|
||||
@ -163,5 +163,5 @@ index 90a21ef825c..029a07b753c 100644
|
||||
if (root_src_dir) strarray_add( &make->include_args, strmake( "-I%s", root_src_dir_path( "include" )));
|
||||
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From df5412c890e61326fc5bb5cfd96a3a7a311d89e6 Mon Sep 17 00:00:00 2001
|
||||
From fab06ab2fd1ec08488160951f4392933237541a4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 29 Jan 2020 15:30:49 -0600
|
||||
Subject: [PATCH 17/45] mf: Introduce handler helper.
|
||||
Subject: [PATCH] mf: Introduce handler helper.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -913,10 +913,10 @@ index 2caf50c54e0..cf58c899843 100644
|
||||
return hr;
|
||||
}
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index e578d194f7f..f2e87494459 100644
|
||||
index 5395d6fd501..4f6b428f067 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -3,12 +3,13 @@ IMPORTS = strmiids uuid ole32 mfuuid
|
||||
@@ -3,7 +3,7 @@ IMPORTS = strmiids uuid ole32 mfuuid
|
||||
DELAYIMPORTS = mfplat
|
||||
EXTRAINCL = $(GSTREAMER_CFLAGS)
|
||||
EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||
@ -924,6 +924,8 @@ index e578d194f7f..f2e87494459 100644
|
||||
+PARENTSRC = ../strmbase ../mf
|
||||
|
||||
C_SRCS = \
|
||||
audioconvert.c \
|
||||
@@ -11,6 +11,7 @@ C_SRCS = \
|
||||
filter.c \
|
||||
gst_cbs.c \
|
||||
gstdemux.c \
|
||||
@ -932,7 +934,7 @@ index e578d194f7f..f2e87494459 100644
|
||||
media_source.c \
|
||||
mediatype.c \
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index ea299c124dd..2df86814679 100644
|
||||
index 941d7c27473..0085459f86f 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -23,6 +23,7 @@
|
||||
@ -943,7 +945,7 @@ index ea299c124dd..2df86814679 100644
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
@@ -1608,21 +1609,11 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1633,21 +1634,11 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
return hr;
|
||||
}
|
||||
|
||||
@ -966,7 +968,7 @@ index ea299c124dd..2df86814679 100644
|
||||
};
|
||||
|
||||
static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface)
|
||||
@@ -1630,11 +1621,6 @@ static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFBy
|
||||
@@ -1655,11 +1646,6 @@ static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFBy
|
||||
return CONTAINING_RECORD(iface, struct winegstreamer_stream_handler, IMFByteStreamHandler_iface);
|
||||
}
|
||||
|
||||
@ -978,7 +980,7 @@ index ea299c124dd..2df86814679 100644
|
||||
static HRESULT WINAPI winegstreamer_stream_handler_QueryInterface(IMFByteStreamHandler *iface, REFIID riid, void **obj)
|
||||
{
|
||||
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||
@@ -1664,247 +1650,44 @@ static ULONG WINAPI winegstreamer_stream_handler_AddRef(IMFByteStreamHandler *if
|
||||
@@ -1689,247 +1675,44 @@ static ULONG WINAPI winegstreamer_stream_handler_AddRef(IMFByteStreamHandler *if
|
||||
|
||||
static ULONG WINAPI winegstreamer_stream_handler_Release(IMFByteStreamHandler *iface)
|
||||
{
|
||||
@ -1233,7 +1235,7 @@ index ea299c124dd..2df86814679 100644
|
||||
}
|
||||
|
||||
static HRESULT WINAPI winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes)
|
||||
@@ -1924,47 +1707,16 @@ static const IMFByteStreamHandlerVtbl winegstreamer_stream_handler_vtbl =
|
||||
@@ -1949,47 +1732,16 @@ static const IMFByteStreamHandlerVtbl winegstreamer_stream_handler_vtbl =
|
||||
winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution,
|
||||
};
|
||||
|
||||
@ -1284,7 +1286,7 @@ index ea299c124dd..2df86814679 100644
|
||||
|
||||
if (FAILED(hr = media_source_constructor(stream, &new_source)))
|
||||
return hr;
|
||||
@@ -1983,64 +1735,6 @@ static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_s
|
||||
@@ -2008,64 +1760,6 @@ static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_s
|
||||
}
|
||||
}
|
||||
|
||||
@ -1349,7 +1351,7 @@ index ea299c124dd..2df86814679 100644
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj)
|
||||
{
|
||||
struct winegstreamer_stream_handler *this;
|
||||
@@ -2052,11 +1746,9 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj)
|
||||
@@ -2077,11 +1771,9 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj)
|
||||
if (!this)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
@ -1363,5 +1365,5 @@ index ea299c124dd..2df86814679 100644
|
||||
|
||||
hr = IMFByteStreamHandler_QueryInterface(&this->IMFByteStreamHandler_iface, riid, obj);
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 4ad320392b3671f27fa79609ec942e0a5c741da1 Mon Sep 17 00:00:00 2001
|
||||
From 2cf98353e8634f38e2823899d554535fcda3b81f Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 16 Mar 2020 12:09:39 -0500
|
||||
Subject: [PATCH 19/45] winegstreamer: Implement decoder MFT on gstreamer.
|
||||
Subject: [PATCH] winegstreamer: Implement decoder MFT on gstreamer.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/Makefile.in | 1 +
|
||||
@ -9,18 +9,18 @@ Subject: [PATCH 19/45] winegstreamer: Implement decoder MFT on gstreamer.
|
||||
dlls/winegstreamer/gst_cbs.h | 23 +
|
||||
dlls/winegstreamer/gst_private.h | 7 +
|
||||
dlls/winegstreamer/main.c | 3 +-
|
||||
dlls/winegstreamer/mf_decode.c | 1322 ++++++++++++++++++
|
||||
dlls/winegstreamer/mfplat.c | 118 +-
|
||||
dlls/winegstreamer/mf_decode.c | 1320 ++++++++++++++++++
|
||||
dlls/winegstreamer/mfplat.c | 63 +-
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 12 +
|
||||
include/mfidl.idl | 2 +
|
||||
9 files changed, 1551 insertions(+), 2 deletions(-)
|
||||
9 files changed, 1494 insertions(+), 2 deletions(-)
|
||||
create mode 100644 dlls/winegstreamer/mf_decode.c
|
||||
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index f2e87494459..e2af4085827 100644
|
||||
index 4f6b428f067..81c670c17e4 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -13,6 +13,7 @@ C_SRCS = \
|
||||
@@ -15,6 +15,7 @@ C_SRCS = \
|
||||
main.c \
|
||||
media_source.c \
|
||||
mediatype.c \
|
||||
@ -163,7 +163,7 @@ index a48999bbf71..6659aedefa5 100644
|
||||
|
||||
#endif
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 321143396d6..ba9b7abbd78 100644
|
||||
index 6a6da817d58..b7817608653 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -75,6 +75,7 @@ BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
|
||||
@ -186,7 +186,7 @@ index 321143396d6..ba9b7abbd78 100644
|
||||
+HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __GST_PRIVATE_INCLUDED__ */
|
||||
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
|
||||
index 4ca371d58bd..385c5550235 100644
|
||||
--- a/dlls/winegstreamer/main.c
|
||||
@ -203,10 +203,10 @@ index 4ca371d58bd..385c5550235 100644
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
new file mode 100644
|
||||
index 00000000000..70a20ebe69b
|
||||
index 00000000000..7055ffa54fc
|
||||
--- /dev/null
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -0,0 +1,1322 @@
|
||||
@@ -0,0 +1,1320 @@
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <gst/gst.h>
|
||||
@ -509,6 +509,9 @@ index 00000000000..70a20ebe69b
|
||||
+ copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_NUM_CHANNELS);
|
||||
+ copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND);
|
||||
+
|
||||
+ IMFMediaType_SetUINT32(output_type, &MF_MT_COMPRESSED, FALSE);
|
||||
+ IMFMediaType_SetUINT32(output_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type)))
|
||||
+ {
|
||||
+ IMFMediaType_Release(output_type);
|
||||
@ -604,88 +607,83 @@ index 00000000000..70a20ebe69b
|
||||
+
|
||||
+static BOOL find_decoder_from_caps(GstCaps *input_caps, GstElement **decoder, GstElement **parser)
|
||||
+{
|
||||
+ GList *decoder_list_one, *decoder_list_two;
|
||||
+ GList *parser_list_one, *parser_list_two;
|
||||
+ GList *walk;
|
||||
+ BOOL ret = TRUE;
|
||||
+
|
||||
+ TRACE("input caps: %s\n", gst_caps_to_string(input_caps));
|
||||
+
|
||||
+ decoder_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER, 1);
|
||||
+ decoder_list_two = gst_element_factory_list_filter(decoder_list_one, input_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ decoder_list_one = decoder_list_two;
|
||||
+ if (g_list_length(decoder_list_one) &&
|
||||
+ (*decoder = gst_element_factory_create(g_list_first(decoder_list_one)->data, NULL)))
|
||||
+ {
|
||||
+ TRACE("Found decoder %s\n", GST_ELEMENT_NAME(g_list_first(decoder_list_one)->data));
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+
|
||||
+ parser_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER, 1);
|
||||
+ parser_list_two = gst_element_factory_list_filter(parser_list_one, input_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ parser_list_one = parser_list_two;
|
||||
+ if (!(g_list_length(parser_list_one)))
|
||||
+
|
||||
+ for (walk = (GList *) parser_list_one; walk; walk = g_list_next(walk))
|
||||
+ {
|
||||
+ GList *decoder_list_one, *decoder_list_two;
|
||||
+ decoder_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER, 1);
|
||||
+ decoder_list_two = gst_element_factory_list_filter(decoder_list_one, input_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ decoder_list_one = decoder_list_two;
|
||||
+ if (!(g_list_length(decoder_list_one)) ||
|
||||
+ !(*decoder = gst_element_factory_create(g_list_first(decoder_list_one)->data, NULL)))
|
||||
+ GstElementFactory *parser_factory = walk->data;
|
||||
+ const GList *templates, *walk_templ;
|
||||
+
|
||||
+ templates = gst_element_factory_get_static_pad_templates(parser_factory);
|
||||
+
|
||||
+ for (walk_templ = (GList *)templates; walk_templ; walk_templ = g_list_next(walk_templ))
|
||||
+ {
|
||||
+ GstStaticPadTemplate *templ = walk_templ->data;
|
||||
+ GstCaps *templ_caps;
|
||||
+
|
||||
+ if (templ->direction != GST_PAD_SRC)
|
||||
+ continue;
|
||||
+
|
||||
+ templ_caps = gst_static_pad_template_get_caps(templ);
|
||||
+
|
||||
+ TRACE("Matching parser src caps %s to decoder.\n", gst_caps_to_string(templ_caps));
|
||||
+
|
||||
+ decoder_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER, 1);
|
||||
+ decoder_list_two = gst_element_factory_list_filter(decoder_list_one, templ_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ ERR("Failed to create decoder\n");
|
||||
+ ret = FALSE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ TRACE("Found decoder %s\n", GST_ELEMENT_NAME(g_list_first(decoder_list_one)->data));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (walk = (GList *) parser_list_one; walk; walk = g_list_next(walk))
|
||||
+ {
|
||||
+ GstElementFactory *parser_factory = walk->data;
|
||||
+ const GList *templates, *walk_templ;
|
||||
+ decoder_list_one = decoder_list_two;
|
||||
+ gst_caps_unref(templ_caps);
|
||||
+
|
||||
+ templates = gst_element_factory_get_static_pad_templates(parser_factory);
|
||||
+ if (!(g_list_length(decoder_list_one)))
|
||||
+ continue;
|
||||
+
|
||||
+ for (walk_templ = (GList *)templates; walk_templ; walk_templ = g_list_next(walk_templ))
|
||||
+ if (!(*parser = gst_element_factory_create(parser_factory, NULL)))
|
||||
+ {
|
||||
+ GList *decoder_list_one, *decoder_list_two;
|
||||
+ GstStaticPadTemplate *templ = walk_templ->data;
|
||||
+ GstCaps *templ_caps;
|
||||
+
|
||||
+ if (templ->direction != GST_PAD_SRC)
|
||||
+ continue;
|
||||
+
|
||||
+ templ_caps = gst_static_pad_template_get_caps(templ);
|
||||
+
|
||||
+ TRACE("Matching parser src caps %s to decoder.\n", gst_caps_to_string(templ_caps));
|
||||
+
|
||||
+ decoder_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER, 1);
|
||||
+ decoder_list_two = gst_element_factory_list_filter(decoder_list_one, templ_caps, GST_PAD_SINK, 0);
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ decoder_list_one = decoder_list_two;
|
||||
+ gst_caps_unref(templ_caps);
|
||||
+
|
||||
+ if (!(g_list_length(decoder_list_one)))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!(*parser = gst_element_factory_create(parser_factory, NULL)))
|
||||
+ {
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ ERR("Failed to create parser\n");
|
||||
+ ret = FALSE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!(*decoder = gst_element_factory_create(g_list_first(decoder_list_one)->data, NULL)))
|
||||
+ {
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ ERR("Failed to create decoder\n");
|
||||
+ ret = FALSE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ TRACE("Found decoder %s parser %s\n",
|
||||
+ GST_ELEMENT_NAME(g_list_first(decoder_list_one)->data), GST_ELEMENT_NAME(parser_factory));
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+
|
||||
+ ERR("Failed to create parser\n");
|
||||
+ ret = FALSE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!(*decoder = gst_element_factory_create(g_list_first(decoder_list_one)->data, NULL)))
|
||||
+ {
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+ ERR("Failed to create decoder\n");
|
||||
+ ret = FALSE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ TRACE("Found decoder %s parser %s\n",
|
||||
+ GST_ELEMENT_NAME(g_list_first(decoder_list_one)->data), GST_ELEMENT_NAME(parser_factory));
|
||||
+ gst_plugin_feature_list_free(decoder_list_one);
|
||||
+
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ done:
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ return ret;
|
||||
@ -1530,12 +1528,12 @@ index 00000000000..70a20ebe69b
|
||||
+ }
|
||||
+}
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7b7300d5e8e..7ff01b5b4bd 100644
|
||||
index 65d2d2efd64..8bc05d3ea94 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -406,6 +406,16 @@ failed:
|
||||
@@ -410,6 +410,16 @@ static GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a
|
||||
|
||||
static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
|
||||
static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}};
|
||||
|
||||
+static HRESULT h264_decoder_create(REFIID riid, void **ret)
|
||||
+{
|
||||
@ -1550,20 +1548,19 @@ index 7b7300d5e8e..7ff01b5b4bd 100644
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -415,6 +425,8 @@ class_objects[] =
|
||||
{
|
||||
{ &CLSID_VideoProcessorMFT, &video_processor_create },
|
||||
@@ -421,6 +431,8 @@ class_objects[] =
|
||||
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
|
||||
{ &CLSID_WINEAudioConverter, &audio_converter_create },
|
||||
{ &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
+ { &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
|
||||
+ { &CLSID_CMSAACDecMFT, &aac_decoder_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -443,6 +455,111 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
@@ -477,6 +489,32 @@ const GUID *color_converter_supported_types[] =
|
||||
&MFVideoFormat_YVYU,
|
||||
};
|
||||
|
||||
+
|
||||
+static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0};
|
||||
+const GUID *h264_decoder_input_types[] =
|
||||
+{
|
||||
@ -1590,21 +1587,13 @@ index 7b7300d5e8e..7ff01b5b4bd 100644
|
||||
+ &MFAudioFormat_PCM,
|
||||
+};
|
||||
+
|
||||
+static const struct mft
|
||||
+{
|
||||
+ const GUID *clsid;
|
||||
+ const GUID *category;
|
||||
+ LPWSTR name;
|
||||
+ const UINT32 flags;
|
||||
+ const GUID *major_type;
|
||||
+ const UINT32 input_types_count;
|
||||
+ const GUID **input_types;
|
||||
+ const UINT32 output_types_count;
|
||||
+ const GUID **output_types;
|
||||
+ IMFAttributes *attributes;
|
||||
+}
|
||||
+mfts[] =
|
||||
+{
|
||||
static const struct mft
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -516,6 +554,30 @@ mfts[] =
|
||||
color_converter_supported_types,
|
||||
NULL
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_CMSH264DecoderMFT,
|
||||
+ &MFT_CATEGORY_VIDEO_DECODER,
|
||||
@ -1628,50 +1617,11 @@ index 7b7300d5e8e..7ff01b5b4bd 100644
|
||||
+ ARRAY_SIZE(aac_decoder_output_types),
|
||||
+ aac_decoder_output_types,
|
||||
+ NULL
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+HRESULT mfplat_DllRegisterServer(void)
|
||||
+{
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ for (unsigned int i = 0; i < ARRAY_SIZE(mfts); i++)
|
||||
+ {
|
||||
+ const struct mft *cur = &mfts[i];
|
||||
+
|
||||
+ MFT_REGISTER_TYPE_INFO *input_types, *output_types;
|
||||
+ input_types = heap_alloc(cur->input_types_count * sizeof(input_types[0]));
|
||||
+ output_types = heap_alloc(cur->output_types_count * sizeof(output_types[0]));
|
||||
+ for (unsigned int i = 0; i < cur->input_types_count; i++)
|
||||
+ {
|
||||
+ input_types[i].guidMajorType = *(cur->major_type);
|
||||
+ input_types[i].guidSubtype = *(cur->input_types[i]);
|
||||
+ }
|
||||
+ for (unsigned int i = 0; i < cur->output_types_count; i++)
|
||||
+ {
|
||||
+ output_types[i].guidMajorType = *(cur->major_type);
|
||||
+ output_types[i].guidSubtype = *(cur->output_types[i]);
|
||||
+ }
|
||||
+
|
||||
+ hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count,
|
||||
+ input_types, cur->output_types_count, output_types, cur->attributes);
|
||||
+
|
||||
+ heap_free(input_types);
|
||||
+ heap_free(output_types);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ FIXME("Failed to register MFT, hr %#x\n", hr);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
static const struct
|
||||
{
|
||||
const GUID *subtype;
|
||||
@@ -461,7 +578,6 @@ struct aac_user_data
|
||||
+ },
|
||||
};
|
||||
|
||||
HRESULT mfplat_DllRegisterServer(void)
|
||||
@@ -574,7 +636,6 @@ struct aac_user_data
|
||||
{
|
||||
WORD payload_type;
|
||||
WORD profile_level_indication;
|
||||
@ -1680,13 +1630,13 @@ index 7b7300d5e8e..7ff01b5b4bd 100644
|
||||
/* audio-specific-config is stored here */
|
||||
};
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index 1dc4ba9a10b..3f28b4ddec4 100644
|
||||
index 9788fd45d36..6a71031b949 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -61,3 +61,15 @@ coclass VideoProcessorMFT {}
|
||||
uuid(317df618-5e5a-468a-9f15-d827a9a08162)
|
||||
@@ -73,3 +73,15 @@ coclass WINEAudioConverter { }
|
||||
uuid(98230571-0087-4204-b020-3282538e57d3)
|
||||
]
|
||||
coclass GStreamerByteStreamHandler {}
|
||||
coclass CColorConvertDMO { }
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
@ -1710,5 +1660,5 @@ index dd5de8d0d2f..4023c3a62d2 100644
|
||||
+cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);")
|
||||
+cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);")
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 72c0ff199851b1e62e6f88c302191d19201a1e00 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 13 May 2020 12:32:42 -0500
|
||||
Subject: [PATCH 35/45] Support stereo down folding.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/mf_decode.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 2cbe99d3168..0646cb2e845 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -327,9 +327,11 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO
|
||||
|
||||
copy_attr(output_type, decoder->input_type, &MF_MT_FRAME_SIZE);
|
||||
copy_attr(output_type, decoder->input_type, &MF_MT_FRAME_RATE);
|
||||
- copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_NUM_CHANNELS);
|
||||
copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND);
|
||||
|
||||
+ /* TODO: support both stereo folding and matching channels */
|
||||
+ IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_NUM_CHANNELS, 2);
|
||||
+
|
||||
if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type)))
|
||||
{
|
||||
IMFMediaType_Release(output_type);
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 5913e02f7c67c8f8214efd9de4e095f189fcca2e Mon Sep 17 00:00:00 2001
|
||||
From 4202931a370fc4024b01e10291219d4906270096 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 23 Mar 2020 11:55:41 -0500
|
||||
Subject: [PATCH 20/45] mfreadwrite: Select all streams when creating a source
|
||||
Subject: [PATCH] mfreadwrite: Select all streams when creating a source
|
||||
reader.
|
||||
|
||||
---
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH 20/45] mfreadwrite: Select all streams when creating a source
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
|
||||
index cc1b29a2b6a..935074d62f9 100644
|
||||
index 85aec9aaedc..77ce301d8be 100644
|
||||
--- a/dlls/mfreadwrite/reader.c
|
||||
+++ b/dlls/mfreadwrite/reader.c
|
||||
@@ -2127,6 +2127,10 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
|
||||
@@ -2138,6 +2138,10 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
|
||||
break;
|
||||
|
||||
object->streams[i].index = i;
|
||||
@ -24,5 +24,5 @@ index cc1b29a2b6a..935074d62f9 100644
|
||||
|
||||
if (FAILED(hr))
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 109ee18f64293f15f9bbf412ada842ad35e57a10 Mon Sep 17 00:00:00 2001
|
||||
From 030a2783c1fab91535bac4d4e6c7ea7d1e5da4a9 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 2 Nov 2020 09:58:09 -0600
|
||||
Subject: [PATCH 21/45] Miscellaneous
|
||||
Subject: [PATCH] Miscellaneous
|
||||
|
||||
---
|
||||
dlls/mfreadwrite/reader.c | 12 +++++++++++-
|
||||
@ -11,10 +11,10 @@ Subject: [PATCH 21/45] Miscellaneous
|
||||
4 files changed, 43 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
|
||||
index 935074d62f9..9d86a5a0f8f 100644
|
||||
index 77ce301d8be..9fdef9a8c9c 100644
|
||||
--- a/dlls/mfreadwrite/reader.c
|
||||
+++ b/dlls/mfreadwrite/reader.c
|
||||
@@ -1597,6 +1597,7 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea
|
||||
@@ -1584,6 +1584,7 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea
|
||||
{
|
||||
MFT_REGISTER_TYPE_INFO in_type, out_type;
|
||||
CLSID *clsids, mft_clsid, category;
|
||||
@ -22,7 +22,7 @@ index 935074d62f9..9d86a5a0f8f 100644
|
||||
unsigned int i = 0, count;
|
||||
IMFMediaType *input_type;
|
||||
HRESULT hr;
|
||||
@@ -1643,12 +1644,21 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea
|
||||
@@ -1630,12 +1631,21 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea
|
||||
}
|
||||
|
||||
}
|
||||
@ -102,10 +102,10 @@ index 6659aedefa5..825b46d13bb 100644
|
||||
|
||||
#endif
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 2df86814679..0fcc2ca42f3 100644
|
||||
index 0085459f86f..acc9d53ca2e 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -532,6 +532,11 @@ static gboolean bytestream_query(GstPad *pad, GstObject *parent, GstQuery *query
|
||||
@@ -552,6 +552,11 @@ static gboolean bytestream_query(GstPad *pad, GstObject *parent, GstQuery *query
|
||||
gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL);
|
||||
return TRUE;
|
||||
}
|
||||
@ -117,7 +117,7 @@ index 2df86814679..0fcc2ca42f3 100644
|
||||
default:
|
||||
{
|
||||
WARN("Unhandled query type %s\n", GST_QUERY_TYPE_NAME(query));
|
||||
@@ -594,6 +599,23 @@ GstBusSyncReply bus_watch(GstBus *bus, GstMessage *message, gpointer user)
|
||||
@@ -614,6 +619,23 @@ GstBusSyncReply bus_watch(GstBus *bus, GstMessage *message, gpointer user)
|
||||
g_error_free(err);
|
||||
g_free(dbg_info);
|
||||
break;
|
||||
@ -141,7 +141,7 @@ index 2df86814679..0fcc2ca42f3 100644
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1132,7 +1154,7 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO
|
||||
@@ -1152,7 +1174,7 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO
|
||||
if (source->state == SOURCE_SHUTDOWN)
|
||||
return MF_E_SHUTDOWN;
|
||||
|
||||
@ -151,5 +151,5 @@ index 2df86814679..0fcc2ca42f3 100644
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,246 +0,0 @@
|
||||
From dc16275dcbce65fababff4a3497d95c208c8d3d4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 11 Aug 2020 15:58:42 -0500
|
||||
Subject: [PATCH 37/45] Revert "mf/topoloader: Add a structure for iterative
|
||||
branch resolution."
|
||||
|
||||
This reverts commit e308d81a617632fe0fedd243952f79e8d9ec05b4.
|
||||
---
|
||||
dlls/mf/tests/mf.c | 9 +--
|
||||
dlls/mf/topology.c | 138 +--------------------------------------------
|
||||
2 files changed, 4 insertions(+), 143 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index c38c817eb4b..e3b98be0373 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -1401,7 +1401,6 @@ static void test_topology_loader(void)
|
||||
IMFPresentationDescriptor *pd;
|
||||
IMFSourceResolver *resolver;
|
||||
IMFActivate *sink_activate;
|
||||
- IMFStreamSink *stream_sink;
|
||||
unsigned int count, value;
|
||||
IMFMediaType *media_type;
|
||||
IMFStreamDescriptor *sd;
|
||||
@@ -1516,19 +1515,15 @@ todo_wine
|
||||
hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
|
||||
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
|
||||
|
||||
- hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
|
||||
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
-
|
||||
- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink);
|
||||
+ hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink);
|
||||
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
|
||||
|
||||
- IMFStreamSink_Release(stream_sink);
|
||||
-
|
||||
hr = IMFTopology_GetCount(topology, &count);
|
||||
ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
|
||||
ok(count == 0, "Unexpected count %u.\n", count);
|
||||
|
||||
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
+todo_wine
|
||||
ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
|
||||
ok(full_topology != topology, "Unexpected instance.\n");
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 8032e438b73..840f1bd25f4 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1935,41 +1935,17 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
|
||||
|
||||
struct topoloader_context
|
||||
{
|
||||
- IMFTopology *input_topology;
|
||||
IMFTopology *output_topology;
|
||||
- unsigned int marker;
|
||||
GUID key;
|
||||
};
|
||||
|
||||
-static IMFTopologyNode *topology_loader_get_node_for_marker(struct topoloader_context *context, TOPOID *id)
|
||||
-{
|
||||
- IMFTopologyNode *node;
|
||||
- unsigned short i = 0;
|
||||
- unsigned int value;
|
||||
-
|
||||
- while (SUCCEEDED(IMFTopology_GetNode(context->output_topology, i++, &node)))
|
||||
- {
|
||||
- if (SUCCEEDED(IMFTopologyNode_GetUINT32(node, &context->key, &value)) && value == context->marker)
|
||||
- {
|
||||
- IMFTopologyNode_GetTopoNodeID(node, id);
|
||||
- return node;
|
||||
- }
|
||||
- IMFTopologyNode_Release(node);
|
||||
- }
|
||||
-
|
||||
- *id = 0;
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
static HRESULT topology_loader_clone_node(struct topoloader_context *context, IMFTopologyNode *node,
|
||||
- IMFTopologyNode **ret, unsigned int marker)
|
||||
+ unsigned int marker)
|
||||
{
|
||||
IMFTopologyNode *cloned_node;
|
||||
MF_TOPOLOGY_TYPE node_type;
|
||||
HRESULT hr;
|
||||
|
||||
- if (ret) *ret = NULL;
|
||||
-
|
||||
IMFTopologyNode_GetNodeType(node, &node_type);
|
||||
|
||||
if (FAILED(hr = MFCreateTopologyNode(node_type, &cloned_node)))
|
||||
@@ -1981,113 +1957,17 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IMFTopology_AddNode(context->output_topology, cloned_node);
|
||||
|
||||
- if (SUCCEEDED(hr) && ret)
|
||||
- {
|
||||
- *ret = cloned_node;
|
||||
- IMFTopologyNode_AddRef(*ret);
|
||||
- }
|
||||
-
|
||||
IMFTopologyNode_Release(cloned_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");
|
||||
-
|
||||
- return E_NOTIMPL;
|
||||
-}
|
||||
-
|
||||
-static HRESULT topology_loader_resolve_branch(struct topoloader_context *context, IMFTopologyNode *upstream_node,
|
||||
- unsigned int output_index, IMFTopologyNode *downstream_node, unsigned input_index)
|
||||
-{
|
||||
- static const p_topology_loader_connect_func connectors[MF_TOPOLOGY_TEE_NODE+1][MF_TOPOLOGY_TEE_NODE+1] =
|
||||
- {
|
||||
- /* OUTPUT */ { NULL },
|
||||
- /* SOURCESTREAM */ { topology_loader_connect_source_node, NULL, NULL, NULL },
|
||||
- /* TRANSFORM */ { NULL },
|
||||
- /* TEE */ { NULL },
|
||||
- };
|
||||
- MF_TOPOLOGY_TYPE u_type, d_type;
|
||||
- IMFTopologyNode *node;
|
||||
- TOPOID id;
|
||||
-
|
||||
- /* Downstream node might have already been cloned. */
|
||||
- IMFTopologyNode_GetTopoNodeID(downstream_node, &id);
|
||||
- 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);
|
||||
-
|
||||
- if (!connectors[u_type][d_type])
|
||||
- {
|
||||
- WARN("Unsupported branch kind %d -> %d.\n", u_type, d_type);
|
||||
- return E_FAIL;
|
||||
- }
|
||||
-
|
||||
- return connectors[u_type][d_type](context, upstream_node, output_index, downstream_node, input_index);
|
||||
-}
|
||||
-
|
||||
-static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context, unsigned int *layer_size)
|
||||
-{
|
||||
- IMFTopologyNode *downstream_node, *node, *orig_node;
|
||||
- unsigned int input_index, size = 0;
|
||||
- MF_TOPOLOGY_TYPE node_type;
|
||||
- HRESULT hr = S_OK;
|
||||
- TOPOID id;
|
||||
-
|
||||
- while ((node = topology_loader_get_node_for_marker(context, &id)))
|
||||
- {
|
||||
- ++size;
|
||||
-
|
||||
- IMFTopology_GetNodeByID(context->input_topology, id, &orig_node);
|
||||
-
|
||||
- IMFTopologyNode_GetNodeType(node, &node_type);
|
||||
- switch (node_type)
|
||||
- {
|
||||
- case MF_TOPOLOGY_SOURCESTREAM_NODE:
|
||||
- if (FAILED(IMFTopologyNode_GetOutput(orig_node, 0, &downstream_node, &input_index)))
|
||||
- {
|
||||
- IMFTopology_RemoveNode(context->output_topology, node);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- hr = topology_loader_resolve_branch(context, node, 0, downstream_node, input_index);
|
||||
- break;
|
||||
- case MF_TOPOLOGY_TRANSFORM_NODE:
|
||||
- case MF_TOPOLOGY_TEE_NODE:
|
||||
- FIXME("Unsupported node type %d.\n", node_type);
|
||||
- break;
|
||||
- default:
|
||||
- WARN("Unexpected node type %d.\n", node_type);
|
||||
- }
|
||||
-
|
||||
- IMFTopologyNode_DeleteItem(node, &context->key);
|
||||
-
|
||||
- if (FAILED(hr))
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- *layer_size = size;
|
||||
-
|
||||
- return hr;
|
||||
-}
|
||||
-
|
||||
static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
|
||||
IMFTopology **ret_topology, IMFTopology *current_topology)
|
||||
{
|
||||
struct topoloader_context context = { 0 };
|
||||
IMFTopology *output_topology;
|
||||
MF_TOPOLOGY_TYPE node_type;
|
||||
- unsigned int layer_size;
|
||||
IMFTopologyNode *node;
|
||||
unsigned short i = 0;
|
||||
IMFStreamSink *sink;
|
||||
@@ -2136,7 +2016,6 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
if (FAILED(hr = MFCreateTopology(&output_topology)))
|
||||
return hr;
|
||||
|
||||
- context.input_topology = input_topology;
|
||||
context.output_topology = output_topology;
|
||||
memset(&context.key, 0xff, sizeof(context.key));
|
||||
|
||||
@@ -2148,26 +2027,13 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
|
||||
if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||
{
|
||||
- if (FAILED(hr = topology_loader_clone_node(&context, node, NULL, 0)))
|
||||
+ if (FAILED(hr = topology_loader_clone_node(&context, node, 0)))
|
||||
WARN("Failed to clone source node, hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
IMFTopologyNode_Release(node);
|
||||
}
|
||||
|
||||
- for (context.marker = 0;; ++context.marker)
|
||||
- {
|
||||
- if (FAILED(hr = topology_loader_resolve_nodes(&context, &layer_size)))
|
||||
- {
|
||||
- WARN("Failed to resolve for marker %u, hr %#x.\n", context.marker, hr);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* Reached last marker value. */
|
||||
- if (!layer_size)
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
/* For now return original topology. */
|
||||
|
||||
*ret_topology = output_topology;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From eb89bb6b8eed2217d7832168e188ed105248cfc2 Mon Sep 17 00:00:00 2001
|
||||
From a24c920e166f93add20edbf2dc7b156ab2465a6e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 19:07:11 -0500
|
||||
Subject: [PATCH 22/45] WMV
|
||||
Subject: [PATCH] WMV
|
||||
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
@ -12,7 +12,7 @@ Subject: [PATCH 22/45] WMV
|
||||
5 files changed, 59 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index ba9b7abbd78..cebd8d5282f 100644
|
||||
index b7817608653..0eba22fe30f 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -89,6 +89,7 @@ enum decoder_type
|
||||
@ -24,7 +24,7 @@ index ba9b7abbd78..cebd8d5282f 100644
|
||||
HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 70a20ebe69b..2005443a8a6 100644
|
||||
index 7055ffa54fc..3625382c573 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -29,6 +29,9 @@ const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MF
|
||||
@ -52,10 +52,10 @@ index 70a20ebe69b..2005443a8a6 100644
|
||||
};
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7ff01b5b4bd..b699c1dc8ec 100644
|
||||
index 8bc05d3ea94..2a225f82d36 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -416,6 +416,10 @@ static HRESULT aac_decoder_create(REFIID riid, void **ret)
|
||||
@@ -420,6 +420,10 @@ static HRESULT aac_decoder_create(REFIID riid, void **ret)
|
||||
return generic_decoder_construct(riid, ret, DECODER_TYPE_AAC);
|
||||
}
|
||||
|
||||
@ -66,15 +66,15 @@ index 7ff01b5b4bd..b699c1dc8ec 100644
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -427,6 +431,7 @@ class_objects[] =
|
||||
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
|
||||
@@ -433,6 +437,7 @@ class_objects[] =
|
||||
{ &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
{ &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
|
||||
{ &CLSID_CMSAACDecMFT, &aac_decoder_create },
|
||||
+ { &CLSID_CWMVDecMediaObject, &wmv_decoder_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -482,6 +487,29 @@ const GUID *aac_decoder_output_types[] =
|
||||
@@ -515,6 +520,29 @@ const GUID *aac_decoder_output_types[] =
|
||||
&MFAudioFormat_PCM,
|
||||
};
|
||||
|
||||
@ -104,11 +104,10 @@ index 7ff01b5b4bd..b699c1dc8ec 100644
|
||||
static const struct mft
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -520,6 +548,18 @@ mfts[] =
|
||||
ARRAY_SIZE(aac_decoder_output_types),
|
||||
@@ -578,6 +606,18 @@ mfts[] =
|
||||
aac_decoder_output_types,
|
||||
NULL
|
||||
+ },
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_CWMVDecMediaObject,
|
||||
+ &MFT_CATEGORY_VIDEO_DECODER,
|
||||
@ -120,14 +119,15 @@ index 7ff01b5b4bd..b699c1dc8ec 100644
|
||||
+ ARRAY_SIZE(wmv_decoder_output_types),
|
||||
+ wmv_decoder_output_types,
|
||||
+ NULL
|
||||
}
|
||||
+ },
|
||||
};
|
||||
|
||||
HRESULT mfplat_DllRegisterServer(void)
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index 3f28b4ddec4..f9b0158fa6a 100644
|
||||
index 6a71031b949..51d44ad5242 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -73,3 +73,9 @@ coclass CMSH264DecoderMFT { }
|
||||
@@ -85,3 +85,9 @@ coclass CMSH264DecoderMFT { }
|
||||
uuid(32d186a7-218f-4c75-8876-dd77273a8999)
|
||||
]
|
||||
coclass CMSAACDecMFT { }
|
||||
@ -149,5 +149,5 @@ index 4023c3a62d2..7cb027b156a 100644
|
||||
+cpp_quote("EXTERN_GUID(CLSID_CWMVDecMediaObject, 0x82d353df, 0x90bd, 0x4382, 0x8b, 0xc2, 0x3f, 0x61, 0x92, 0xb7, 0x6e, 0x34);")
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,14 +1,14 @@
|
||||
From a135f98d9caaa0a576820ddf76f999a1f90ec81f Mon Sep 17 00:00:00 2001
|
||||
From 9724cb4288ad131c8a40d240320ca4774b26e988 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Fri, 3 Apr 2020 11:12:33 -0500
|
||||
Subject: [PATCH 24/45] Expose PCM output type on AAC decoder.
|
||||
Subject: [PATCH] Expose PCM output type on AAC decoder.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/mf_decode.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 2005443a8a6..05c99365e32 100644
|
||||
index 3625382c573..c188d08c57f 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -27,7 +27,7 @@ const GUID *h264_input_types[] = {&MFVideoFormat_H264};
|
||||
@ -21,5 +21,5 @@ index 2005443a8a6..05c99365e32 100644
|
||||
const GUID *wmv_input_types[] = {&MFVideoFormat_WMV3, &MFVideoFormat_WVC1};
|
||||
const GUID *wmv_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_YV12, &MFVideoFormat_YUY2, &MFVideoFormat_UYVY, &MFVideoFormat_YVYU, &MFVideoFormat_NV11, &MFVideoFormat_RGB32, &MFVideoFormat_RGB24, &MFVideoFormat_RGB555, &MFVideoFormat_RGB8};
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,104 +0,0 @@
|
||||
From b913b275b9cb917f5678edb6933aa4b466ea6f3b Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 11 Aug 2020 15:59:04 -0500
|
||||
Subject: [PATCH 38/45] Revert "mf/topoloader: Clone source nodes as a first
|
||||
layer of resulting topology."
|
||||
|
||||
This reverts commit 16d44b61d15193905ef40661bc1547cb45e7b019.
|
||||
---
|
||||
dlls/mf/topology.c | 61 +++-------------------------------------------
|
||||
1 file changed, 4 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 840f1bd25f4..8522f569691 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1933,40 +1933,9 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
|
||||
return refcount;
|
||||
}
|
||||
|
||||
-struct topoloader_context
|
||||
-{
|
||||
- IMFTopology *output_topology;
|
||||
- GUID key;
|
||||
-};
|
||||
-
|
||||
-static HRESULT topology_loader_clone_node(struct topoloader_context *context, IMFTopologyNode *node,
|
||||
- unsigned int marker)
|
||||
-{
|
||||
- IMFTopologyNode *cloned_node;
|
||||
- MF_TOPOLOGY_TYPE node_type;
|
||||
- HRESULT hr;
|
||||
-
|
||||
- IMFTopologyNode_GetNodeType(node, &node_type);
|
||||
-
|
||||
- if (FAILED(hr = MFCreateTopologyNode(node_type, &cloned_node)))
|
||||
- return hr;
|
||||
-
|
||||
- if (SUCCEEDED(hr = IMFTopologyNode_CloneFrom(cloned_node, node)))
|
||||
- hr = IMFTopologyNode_SetUINT32(cloned_node, &context->key, marker);
|
||||
-
|
||||
- if (SUCCEEDED(hr))
|
||||
- hr = IMFTopology_AddNode(context->output_topology, cloned_node);
|
||||
-
|
||||
- IMFTopologyNode_Release(cloned_node);
|
||||
-
|
||||
- return hr;
|
||||
-}
|
||||
-
|
||||
static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
|
||||
- IMFTopology **ret_topology, IMFTopology *current_topology)
|
||||
+ IMFTopology **output_topology, IMFTopology *current_topology)
|
||||
{
|
||||
- struct topoloader_context context = { 0 };
|
||||
- IMFTopology *output_topology;
|
||||
MF_TOPOLOGY_TYPE node_type;
|
||||
IMFTopologyNode *node;
|
||||
unsigned short i = 0;
|
||||
@@ -1974,7 +1943,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
IUnknown *object;
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
- FIXME("%p, %p, %p, %p.\n", iface, input_topology, ret_topology, current_topology);
|
||||
+ FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology);
|
||||
|
||||
if (current_topology)
|
||||
FIXME("Current topology instance is ignored.\n");
|
||||
@@ -2013,32 +1982,10 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
return hr;
|
||||
}
|
||||
|
||||
- if (FAILED(hr = MFCreateTopology(&output_topology)))
|
||||
+ if (FAILED(hr = MFCreateTopology(output_topology)))
|
||||
return hr;
|
||||
|
||||
- context.output_topology = output_topology;
|
||||
- memset(&context.key, 0xff, sizeof(context.key));
|
||||
-
|
||||
- /* Clone source nodes, use initial marker value. */
|
||||
- i = 0;
|
||||
- while (SUCCEEDED(IMFTopology_GetNode(input_topology, i++, &node)))
|
||||
- {
|
||||
- IMFTopologyNode_GetNodeType(node, &node_type);
|
||||
-
|
||||
- if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||
- {
|
||||
- if (FAILED(hr = topology_loader_clone_node(&context, node, 0)))
|
||||
- WARN("Failed to clone source node, hr %#x.\n", hr);
|
||||
- }
|
||||
-
|
||||
- IMFTopologyNode_Release(node);
|
||||
- }
|
||||
-
|
||||
- /* For now return original topology. */
|
||||
-
|
||||
- *ret_topology = output_topology;
|
||||
-
|
||||
- return IMFTopology_CloneFrom(output_topology, input_topology);
|
||||
+ return IMFTopology_CloneFrom(*output_topology, input_topology);
|
||||
}
|
||||
|
||||
static const IMFTopoLoaderVtbl topologyloadervtbl =
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From cb7bdd310ec8ed0ac8772de715ef19716da744e2 Mon Sep 17 00:00:00 2001
|
||||
From 923e08293c4fd297eaada8f96f7ca134682eff49 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 9 Mar 2020 11:59:17 -0500
|
||||
Subject: [PATCH 28/45] Improve tests
|
||||
Subject: [PATCH] Improve tests
|
||||
|
||||
---
|
||||
dlls/mfplat/tests/mfplat.c | 245 +++++++++++++++++++++++++++--
|
||||
@ -13,10 +13,10 @@ Subject: [PATCH 28/45] Improve tests
|
||||
create mode 100644 dlls/mfreadwrite/tests/test.mp4
|
||||
|
||||
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
|
||||
index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
index 474d6281f5f..f364b80ba21 100644
|
||||
--- a/dlls/mfplat/tests/mfplat.c
|
||||
+++ b/dlls/mfplat/tests/mfplat.c
|
||||
@@ -439,6 +439,9 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
|
||||
@@ -454,6 +454,9 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
static void test_source_resolver(void)
|
||||
{
|
||||
struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
|
||||
@@ -462,6 +465,7 @@ static void test_source_resolver(void)
|
||||
@@ -477,6 +480,7 @@ static void test_source_resolver(void)
|
||||
PROPVARIANT var;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
@ -34,7 +34,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
|
||||
if (!pMFCreateSourceResolver)
|
||||
{
|
||||
@@ -595,13 +599,27 @@ static void test_source_resolver(void)
|
||||
@@ -601,13 +605,27 @@ static void test_source_resolver(void)
|
||||
ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
|
||||
hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
|
||||
ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
|
||||
@ -65,7 +65,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
var.vt = VT_EMPTY;
|
||||
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
||||
ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
|
||||
@@ -612,9 +630,9 @@ todo_wine
|
||||
@@ -618,9 +636,9 @@ todo_wine
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL);
|
||||
|
||||
@ -77,7 +77,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
@@ -629,9 +647,14 @@ todo_wine
|
||||
@@ -635,9 +653,14 @@ todo_wine
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
static const LONGLONG MILLI_TO_100_NANO = 10000;
|
||||
@ -93,7 +93,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
BOOL ret;
|
||||
|
||||
ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
|
||||
@@ -642,19 +665,38 @@ todo_wine
|
||||
@@ -648,19 +671,38 @@ todo_wine
|
||||
ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
|
||||
sample = (IMFSample *)var.punkVal;
|
||||
|
||||
@ -141,7 +141,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
}
|
||||
|
||||
if (i == sample_count)
|
||||
@@ -724,6 +766,178 @@ todo_wine
|
||||
@@ -730,6 +772,178 @@ todo_wine
|
||||
DeleteFileW(filename);
|
||||
}
|
||||
|
||||
@ -320,7 +320,7 @@ index 4f5cf268d2a..82d76f7bbaa 100644
|
||||
static void init_functions(void)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA("mfplat.dll");
|
||||
@@ -6009,6 +6223,7 @@ START_TEST(mfplat)
|
||||
@@ -5982,6 +6196,7 @@ START_TEST(mfplat)
|
||||
test_MFCreateMFByteStreamOnStream();
|
||||
test_system_memory_buffer();
|
||||
test_source_resolver();
|
||||
@ -2679,7 +2679,7 @@ zKs;bQARC}!xiSZ6ESNJ5P+CoKB<O7nEod-NqPX>NU0kHoiM#Wkq*n&-SMq0^0~2cD
|
||||
TJ;x-N6hTeOp(eUDP!ruh^$B~#
|
||||
|
||||
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c
|
||||
index 2a6e3a1cc36..80db5f33772 100644
|
||||
index 8455ac64688..f9b01f4cd72 100644
|
||||
--- a/dlls/mfreadwrite/tests/mfplat.c
|
||||
+++ b/dlls/mfreadwrite/tests/mfplat.c
|
||||
@@ -629,9 +629,17 @@ static void test_source_reader(void)
|
||||
@ -5273,5 +5273,5 @@ literal 0
|
||||
HcmV?d00001
|
||||
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 560114776a915562b1b8806152d942179b561f08 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 11 Aug 2020 15:59:13 -0500
|
||||
Subject: [PATCH 39/45] Revert "mf/topoloader: Switch to public interface for
|
||||
initial topology validation."
|
||||
|
||||
This reverts commit 8e343024b577892bd4908304ded34b758579698d.
|
||||
---
|
||||
dlls/mf/topology.c | 36 ++++++++++++------------------------
|
||||
1 file changed, 12 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 8522f569691..abe66c45fd4 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1936,50 +1936,38 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
|
||||
static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
|
||||
IMFTopology **output_topology, IMFTopology *current_topology)
|
||||
{
|
||||
- MF_TOPOLOGY_TYPE node_type;
|
||||
- IMFTopologyNode *node;
|
||||
- unsigned short i = 0;
|
||||
+ struct topology *topology = unsafe_impl_from_IMFTopology(input_topology);
|
||||
IMFStreamSink *sink;
|
||||
- IUnknown *object;
|
||||
- HRESULT hr = E_FAIL;
|
||||
+ HRESULT hr;
|
||||
+ size_t i;
|
||||
|
||||
FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology);
|
||||
|
||||
if (current_topology)
|
||||
FIXME("Current topology instance is ignored.\n");
|
||||
|
||||
- /* Basic sanity checks for input topology:
|
||||
-
|
||||
- - source nodes must have stream descriptor set;
|
||||
- - sink nodes must be resolved to stream sink objects;
|
||||
- */
|
||||
- while (SUCCEEDED(IMFTopology_GetNode(input_topology, i++, &node)))
|
||||
+ for (i = 0; i < topology->nodes.count; ++i)
|
||||
{
|
||||
- IMFTopologyNode_GetNodeType(node, &node_type);
|
||||
+ struct topology_node *node = topology->nodes.nodes[i];
|
||||
|
||||
- switch (node_type)
|
||||
+ switch (node->node_type)
|
||||
{
|
||||
case MF_TOPOLOGY_OUTPUT_NODE:
|
||||
- if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, &object)))
|
||||
+ if (node->object)
|
||||
{
|
||||
/* Sinks must be bound beforehand. */
|
||||
- if (FAILED(IUnknown_QueryInterface(object, &IID_IMFStreamSink, (void **)&sink)))
|
||||
- hr = MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
|
||||
- else if (sink)
|
||||
- IMFStreamSink_Release(sink);
|
||||
- IUnknown_Release(object);
|
||||
+ if (FAILED(IUnknown_QueryInterface(node->object, &IID_IMFStreamSink, (void **)&sink)))
|
||||
+ return MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
|
||||
+ IMFStreamSink_Release(sink);
|
||||
}
|
||||
break;
|
||||
case MF_TOPOLOGY_SOURCESTREAM_NODE:
|
||||
- hr = IMFTopologyNode_GetItem(node, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL);
|
||||
+ if (FAILED(hr = IMFAttributes_GetItem(node->attributes, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL)))
|
||||
+ return hr;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
-
|
||||
- IMFTopologyNode_Release(node);
|
||||
- if (FAILED(hr))
|
||||
- return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = MFCreateTopology(output_topology)))
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 00e320809b10854a9870c28782eac3aa8fd0e864 Mon Sep 17 00:00:00 2001
|
||||
From 5c66ec65febd0aa62d0e3f0cd757252e0512941d Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 13:58:36 -0500
|
||||
Subject: [PATCH 29/45] Revert "Improve tests"
|
||||
Subject: [PATCH] Revert "Improve tests"
|
||||
|
||||
This reverts commit 603b1717a2b511a66d3be99ab5761d49cd5ef34d.
|
||||
---
|
||||
@ -14,10 +14,10 @@ This reverts commit 603b1717a2b511a66d3be99ab5761d49cd5ef34d.
|
||||
delete mode 100644 dlls/mfreadwrite/tests/test.mp4
|
||||
|
||||
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
|
||||
index 82d76f7bbaa..9634ee059b0 100644
|
||||
index f364b80ba21..9027fd0af3e 100644
|
||||
--- a/dlls/mfplat/tests/mfplat.c
|
||||
+++ b/dlls/mfplat/tests/mfplat.c
|
||||
@@ -439,9 +439,6 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
|
||||
@@ -454,9 +454,6 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
static void test_source_resolver(void)
|
||||
{
|
||||
struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
|
||||
@@ -465,7 +462,6 @@ static void test_source_resolver(void)
|
||||
@@ -480,7 +477,6 @@ static void test_source_resolver(void)
|
||||
PROPVARIANT var;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
@ -35,7 +35,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
|
||||
if (!pMFCreateSourceResolver)
|
||||
{
|
||||
@@ -599,27 +595,12 @@ static void test_source_resolver(void)
|
||||
@@ -605,27 +601,12 @@ static void test_source_resolver(void)
|
||||
ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
|
||||
hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
|
||||
ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
|
||||
@ -65,7 +65,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
var.vt = VT_EMPTY;
|
||||
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
||||
ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
|
||||
@@ -630,9 +611,9 @@ static void test_source_resolver(void)
|
||||
@@ -636,9 +617,9 @@ static void test_source_resolver(void)
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL);
|
||||
|
||||
@ -77,7 +77,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
@@ -647,14 +628,9 @@ static void test_source_resolver(void)
|
||||
@@ -653,14 +634,9 @@ static void test_source_resolver(void)
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
static const LONGLONG MILLI_TO_100_NANO = 10000;
|
||||
@ -93,7 +93,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
BOOL ret;
|
||||
|
||||
ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
|
||||
@@ -665,38 +641,19 @@ static void test_source_resolver(void)
|
||||
@@ -671,38 +647,19 @@ static void test_source_resolver(void)
|
||||
ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
|
||||
sample = (IMFSample *)var.punkVal;
|
||||
|
||||
@ -141,7 +141,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
}
|
||||
|
||||
if (i == sample_count)
|
||||
@@ -766,178 +723,6 @@ static void test_source_resolver(void)
|
||||
@@ -772,178 +729,6 @@ static void test_source_resolver(void)
|
||||
DeleteFileW(filename);
|
||||
}
|
||||
|
||||
@ -320,7 +320,7 @@ index 82d76f7bbaa..9634ee059b0 100644
|
||||
static void init_functions(void)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA("mfplat.dll");
|
||||
@@ -6223,7 +6008,6 @@ START_TEST(mfplat)
|
||||
@@ -6196,7 +5981,6 @@ START_TEST(mfplat)
|
||||
test_MFCreateMFByteStreamOnStream();
|
||||
test_system_memory_buffer();
|
||||
test_source_resolver();
|
||||
@ -2679,7 +2679,7 @@ zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px
|
||||
p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ
|
||||
|
||||
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c
|
||||
index 80db5f33772..02ed9394c20 100644
|
||||
index f9b01f4cd72..b7d5d3808c0 100644
|
||||
--- a/dlls/mfreadwrite/tests/mfplat.c
|
||||
+++ b/dlls/mfreadwrite/tests/mfplat.c
|
||||
@@ -629,15 +629,10 @@ static void test_source_reader(void)
|
||||
@ -5270,5 +5270,5 @@ zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px
|
||||
p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ
|
||||
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,419 +0,0 @@
|
||||
From c43cb0299991d7fdfa0d7e7663efbaa55a703e98 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?=
|
||||
<sdelreal@codeweavers.com>
|
||||
Date: Wed, 1 Apr 2020 16:11:07 -0500
|
||||
Subject: [PATCH 40/45] mf: Partially implement the topology loader.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Sergio Gómez Del Real <sdelreal@codeweavers.com>
|
||||
---
|
||||
dlls/mf/tests/mf.c | 3 -
|
||||
dlls/mf/topology.c | 337 ++++++++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 321 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index e3b98be0373..2d67834f0d5 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -1429,7 +1429,6 @@ static void test_topology_loader(void)
|
||||
|
||||
/* Empty topology */
|
||||
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
-todo_wine
|
||||
ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = MFCreateSourceResolver(&resolver);
|
||||
@@ -1476,7 +1475,6 @@ todo_wine
|
||||
|
||||
/* Source node only. */
|
||||
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
-todo_wine
|
||||
ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
/* Add grabber sink. */
|
||||
@@ -1502,7 +1500,6 @@ todo_wine
|
||||
ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
|
||||
|
||||
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
|
||||
-todo_wine
|
||||
ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index abe66c45fd4..d4a59f7136e 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1933,47 +1933,352 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
|
||||
return refcount;
|
||||
}
|
||||
|
||||
+static void topology_loader_add_branch(struct topology *topology, IMFTopologyNode *first, IMFTopologyNode *last)
|
||||
+{
|
||||
+ IMFTopology *full_topo = &topology->IMFTopology_iface;
|
||||
+ IMFTopologyNode *in, *out;
|
||||
+ DWORD index;
|
||||
+
|
||||
+ in = first;
|
||||
+ IMFTopology_AddNode(full_topo, in);
|
||||
+ while (SUCCEEDED(IMFTopologyNode_GetOutput(in, 0, &out, &index)))
|
||||
+ {
|
||||
+ IMFTopology_AddNode(full_topo, out);
|
||||
+ in = out;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static HRESULT topology_loader_resolve_branch(IMFTopologyNode *src, IMFMediaType *mediatype, IMFTopologyNode *sink, MF_CONNECT_METHOD method)
|
||||
+{
|
||||
+ IMFStreamSink *streamsink;
|
||||
+ IMFMediaTypeHandler *mth;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ IMFTopologyNode_GetObject(sink, (IUnknown **)&streamsink);
|
||||
+ IMFStreamSink_GetMediaTypeHandler(streamsink, &mth);
|
||||
+ if (method == MF_CONNECT_DIRECT)
|
||||
+ {
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype)))
|
||||
+ return hr;
|
||||
+ hr = IMFTopologyNode_ConnectOutput(src, 0, sink, 0);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ IMFTopologyNode *node_dec, *node_conv;
|
||||
+ GUID major_type, subtype, mft_category;
|
||||
+ MFT_REGISTER_TYPE_INFO mft_typeinfo;
|
||||
+ UINT32 flags = MFT_ENUM_FLAG_ALL;
|
||||
+ IMFActivate **activates_decs;
|
||||
+ UINT32 num_activates_decs;
|
||||
+ int i, j;
|
||||
+
|
||||
+ IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &major_type);
|
||||
+ if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
+ mft_category = MFT_CATEGORY_AUDIO_DECODER;
|
||||
+ else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
+ mft_category = MFT_CATEGORY_VIDEO_DECODER;
|
||||
+ else
|
||||
+ return MF_E_INVALIDMEDIATYPE;
|
||||
+
|
||||
+ IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &subtype);
|
||||
+ mft_typeinfo.guidMajorType = major_type;
|
||||
+ mft_typeinfo.guidSubtype = subtype;
|
||||
+ MFTEnumEx(mft_category, flags, &mft_typeinfo, NULL, &activates_decs, &num_activates_decs);
|
||||
+
|
||||
+ /* for getting converters later on */
|
||||
+ if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
+ mft_category = MFT_CATEGORY_AUDIO_EFFECT;
|
||||
+ else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
+ mft_category = MFT_CATEGORY_VIDEO_EFFECT;
|
||||
+
|
||||
+ /*
|
||||
+ * Iterate over number of decoders.
|
||||
+ * Try to set input type on decoder with source's output media type.
|
||||
+ * If succeeds, iterate over decoder's output media types.
|
||||
+ * Try to set input type on sink with decoder's output media type.
|
||||
+ * If fails, iterate over number of converters.
|
||||
+ * Try to set input type on converter with decoder's output media type.
|
||||
+ * If succeeds, iterate over converters output media types.
|
||||
+ * Try to set input type on sink with converter's output media type.
|
||||
+ */
|
||||
+ for (i = 0; i < num_activates_decs; i++)
|
||||
+ {
|
||||
+ IMFTransform *decoder;
|
||||
+
|
||||
+ IMFActivate_ActivateObject(activates_decs[i], &IID_IMFTransform, (void **)&decoder);
|
||||
+ if (SUCCEEDED(hr = IMFTransform_SetInputType(decoder, 0, mediatype, 0)))
|
||||
+ {
|
||||
+ UINT32 num_activates_convs;
|
||||
+ IMFActivate **activates_convs;
|
||||
+ IMFMediaType *decoder_mtype;
|
||||
+
|
||||
+ int count = 0;
|
||||
+ while (SUCCEEDED(IMFTransform_GetOutputAvailableType(decoder, 0, count++, &decoder_mtype)))
|
||||
+ {
|
||||
+ IMFTransform *converter;
|
||||
+
|
||||
+ /* succeeded with source -> decoder -> sink */
|
||||
+ if (SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(mth, decoder_mtype)))
|
||||
+ {
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_dec);
|
||||
+ IMFTopologyNode_SetObject(node_dec, (IUnknown *)decoder);
|
||||
+ IMFTopologyNode_ConnectOutput(src, 0, node_dec, 0);
|
||||
+ IMFTopologyNode_ConnectOutput(node_dec, 0, sink, 0);
|
||||
+
|
||||
+ IMFActivate_ShutdownObject(activates_convs[i]);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ IMFMediaType_GetGUID(decoder_mtype, &MF_MT_SUBTYPE, &subtype);
|
||||
+ mft_typeinfo.guidSubtype = subtype;
|
||||
+ MFTEnumEx(mft_category, flags, &mft_typeinfo, NULL, &activates_convs, &num_activates_convs);
|
||||
+ for (j = 0; j < num_activates_convs; j++)
|
||||
+ {
|
||||
+ IMFMediaType *converter_mtype;
|
||||
+
|
||||
+ IMFActivate_ActivateObject(activates_convs[j], &IID_IMFTransform, (void **)&converter);
|
||||
+ if (SUCCEEDED(IMFTransform_SetInputType(converter, 0, decoder_mtype, 0)))
|
||||
+ {
|
||||
+ int count = 0;
|
||||
+ while (SUCCEEDED(IMFTransform_GetOutputAvailableType(converter, 0, count++, &converter_mtype)))
|
||||
+ {
|
||||
+ /* succeeded with source -> decoder -> converter -> sink */
|
||||
+ if (SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(mth, converter_mtype)))
|
||||
+ {
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_dec);
|
||||
+ IMFTopologyNode_SetObject(node_dec, (IUnknown *)decoder);
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_conv);
|
||||
+ IMFTopologyNode_SetObject(node_conv, (IUnknown *)converter);
|
||||
+ IMFTopologyNode_ConnectOutput(src, 0, node_dec, 0);
|
||||
+ IMFTopologyNode_ConnectOutput(node_dec, 0, node_conv, 0);
|
||||
+ IMFTopologyNode_ConnectOutput(node_conv, 0, sink, 0);
|
||||
+
|
||||
+ IMFActivate_ShutdownObject(activates_convs[j]);
|
||||
+ IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ IMFActivate_ShutdownObject(activates_convs[j]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT topology_loader_resolve_partial_topology(struct topology_node *src, struct topology_node *sink, struct topology *topology, struct topology **full_topology)
|
||||
+{
|
||||
+ IMFMediaTypeHandler *mth_src, *mth_sink;
|
||||
+ IMFTopologyNode *clone_src, *clone_sink;
|
||||
+ UINT32 method, enum_src_types, streamid;
|
||||
+ IMFMediaType **src_mediatypes;
|
||||
+ IMFStreamDescriptor *desc;
|
||||
+ IMFAttributes *attrs_src;
|
||||
+ IMFStreamSink *strm_sink;
|
||||
+ IMFMediaType *mtype_src;
|
||||
+ DWORD num_media_types;
|
||||
+ HRESULT hr;
|
||||
+ int i;
|
||||
+
|
||||
+ attrs_src = src->attributes;
|
||||
+ if (FAILED(hr = IMFAttributes_GetUnknown(attrs_src, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&desc)))
|
||||
+ return hr;
|
||||
+ strm_sink = (IMFStreamSink *)sink->object;
|
||||
+
|
||||
+ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(desc, &mth_src)))
|
||||
+ {
|
||||
+ IMFStreamDescriptor_Release(desc);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ if (FAILED(hr = IMFStreamSink_GetMediaTypeHandler(strm_sink, &mth_sink)))
|
||||
+ {
|
||||
+ IMFStreamDescriptor_Release(desc);
|
||||
+ IMFMediaTypeHandler_Release(mth_src);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ hr = IMFTopology_GetUINT32(&topology->IMFTopology_iface, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enum_src_types);
|
||||
+
|
||||
+ mtype_src = NULL;
|
||||
+ if (FAILED(hr) || !enum_src_types)
|
||||
+ {
|
||||
+ num_media_types = 1;
|
||||
+ enum_src_types = 0;
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(mth_src, &mtype_src)))
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, 0, &mtype_src)))
|
||||
+ {
|
||||
+ IMFMediaTypeHandler_Release(mth_src);
|
||||
+ IMFMediaTypeHandler_Release(mth_sink);
|
||||
+ IMFStreamDescriptor_Release(desc);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ IMFMediaTypeHandler_GetMediaTypeCount(mth_src, &num_media_types);
|
||||
+
|
||||
+ src_mediatypes = heap_alloc(sizeof(IMFMediaType *) * num_media_types);
|
||||
+
|
||||
+ if (mtype_src)
|
||||
+ src_mediatypes[0] = mtype_src;
|
||||
+ else
|
||||
+ for (i = 0; i < num_media_types; i++)
|
||||
+ IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, i, &src_mediatypes[i]);
|
||||
+
|
||||
+
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &clone_src);
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &clone_sink);
|
||||
+ IMFTopologyNode_CloneFrom(clone_src, &src->IMFTopologyNode_iface);
|
||||
+ IMFTopologyNode_CloneFrom(clone_sink, &sink->IMFTopologyNode_iface);
|
||||
+
|
||||
+ if (FAILED(IMFTopologyNode_GetUINT32(clone_sink, &MF_TOPONODE_STREAMID, &streamid)))
|
||||
+ IMFTopologyNode_SetUINT32(clone_sink, &MF_TOPONODE_STREAMID, 0);
|
||||
+
|
||||
+ if (enum_src_types)
|
||||
+ {
|
||||
+ hr = IMFAttributes_GetUINT32(attrs_src, &MF_TOPONODE_CONNECT_METHOD, &method);
|
||||
+ if (hr == S_OK && method != MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)
|
||||
+ {
|
||||
+ for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ for (i = 0; i < num_media_types; i++)
|
||||
+ if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method)))
|
||||
+ {
|
||||
+ topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
+ heap_free(src_mediatypes);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (i = 0; i < num_media_types; i++)
|
||||
+ for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method)))
|
||||
+ {
|
||||
+ topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
+ heap_free(src_mediatypes);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[0], clone_sink, MF_CONNECT_DIRECT)))
|
||||
+ {
|
||||
+ topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
+ heap_free(src_mediatypes);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ heap_free(src_mediatypes);
|
||||
+ return MF_E_TOPO_UNSUPPORTED;
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
|
||||
IMFTopology **output_topology, IMFTopology *current_topology)
|
||||
{
|
||||
struct topology *topology = unsafe_impl_from_IMFTopology(input_topology);
|
||||
+ struct topology_node *(*node_pairs)[2];
|
||||
+ int num_connections;
|
||||
IMFStreamSink *sink;
|
||||
HRESULT hr;
|
||||
- size_t i;
|
||||
+ int i, idx;
|
||||
|
||||
FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology);
|
||||
|
||||
if (current_topology)
|
||||
FIXME("Current topology instance is ignored.\n");
|
||||
|
||||
+ if (!topology || topology->nodes.count < 2)
|
||||
+ return MF_E_TOPO_UNSUPPORTED;
|
||||
+
|
||||
+ num_connections = 0;
|
||||
+ for (i = 0; i < topology->nodes.count; i++)
|
||||
+ {
|
||||
+ struct topology_node *node = topology->nodes.nodes[i];
|
||||
+
|
||||
+ if (node->node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||
+ {
|
||||
+ if (node->outputs.count && node->outputs.streams->connection)
|
||||
+ num_connections++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!num_connections)
|
||||
+ return MF_E_TOPO_UNSUPPORTED;
|
||||
+
|
||||
+ node_pairs = heap_alloc_zero(sizeof(struct topology_node *[2]) * num_connections);
|
||||
+
|
||||
+ idx = 0;
|
||||
for (i = 0; i < topology->nodes.count; ++i)
|
||||
{
|
||||
struct topology_node *node = topology->nodes.nodes[i];
|
||||
|
||||
- switch (node->node_type)
|
||||
+ if (node->node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
|
||||
{
|
||||
- case MF_TOPOLOGY_OUTPUT_NODE:
|
||||
- if (node->object)
|
||||
+ if (node->outputs.count && node->outputs.streams->connection)
|
||||
+ {
|
||||
+ node_pairs[idx][0] = node;
|
||||
+ if (node->outputs.streams->connection->node_type == MF_TOPOLOGY_TRANSFORM_NODE)
|
||||
{
|
||||
- /* Sinks must be bound beforehand. */
|
||||
- if (FAILED(IUnknown_QueryInterface(node->object, &IID_IMFStreamSink, (void **)&sink)))
|
||||
- return MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
|
||||
- IMFStreamSink_Release(sink);
|
||||
+ struct topology_node *sink = node->outputs.streams->connection;
|
||||
+
|
||||
+ while (sink && sink->node_type != MF_TOPOLOGY_OUTPUT_NODE && sink->outputs.count)
|
||||
+ sink = sink->outputs.streams->connection;
|
||||
+ if (!sink || !sink->outputs.count)
|
||||
+ {
|
||||
+ FIXME("Check for MF_CONNECT_AS_OPTIONAL and MF_CONNECT_AS_OPTIONAL_BRANCH flags.\n");
|
||||
+ heap_free(node_pairs);
|
||||
+ return MF_E_TOPO_UNSUPPORTED;
|
||||
+ }
|
||||
+ node_pairs[idx][1] = sink;
|
||||
}
|
||||
- break;
|
||||
- case MF_TOPOLOGY_SOURCESTREAM_NODE:
|
||||
- if (FAILED(hr = IMFAttributes_GetItem(node->attributes, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL)))
|
||||
- return hr;
|
||||
- break;
|
||||
- default:
|
||||
- ;
|
||||
+ else if (node->outputs.streams->connection->node_type == MF_TOPOLOGY_OUTPUT_NODE)
|
||||
+ node_pairs[idx][1] = node->outputs.streams->connection;
|
||||
+ else {
|
||||
+ FIXME("Tee nodes currently unhandled.\n");
|
||||
+ heap_free(node_pairs);
|
||||
+ return MF_E_TOPO_UNSUPPORTED;
|
||||
+ }
|
||||
+ idx++;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
+ /* all sinks must be activated */
|
||||
+ for (i = 0; i < num_connections; i++)
|
||||
+ {
|
||||
+ if (FAILED(IUnknown_QueryInterface(node_pairs[i][1]->object, &IID_IMFStreamSink, (void **)&sink)))
|
||||
+ {
|
||||
+ FIXME("Check for MF_CONNECT_AS_OPTIONAL and MF_CONNECT_AS_OPTIONAL_BRANCH flags.\n");
|
||||
+ heap_free(node_pairs);
|
||||
+ return MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
|
||||
+ }
|
||||
+ IMFStreamSink_Release(sink);
|
||||
+ }
|
||||
+
|
||||
if (FAILED(hr = MFCreateTopology(output_topology)))
|
||||
return hr;
|
||||
|
||||
- return IMFTopology_CloneFrom(*output_topology, input_topology);
|
||||
+ /* resolve each branch */
|
||||
+ for (i = 0; i < num_connections; i++)
|
||||
+ {
|
||||
+ struct topology_node *src = node_pairs[i][0];
|
||||
+ struct topology_node *sink = node_pairs[i][1];
|
||||
+ struct topology *full_topology = unsafe_impl_from_IMFTopology(*output_topology);
|
||||
+
|
||||
+ if (FAILED(hr = topology_loader_resolve_partial_topology(src, sink, topology, &full_topology)))
|
||||
+ {
|
||||
+ heap_free(node_pairs);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ heap_free(node_pairs);
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static const IMFTopoLoaderVtbl topologyloadervtbl =
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,27 +1,26 @@
|
||||
From eaa6710bbf3abb9803e44033a8c504b7c6ba4c44 Mon Sep 17 00:00:00 2001
|
||||
From 0876c6332d81b43a956e48aee31a113807a486a5 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 5 May 2020 15:35:16 -0500
|
||||
Subject: [PATCH] Report streams backwards and only select one of each stream
|
||||
type.
|
||||
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 25 ++++++++++++++++++++++---
|
||||
1 file changed, 22 insertions(+), 3 deletions(-)
|
||||
dlls/winegstreamer/media_source.c | 24 ++++++++++++++++++++++--
|
||||
1 file changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 2f74868956f..dd99afb2214 100644
|
||||
index acc9d53ca2e..26e9a1805fb 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1458,7 +1458,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
{
|
||||
@@ -1484,6 +1484,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
GstStaticPadTemplate src_template =
|
||||
GST_STATIC_PAD_TEMPLATE("mf_src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
|
||||
-
|
||||
|
||||
+ BOOL video_selected = FALSE, audio_selected = FALSE;
|
||||
IMFStreamDescriptor **descriptors = NULL;
|
||||
struct media_source *object;
|
||||
IMFAttributes *byte_stream_attributes;
|
||||
@@ -1573,15 +1573,34 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
struct media_source *object;
|
||||
@@ -1598,15 +1599,34 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
descriptors = heap_alloc(object->stream_count * sizeof(IMFStreamDescriptor*));
|
||||
for (i = 0; i < object->stream_count; i++)
|
||||
{
|
@ -1,46 +0,0 @@
|
||||
From 834d9e0e52a501ee1443ded7e40ee78a1c8936ea Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 2 Apr 2020 15:43:52 -0500
|
||||
Subject: [PATCH 41/45] mf: Miscelaneous fixes to topology resolution.
|
||||
|
||||
---
|
||||
dlls/mf/topology.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index d4a59f7136e..2e849204343 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -2026,7 +2026,7 @@ static HRESULT topology_loader_resolve_branch(IMFTopologyNode *src, IMFMediaType
|
||||
IMFTopologyNode_ConnectOutput(src, 0, node_dec, 0);
|
||||
IMFTopologyNode_ConnectOutput(node_dec, 0, sink, 0);
|
||||
|
||||
- IMFActivate_ShutdownObject(activates_convs[i]);
|
||||
+ IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -2165,12 +2165,14 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[0], clone_sink, MF_CONNECT_DIRECT)))
|
||||
- {
|
||||
- topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
- heap_free(src_mediatypes);
|
||||
- return S_OK;
|
||||
- }
|
||||
+ for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[0], clone_sink, method)))
|
||||
+ {
|
||||
+ TRACE("Successfully connected nodes with method %u\n", method);
|
||||
+ topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
+ heap_free(src_mediatypes);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
}
|
||||
|
||||
heap_free(src_mediatypes);
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,369 +0,0 @@
|
||||
From bf5491001ff68bd3f3a47f9569c16615990e13b2 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Thu, 2 Apr 2020 15:45:52 -0500
|
||||
Subject: [PATCH 42/45] Rewrite branch resolver.
|
||||
|
||||
and a HACK: Set output type of found decoder, this should probably happen somewhere else.
|
||||
---
|
||||
dlls/mf/topology.c | 280 ++++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 173 insertions(+), 107 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
|
||||
index 2e849204343..91d29782582 100644
|
||||
--- a/dlls/mf/topology.c
|
||||
+++ b/dlls/mf/topology.c
|
||||
@@ -1948,135 +1948,196 @@ static void topology_loader_add_branch(struct topology *topology, IMFTopologyNod
|
||||
}
|
||||
}
|
||||
|
||||
+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;
|
||||
+
|
||||
+ IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void**) &mft);
|
||||
+
|
||||
+ 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_ShutdownObject(activates[i]);
|
||||
+ return hr;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ IMFActivate_ShutdownObject(activates[i]);
|
||||
+ }
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+struct connect_to_sink_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);
|
||||
+
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(ctx->sink_mth, type->type);
|
||||
+ IMFTransform_SetOutputType(type->transform, 0, type->type, 0);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+
|
||||
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
|
||||
+ IMFTopologyNode_SetObject(node, (IUnknown *) type->transform);
|
||||
+
|
||||
+ sink_ctx = ctx->sink_ctx;
|
||||
+ sink_ctx.src = node;
|
||||
+ if (SUCCEEDED(topology_loader_enumerate_output_types(ctx->converter_category, type->type, connect_to_sink, &sink_ctx)))
|
||||
+ {
|
||||
+ IMFTopologyNode_ConnectOutput(ctx->sink_ctx.src, 0, node, 0);
|
||||
+
|
||||
+ IMFTransform_SetOutputType(type->transform, 0, type->type, 0);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ IMFTopologyNode_Release(node);
|
||||
+ return E_FAIL;
|
||||
+}
|
||||
+
|
||||
static HRESULT topology_loader_resolve_branch(IMFTopologyNode *src, IMFMediaType *mediatype, IMFTopologyNode *sink, MF_CONNECT_METHOD method)
|
||||
{
|
||||
+ struct connect_to_converter_context convert_ctx;
|
||||
+ struct connect_to_sink_context sink_ctx;
|
||||
+ GUID major_type, decode_cat, convert_cat;
|
||||
IMFStreamSink *streamsink;
|
||||
IMFMediaTypeHandler *mth;
|
||||
HRESULT hr;
|
||||
|
||||
+ TRACE("method %u\n", method);
|
||||
+
|
||||
IMFTopologyNode_GetObject(sink, (IUnknown **)&streamsink);
|
||||
IMFStreamSink_GetMediaTypeHandler(streamsink, &mth);
|
||||
- if (method == MF_CONNECT_DIRECT)
|
||||
+
|
||||
+ if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(mth, mediatype, NULL)))
|
||||
{
|
||||
- if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype)))
|
||||
- return hr;
|
||||
- hr = IMFTopologyNode_ConnectOutput(src, 0, sink, 0);
|
||||
+ IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype);
|
||||
+ return IMFTopologyNode_ConnectOutput(src, 0, sink, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_GetMajorType(mediatype, &major_type)))
|
||||
return hr;
|
||||
+
|
||||
+ if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
+ {
|
||||
+ decode_cat = MFT_CATEGORY_AUDIO_DECODER;
|
||||
+ convert_cat = MFT_CATEGORY_AUDIO_EFFECT;
|
||||
}
|
||||
- else
|
||||
+ else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
{
|
||||
- IMFTopologyNode *node_dec, *node_conv;
|
||||
- GUID major_type, subtype, mft_category;
|
||||
- MFT_REGISTER_TYPE_INFO mft_typeinfo;
|
||||
- UINT32 flags = MFT_ENUM_FLAG_ALL;
|
||||
- IMFActivate **activates_decs;
|
||||
- UINT32 num_activates_decs;
|
||||
- int i, j;
|
||||
-
|
||||
- IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &major_type);
|
||||
- if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
- mft_category = MFT_CATEGORY_AUDIO_DECODER;
|
||||
- else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
- mft_category = MFT_CATEGORY_VIDEO_DECODER;
|
||||
- else
|
||||
- return MF_E_INVALIDMEDIATYPE;
|
||||
-
|
||||
- IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &subtype);
|
||||
- mft_typeinfo.guidMajorType = major_type;
|
||||
- mft_typeinfo.guidSubtype = subtype;
|
||||
- MFTEnumEx(mft_category, flags, &mft_typeinfo, NULL, &activates_decs, &num_activates_decs);
|
||||
-
|
||||
- /* for getting converters later on */
|
||||
- if (IsEqualGUID(&major_type, &MFMediaType_Audio))
|
||||
- mft_category = MFT_CATEGORY_AUDIO_EFFECT;
|
||||
- else if (IsEqualGUID(&major_type, &MFMediaType_Video))
|
||||
- mft_category = MFT_CATEGORY_VIDEO_EFFECT;
|
||||
-
|
||||
- /*
|
||||
- * Iterate over number of decoders.
|
||||
- * Try to set input type on decoder with source's output media type.
|
||||
- * If succeeds, iterate over decoder's output media types.
|
||||
- * Try to set input type on sink with decoder's output media type.
|
||||
- * If fails, iterate over number of converters.
|
||||
- * Try to set input type on converter with decoder's output media type.
|
||||
- * If succeeds, iterate over converters output media types.
|
||||
- * Try to set input type on sink with converter's output media type.
|
||||
- */
|
||||
- for (i = 0; i < num_activates_decs; i++)
|
||||
- {
|
||||
- IMFTransform *decoder;
|
||||
+ decode_cat = MFT_CATEGORY_VIDEO_DECODER;
|
||||
+ convert_cat = MFT_CATEGORY_VIDEO_EFFECT;
|
||||
+ }
|
||||
+ else
|
||||
+ return E_FAIL;
|
||||
|
||||
- IMFActivate_ActivateObject(activates_decs[i], &IID_IMFTransform, (void **)&decoder);
|
||||
- if (SUCCEEDED(hr = IMFTransform_SetInputType(decoder, 0, mediatype, 0)))
|
||||
- {
|
||||
- UINT32 num_activates_convs;
|
||||
- IMFActivate **activates_convs;
|
||||
- IMFMediaType *decoder_mtype;
|
||||
+ sink_ctx.src = src;
|
||||
+ sink_ctx.sink = sink;
|
||||
+ sink_ctx.sink_mth = mth;
|
||||
|
||||
- int count = 0;
|
||||
- while (SUCCEEDED(IMFTransform_GetOutputAvailableType(decoder, 0, count++, &decoder_mtype)))
|
||||
- {
|
||||
- IMFTransform *converter;
|
||||
+ convert_ctx.sink_ctx = sink_ctx;
|
||||
+ convert_ctx.converter_category = &convert_cat;
|
||||
|
||||
- /* succeeded with source -> decoder -> sink */
|
||||
- if (SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(mth, decoder_mtype)))
|
||||
- {
|
||||
- MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_dec);
|
||||
- IMFTopologyNode_SetObject(node_dec, (IUnknown *)decoder);
|
||||
- IMFTopologyNode_ConnectOutput(src, 0, node_dec, 0);
|
||||
- IMFTopologyNode_ConnectOutput(node_dec, 0, sink, 0);
|
||||
+ hr = E_FAIL;
|
||||
|
||||
- IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
- return S_OK;
|
||||
- }
|
||||
+ if (method & MF_CONNECT_ALLOW_CONVERTER)
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&convert_cat, mediatype, connect_to_sink, &sink_ctx)))
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- IMFMediaType_GetGUID(decoder_mtype, &MF_MT_SUBTYPE, &subtype);
|
||||
- mft_typeinfo.guidSubtype = subtype;
|
||||
- MFTEnumEx(mft_category, flags, &mft_typeinfo, NULL, &activates_convs, &num_activates_convs);
|
||||
- for (j = 0; j < num_activates_convs; j++)
|
||||
- {
|
||||
- IMFMediaType *converter_mtype;
|
||||
-
|
||||
- IMFActivate_ActivateObject(activates_convs[j], &IID_IMFTransform, (void **)&converter);
|
||||
- if (SUCCEEDED(IMFTransform_SetInputType(converter, 0, decoder_mtype, 0)))
|
||||
- {
|
||||
- int count = 0;
|
||||
- while (SUCCEEDED(IMFTransform_GetOutputAvailableType(converter, 0, count++, &converter_mtype)))
|
||||
- {
|
||||
- /* succeeded with source -> decoder -> converter -> sink */
|
||||
- if (SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(mth, converter_mtype)))
|
||||
- {
|
||||
- MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_dec);
|
||||
- IMFTopologyNode_SetObject(node_dec, (IUnknown *)decoder);
|
||||
- MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_conv);
|
||||
- IMFTopologyNode_SetObject(node_conv, (IUnknown *)converter);
|
||||
- IMFTopologyNode_ConnectOutput(src, 0, node_dec, 0);
|
||||
- IMFTopologyNode_ConnectOutput(node_dec, 0, node_conv, 0);
|
||||
- IMFTopologyNode_ConnectOutput(node_conv, 0, sink, 0);
|
||||
-
|
||||
- IMFActivate_ShutdownObject(activates_convs[j]);
|
||||
- IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
- return S_OK;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- IMFActivate_ShutdownObject(activates_convs[j]);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- IMFActivate_ShutdownObject(activates_decs[i]);
|
||||
+ /* 2 = decoder flag */
|
||||
+ if (method & 2)
|
||||
+ {
|
||||
+ if (method & MF_CONNECT_ALLOW_CONVERTER)
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&decode_cat, mediatype, connect_to_converter, &convert_ctx)))
|
||||
+ goto done;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (SUCCEEDED(hr = topology_loader_enumerate_output_types(&decode_cat, mediatype, connect_to_sink, &sink_ctx)))
|
||||
+ goto done;
|
||||
}
|
||||
}
|
||||
- return E_FAIL;
|
||||
+
|
||||
+ done:
|
||||
+ IMFMediaTypeHandler_Release(mth);
|
||||
+ IMFStreamSink_Release(streamsink);
|
||||
+ return hr;
|
||||
}
|
||||
|
||||
static HRESULT topology_loader_resolve_partial_topology(struct topology_node *src, struct topology_node *sink, struct topology *topology, struct topology **full_topology)
|
||||
{
|
||||
+ UINT32 method, src_method, sink_method, enum_src_types, streamid;
|
||||
IMFMediaTypeHandler *mth_src, *mth_sink;
|
||||
IMFTopologyNode *clone_src, *clone_sink;
|
||||
- UINT32 method, enum_src_types, streamid;
|
||||
IMFMediaType **src_mediatypes;
|
||||
IMFStreamDescriptor *desc;
|
||||
+ IMFAttributes *attrs_sink;
|
||||
IMFAttributes *attrs_src;
|
||||
IMFStreamSink *strm_sink;
|
||||
IMFMediaType *mtype_src;
|
||||
@@ -2084,6 +2145,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr
|
||||
HRESULT hr;
|
||||
int i;
|
||||
|
||||
+ attrs_sink = sink->attributes;
|
||||
attrs_src = src->attributes;
|
||||
if (FAILED(hr = IMFAttributes_GetUnknown(attrs_src, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&desc)))
|
||||
return hr;
|
||||
@@ -2137,12 +2199,15 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr
|
||||
if (FAILED(IMFTopologyNode_GetUINT32(clone_sink, &MF_TOPONODE_STREAMID, &streamid)))
|
||||
IMFTopologyNode_SetUINT32(clone_sink, &MF_TOPONODE_STREAMID, 0);
|
||||
|
||||
+ if (FAILED(IMFAttributes_GetUINT32(attrs_sink, &MF_TOPONODE_CONNECT_METHOD, &sink_method)))
|
||||
+ sink_method = MF_CONNECT_ALLOW_DECODER;
|
||||
+
|
||||
if (enum_src_types)
|
||||
{
|
||||
- hr = IMFAttributes_GetUINT32(attrs_src, &MF_TOPONODE_CONNECT_METHOD, &method);
|
||||
- if (hr == S_OK && method != MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)
|
||||
+ hr = IMFAttributes_GetUINT32(attrs_src, &MF_TOPONODE_CONNECT_METHOD, &src_method);
|
||||
+ if (hr == S_OK && src_method != MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)
|
||||
{
|
||||
- for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ for (method = MF_CONNECT_DIRECT; method <= sink_method; method++)
|
||||
for (i = 0; i < num_media_types; i++)
|
||||
if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method)))
|
||||
{
|
||||
@@ -2154,7 +2219,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr
|
||||
else
|
||||
{
|
||||
for (i = 0; i < num_media_types; i++)
|
||||
- for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ for (method = MF_CONNECT_DIRECT; method <= sink_method; method++)
|
||||
if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method)))
|
||||
{
|
||||
topology_loader_add_branch(*full_topology, clone_src, clone_sink);
|
||||
@@ -2165,7 +2230,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr
|
||||
}
|
||||
else
|
||||
{
|
||||
- for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
|
||||
+ for (method = MF_CONNECT_DIRECT; method <= sink_method; method++)
|
||||
if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[0], clone_sink, method)))
|
||||
{
|
||||
TRACE("Successfully connected nodes with method %u\n", method);
|
||||
@@ -2274,6 +2339,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
|
||||
|
||||
if (FAILED(hr = topology_loader_resolve_partial_topology(src, sink, topology, &full_topology)))
|
||||
{
|
||||
+ ERR("Failed to resolve connection between %p and %p. %x\n", src, sink, hr);
|
||||
heap_free(node_pairs);
|
||||
return hr;
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,20 +1,19 @@
|
||||
From 47f494894fa474319f1323e6489d1db3c145f478 Mon Sep 17 00:00:00 2001
|
||||
From 88551b8014795f2cfbf87249d81a56a242ee2863 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 11 May 2020 16:05:50 -0500
|
||||
Subject: [PATCH 32/45] winegstreamer: Introduce MPEG-4 Section-2 video
|
||||
decoder.
|
||||
Subject: [PATCH] winegstreamer: Introduce MPEG-4 Section-2 video decoder.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mf_decode.c | 10 ++++++
|
||||
dlls/winegstreamer/mfplat.c | 34 ++++++++++++++++++++
|
||||
dlls/winegstreamer/mfplat.c | 35 ++++++++++++++++++++
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 6 ++++
|
||||
include/mfidl.idl | 1 +
|
||||
5 files changed, 52 insertions(+)
|
||||
5 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index eb467ffeeea..09306414616 100644
|
||||
index 0eba22fe30f..0dc31d16b87 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -90,6 +90,7 @@ enum decoder_type
|
||||
@ -26,7 +25,7 @@ index eb467ffeeea..09306414616 100644
|
||||
HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 64138f8cd94..285b3595143 100644
|
||||
index c188d08c57f..b5220bc3332 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -32,6 +32,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM};
|
||||
@ -54,30 +53,31 @@ index 64138f8cd94..285b3595143 100644
|
||||
};
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 0b177198e5e..3fbb9fcbe1d 100644
|
||||
index 2a225f82d36..09598e0886f 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -421,6 +421,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret)
|
||||
@@ -424,6 +424,12 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret)
|
||||
{
|
||||
return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV);
|
||||
}
|
||||
|
||||
+
|
||||
+static HRESULT m4s2_decoder_create(REFIID riid, void **ret)
|
||||
+{
|
||||
+ return generic_decoder_construct(riid, ret, DECODER_TYPE_M4S2);
|
||||
+}
|
||||
+
|
||||
static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}};
|
||||
|
||||
static const struct class_object
|
||||
@@ -435,6 +440,7 @@ class_objects[] =
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -438,6 +444,7 @@ class_objects[] =
|
||||
{ &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
|
||||
{ &CLSID_CMSAACDecMFT, &aac_decoder_create },
|
||||
{ &CLSID_CWMVDecMediaObject, &wmv_decoder_create },
|
||||
+ { &CLSID_CMpeg4sDecMFT, m4s2_decoder_create },
|
||||
{ &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
};
|
||||
|
||||
@@ -534,6 +540,22 @@ const GUID *wmv_decoder_output_types[] =
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -543,6 +550,22 @@ const GUID *wmv_decoder_output_types[] =
|
||||
&MFVideoFormat_RGB8,
|
||||
};
|
||||
|
||||
@ -100,11 +100,10 @@ index 0b177198e5e..3fbb9fcbe1d 100644
|
||||
static const struct mft
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -596,6 +618,18 @@ mfts[] =
|
||||
ARRAY_SIZE(wmv_decoder_output_types),
|
||||
@@ -618,6 +641,18 @@ mfts[] =
|
||||
wmv_decoder_output_types,
|
||||
NULL
|
||||
+ },
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_CMpeg4sDecMFT,
|
||||
+ &MFT_CATEGORY_VIDEO_DECODER,
|
||||
@ -116,14 +115,15 @@ index 0b177198e5e..3fbb9fcbe1d 100644
|
||||
+ ARRAY_SIZE(m4s2_decoder_output_types),
|
||||
+ m4s2_decoder_output_types,
|
||||
+ NULL
|
||||
}
|
||||
+ },
|
||||
};
|
||||
|
||||
HRESULT mfplat_DllRegisterServer(void)
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index 1556b6cff9f..5969eaa591a 100644
|
||||
index 51d44ad5242..337a32bf6cb 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -74,6 +74,12 @@ coclass CMSH264DecoderMFT { }
|
||||
@@ -86,6 +86,12 @@ coclass CMSH264DecoderMFT { }
|
||||
]
|
||||
coclass CMSAACDecMFT { }
|
||||
|
||||
@ -149,5 +149,5 @@ index 7cb027b156a..926f593b3bc 100644
|
||||
cpp_quote("EXTERN_GUID(CLSID_CWMVDecMediaObject, 0x82d353df, 0x90bd, 0x4382, 0x8b, 0xc2, 0x3f, 0x61, 0x92, 0xb7, 0x6e, 0x34);")
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,879 +0,0 @@
|
||||
From 4e88271299bbdf5e9a1090359f756a2769cc1024 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 26 Aug 2020 10:28:37 -0500
|
||||
Subject: [PATCH 43/45] winegstreamer: Implement audio conversion MFT.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/Makefile.in | 1 +
|
||||
dlls/winegstreamer/audioconvert.c | 762 +++++++++++++++++++
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/mfplat.c | 23 +
|
||||
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
|
||||
5 files changed, 793 insertions(+)
|
||||
create mode 100644 dlls/winegstreamer/audioconvert.c
|
||||
|
||||
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
|
||||
index a266b0a95e4..81c670c17e4 100644
|
||||
--- a/dlls/winegstreamer/Makefile.in
|
||||
+++ b/dlls/winegstreamer/Makefile.in
|
||||
@@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||
PARENTSRC = ../strmbase ../mf
|
||||
|
||||
C_SRCS = \
|
||||
+ audioconvert.c \
|
||||
colorconvert.c \
|
||||
filter.c \
|
||||
gst_cbs.c \
|
||||
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
|
||||
new file mode 100644
|
||||
index 00000000000..acb842242f1
|
||||
--- /dev/null
|
||||
+++ b/dlls/winegstreamer/audioconvert.c
|
||||
@@ -0,0 +1,762 @@
|
||||
+#include "config.h"
|
||||
+#include <gst/gst.h>
|
||||
+
|
||||
+#include "gst_private.h"
|
||||
+#include "gst_cbs.h"
|
||||
+
|
||||
+#include "mfapi.h"
|
||||
+#include "mferror.h"
|
||||
+#include "mfidl.h"
|
||||
+
|
||||
+#include "wine/debug.h"
|
||||
+#include "wine/heap.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||
+
|
||||
+static const GUID *raw_types[] = {
|
||||
+ &MFAudioFormat_PCM,
|
||||
+ &MFAudioFormat_Float,
|
||||
+};
|
||||
+
|
||||
+struct audio_converter
|
||||
+{
|
||||
+ IMFTransform IMFTransform_iface;
|
||||
+ LONG refcount;
|
||||
+ IMFAttributes *attributes;
|
||||
+ IMFAttributes *output_attributes;
|
||||
+ IMFMediaType *input_type;
|
||||
+ IMFMediaType *output_type;
|
||||
+ BOOL valid_state, inflight;
|
||||
+ GstElement *container, *appsrc, *audioconvert, *resampler, *appsink;
|
||||
+ GstBus *bus;
|
||||
+ CRITICAL_SECTION cs;
|
||||
+};
|
||||
+
|
||||
+static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, struct audio_converter, IMFTransform_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
|
||||
+{
|
||||
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
|
||||
+ IsEqualIID(riid, &IID_IUnknown))
|
||||
+ {
|
||||
+ *obj = iface;
|
||||
+ IMFTransform_AddRef(iface);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
|
||||
+ *obj = NULL;
|
||||
+ return E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI audio_converter_AddRef(IMFTransform *iface)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedIncrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ ULONG refcount = InterlockedDecrement(&transform->refcount);
|
||||
+
|
||||
+ TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
+
|
||||
+ if (!refcount)
|
||||
+ {
|
||||
+ if (transform->attributes)
|
||||
+ IMFAttributes_Release(transform->attributes);
|
||||
+ if (transform->output_attributes)
|
||||
+ IMFAttributes_Release(transform->output_attributes);
|
||||
+ heap_free(transform);
|
||||
+ }
|
||||
+
|
||||
+ return refcount;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
|
||||
+ DWORD *output_minimum, DWORD *output_maximum)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
|
||||
+
|
||||
+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
|
||||
+{
|
||||
+ TRACE("%p, %p, %p.\n", iface, inputs, outputs);
|
||||
+
|
||||
+ *inputs = *outputs = 1;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
|
||||
+ DWORD output_size, DWORD *outputs)
|
||||
+{
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ TRACE("%p %u %p\n", converter, id, info);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ /* If we create a wrapped GstBuffer, remove MFT_INPUT_STREAM_DOES_NOT_ADDREF */
|
||||
+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF;
|
||||
+ info->cbMaxLookahead = 0;
|
||||
+ info->cbAlignment = 0;
|
||||
+ /* this is incorrect */
|
||||
+ info->hnsMaxLatency = 0;
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ MFT_OUTPUT_STREAM_INFO stream_info = {};
|
||||
+
|
||||
+ 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)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ 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,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||
+ IMFAttributes **attributes)
|
||||
+{
|
||||
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
|
||||
+
|
||||
+ 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)
|
||||
+{
|
||||
+ TRACE("%p, %u.\n", iface, id);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ IMFMediaType *ret;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (index >= ARRAY_SIZE(raw_types))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&ret)))
|
||||
+ return hr;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio)))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index])))
|
||||
+ {
|
||||
+ IMFMediaType_Release(ret);
|
||||
+ return hr;
|
||||
+ }
|
||||
+
|
||||
+ *type = ret;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static void copy_attr(IMFMediaType *target, IMFMediaType *source, const GUID *key)
|
||||
+{
|
||||
+ PROPVARIANT val;
|
||||
+
|
||||
+ if (SUCCEEDED(IMFAttributes_GetItem((IMFAttributes *)source, key, &val)))
|
||||
+ {
|
||||
+ IMFAttributes_SetItem((IMFAttributes* )target, key, &val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||
+ IMFMediaType **type)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ IMFMediaType *output_type;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ static const DWORD rates[] = {44100, 48000};
|
||||
+ static const DWORD channel_cnts[] = {1, 2, 6};
|
||||
+ static const DWORD sizes[] = {16, 24, 32};
|
||||
+ const GUID *subtype;
|
||||
+ DWORD rate, channels, bps;
|
||||
+
|
||||
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||
+
|
||||
+ if (id != 0)
|
||||
+ return MF_E_INVALIDSTREAMNUMBER;
|
||||
+
|
||||
+ if (!(converter->input_type))
|
||||
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
|
||||
+
|
||||
+ if (index >= (2/*rates*/ * 3/*layouts*/ * 3/*bps PCM*/) + (2 * 3))
|
||||
+ return MF_E_NO_MORE_TYPES;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMediaType(&output_type)))
|
||||
+ return hr;
|
||||
+
|
||||
+ copy_attr(output_type, converter->input_type, &MF_MT_MAJOR_TYPE);
|
||||
+
|
||||
+ if (index < 2 * 3 * 3)
|
||||
+ {
|
||||
+ subtype = &MFAudioFormat_PCM;
|
||||
+ rate = rates[index % 2];
|
||||
+ channels = channel_cnts[(index / 2) % 3];
|
||||
+ bps = sizes[(index / (2*3)) % 3];
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ index -= (2 * 3 * 3);
|
||||
+ subtype = &MFAudioFormat_Float;
|
||||
+ bps = 32;
|
||||
+ rate = rates[index % 2];
|
||||
+ channels = channel_cnts[(index / 2) % 3];
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, subtype)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_NUM_CHANNELS, channels)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, bps)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, channels * bps / 8)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, rate * channels * bps / 8)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_CHANNEL_MASK,
|
||||
+ channels == 1 ? SPEAKER_FRONT_CENTER :
|
||||
+ channels == 2 ? SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT :
|
||||
+ /*channels == 6*/ 0x3F)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ *type = output_type;
|
||||
+
|
||||
+ return S_OK;
|
||||
+ fail:
|
||||
+ IMFMediaType_Release(output_type);
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static void audio_converter_update_pipeline_state(struct audio_converter *converter)
|
||||
+{
|
||||
+ GstCaps *input_caps, *output_caps;
|
||||
+ gchar *input_caps_str, *output_caps_str;
|
||||
+
|
||||
+ converter->valid_state = converter->input_type && converter->output_type;
|
||||
+
|
||||
+ if (!converter->valid_state)
|
||||
+ {
|
||||
+ gst_element_set_state(converter->container, GST_STATE_READY);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_object_set(converter->appsrc, "caps", (input_caps = caps_from_mf_media_type(converter->input_type)), NULL);
|
||||
+ g_object_set(converter->appsink, "caps", (output_caps = caps_from_mf_media_type(converter->output_type)), NULL);
|
||||
+
|
||||
+ input_caps_str = gst_caps_to_string(input_caps);
|
||||
+ output_caps_str = gst_caps_to_string(output_caps);
|
||||
+ TRACE("AUDIO CONVERTER IN =\n%s\nAUDIO CONVERTER OUT = \n%s\n", debugstr_a(input_caps_str), debugstr_a(output_caps_str));
|
||||
+ g_free(input_caps_str);
|
||||
+ g_free(output_caps_str);
|
||||
+
|
||||
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
|
||||
+{
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ 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;
|
||||
+ DWORD unused;
|
||||
+ BOOL found = FALSE;
|
||||
+
|
||||
+ 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 (unsigned int 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)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ HRESULT hr;
|
||||
+ GUID major_type, subtype;
|
||||
+ DWORD output_sample_rate;
|
||||
+ DWORD unused;
|
||||
+
|
||||
+ 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, &output_sample_rate)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
|
||||
+ return MF_E_INVALIDTYPE;
|
||||
+
|
||||
+ for (unsigned int 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)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, type);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %u, %p.\n", iface, id, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
|
||||
+{
|
||||
+ FIXME("%p, %p.\n", iface, flags);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
|
||||
+{
|
||||
+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
|
||||
+{
|
||||
+ TRACE("%p, %u, %p.\n", iface, id, event);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||
+{
|
||||
+ FIXME("%p, %u.\n", iface, message);
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ GstBuffer *gst_buffer;
|
||||
+ HRESULT hr = S_OK;
|
||||
+ int ret;
|
||||
+
|
||||
+ 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)
|
||||
+{
|
||||
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
|
||||
+ MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL;
|
||||
+ GstSample *sample;
|
||||
+ HRESULT hr = S_OK;
|
||||
+
|
||||
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
|
||||
+
|
||||
+ if (flags)
|
||||
+ WARN("Unsupported flags %#x\n", flags);
|
||||
+
|
||||
+ for (unsigned int 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 =
|
||||
+{
|
||||
+ audio_converter_QueryInterface,
|
||||
+ audio_converter_AddRef,
|
||||
+ audio_converter_Release,
|
||||
+ audio_converter_GetStreamLimits,
|
||||
+ audio_converter_GetStreamCount,
|
||||
+ audio_converter_GetStreamIDs,
|
||||
+ audio_converter_GetInputStreamInfo,
|
||||
+ audio_converter_GetOutputStreamInfo,
|
||||
+ audio_converter_GetAttributes,
|
||||
+ audio_converter_GetInputStreamAttributes,
|
||||
+ audio_converter_GetOutputStreamAttributes,
|
||||
+ audio_converter_DeleteInputStream,
|
||||
+ audio_converter_AddInputStreams,
|
||||
+ audio_converter_GetInputAvailableType,
|
||||
+ audio_converter_GetOutputAvailableType,
|
||||
+ audio_converter_SetInputType,
|
||||
+ audio_converter_SetOutputType,
|
||||
+ audio_converter_GetInputCurrentType,
|
||||
+ audio_converter_GetOutputCurrentType,
|
||||
+ audio_converter_GetInputStatus,
|
||||
+ audio_converter_GetOutputStatus,
|
||||
+ audio_converter_SetOutputBounds,
|
||||
+ audio_converter_ProcessEvent,
|
||||
+ audio_converter_ProcessMessage,
|
||||
+ audio_converter_ProcessInput,
|
||||
+ audio_converter_ProcessOutput,
|
||||
+};
|
||||
+
|
||||
+HRESULT audio_converter_create(REFIID riid, void **ret)
|
||||
+{
|
||||
+ struct audio_converter *object;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("%s %p\n", debugstr_guid(riid), ret);
|
||||
+
|
||||
+ if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
|
||||
+ object->refcount = 1;
|
||||
+
|
||||
+ 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);
|
||||
+ object->bus = gst_bus_new();
|
||||
+ gst_element_set_bus(object->container, object->bus);
|
||||
+
|
||||
+ 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;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index e5e11d06da6..a5fe02ff879 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -97,5 +97,6 @@ HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DE
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT color_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
|
||||
+HRESULT audio_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 4e2979483d9..c330416c939 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -433,6 +433,8 @@ static HRESULT m4s2_decoder_create(REFIID riid, void **ret)
|
||||
|
||||
static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}};
|
||||
|
||||
+static GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
|
||||
+
|
||||
static const struct class_object
|
||||
{
|
||||
const GUID *clsid;
|
||||
@@ -448,6 +450,7 @@ class_objects[] =
|
||||
{ &CLSID_CWMADecMediaObject, &wma_decoder_create },
|
||||
{ &CLSID_CMpeg4sDecMFT, m4s2_decoder_create },
|
||||
{ &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
+ { &CLSID_WINEAudioConverter, &audio_converter_create },
|
||||
};
|
||||
|
||||
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
@@ -497,6 +500,14 @@ const GUID *color_converter_supported_types[] =
|
||||
&MFVideoFormat_YVYU,
|
||||
};
|
||||
|
||||
+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[] =
|
||||
+{
|
||||
+ &MFAudioFormat_PCM,
|
||||
+ &MFAudioFormat_Float,
|
||||
+};
|
||||
+
|
||||
static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0};
|
||||
const GUID *h264_decoder_input_types[] =
|
||||
{
|
||||
@@ -603,6 +614,18 @@ mfts[] =
|
||||
color_converter_supported_types,
|
||||
NULL
|
||||
},
|
||||
+ {
|
||||
+ &CLSID_WINEAudioConverter,
|
||||
+ &MFT_CATEGORY_AUDIO_EFFECT,
|
||||
+ audio_converterW,
|
||||
+ MFT_ENUM_FLAG_SYNCMFT,
|
||||
+ &MFMediaType_Audio,
|
||||
+ ARRAY_SIZE(audio_converter_supported_types),
|
||||
+ audio_converter_supported_types,
|
||||
+ ARRAY_SIZE(audio_converter_supported_types),
|
||||
+ audio_converter_supported_types,
|
||||
+ NULL
|
||||
+ },
|
||||
{
|
||||
&CLSID_CMSH264DecoderMFT,
|
||||
&MFT_CATEGORY_VIDEO_DECODER,
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index c014d359a39..c58fa417bbe 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -97,3 +97,9 @@ coclass CLSID_CWMADecMediaObject {}
|
||||
uuid(98230571-0087-4204-b020-3282538e57d3)
|
||||
]
|
||||
coclass CColorConvertDMO { }
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
+ uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
|
||||
+]
|
||||
+coclass WINEAudioConverter { }
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 5b255a7924716e975762b27c691596182cbcbd3b Mon Sep 17 00:00:00 2001
|
||||
From d0ad478928f1814523cb9c1f33c0e0c87471a1f0 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 16:50:41 -0500
|
||||
Subject: [PATCH 34/45] winegstreamer: Introduce WMA audio decoder.
|
||||
Subject: [PATCH] winegstreamer: Introduce WMA audio decoder.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
5 files changed, 51 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 09306414616..e5e11d06da6 100644
|
||||
index 0dc31d16b87..17be65995e3 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -90,6 +90,7 @@ enum decoder_type
|
||||
@ -25,7 +25,7 @@ index 09306414616..e5e11d06da6 100644
|
||||
};
|
||||
HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c
|
||||
index 285b3595143..2cbe99d3168 100644
|
||||
index b5220bc3332..9b10cfd9e4a 100644
|
||||
--- a/dlls/winegstreamer/mf_decode.c
|
||||
+++ b/dlls/winegstreamer/mf_decode.c
|
||||
@@ -32,6 +32,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM};
|
||||
@ -53,10 +53,10 @@ index 285b3595143..2cbe99d3168 100644
|
||||
&MFMediaType_Video,
|
||||
m4s2_input_types,
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 3fbb9fcbe1d..4e2979483d9 100644
|
||||
index 09598e0886f..8ee152fce92 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -421,6 +421,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret)
|
||||
@@ -425,6 +425,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret)
|
||||
return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV);
|
||||
}
|
||||
|
||||
@ -68,15 +68,15 @@ index 3fbb9fcbe1d..4e2979483d9 100644
|
||||
static HRESULT m4s2_decoder_create(REFIID riid, void **ret)
|
||||
{
|
||||
return generic_decoder_construct(riid, ret, DECODER_TYPE_M4S2);
|
||||
@@ -440,6 +445,7 @@ class_objects[] =
|
||||
@@ -444,6 +449,7 @@ class_objects[] =
|
||||
{ &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
|
||||
{ &CLSID_CMSAACDecMFT, &aac_decoder_create },
|
||||
{ &CLSID_CWMVDecMediaObject, &wmv_decoder_create },
|
||||
+ { &CLSID_CWMADecMediaObject, &wma_decoder_create },
|
||||
{ &CLSID_CMpeg4sDecMFT, m4s2_decoder_create },
|
||||
{ &CLSID_CColorConvertDMO, &color_converter_create },
|
||||
};
|
||||
@@ -540,6 +546,20 @@ const GUID *wmv_decoder_output_types[] =
|
||||
|
||||
@@ -550,6 +556,20 @@ const GUID *wmv_decoder_output_types[] =
|
||||
&MFVideoFormat_RGB8,
|
||||
};
|
||||
|
||||
@ -97,7 +97,7 @@ index 3fbb9fcbe1d..4e2979483d9 100644
|
||||
static WCHAR m4s2decoderW[] = {'M','p','e','g','4','s',' ','D','e','c','o','d','e','r',' ','M','F','T',0};
|
||||
|
||||
const GUID *m4s2_decoder_input_types[] =
|
||||
@@ -619,6 +639,18 @@ mfts[] =
|
||||
@@ -641,6 +661,18 @@ mfts[] =
|
||||
wmv_decoder_output_types,
|
||||
NULL
|
||||
},
|
||||
@ -117,22 +117,19 @@ index 3fbb9fcbe1d..4e2979483d9 100644
|
||||
&CLSID_CMpeg4sDecMFT,
|
||||
&MFT_CATEGORY_VIDEO_DECODER,
|
||||
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
index 5969eaa591a..c014d359a39 100644
|
||||
index 337a32bf6cb..ec92c2d0616 100644
|
||||
--- a/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
|
||||
@@ -86,6 +86,12 @@ coclass CMpeg4sDecMFT { }
|
||||
@@ -97,3 +97,9 @@ coclass CMpeg4sDecMFT { }
|
||||
uuid(82d353df-90bd-4382-8bc2-3f6192b76e34)
|
||||
]
|
||||
coclass CLSID_CWMVDecMediaObject {}
|
||||
|
||||
+
|
||||
+[
|
||||
+ threading(both),
|
||||
+ uuid(2eeb4adf-4578-4d10-bca7-bb955f56320a)
|
||||
+]
|
||||
+coclass CLSID_CWMADecMediaObject {}
|
||||
+
|
||||
[
|
||||
threading(both),
|
||||
uuid(98230571-0087-4204-b020-3282538e57d3)
|
||||
diff --git a/include/mfidl.idl b/include/mfidl.idl
|
||||
index 926f593b3bc..ca469846458 100644
|
||||
--- a/include/mfidl.idl
|
||||
@ -147,5 +144,5 @@ index 926f593b3bc..ca469846458 100644
|
||||
+cpp_quote("EXTERN_GUID(CLSID_CWMADecMediaObject, 0x2eeb4adf, 0x4578, 0x4d10, 0xbc, 0xa7, 0xbb, 0x95, 0x5f, 0x56, 0x32, 0x0a);")
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
From c7b2d030313e7a3cbdc5ee960698020dffc99b20 Mon Sep 17 00:00:00 2001
|
||||
From 2e307dbb8d28616bca55b661f55dcdc0b702e0eb Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 11 Aug 2020 13:41:15 -0500
|
||||
Subject: [PATCH 36/45] winegstreamer: Implement MF_SD_LANGUAGE.
|
||||
Subject: [PATCH] winegstreamer: Implement MF_SD_LANGUAGE.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 20417bca8f6..b138ddb7cb6 100644
|
||||
index 26e9a1805fb..54273d1959b 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1635,11 +1635,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1634,11 +1634,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
|
||||
for (i = 0; i < object->stream_count; i++)
|
||||
{
|
||||
@ -28,7 +28,7 @@ index 20417bca8f6..b138ddb7cb6 100644
|
||||
if (stream_pres_time > total_pres_time)
|
||||
total_pres_time = stream_pres_time;
|
||||
}
|
||||
@@ -1647,6 +1648,31 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1646,6 +1647,31 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
{
|
||||
WARN("Unable to get presentation time of stream %u\n", i);
|
||||
}
|
||||
@ -61,5 +61,5 @@ index 20417bca8f6..b138ddb7cb6 100644
|
||||
|
||||
if (object->stream_count)
|
||||
--
|
||||
2.28.0
|
||||
2.29.2
|
||||
|
@ -2752,57 +2752,59 @@ fi
|
||||
# | * [#49692] Multiple applications need a Media Foundation media source implementation
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/mf/Makefile.in, dlls/mf/handler.c, dlls/mf/handler.h, dlls/mf/main.c, dlls/mf/session.c, dlls/mf/tests/mf.c,
|
||||
# | dlls/mf/topology.c, dlls/mfplat/tests/mfplat.c, dlls/mfplat/tests/test.mp4, dlls/mfreadwrite/reader.c,
|
||||
# | dlls/mfreadwrite/tests/mfplat.c, dlls/mfreadwrite/tests/resource.rc, dlls/mfreadwrite/tests/test.mp4,
|
||||
# | dlls/winegstreamer/Makefile.in, dlls/winegstreamer/audioconvert.c, dlls/winegstreamer/colorconvert.c,
|
||||
# | dlls/winegstreamer/gst_cbs.c, dlls/winegstreamer/gst_cbs.h, dlls/winegstreamer/gst_private.h, dlls/winegstreamer/main.c,
|
||||
# | * dlls/mf/Makefile.in, dlls/mf/handler.c, dlls/mf/handler.h, dlls/mf/main.c, dlls/mf/session.c, dlls/mf/tests/Makefile.in,
|
||||
# | dlls/mf/tests/mf.c, dlls/mf/tests/resource.rc, dlls/mf/topology.c, dlls/mfplat/tests/mfplat.c,
|
||||
# | dlls/mfplat/tests/test.mp4, dlls/mfreadwrite/reader.c, dlls/mfreadwrite/tests/mfplat.c,
|
||||
# | dlls/mfreadwrite/tests/resource.rc, dlls/mfreadwrite/tests/test.mp4, dlls/winegstreamer/Makefile.in,
|
||||
# | dlls/winegstreamer/audioconvert.c, dlls/winegstreamer/colorconvert.c, dlls/winegstreamer/gst_cbs.c,
|
||||
# | dlls/winegstreamer/gst_cbs.h, dlls/winegstreamer/gst_private.h, dlls/winegstreamer/main.c,
|
||||
# | dlls/winegstreamer/media_source.c, dlls/winegstreamer/mf_decode.c, dlls/winegstreamer/mfplat.c,
|
||||
# | dlls/winegstreamer/winegstreamer_classes.idl, include/mfidl.idl, tools/make_makefiles, tools/makedep.c
|
||||
# |
|
||||
if test "$enable_mfplat_streaming_support" -eq 1; then
|
||||
patch_apply mfplat-streaming-support/0001-winegstreamer-Add-IMFSeekInfo-GetNearestKeyFrames-st.patch
|
||||
patch_apply mfplat-streaming-support/0002-winegstreamer-Fixup-raw-audio-caps-to-be-compatible-.patch
|
||||
patch_apply mfplat-streaming-support/0003-winegstreamer-Set-MF_PD_MIME_TYPE-on-source-s-presen.patch
|
||||
patch_apply mfplat-streaming-support/0004-mf-Unconditionally-deliver-NULL-EOS-samples.patch
|
||||
patch_apply mfplat-streaming-support/0005-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch
|
||||
patch_apply mfplat-streaming-support/0006-winegstreamer-Translate-H.264-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0007-winegstreamer-Translate-WMV-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0008-winegstreamer-Translate-AAC-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0009-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch
|
||||
patch_apply mfplat-streaming-support/0010-winegstreamer-Translate-WMA-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0011-winegstreamer-Translate-H.264-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0012-winegstreamer-Translate-WMV-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0013-winegstreamer-Translate-AAC-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0014-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch
|
||||
patch_apply mfplat-streaming-support/0015-winegstreamer-Translate-WMA-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0016-tools-Add-support-for-multiple-parent-directories.patch
|
||||
patch_apply mfplat-streaming-support/0017-mf-Introduce-handler-helper.patch
|
||||
patch_apply mfplat-streaming-support/0018-Introduce-IMFSample-GstBuffer-converter.patch
|
||||
patch_apply mfplat-streaming-support/0019-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch
|
||||
patch_apply mfplat-streaming-support/0020-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch
|
||||
patch_apply mfplat-streaming-support/0021-Miscellaneous.patch
|
||||
patch_apply mfplat-streaming-support/0022-WMV.patch
|
||||
patch_apply mfplat-streaming-support/0023-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch
|
||||
patch_apply mfplat-streaming-support/0024-Expose-PCM-output-type-on-AAC-decoder.patch
|
||||
patch_apply mfplat-streaming-support/0026-winegstreamer-Implement-Color-Converter-MFT.patch
|
||||
patch_apply mfplat-streaming-support/0027-HACK-Set-BPS-to-16-for-output-template.patch
|
||||
patch_apply mfplat-streaming-support/0028-Improve-tests.patch
|
||||
patch_apply mfplat-streaming-support/0029-Revert-Improve-tests.patch
|
||||
patch_apply mfplat-streaming-support/0030-Report-streams-backwards-and-only-select-one-of-each.patch
|
||||
patch_apply mfplat-streaming-support/0031-winegstreamer-Implement-IMFMediaSource-Stop.patch
|
||||
patch_apply mfplat-streaming-support/0032-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch
|
||||
patch_apply mfplat-streaming-support/0034-winegstreamer-Introduce-WMA-audio-decoder.patch
|
||||
patch_apply mfplat-streaming-support/0035-Support-stereo-down-folding.patch
|
||||
patch_apply mfplat-streaming-support/0036-winegstreamer-Implement-MF_SD_LANGUAGE.patch
|
||||
patch_apply mfplat-streaming-support/0037-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch
|
||||
patch_apply mfplat-streaming-support/0038-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch
|
||||
patch_apply mfplat-streaming-support/0039-Revert-mf-topoloader-Switch-to-public-interface-for-.patch
|
||||
patch_apply mfplat-streaming-support/0040-mf-Partially-implement-the-topology-loader.patch
|
||||
patch_apply mfplat-streaming-support/0041-mf-Miscelaneous-fixes-to-topology-resolution.patch
|
||||
patch_apply mfplat-streaming-support/0042-Rewrite-branch-resolver.patch
|
||||
patch_apply mfplat-streaming-support/0043-winegstreamer-Implement-audio-conversion-MFT.patch
|
||||
patch_apply mfplat-streaming-support/0045-HACK-Flush-decoder-when-changing-times.patch
|
||||
patch_apply mfplat-streaming-support/0001-mf-topoloader-Add-partial-topology-resolution-tests.patch
|
||||
patch_apply mfplat-streaming-support/0002-mf-topoloader-Move-node-connection-responsibility-to.patch
|
||||
patch_apply mfplat-streaming-support/0003-mf-topoloader-Implement-source-node-to-sink-node-bra.patch
|
||||
patch_apply mfplat-streaming-support/0004-mf-topoloader-Unstub-IMFTopologyLoader-Load.patch
|
||||
patch_apply mfplat-streaming-support/0005-winegstreamer-Introduce-audio-conversion-transform.patch
|
||||
patch_apply mfplat-streaming-support/0006-winegstreamer-Implement-Set-Input-Output-Type-for-au.patch
|
||||
patch_apply mfplat-streaming-support/0007-winegstreamer-Implement-Process-Input-Output-for-aud.patch
|
||||
patch_apply mfplat-streaming-support/0008-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch
|
||||
patch_apply mfplat-streaming-support/0009-winegstreamer-Implement-Get-Attributes-functions-for.patch
|
||||
patch_apply mfplat-streaming-support/0010-Implement-Get-Input-Output-CurrentType-functions-for.patch
|
||||
patch_apply mfplat-streaming-support/0011-winegstreamer-Implement-Color-Converter-MFT.patch
|
||||
patch_apply mfplat-streaming-support/0012-mf-session-Unconditionally-deliver-NULL-EOS-samples.patch
|
||||
patch_apply mfplat-streaming-support/0013-mf-session-Request-more-samples-when-a-transform-nee.patch
|
||||
patch_apply mfplat-streaming-support/0015-winegstreamer-Implement-IMFMediaSource-Stop.patch
|
||||
patch_apply mfplat-streaming-support/0016-Set-MF_MT_ALL_SAMPLES_INDEPENDENT-on-raw-video-types.patch
|
||||
patch_apply mfplat-streaming-support/0017-HACK-Flush-decoder-when-changing-times.patch
|
||||
patch_apply mfplat-streaming-support/0018-winegstreamer-Add-IMFSeekInfo-GetNearestKeyFrames-st.patch
|
||||
patch_apply mfplat-streaming-support/0019-winegstreamer-Fixup-raw-audio-caps-to-be-compatible-.patch
|
||||
patch_apply mfplat-streaming-support/0020-winegstreamer-Set-MF_PD_MIME_TYPE-on-source-s-presen.patch
|
||||
patch_apply mfplat-streaming-support/0021-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch
|
||||
patch_apply mfplat-streaming-support/0022-winegstreamer-Translate-H.264-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0023-winegstreamer-Translate-WMV-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0024-winegstreamer-Translate-AAC-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0025-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch
|
||||
patch_apply mfplat-streaming-support/0026-winegstreamer-Translate-WMA-caps-to-attributes.patch
|
||||
patch_apply mfplat-streaming-support/0027-winegstreamer-Translate-H.264-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0028-winegstreamer-Translate-WMV-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0029-winegstreamer-Translate-AAC-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0030-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch
|
||||
patch_apply mfplat-streaming-support/0031-winegstreamer-Translate-WMA-attributes-to-caps.patch
|
||||
patch_apply mfplat-streaming-support/0032-tools-Add-support-for-multiple-parent-directories.patch
|
||||
patch_apply mfplat-streaming-support/0033-mf-Introduce-handler-helper.patch
|
||||
patch_apply mfplat-streaming-support/0034-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch
|
||||
patch_apply mfplat-streaming-support/0035-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch
|
||||
patch_apply mfplat-streaming-support/0036-Miscellaneous.patch
|
||||
patch_apply mfplat-streaming-support/0037-WMV.patch
|
||||
patch_apply mfplat-streaming-support/0038-Expose-PCM-output-type-on-AAC-decoder.patch
|
||||
patch_apply mfplat-streaming-support/0039-Improve-tests.patch
|
||||
patch_apply mfplat-streaming-support/0040-Revert-Improve-tests.patch
|
||||
patch_apply mfplat-streaming-support/0041-Report-streams-backwards-and-only-select-one-of-each.patch
|
||||
patch_apply mfplat-streaming-support/0042-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch
|
||||
patch_apply mfplat-streaming-support/0043-winegstreamer-Introduce-WMA-audio-decoder.patch
|
||||
patch_apply mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch
|
||||
patch_apply mfplat-streaming-support/0060-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch
|
||||
fi
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user