winegstreamer: Add stub Video Processor MFT.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f89ab56ef6
commit
787ed80858
|
@ -2079,11 +2079,11 @@ static void test_video_processor(void)
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
|
hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
|
||||||
(void **)&transform);
|
(void **)&transform);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "Failed to create video processor transform, hr %#x.\n", hr);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
skip("Failed to create Video Processor instance, skipping tests.\n");
|
||||||
goto failed;
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
hr = IMFTransform_QueryInterface(transform, &IID_IMFMediaEventGenerator, (void **)&unk);
|
hr = IMFTransform_QueryInterface(transform, &IID_IMFMediaEventGenerator, (void **)&unk);
|
||||||
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
|
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
|
||||||
|
@ -2120,12 +2120,14 @@ todo_wine
|
||||||
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
|
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetInputStatus(transform, 0, &flags);
|
hr = IMFTransform_GetInputStatus(transform, 0, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
|
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
|
||||||
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
|
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputStatus(transform, &flags);
|
hr = IMFTransform_GetOutputStatus(transform, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
|
hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
|
||||||
|
@ -2137,30 +2139,38 @@ todo_wine
|
||||||
IMFAttributes_Release(attributes2);
|
IMFAttributes_Release(attributes2);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
|
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
|
hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type);
|
hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
|
hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type);
|
hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
|
hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
memset(&input_info, 0xcc, sizeof(input_info));
|
||||||
hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
|
hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
|
||||||
|
todo_wine {
|
||||||
ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
|
||||||
ok(input_info.dwFlags == 0, "Unexpected flag %#x.\n", input_info.dwFlags);
|
ok(input_info.dwFlags == 0, "Unexpected flag %#x.\n", input_info.dwFlags);
|
||||||
ok(input_info.cbSize == 0, "Unexpected size %u.\n", input_info.cbSize);
|
ok(input_info.cbSize == 0, "Unexpected size %u.\n", input_info.cbSize);
|
||||||
ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
|
ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
|
||||||
ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
|
ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
|
||||||
|
}
|
||||||
hr = MFCreateMediaEvent(MEUnknown, &GUID_NULL, S_OK, NULL, &event);
|
hr = MFCreateMediaEvent(MEUnknown, &GUID_NULL, S_OK, NULL, &event);
|
||||||
ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
|
||||||
hr = IMFTransform_ProcessEvent(transform, 0, event);
|
hr = IMFTransform_ProcessEvent(transform, 0, event);
|
||||||
|
@ -2174,6 +2184,7 @@ todo_wine
|
||||||
{
|
{
|
||||||
if (FAILED(hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type)))
|
if (FAILED(hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type)))
|
||||||
{
|
{
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2254,17 +2265,22 @@ todo_wine
|
||||||
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
|
hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
|
||||||
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
|
hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
|
||||||
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
|
hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
|
||||||
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
memset(&output_info, 0, sizeof(output_info));
|
||||||
hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
|
hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
|
||||||
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
|
||||||
ok(output_info.dwFlags == 0, "Unexpected flags %#x.\n", output_info.dwFlags);
|
ok(output_info.dwFlags == 0, "Unexpected flags %#x.\n", output_info.dwFlags);
|
||||||
|
todo_wine
|
||||||
ok(output_info.cbSize > 0, "Unexpected size %u.\n", output_info.cbSize);
|
ok(output_info.cbSize > 0, "Unexpected size %u.\n", output_info.cbSize);
|
||||||
ok(output_info.cbAlignment == 0, "Unexpected alignment %u.\n", output_info.cbAlignment);
|
ok(output_info.cbAlignment == 0, "Unexpected alignment %u.\n", output_info.cbAlignment);
|
||||||
|
|
||||||
|
@ -2278,20 +2294,24 @@ todo_wine
|
||||||
output_buffer.pSample = sample;
|
output_buffer.pSample = sample;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
|
||||||
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
||||||
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
||||||
|
|
||||||
hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
|
hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
|
||||||
|
todo_wine
|
||||||
ok(hr == S_OK, "Failed to push a sample, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to push a sample, hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
|
hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
memset(&output_buffer, 0, sizeof(output_buffer));
|
memset(&output_buffer, 0, sizeof(output_buffer));
|
||||||
output_buffer.pSample = sample;
|
output_buffer.pSample = sample;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
|
||||||
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
||||||
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
||||||
|
@ -2302,6 +2322,7 @@ todo_wine
|
||||||
output_buffer.pSample = sample;
|
output_buffer.pSample = sample;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||||
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
||||||
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
||||||
|
@ -2319,6 +2340,7 @@ todo_wine
|
||||||
output_buffer.pSample = sample;
|
output_buffer.pSample = sample;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
|
||||||
|
todo_wine
|
||||||
ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr);
|
ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr);
|
||||||
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
|
||||||
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
ok(flags == 0, "Unexpected status %#x.\n", flags);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
MODULE = winegstreamer.dll
|
MODULE = winegstreamer.dll
|
||||||
IMPORTS = strmbase strmiids uuid winmm msacm32 msvfw32 ole32 oleaut32 user32 gdi32 advapi32
|
IMPORTS = strmbase strmiids uuid winmm msacm32 msvfw32 ole32 oleaut32 user32 gdi32 advapi32 mfplat mfuuid
|
||||||
EXTRAINCL = $(GSTREAMER_CFLAGS)
|
EXTRAINCL = $(GSTREAMER_CFLAGS)
|
||||||
EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
@ -7,7 +7,10 @@ C_SRCS = \
|
||||||
gst_cbs.c \
|
gst_cbs.c \
|
||||||
gstdemux.c \
|
gstdemux.c \
|
||||||
gsttffilter.c \
|
gsttffilter.c \
|
||||||
main.c
|
main.c \
|
||||||
|
mfplat.c
|
||||||
|
|
||||||
|
IDL_SRCS = mfplat.idl
|
||||||
|
|
||||||
RC_SRCS = \
|
RC_SRCS = \
|
||||||
rsrc.rc
|
rsrc.rc
|
||||||
|
|
|
@ -53,4 +53,7 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern const char *media_quark_string DECLSPEC_HIDDEN;
|
extern const char *media_quark_string DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||||
|
extern HRESULT mfplat_can_unload_now(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#endif /* __GST_PRIVATE_INCLUDED__ */
|
#endif /* __GST_PRIVATE_INCLUDED__ */
|
||||||
|
|
|
@ -232,7 +232,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI DllCanUnloadNow(void)
|
HRESULT WINAPI DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
return STRMBASE_DllCanUnloadNow();
|
HRESULT hr = STRMBASE_DllCanUnloadNow();
|
||||||
|
|
||||||
|
if (hr == S_OK)
|
||||||
|
hr = mfplat_can_unload_now();
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -240,7 +245,12 @@ HRESULT WINAPI DllCanUnloadNow(void)
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||||
{
|
{
|
||||||
return STRMBASE_DllGetClassObject( rclsid, riid, ppv );
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (FAILED(hr = mfplat_get_class_object(rclsid, riid, ppv)))
|
||||||
|
hr = STRMBASE_DllGetClassObject( rclsid, riid, ppv );
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GStreamer common functions */
|
/* GStreamer common functions */
|
||||||
|
|
|
@ -0,0 +1,444 @@
|
||||||
|
/*
|
||||||
|
* 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 <stdarg.h>
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#define NONAMELESSUNION
|
||||||
|
|
||||||
|
#include "mfapi.h"
|
||||||
|
#include "mfidl.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
||||||
|
|
||||||
|
static LONG object_locks;
|
||||||
|
|
||||||
|
struct video_processor
|
||||||
|
{
|
||||||
|
IMFTransform IMFTransform_iface;
|
||||||
|
LONG refcount;
|
||||||
|
IMFAttributes *attributes;
|
||||||
|
IMFAttributes *output_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct video_processor *impl_video_processor_from_IMFTransform(IMFTransform *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct video_processor, IMFTransform_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_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 video_processor_AddRef(IMFTransform *iface)
|
||||||
|
{
|
||||||
|
struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
|
||||||
|
ULONG refcount = InterlockedIncrement(&transform->refcount);
|
||||||
|
|
||||||
|
TRACE("%p, refcount %u.\n", iface, refcount);
|
||||||
|
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI video_processor_Release(IMFTransform *iface)
|
||||||
|
{
|
||||||
|
struct video_processor *transform = impl_video_processor_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 video_processor_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 video_processor_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
|
||||||
|
{
|
||||||
|
TRACE("%p, %p, %p.\n", iface, inputs, outputs);
|
||||||
|
|
||||||
|
*inputs = *outputs = 1;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
|
||||||
|
DWORD output_size, DWORD *outputs)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
|
||||||
|
{
|
||||||
|
struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
|
||||||
|
|
||||||
|
TRACE("%p, %p.\n", iface, attributes);
|
||||||
|
|
||||||
|
*attributes = transform->attributes;
|
||||||
|
IMFAttributes_AddRef(*attributes);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||||
|
IMFAttributes **attributes)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||||
|
IMFAttributes **attributes)
|
||||||
|
{
|
||||||
|
struct video_processor *transform = impl_video_processor_from_IMFTransform(iface);
|
||||||
|
|
||||||
|
TRACE("%p, %u, %p.\n", iface, id, attributes);
|
||||||
|
|
||||||
|
*attributes = transform->output_attributes;
|
||||||
|
IMFAttributes_AddRef(*attributes);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_DeleteInputStream(IMFTransform *iface, DWORD id)
|
||||||
|
{
|
||||||
|
TRACE("%p, %u.\n", iface, id);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
|
||||||
|
{
|
||||||
|
TRACE("%p, %u, %p.\n", iface, streams, ids);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||||
|
IMFMediaType **type)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
|
||||||
|
IMFMediaType **type)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_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 video_processor_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 video_processor_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u, %p.\n", iface, id, type);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u, %p.\n", iface, id, type);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u, %p.\n", iface, id, flags);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_GetOutputStatus(IMFTransform *iface, DWORD *flags)
|
||||||
|
{
|
||||||
|
FIXME("%p, %p.\n", iface, flags);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_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 video_processor_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
|
||||||
|
{
|
||||||
|
TRACE("%p, %u, %p.\n", iface, id, event);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
|
||||||
|
{
|
||||||
|
FIXME("%p, %u.\n", iface, message);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_processor_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 video_processor_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 video_processor_vtbl =
|
||||||
|
{
|
||||||
|
video_processor_QueryInterface,
|
||||||
|
video_processor_AddRef,
|
||||||
|
video_processor_Release,
|
||||||
|
video_processor_GetStreamLimits,
|
||||||
|
video_processor_GetStreamCount,
|
||||||
|
video_processor_GetStreamIDs,
|
||||||
|
video_processor_GetInputStreamInfo,
|
||||||
|
video_processor_GetOutputStreamInfo,
|
||||||
|
video_processor_GetAttributes,
|
||||||
|
video_processor_GetInputStreamAttributes,
|
||||||
|
video_processor_GetOutputStreamAttributes,
|
||||||
|
video_processor_DeleteInputStream,
|
||||||
|
video_processor_AddInputStreams,
|
||||||
|
video_processor_GetInputAvailableType,
|
||||||
|
video_processor_GetOutputAvailableType,
|
||||||
|
video_processor_SetInputType,
|
||||||
|
video_processor_SetOutputType,
|
||||||
|
video_processor_GetInputCurrentType,
|
||||||
|
video_processor_GetOutputCurrentType,
|
||||||
|
video_processor_GetInputStatus,
|
||||||
|
video_processor_GetOutputStatus,
|
||||||
|
video_processor_SetOutputBounds,
|
||||||
|
video_processor_ProcessEvent,
|
||||||
|
video_processor_ProcessMessage,
|
||||||
|
video_processor_ProcessInput,
|
||||||
|
video_processor_ProcessOutput,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct class_factory
|
||||||
|
{
|
||||||
|
IClassFactory IClassFactory_iface;
|
||||||
|
LONG refcount;
|
||||||
|
HRESULT (*create_instance)(REFIID riid, void **obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
|
||||||
|
{
|
||||||
|
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||||
|
|
||||||
|
if (IsEqualGUID(riid, &IID_IClassFactory) ||
|
||||||
|
IsEqualGUID(riid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*obj = iface;
|
||||||
|
IClassFactory_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("%s is not supported.\n", debugstr_guid(riid));
|
||||||
|
*obj = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
struct class_factory *factory = impl_from_IClassFactory(iface);
|
||||||
|
return InterlockedIncrement(&factory->refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI class_factory_Release(IClassFactory *iface)
|
||||||
|
{
|
||||||
|
struct class_factory *factory = impl_from_IClassFactory(iface);
|
||||||
|
ULONG refcount = InterlockedDecrement(&factory->refcount);
|
||||||
|
|
||||||
|
if (!refcount)
|
||||||
|
heap_free(factory);
|
||||||
|
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
|
||||||
|
{
|
||||||
|
struct class_factory *factory = impl_from_IClassFactory(iface);
|
||||||
|
|
||||||
|
TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), obj);
|
||||||
|
|
||||||
|
if (outer)
|
||||||
|
{
|
||||||
|
*obj = NULL;
|
||||||
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory->create_instance(riid, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock)
|
||||||
|
{
|
||||||
|
TRACE("%p, %d.\n", iface, dolock);
|
||||||
|
|
||||||
|
if (dolock)
|
||||||
|
InterlockedIncrement(&object_locks);
|
||||||
|
else
|
||||||
|
InterlockedDecrement(&object_locks);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IClassFactoryVtbl class_factory_vtbl =
|
||||||
|
{
|
||||||
|
class_factory_QueryInterface,
|
||||||
|
class_factory_AddRef,
|
||||||
|
class_factory_Release,
|
||||||
|
class_factory_CreateInstance,
|
||||||
|
class_factory_LockServer,
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT video_processor_create(REFIID riid, void **ret)
|
||||||
|
{
|
||||||
|
struct video_processor *object;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
object->IMFTransform_iface.lpVtbl = &video_processor_vtbl;
|
||||||
|
object->refcount = 1;
|
||||||
|
|
||||||
|
if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
*ret = &object->IMFTransform_iface;
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
|
||||||
|
IMFTransform_Release(&object->IMFTransform_iface);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct class_object
|
||||||
|
{
|
||||||
|
const GUID *clsid;
|
||||||
|
HRESULT (*create_instance)(REFIID riid, void **obj);
|
||||||
|
}
|
||||||
|
class_objects[] =
|
||||||
|
{
|
||||||
|
{ &CLSID_VideoProcessorMFT, &video_processor_create },
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||||
|
{
|
||||||
|
struct class_factory *factory;
|
||||||
|
unsigned int i;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(class_objects); ++i)
|
||||||
|
{
|
||||||
|
if (IsEqualGUID(class_objects[i].clsid, rclsid))
|
||||||
|
{
|
||||||
|
if (!(factory = heap_alloc(sizeof(*factory))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
factory->IClassFactory_iface.lpVtbl = &class_factory_vtbl;
|
||||||
|
factory->refcount = 1;
|
||||||
|
factory->create_instance = class_objects[i].create_instance;
|
||||||
|
|
||||||
|
hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
|
||||||
|
IClassFactory_Release(&factory->IClassFactory_iface);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT mfplat_can_unload_now(void)
|
||||||
|
{
|
||||||
|
return !object_locks ? S_OK : S_FALSE;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma makedep register
|
||||||
|
|
||||||
|
[
|
||||||
|
threading(both),
|
||||||
|
uuid(88753b26-5b24-49bd-b2e7-0c445c78c982)
|
||||||
|
|
||||||
|
]
|
||||||
|
coclass VideoProcessorMFT { }
|
Loading…
Reference in New Issue