mf/evr: Create sample allocator for each stream.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-10-08 14:44:16 +03:00 committed by Alexandre Julliard
parent bcee4fbb94
commit 30e5405aca
3 changed files with 66 additions and 4 deletions

View File

@ -1,6 +1,7 @@
MODULE = mf.dll
IMPORTLIB = mf
IMPORTS = advapi32 mfplat ole32 uuid mfuuid strmiids
DELAYIMPORTS = evr
EXTRADLLFLAGS = -mno-cygwin

View File

@ -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)

View File

@ -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);