Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/Makefile.in | 1 + dlls/mf/evr.c | 27 +++++++++++++++++++++++++-- dlls/mf/tests/mf.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/Makefile.in b/dlls/mf/Makefile.in index b64cdb4a64d..f1d0571d143 100644 --- a/dlls/mf/Makefile.in +++ b/dlls/mf/Makefile.in @@ -1,6 +1,7 @@ MODULE = mf.dll IMPORTLIB = mf IMPORTS = advapi32 mfplat ole32 uuid mfuuid strmiids +DELAYIMPORTS = evr
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index af5c5d31038..ac3f17fa585 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -46,6 +46,7 @@ struct video_stream unsigned int id; struct video_renderer *parent; IMFMediaEventQueue *event_queue; + IMFVideoSampleAllocator *allocator; };
struct video_renderer @@ -203,6 +204,8 @@ static ULONG WINAPI video_stream_sink_Release(IMFStreamSink *iface) { if (stream->event_queue) IMFMediaEventQueue_Release(stream->event_queue); + if (stream->allocator) + IMFVideoSampleAllocator_Release(stream->allocator); heap_free(stream); }
@@ -445,7 +448,18 @@ static ULONG WINAPI video_stream_get_service_Release(IMFGetService *iface)
static HRESULT WINAPI video_stream_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) { - FIXME("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj); + struct video_stream *stream = impl_from_stream_IMFGetService(iface); + + TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj); + + if (IsEqualGUID(service, &MR_VIDEO_ACCELERATION_SERVICE)) + { + if (IsEqualIID(riid, &IID_IMFVideoSampleAllocator)) + return IMFVideoSampleAllocator_QueryInterface(stream->allocator, riid, obj); + return E_NOINTERFACE; + } + + FIXME("Unsupported service %s.\n", debugstr_guid(service));
return E_NOTIMPL; } @@ -473,7 +487,10 @@ static HRESULT video_renderer_stream_create(struct video_renderer *renderer, uns stream->refcount = 1;
if (FAILED(hr = MFCreateEventQueue(&stream->event_queue))) - return hr; + goto failed; + + if (FAILED(hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&stream->allocator))) + goto failed;
stream->parent = renderer; IMFMediaSink_AddRef(&stream->parent->IMFMediaSink_iface); @@ -482,6 +499,12 @@ static HRESULT video_renderer_stream_create(struct video_renderer *renderer, uns *ret = stream;
return S_OK; + +failed: + + IMFStreamSink_Release(&stream->IMFStreamSink_iface); + + return hr; }
static HRESULT WINAPI video_renderer_sink_QueryInterface(IMFMediaSink *iface, REFIID riid, void **obj) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 88cfa8d7625..bd6e66a5132 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3235,16 +3235,20 @@ todo_wine
static void test_evr(void) { + IMFVideoSampleAllocatorCallback *allocator_callback; + IMFStreamSink *stream_sink, *stream_sink2; IMFMediaEventGenerator *ev_generator; + IMFVideoSampleAllocator *allocator; IMFMediaTypeHandler *type_handler; IMFVideoRenderer *video_renderer; IMFClockStateSink *clock_sink; IMFMediaSinkPreroll *preroll; IMFMediaSink *sink, *sink2; - IMFStreamSink *stream_sink; IMFActivate *activate; DWORD flags, count; + LONG sample_count; IMFGetService *gs; + IMFSample *sample; IUnknown *unk; UINT64 value; HRESULT hr; @@ -3292,9 +3296,43 @@ static void test_evr(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
- IMFStreamSink_Release(stream_sink); IMFMediaTypeHandler_Release(type_handler);
+ /* Stream uses an allocator. */ + hr = MFGetService((IUnknown *)stream_sink, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator, + (void **)&allocator); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_callback); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + sample_count = 0; + hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback, &sample_count); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!sample_count, "Unexpected sample count %d.\n", sample_count); + + hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample); +todo_wine + ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + + IMFVideoSampleAllocatorCallback_Release(allocator_callback); + IMFVideoSampleAllocator_Release(allocator); + + /* Same test for a substream. */ + hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream_sink2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFGetService((IUnknown *)stream_sink2, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator, + (void **)&allocator); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFVideoSampleAllocator_Release(allocator); + + hr = IMFMediaSink_RemoveStreamSink(sink, 1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFStreamSink_Release(stream_sink2); + hr = IMFMediaSink_GetCharacteristics(sink, &flags); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(flags == (MEDIASINK_CAN_PREROLL | MEDIASINK_CLOCK_REQUIRED), "Unexpected flags %#x.\n", flags);