forked from Mirrors/wine-wine
evr: Create attributes for input mixer streams.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
d6e5b6ca02
commit
68374e4315
|
@ -1,6 +1,7 @@
|
||||||
MODULE = evr.dll
|
MODULE = evr.dll
|
||||||
IMPORTLIB = evr
|
IMPORTLIB = evr
|
||||||
IMPORTS = mfuuid strmiids strmbase uuid dxguid ole32 oleaut32
|
IMPORTS = mfuuid strmiids strmbase uuid dxguid ole32 oleaut32
|
||||||
|
DELAYIMPORTS = mfplat
|
||||||
|
|
||||||
EXTRADLLFLAGS = -mno-cygwin
|
EXTRADLLFLAGS = -mno-cygwin
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "evr.h"
|
#include "evr.h"
|
||||||
#include "d3d9.h"
|
#include "d3d9.h"
|
||||||
|
#include "mfapi.h"
|
||||||
#include "mferror.h"
|
#include "mferror.h"
|
||||||
|
|
||||||
#include "evr_classes.h"
|
#include "evr_classes.h"
|
||||||
|
@ -32,6 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(evr);
|
||||||
struct input_stream
|
struct input_stream
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
IMFAttributes *attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct video_mixer
|
struct video_mixer
|
||||||
|
@ -77,6 +79,12 @@ static struct input_stream * video_mixer_get_input(const struct video_mixer *mix
|
||||||
return bsearch(&id, mixer->inputs, mixer->input_count, sizeof(*mixer->inputs), video_mixer_compare_input_id);
|
return bsearch(&id, mixer->inputs, mixer->input_count, sizeof(*mixer->inputs), video_mixer_compare_input_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void video_mixer_init_input(struct input_stream *stream)
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(MFCreateAttributes(&stream->attributes, 1)))
|
||||||
|
IMFAttributes_SetUINT32(stream->attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
|
static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
|
||||||
{
|
{
|
||||||
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
||||||
|
@ -121,11 +129,17 @@ static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface)
|
||||||
{
|
{
|
||||||
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
||||||
ULONG refcount = InterlockedDecrement(&mixer->refcount);
|
ULONG refcount = InterlockedDecrement(&mixer->refcount);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
TRACE("%p, refcount %u.\n", iface, refcount);
|
TRACE("%p, refcount %u.\n", iface, refcount);
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
for (i = 0; i < mixer->input_count; ++i)
|
||||||
|
{
|
||||||
|
if (mixer->inputs[i].attributes)
|
||||||
|
IMFAttributes_Release(mixer->inputs[i].attributes);
|
||||||
|
}
|
||||||
DeleteCriticalSection(&mixer->cs);
|
DeleteCriticalSection(&mixer->cs);
|
||||||
free(mixer);
|
free(mixer);
|
||||||
}
|
}
|
||||||
|
@ -223,9 +237,26 @@ static HRESULT WINAPI video_mixer_transform_GetAttributes(IMFTransform *iface, I
|
||||||
static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||||
IMFAttributes **attributes)
|
IMFAttributes **attributes)
|
||||||
{
|
{
|
||||||
FIXME("%p, %u, %p.\n", iface, id, attributes);
|
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
||||||
|
struct input_stream *input;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
return E_NOTIMPL;
|
TRACE("%p, %u, %p.\n", iface, id, attributes);
|
||||||
|
|
||||||
|
EnterCriticalSection(&mixer->cs);
|
||||||
|
|
||||||
|
if (!(input = video_mixer_get_input(mixer, id)))
|
||||||
|
hr = MF_E_INVALIDSTREAMNUMBER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*attributes = input->attributes;
|
||||||
|
if (*attributes)
|
||||||
|
IMFAttributes_AddRef(*attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&mixer->cs);
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI video_mixer_transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
static HRESULT WINAPI video_mixer_transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
|
||||||
|
@ -256,6 +287,8 @@ static HRESULT WINAPI video_mixer_transform_DeleteInputStream(IMFTransform *ifac
|
||||||
idx = input - mixer->inputs;
|
idx = input - mixer->inputs;
|
||||||
if (idx < mixer->input_count)
|
if (idx < mixer->input_count)
|
||||||
{
|
{
|
||||||
|
if (mixer->inputs[idx].attributes)
|
||||||
|
IMFAttributes_Release(mixer->inputs[idx].attributes);
|
||||||
memmove(&mixer->inputs[idx], &mixer->inputs[idx + 1], (mixer->input_count - idx) * sizeof(*mixer->inputs));
|
memmove(&mixer->inputs[idx], &mixer->inputs[idx + 1], (mixer->input_count - idx) * sizeof(*mixer->inputs));
|
||||||
memmove(&mixer->input_ids[idx], &mixer->input_ids[idx + 1], (mixer->input_count - idx) *
|
memmove(&mixer->input_ids[idx], &mixer->input_ids[idx + 1], (mixer->input_count - idx) *
|
||||||
sizeof(*mixer->input_ids));
|
sizeof(*mixer->input_ids));
|
||||||
|
@ -277,6 +310,7 @@ static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface,
|
||||||
{
|
{
|
||||||
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
struct video_mixer *mixer = impl_from_IMFTransform(iface);
|
||||||
struct input_stream inputs[MAX_MIXER_INPUT_STREAMS] = { {0} };
|
struct input_stream inputs[MAX_MIXER_INPUT_STREAMS] = { {0} };
|
||||||
|
struct input_stream *input;
|
||||||
unsigned int i, len;
|
unsigned int i, len;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
@ -310,6 +344,11 @@ static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface,
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if ((input = bsearch(&ids[i], inputs, len, sizeof(*inputs), video_mixer_compare_input_id)))
|
||||||
|
video_mixer_init_input(input);
|
||||||
|
}
|
||||||
memcpy(&mixer->input_ids[mixer->input_count], ids, count * sizeof(*ids));
|
memcpy(&mixer->input_ids[mixer->input_count], ids, count * sizeof(*ids));
|
||||||
memcpy(mixer->inputs, inputs, len * sizeof(*inputs));
|
memcpy(mixer->inputs, inputs, len * sizeof(*inputs));
|
||||||
mixer->input_count += count;
|
mixer->input_count += count;
|
||||||
|
@ -552,6 +591,7 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out)
|
||||||
object->IMFTopologyServiceLookupClient_iface.lpVtbl = &video_mixer_service_client_vtbl;
|
object->IMFTopologyServiceLookupClient_iface.lpVtbl = &video_mixer_service_client_vtbl;
|
||||||
object->refcount = 1;
|
object->refcount = 1;
|
||||||
object->input_count = 1;
|
object->input_count = 1;
|
||||||
|
video_mixer_init_input(&object->inputs[0]);
|
||||||
InitializeCriticalSection(&object->cs);
|
InitializeCriticalSection(&object->cs);
|
||||||
|
|
||||||
*out = &object->IMFTransform_iface;
|
*out = &object->IMFTransform_iface;
|
||||||
|
|
|
@ -406,7 +406,6 @@ static void test_default_mixer(void)
|
||||||
ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
|
ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
|
||||||
|
|
||||||
hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
|
hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
|
||||||
todo_wine
|
|
||||||
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
|
hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
|
||||||
|
@ -444,29 +443,22 @@ todo_wine
|
||||||
|
|
||||||
attributes = NULL;
|
attributes = NULL;
|
||||||
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
|
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
|
||||||
todo_wine {
|
|
||||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||||
ok(!!attributes, "Unexpected attributes.\n");
|
ok(!!attributes, "Unexpected attributes.\n");
|
||||||
}
|
|
||||||
attributes2 = NULL;
|
attributes2 = NULL;
|
||||||
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
|
hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||||
ok(attributes == attributes2, "Unexpected instance.\n");
|
ok(attributes == attributes2, "Unexpected instance.\n");
|
||||||
|
|
||||||
if (attributes2)
|
IMFAttributes_Release(attributes2);
|
||||||
IMFAttributes_Release(attributes2);
|
IMFAttributes_Release(attributes);
|
||||||
if (attributes)
|
|
||||||
IMFAttributes_Release(attributes);
|
|
||||||
|
|
||||||
attributes = NULL;
|
attributes = NULL;
|
||||||
hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
|
hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
|
||||||
todo_wine {
|
|
||||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||||
ok(!!attributes, "Unexpected attributes.\n");
|
ok(!!attributes, "Unexpected attributes.\n");
|
||||||
}
|
IMFAttributes_Release(attributes);
|
||||||
if (attributes)
|
|
||||||
IMFAttributes_Release(attributes);
|
|
||||||
|
|
||||||
hr = IMFTransform_DeleteInputStream(transform, 0);
|
hr = IMFTransform_DeleteInputStream(transform, 0);
|
||||||
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
Loading…
Reference in New Issue