From: Bernhard Kölbl besentv@gmail.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/mfmediaengine/tests/mfmediaengine.c | 777 ++++++++++++++++++ dlls/mfmediaengine/tests/resource.rc | 4 + .../tests/rgb32frame_static_colors.bmp | Bin 0 -> 16438 bytes 3 files changed, 781 insertions(+) create mode 100644 dlls/mfmediaengine/tests/rgb32frame_static_colors.bmp
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 655b19af050..c4d444b1aa2 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1326,6 +1326,782 @@ done: CloseHandle(notify.ready_event); }
+#define EFFECT_PAINT_TOP 0x00000001 +#define EFFECT_PAINT_RIGHT 0x00000002 +#define EFFECT_PAINT_BOTTOM 0x00000003 +#define EFFECT_PAINT_LEFT 0x00000004 + +struct static_color_effect +{ + IMFTransform IMFTransform_iface; + LONG refcount; + + IMFMediaType *media_type_in, *media_type_out; + DWORD frame_size, frame_width, frame_height; + LONG processing_delta, paint_area; + IMFSample *sample_buf; + BYTE u, v; + + CRITICAL_SECTION cs; +}; + +const GUID *media_subtypes[] = +{ + &MFVideoFormat_I420, + /* Add more formats if needed. */ +}; + +static struct static_color_effect *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct static_color_effect, IMFTransform_iface); +} + +static HRESULT WINAPI static_color_effect_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IMFTransform)) + { + *out = &impl->IMFTransform_iface; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI static_color_effect_AddRef(IMFTransform *iface) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&impl->refcount); + return refcount; +} + +static ULONG WINAPI static_color_effect_Release(IMFTransform *iface) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&impl->refcount); + + if (!refcount) + { + if (impl->media_type_out) IMFMediaType_Release(impl->media_type_out); + if (impl->media_type_in) IMFMediaType_Release(impl->media_type_in); + DeleteCriticalSection(&impl->cs); + free(impl); + } + + return refcount; +} + +static HRESULT WINAPI static_color_effect_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; + return S_OK; +} + +static HRESULT WINAPI static_color_effect_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + *inputs = *outputs = 1; + return S_OK; +} + +static HRESULT WINAPI static_color_effect_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + info->dwFlags = + MFT_OUTPUT_STREAM_WHOLE_SAMPLES | + MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | + MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER; + + info->cbAlignment = 0; + info->cbSize = impl->frame_size; + + return S_OK; +} + +static HRESULT WINAPI static_color_effect_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + IMFMediaType *mt; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (impl->media_type_in) + { + if (index > 0) + goto no_more_types; + + *type = impl->media_type_in; + IMFMediaType_AddRef(*type); + } + else + { + if (index >= ARRAY_SIZE(media_subtypes)) + goto no_more_types; + + MFCreateMediaType(&mt); + IMFMediaType_SetGUID(mt, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + IMFMediaType_SetGUID(mt, &MF_MT_SUBTYPE, media_subtypes[index]); + *type = mt; + } + LeaveCriticalSection(&impl->cs); + + return S_OK; + +no_more_types: + LeaveCriticalSection(&impl->cs); + + return MF_E_NO_MORE_TYPES; +} + +static HRESULT WINAPI static_color_effect_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + IMFMediaType *mt; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (impl->media_type_out) + { + if (index > 0) + goto no_more_types; + + *type = impl->media_type_out; + IMFMediaType_AddRef(*type); + } + else + { + if (index >= ARRAY_SIZE(media_subtypes)) + goto no_more_types; + + MFCreateMediaType(&mt); + IMFMediaType_SetGUID(mt, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + IMFMediaType_SetGUID(mt, &MF_MT_SUBTYPE, media_subtypes[index]); + *type = mt; + } + + LeaveCriticalSection(&impl->cs); + + return S_OK; + +no_more_types: + LeaveCriticalSection(&impl->cs); + + return MF_E_NO_MORE_TYPES; +} + +static HRESULT WINAPI static_color_effect_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + UINT32 height, width, i; + PROPVARIANT propvar; + HRESULT hr; + GUID value; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &value))) + goto done; + + for (hr = MF_E_INVALIDMEDIATYPE, i = 0; i < ARRAY_SIZE(media_subtypes); ++i) + { + if (IsEqualGUID(&value, media_subtypes[i])) + { + hr = S_OK; + break; + } + } + + if (FAILED(hr)) + goto done; + + if (FAILED(hr = IMFMediaType_GetItem(type, &MF_MT_FRAME_SIZE, &propvar))) + goto done; + + impl->frame_width = width = propvar.uhVal.HighPart; + impl->frame_height = height = propvar.uhVal.LowPart; + + if (impl->media_type_in) IMFMediaType_Release(impl->media_type_in); + impl->media_type_in = type; + IMFMediaType_AddRef(impl->media_type_in); + + /* Idk why, but Windows apparently expects this function to also set an output type... */ + if (impl->media_type_out) IMFMediaType_Release(impl->media_type_out); + impl->media_type_out = type; + IMFMediaType_AddRef(impl->media_type_out); + + if (IsEqualGUID(&value, &MFVideoFormat_I420)) + { + impl->frame_size = width * (height + (height / 2)); /* 12bpp */ + } + else + { + impl->frame_size = 0; + } + +done: + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static HRESULT WINAPI static_color_effect_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (impl->media_type_out) + IMFMediaType_Release(impl->media_type_out); + + impl->media_type_out = type; + IMFMediaType_AddRef(impl->media_type_out); + + LeaveCriticalSection(&impl->cs); + + return S_OK; +} + +static HRESULT WINAPI static_color_effect_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + HRESULT hr; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (!impl->media_type_in) + { + hr = MF_E_TRANSFORM_TYPE_NOT_SET; + } + else + { + *type = impl->media_type_in; + IMFMediaType_AddRef(*type); + hr = S_OK; + } + + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static HRESULT WINAPI static_color_effect_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + HRESULT hr; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + + if (!impl->media_type_out) + { + hr = MF_E_TRANSFORM_TYPE_NOT_SET; + } + else + { + *type = impl->media_type_out; + IMFMediaType_AddRef(*type); + hr = S_OK; + } + + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static HRESULT WINAPI static_color_effect_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI static_color_effect_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + HRESULT hr = S_OK; + + EnterCriticalSection(&impl->cs); + + switch (message) + { + case MFT_MESSAGE_COMMAND_FLUSH: + hr = E_NOTIMPL; + break; + + default: + break; + } + + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static HRESULT WINAPI static_color_effect_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + DWORD buf_count = 0; + HRESULT hr = S_OK; + + if (id) return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&impl->cs); + if (impl->sample_buf) + { + hr = MF_E_NOTACCEPTING; + goto done; + } + + if (FAILED(hr = IMFSample_GetBufferCount(sample, &buf_count))) + goto done; + + if (!buf_count) + { + hr = E_FAIL; + goto done; + } + else if (buf_count > 1) + { + hr = MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS; + } + + IMFSample_AddRef((impl->sample_buf = sample)); + impl->processing_delta++; + +done: + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static HRESULT static_color_effect_convert_frame(struct static_color_effect *impl, GUID *subtype, IMFMediaBuffer *in, IMFMediaBuffer *out) +{ + DWORD len = 0, max = 0, i, height, width, x_start, x_end, y_start, y_end; + IMF2DBuffer *src_2d = NULL, *dst_2d = NULL; + BYTE *src, *dst; + HRESULT hr; + + if (FAILED(hr = IMFMediaBuffer_Lock(in, &src, NULL, NULL))) + goto done; + + if (FAILED(hr = IMFMediaBuffer_Lock(out, &dst, &max, &len))) + { + IMFMediaBuffer_Unlock(in); + goto done; + } + + y_start = 0; + x_start = 0; + height = y_end = impl->frame_height; + width = x_end = impl->frame_width; + + /* Note: The area begins in the bottom left corner. */ + if (impl->paint_area == EFFECT_PAINT_BOTTOM) + { + y_end = height / 2; + } + else if (impl->paint_area == EFFECT_PAINT_LEFT) + { + x_end = width / 2; + } + else if (impl->paint_area == EFFECT_PAINT_RIGHT) + { + x_start = width / 2; + } + else if (impl->paint_area == EFFECT_PAINT_TOP) + { + y_start = height / 2; + } + + if (IsEqualGUID(subtype, &MFVideoFormat_I420)) + { + /* Y plane */ + for (i = 0; i < height; ++i) + { + memcpy(dst, src, width); + + if (i >= y_start && i < y_end) + memset(dst + x_start, 0x80, x_end - x_start); + + dst += width; + src += width; + } + + /* Half all values because U and V plane are half the size. */ + x_start = x_start / 2; + y_start = y_start / 2; + x_end = x_end / 2; + y_end = y_end / 2; + height = height / 2; + width = width / 2; + + /* U plane */ + for (i = 0; i < height; ++i) + { + memcpy(dst, src, width); + + if (i >= y_start && i < y_end) + memset(dst + x_start, impl->u, x_end - x_start); + + dst += width; + src += width; + } + + /* V plane */ + for (i = 0; i < height; ++i) + { + memcpy(dst, src, width); + + if (i >= y_start && i < y_end) + memset(dst + x_start, impl->v, x_end - x_start); + + dst += width; + src += width; + } + } + else hr = E_FAIL; + + if (SUCCEEDED(hr)) + hr = IMFMediaBuffer_SetCurrentLength(out, max); + + IMFMediaBuffer_Unlock(out); + IMFMediaBuffer_Unlock(in); + +done: + if (dst_2d) IMF2DBuffer_Release(dst_2d); + if (src_2d) IMF2DBuffer_Release(src_2d); + return hr; +} + +static HRESULT WINAPI static_color_effect_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + struct static_color_effect *impl = impl_from_IMFTransform(iface); + IMFMediaBuffer *in_buf = NULL, *out_buf = NULL; + LONGLONG duration = 0, time = 0; + HRESULT hr = S_OK; + GUID subtype; + + if (count != 1) return E_INVALIDARG; + + EnterCriticalSection(&impl->cs); + + if (!impl->sample_buf) + { + hr = MF_E_TRANSFORM_NEED_MORE_INPUT; + goto done; + } + + if (FAILED(hr = IMFMediaType_GetGUID(impl->media_type_in, &MF_MT_SUBTYPE, &subtype))) + goto done; + + if (SUCCEEDED(hr = IMFSample_GetSampleDuration(impl->sample_buf, &duration))) + { + if (FAILED(hr = IMFSample_SetSampleDuration(samples[0].pSample, duration))) + goto done; + } + + if (SUCCEEDED(hr = IMFSample_GetSampleTime(impl->sample_buf, &time))) + { + if (FAILED(hr = IMFSample_SetSampleTime(samples[0].pSample, time))) + goto done; + } + + if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(impl->sample_buf, &in_buf))) + goto done; + + if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(samples[0].pSample, &out_buf))) + goto done; + + if (FAILED(hr = static_color_effect_convert_frame(impl, &subtype, in_buf, out_buf))) + goto done; + + *status = samples[0].dwStatus = 0; + impl->processing_delta--; +done: + if (impl->sample_buf) IMFSample_Release(impl->sample_buf); + impl->sample_buf = NULL; + if (out_buf) IMFMediaBuffer_Release(out_buf); + if (in_buf) IMFMediaBuffer_Release(in_buf); + + LeaveCriticalSection(&impl->cs); + + return hr; +} + +static const IMFTransformVtbl static_color_effect_vtbl = +{ + static_color_effect_QueryInterface, + static_color_effect_AddRef, + static_color_effect_Release, + static_color_effect_GetStreamLimits, + static_color_effect_GetStreamCount, + static_color_effect_GetStreamIDs, + static_color_effect_GetInputStreamInfo, + static_color_effect_GetOutputStreamInfo, + static_color_effect_GetAttributes, + static_color_effect_GetInputStreamAttributes, + static_color_effect_GetOutputStreamAttributes, + static_color_effect_DeleteInputStream, + static_color_effect_AddInputStreams, + static_color_effect_GetInputAvailableType, + static_color_effect_GetOutputAvailableType, + static_color_effect_SetInputType, + static_color_effect_SetOutputType, + static_color_effect_GetInputCurrentType, + static_color_effect_GetOutputCurrentType, + static_color_effect_GetInputStatus, + static_color_effect_GetOutputStatus, + static_color_effect_SetOutputBounds, + static_color_effect_ProcessEvent, + static_color_effect_ProcessMessage, + static_color_effect_ProcessInput, + static_color_effect_ProcessOutput, +}; + +HRESULT static_color_effect_create(BYTE u, BYTE v, LONG area, struct static_color_effect **out) +{ + struct static_color_effect *impl; + + if (!(impl = calloc(1, sizeof(*impl)))) + return E_OUTOFMEMORY; + + impl->IMFTransform_iface.lpVtbl = &static_color_effect_vtbl; + impl->refcount = 1; + impl->paint_area = area; + impl->u = u; + impl->v = v; + + InitializeCriticalSection(&impl->cs); + + *out = impl; + return S_OK; +} + +static void test_video_effect(void) +{ + struct test_transfer_notify notify = {{&test_transfer_notify_vtbl}}; + WCHAR url[] = { L"i420-64x64.avi" }; + struct static_color_effect *video_effect, *video_effect2, *video_effect3; + ID3D11Texture2D *texture, *rb_texture; + D3D11_MAPPED_SUBRESOURCE map_desc; + IMFMediaEngineEx *media_engine_ex; + IMFDXGIDeviceManager *manager; + ID3D11DeviceContext *context; + D3D11_TEXTURE2D_DESC desc; + IMFByteStream *stream; + ID3D11Device *device; + RECT dst_rect; + UINT token; + HRESULT hr; + DWORD res; + ULONG ref; + + stream = load_resource(L"i420-64x64.avi", L"video/avi"); + + notify.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!notify.ready_event, "CreateEventW failed, error %lu\n", GetLastError()); + + if (!(device = create_d3d11_device())) + { + skip("Failed to create a D3D11 device, skipping tests.\n"); + return; + } + + hr = pMFCreateDXGIDeviceManager(&token, &manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + media_engine_ex = create_media_engine_ex(¬ify.IMFMediaEngineNotify_iface, + manager, DXGI_FORMAT_B8G8R8X8_UNORM); + + IMFDXGIDeviceManager_Release(manager); + + if (!(notify.media_engine = media_engine_ex)) + return; + + memset(&desc, 0, sizeof(desc)); + desc.Width = 64; + desc.Height = 64; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + desc.SampleDesc.Count = 1; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + video_effect = NULL; + hr = static_color_effect_create(0x00, 0x00, EFFECT_PAINT_TOP, &video_effect); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + video_effect2 = NULL; + hr = static_color_effect_create(0xff, 0xff, EFFECT_PAINT_RIGHT, &video_effect2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + video_effect3 = NULL; + hr = static_color_effect_create(0x00, 0xff, EFFECT_PAINT_BOTTOM, &video_effect3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(&video_effect->IMFTransform_iface, 2); + + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect2->IMFTransform_iface, FALSE); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(&video_effect2->IMFTransform_iface, 2); + + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect3->IMFTransform_iface, FALSE); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(&video_effect3->IMFTransform_iface, 2); + + if (FAILED(hr)) + goto done; + + hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine_ex, stream, url); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFByteStream_Release(stream); + + res = WaitForSingleObject(notify.ready_event, 5000); + ok(!res, "Unexpected res %#lx.\n", res); + + if (FAILED(notify.error)) + { + win_skip("Media engine reported error %#lx, skipping tests.\n", notify.error); + goto done; + } + + /* FIXME: Wine first video frame is often full of garbage, wait for another update */ + res = WaitForSingleObject(notify.ready_event, 500); + /* It's also missing the MF_MEDIA_ENGINE_EVENT_TIMEUPDATE notifications */ + todo_wine + ok(!res, "Unexpected res %#lx.\n", res); + + SetRect(&dst_rect, 0, 0, desc.Width, desc.Height); + hr = IMFMediaEngineEx_TransferVideoFrame(notify.media_engine, (IUnknown *)texture, NULL, NULL, NULL); + ok(hr == S_OK || broken(hr == E_POINTER) /* w1064v1507 */, "Unexpected hr %#lx.\n", hr); + + ID3D11Texture2D_GetDesc(texture, &desc); + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &rb_texture); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)rb_texture, + 0, 0, 0, 0, (ID3D11Resource *)texture, 0, NULL); + + memset(&map_desc, 0, sizeof(map_desc)); + hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)rb_texture, 0, D3D11_MAP_READ, 0, &map_desc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!map_desc.pData, "got pData %p\n", map_desc.pData); + ok(map_desc.DepthPitch == 16384, "got DepthPitch %u\n", map_desc.DepthPitch); + ok(map_desc.RowPitch == desc.Width * 4, "got RowPitch %u\n", map_desc.RowPitch); + check_rgb32_data(L"rgb32frame_static_colors.bmp", map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect); + ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)rb_texture, 0); + + ok(video_effect->processing_delta == 0, "Unexpected delta %lu.\n", video_effect->processing_delta); + ok(video_effect2->processing_delta == 0, "Unexpected delta %lu.\n", video_effect2->processing_delta); + ok(video_effect3->processing_delta == 0, "Unexpected delta %lu.\n", video_effect3->processing_delta); + + ID3D11DeviceContext_Release(context); + ID3D11Texture2D_Release(rb_texture); + +done: + IMFMediaEngineEx_Shutdown(media_engine_ex); + + ref = IMFMediaEngineEx_Release(media_engine_ex); + ok(!ref, "Unexpected ref %lu.\n", ref); + + ID3D11Texture2D_Release(texture); + ID3D11Device_Release(device); + + ref = IMFTransform_Release(&video_effect3->IMFTransform_iface); + ok(!ref, "Unexpected ref %lu.\n", ref); + ref = IMFTransform_Release(&video_effect2->IMFTransform_iface); + ok(!ref, "Unexpected ref %lu.\n", ref); + ref = IMFTransform_Release(&video_effect->IMFTransform_iface); + ok(!ref, "Unexpected ref %lu.\n", ref); + + CloseHandle(notify.ready_event); +} + +#undef EFFECT_PAINT_TOP +#undef EFFECT_PAINT_RIGHT +#undef EFFECT_PAINT_BOTTOM +#undef EFFECT_PAINT_LEFT + START_TEST(mfmediaengine) { HRESULT hr; @@ -1357,6 +2133,7 @@ START_TEST(mfmediaengine) test_SetSourceFromByteStream(); test_audio_configuration(); test_TransferVideoFrame(); + test_video_effect();
IMFMediaEngineClassFactory_Release(factory);
diff --git a/dlls/mfmediaengine/tests/resource.rc b/dlls/mfmediaengine/tests/resource.rc index 50152586758..141418ac928 100644 --- a/dlls/mfmediaengine/tests/resource.rc +++ b/dlls/mfmediaengine/tests/resource.rc @@ -30,3 +30,7 @@ i420-64x64.avi RCDATA i420-64x64.avi /* Generated from running the tests on Windows */ /* @makedep: rgb32frame.bmp */ rgb32frame.bmp RCDATA rgb32frame.bmp + +/* Generated from running the tests on Windows */ +/* @makedep: rgb32frame_static_colors.bmp */ +rgb32frame_static_colors.bmp RCDATA rgb32frame_static_colors.bmp diff --git a/dlls/mfmediaengine/tests/rgb32frame_static_colors.bmp b/dlls/mfmediaengine/tests/rgb32frame_static_colors.bmp new file mode 100644 index 0000000000000000000000000000000000000000..71a38a5b80a6f67e8a039b9e7ff23a2d0fb861cf GIT binary patch literal 16438 zcmeI&u?@m75Cu@f9!Qi7fKo^4vjBV0qwJKOvc=&<G)(Y8dO>H=S$5t(u3(ynu^rFQ z*ITdgQ>S+A-}*Bi>-REOHRTQ%V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0S5lvz-z0Psz=rNo~^cBDpk{S?T4>uwaR^#W$Ayu=;ses?)0sk-}_J6-}mM}cLVY- z|MKtmKWQM>{mei5zy6=h{=T>T=Wam$<zN2Ie@O$m?q~kf|MmZ5_V>NzKX(K2FaPpy N{!1Fjb-&-3|K38dTF?Lh
literal 0 HcmV?d00001