Compare commits

..

42 Commits
v6.11 ... v6.15

Author SHA1 Message Date
Alistair Leslie-Hughes
4b6879f30f Release v6.15 2021-08-14 17:18:31 +10:00
Alistair Leslie-Hughes
94337e021c Rebase against 7f144646ffac6f3632d0c39b217dbd433c1154a0. 2021-08-14 15:52:01 +10:00
Alistair Leslie-Hughes
05c42b1df2 Rebase against 6b58d34a625ffaad181a7316009398f3c6444181. 2021-08-13 08:52:12 +10:00
Zebediah Figura
1bc4da9d59 Rebase against 91494ae6f2e47254d15a47e292ff569f3b400be6. 2021-08-11 22:25:44 -05:00
Alistair Leslie-Hughes
16476ce303 Updated mfplat-streaming-support patchset
Added a patch again to disable Function MFCreateDXGIDeviceManager.

This causes videos to render as a black screen.
Until support for the internal rendering flag SOURCE_READER_HAS_DEVICE_MANAGER is
better support through mf*, this patch will be here to stay.

Games affected.
Power Ranger: Battle for the Grid (Steam).
Oddworld: Soulstorm (Epic).
2021-08-11 09:37:19 +10:00
Alistair Leslie-Hughes
bdb9f49c3e Rebase against f63ecaedc72f3580e7016ba71a480025e4d86e99. 2021-08-11 09:04:37 +10:00
Alistair Leslie-Hughes
82118b0d67 Rebase against 3f2850aeaa159270384764843cdb1dc3cbe902c6. 2021-08-06 09:55:38 +10:00
Alistair Leslie-Hughes
00985bf311 Removed patchset ntdll-aarch-TEB
As request on bug.
2021-08-04 09:53:18 +10:00
Alistair Leslie-Hughes
3c8c7910e7 Rebase against ccbb0eef7bcaae672e9f7f69d3a9cdce62574177. 2021-08-04 09:18:47 +10:00
Alistair Leslie-Hughes
069adfd1b0 Release v6.14 2021-07-31 12:05:20 +10:00
Zebediah Figura
c91c63a5da ntdll-Junction_Points: Updates from Erich E. Hoover.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50770
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51438
2021-07-30 18:44:16 -05:00
Alistair Leslie-Hughes
f7c80250ec Rebase against 10fb33026f2a55209dea0fb00caa279610027a0f. 2021-07-30 09:10:58 +10:00
Alistair Leslie-Hughes
b059114710 Updated nvcuda-CUDA_Support patchset 2021-07-29 09:46:04 +10:00
Alistair Leslie-Hughes
f27610e7e7 Rebase against 5dffe2263de41e76100ba0acd7c717267dc4c878. 2021-07-29 09:00:26 +10:00
Alistair Leslie-Hughes
9da0fe04d3 Rebase against 04d52eb83fa5c37cfe1100f435e36c2f78918338. 2021-07-28 08:40:53 +10:00
Alistair Leslie-Hughes
dc38777093 Rebase against a5f787ac445a682ea7ced5dd78c3516d4b8b9311. 2021-07-24 10:32:46 +10:00
Alistair Leslie-Hughes
b57bf86ec0 Updated mfplat-streaming-support patchset 2021-07-23 12:30:40 +10:00
Zebediah Figura
4e99d1b2a8 Rebase against c518a5362b925379b1a79e8323d60e19863effc1. 2021-07-22 17:41:21 -05:00
Alistair Leslie-Hughes
8ad669e434 Rebase against 384fc71a480b48443a6a899cbf3470dbf4fe2214. 2021-07-22 09:17:36 +10:00
Alistair Leslie-Hughes
52dd338148 Release v6.13 2021-07-21 09:59:17 +10:00
Alistair Leslie-Hughes
f841424edd Rebase against feb088b2247e1722b848ac0d67483596d33758ba. 2021-07-21 08:53:44 +10:00
Alistair Leslie-Hughes
5e8fbbf200 Rebase against d60c450c7be196c2072f74e34f7760d39e3bad32. 2021-07-20 11:27:20 +10:00
Alistair Leslie-Hughes
183fd3e089 Updated winepulse-PulseAudio_Support patchset 2021-07-18 11:55:05 +10:00
Alistair Leslie-Hughes
092f3b1ed1 Rebase against 49cde0995827b24aa9c1ef1b6a0372797f4166e0. 2021-07-10 17:14:03 +10:00
Alistair Leslie-Hughes
e59eb7639a Rebase against 6763ed84cf0629dd7d1495263e1e3ea9aaf3d663. 2021-07-08 11:16:34 +10:00
Alistair Leslie-Hughes
a0716c9cfe Rebase against adffa11609093c3c21cf43970bbecda1b2c43eb1. 2021-07-07 12:21:45 +10:00
Alistair Leslie-Hughes
fcf7b80107 Rebase against 14f03e84d46dbd94ae2e3711687420f816dc784f. 2021-07-06 09:05:43 +10:00
Alistair Leslie-Hughes
163f74fe61 Updated ws2_32-connect-already-connected patchset 2021-07-03 22:22:11 +10:00
Alistair Leslie-Hughes
ce643e9d2a Release v6.12 2021-07-03 18:38:59 +10:00
Alistair Leslie-Hughes
f18cff9e7a Updated ws2_32-connect-already-connected patchset 2021-07-03 17:19:37 +10:00
Alistair Leslie-Hughes
f5fe9c0c89 Added winemac.drv-no-flicker-patch patchset 2021-07-02 13:11:39 +10:00
Alistair Leslie-Hughes
c6e832ee03 Added ws2_32-connect-already-connected patchset 2021-07-02 13:10:36 +10:00
Zebediah Figura
a7ae280480 Rebase against 52ba1b498a9694daf804c9aea99c788bb4e753a3. 2021-07-01 16:56:20 -05:00
Zebediah Figura
8988a92bee Rebase against 0ec555e58ea9d5b33f4c825e96965ad0cb15d00f. 2021-06-30 17:34:42 -05:00
Zebediah Figura
260734214e Rebase against 7f1623bc626d3ca2411c1a3088512d8ef461252b. 2021-06-29 18:39:35 -05:00
Zebediah Figura
1a3b158f0b Rebase against 362eed3ae30e17da64888407140334925499071c. 2021-06-28 21:09:56 -05:00
Alistair Leslie-Hughes
1af6d6980c Updated mfplat-streaming-support patchset 2021-06-28 15:12:28 +10:00
Zebediah Figura
1c9c21dc1c Rebase against 542175ab10420953920779f3c64eb310dd3aa258. 2021-06-26 12:20:36 -05:00
Alistair Leslie-Hughes
0dd44a250f Rebase against ad03df1222c2bb22e991641dcc0d9e4ed684158b. 2021-06-24 11:10:07 +10:00
Alistair Leslie-Hughes
9bf50b7e1f Updated mfplat-streaming-support patchset 2021-06-22 15:33:24 +10:00
Alistair Leslie-Hughes
9c8608eea6 Rebase against 5c756468656afc9207c0f51f774bbc29267e1469. 2021-06-22 09:06:59 +10:00
Zebediah Figura
fd5866f6f1 server-default_integrity: Remove the NOCLOBBER flag from EnableLUA.
Otherwise old prefixes will never get changed (cf. [1] for why this is a bad
thing). I don't think there's any reason the user should be manually modifying
this; in theory it's configurable but in practice there's no way to ask the
user to enter credentials.

[1] https://bugs.winehq.org/show_bug.cgi?id=40613#c39
2021-06-19 11:21:22 -05:00
184 changed files with 6321 additions and 9052 deletions

View File

@@ -1,4 +1,4 @@
From d94124650cd292dfdc364c43f117d35eecce39bf Mon Sep 17 00:00:00 2001
From 5be4173b6c3e89b1d9267679cd392a7343088a52 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 8 Jun 2021 09:10:37 +1000
Subject: [PATCH] ntdll: Avoid implicit cast of interface pointer.
@@ -8,27 +8,27 @@ Subject: [PATCH] ntdll: Avoid implicit cast of interface pointer.
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index b7531c1bdb7..97c5b741776 100644
index 34b332a613c..111c851b43b 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -3162,7 +3162,7 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
@@ -3016,7 +3016,7 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
{
- TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
+ TEB *teb = CONTAINING_RECORD( (GDI_TEB_BATCH *)thread_data, TEB, GdiTebBatch );
teb->TlsSlots[index] = 0;
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
@@ -3176,7 +3176,7 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
#ifdef _WIN64
WOW_TEB *wow_teb = get_wow_teb( teb );
if (wow_teb) wow_teb->TlsSlots[index] = 0;
@@ -3034,7 +3034,7 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
{
- TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
+ TEB *teb = CONTAINING_RECORD( (GDI_TEB_BATCH *)thread_data, TEB, GdiTebBatch );
if (teb->TlsExpansionSlots) teb->TlsExpansionSlots[index] = 0;
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
#ifdef _WIN64
WOW_TEB *wow_teb = get_wow_teb( teb );
if (wow_teb)
--
2.30.2

View File

@@ -1,15 +1,15 @@
From e51b05c3a9d03e4dd84a107a30841d95f8a519c3 Mon Sep 17 00:00:00 2001
From 916189d1cdf149f16867870121171e20f129da9f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 2 Oct 2014 19:44:31 +0200
Subject: [PATCH] ntdll: Print a warning message specifying the wine-staging
branch name and version.
---
dlls/ntdll/loader.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
dlls/ntdll/loader.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index ee453700e51..c2d4b3c2f86 100644
index 3339596944a..1d435f88755 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -44,6 +44,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
@@ -20,7 +20,7 @@ index ee453700e51..c2d4b3c2f86 100644
#ifdef _WIN64
#define DEFAULT_SECURITY_COOKIE_64 (((ULONGLONG)0x00002b99 << 32) | 0x2ddfa232)
@@ -3307,6 +3308,7 @@ void WINAPI LdrShutdownProcess(void)
@@ -3373,6 +3374,7 @@ void WINAPI LdrShutdownProcess(void)
process_detach();
}
@@ -28,7 +28,7 @@ index ee453700e51..c2d4b3c2f86 100644
/******************************************************************
* RtlExitUserProcess (NTDLL.@)
@@ -3673,6 +3675,9 @@ static void init_wow64(void)
@@ -3783,6 +3785,9 @@ static void init_wow64( CONTEXT *context )
*/
void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR unknown3, ULONG_PTR unknown4 )
{
@@ -38,9 +38,9 @@ index ee453700e51..c2d4b3c2f86 100644
static int attach_done;
int i;
NTSTATUS status;
@@ -3753,6 +3758,17 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
}
else wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
@@ -3869,6 +3874,16 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
#endif
+ RtlInitUnicodeString( &staging_event_string, L"\\__wine_staging_warn_event" );
+ InitializeObjectAttributes( &staging_event_attr, &staging_event_string, OBJ_OPENIF, NULL, NULL );
@@ -51,7 +51,6 @@ index ee453700e51..c2d4b3c2f86 100644
+ }
+ else
+ WARN_(winediag)("wine-staging %s is a testing version containing experimental patches.\n", wine_get_version());
+
+
RtlAcquirePebLock();
InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );

View File

@@ -1,92 +0,0 @@
From f0cfa1dc94330d07589e09ae5961956364adac4d Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Fri, 14 May 2021 15:51:55 -0500
Subject: [PATCH] wined3d: Implement
wined3d_deferred_context_update_sub_resource().
Needed by Wolcen: Lords of Mayhem.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/wined3d/cs.c | 37 +++++++++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 50a08334dab..e6f84134795 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -490,6 +490,7 @@ struct wined3d_cs_update_sub_resource
unsigned int sub_resource_idx;
struct wined3d_box box;
struct wined3d_sub_resource_data data;
+ /* If data.data is NULL, the structure is followed by the data in memory. */
};
struct wined3d_cs_add_dirty_texture_region
@@ -2597,6 +2598,7 @@ void wined3d_device_context_emit_blt_sub_resource(struct wined3d_device_context
static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_update_sub_resource *op = data;
+ const void *src_data = op->data.data ? op->data.data : (const BYTE *)(op + 1);
struct wined3d_resource *resource = op->resource;
const struct wined3d_box *box = &op->box;
unsigned int width, height, depth, level;
@@ -2617,7 +2619,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
goto done;
}
- wined3d_buffer_upload_data(buffer, context, box, op->data.data);
+ wined3d_buffer_upload_data(buffer, context, box, src_data);
wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
goto done;
}
@@ -2630,7 +2632,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
depth = wined3d_texture_get_level_depth(texture, level);
addr.buffer_object = 0;
- addr.addr = op->data.data;
+ addr.addr = src_data;
/* Only load the sub-resource for partial updates. */
if (!box->left && !box->top && !box->front
@@ -3375,8 +3377,35 @@ static void wined3d_deferred_context_update_sub_resource(struct wined3d_device_c
struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box,
const void *data, unsigned int row_pitch, unsigned int slice_pitch)
{
- FIXME("context %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, slice_pitch %u, stub!\n",
- context, resource, sub_resource_idx, debug_box(box), data, row_pitch, slice_pitch);
+ struct wined3d_cs_update_sub_resource *op;
+ size_t data_size;
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ data_size = box->right - box->left;
+ }
+ else
+ {
+ const struct wined3d_format *format = resource->format;
+
+ data_size = (box->back - box->front - 1) * slice_pitch
+ + ((box->bottom - box->top - 1) / format->block_height) * row_pitch
+ + ((box->right - box->left + format->block_width - 1) / format->block_width) * format->block_byte_count;
+ }
+
+ op = wined3d_device_context_require_space(context, sizeof(*op) + data_size, WINED3D_CS_QUEUE_DEFAULT);
+ op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE;
+ op->resource = resource;
+ op->sub_resource_idx = sub_resource_idx;
+ op->box = *box;
+ op->data.row_pitch = row_pitch;
+ op->data.slice_pitch = slice_pitch;
+ op->data.data = NULL;
+ memcpy(op + 1, data, data_size);
+
+ wined3d_device_context_acquire_resource(context, resource);
+
+ wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
}
static void wined3d_deferred_context_issue_query(struct wined3d_device_context *context,
--
2.30.2

View File

@@ -1,461 +0,0 @@
From cff68ab6407f62fa76e00d28532f741aa6498ad1 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Wed, 19 May 2021 19:00:56 -0500
Subject: [PATCH] wined3d: Implement wined3d_deferred_context_map().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/d3d11/tests/d3d11.c | 15 +---
dlls/wined3d/buffer.c | 14 ++++
dlls/wined3d/cs.c | 136 ++++++++++++++++++++++++++++++---
dlls/wined3d/resource.c | 29 +++----
dlls/wined3d/texture.c | 25 ++++++
dlls/wined3d/wined3d_private.h | 5 ++
6 files changed, 189 insertions(+), 35 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 408c0492cd2..a2fdc116e61 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -32735,21 +32735,14 @@ static void test_deferred_context_map(void)
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE, 0, &map_desc);
- todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map_desc);
- todo_wine ok(hr == D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD, "Got unexpected hr %#x.\n", hr);
+ ok(hr == D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc);
- todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- if (hr != S_OK)
- {
- ID3D11Buffer_Release(buffer2);
- ID3D11Buffer_Release(buffer);
- ID3D11DeviceContext_Release(deferred);
- release_test_context(&test_context);
- return;
- }
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
map_data = map_desc.pData;
/* The previous contents of map_data are undefined and may in practice be
* uninitialized garbage. */
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 12d038c0120..12b90cb54c2 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -826,6 +826,19 @@ struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffe
return &buffer->resource;
}
+static HRESULT buffer_resource_sub_resource_get_size(struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, unsigned int *size, unsigned int *row_pitch, unsigned int *slice_pitch)
+{
+ if (sub_resource_idx)
+ {
+ WARN("Invalid sub_resource_idx %u.\n", sub_resource_idx);
+ return E_INVALIDARG;
+ }
+
+ *size = *row_pitch = *slice_pitch = resource->size;
+ return S_OK;
+}
+
static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, uint32_t flags)
{
@@ -1084,6 +1097,7 @@ static const struct wined3d_resource_ops buffer_resource_ops =
buffer_resource_decref,
buffer_resource_preload,
buffer_resource_unload,
+ buffer_resource_sub_resource_get_size,
buffer_resource_sub_resource_map,
buffer_resource_sub_resource_unmap,
};
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index e6f84134795..1f7213232fa 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -26,6 +26,13 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
#define WINED3D_INITIAL_CS_SIZE 4096
+struct wined3d_acquired_resource
+{
+ struct wined3d_resource *resource;
+ unsigned int sub_resource_idx;
+ void *sysmem;
+};
+
struct wined3d_command_list
{
LONG refcount;
@@ -36,7 +43,7 @@ struct wined3d_command_list
void *data;
SIZE_T resource_count;
- struct wined3d_resource **resources;
+ struct wined3d_acquired_resource *resources;
/* List of command lists queued for execution on this command list. We might
* be the only thing holding a pointer to another command list, so we need
@@ -48,9 +55,13 @@ struct wined3d_command_list
static void wined3d_command_list_destroy_object(void *object)
{
struct wined3d_command_list *list = object;
+ SIZE_T i;
TRACE("list %p.\n", list);
+ for (i = 0; i < list->resource_count; ++i)
+ wined3d_free_sysmem(list->resources[i].sysmem);
+
heap_free(list->resources);
heap_free(list->data);
heap_free(list);
@@ -79,7 +90,7 @@ ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list)
for (i = 0; i < list->command_list_count; ++i)
wined3d_command_list_decref(list->command_lists[i]);
for (i = 0; i < list->resource_count; ++i)
- wined3d_resource_decref(list->resources[i]);
+ wined3d_resource_decref(list->resources[i].resource);
wined3d_cs_destroy_object(device->cs, wined3d_command_list_destroy_object, list);
}
@@ -139,6 +150,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_COPY_UAV_COUNTER,
WINED3D_CS_OP_GENERATE_MIPMAPS,
WINED3D_CS_OP_EXECUTE_COMMAND_LIST,
+ WINED3D_CS_OP_UPLOAD_SUB_RESOURCE,
WINED3D_CS_OP_STOP,
};
@@ -469,6 +481,15 @@ struct wined3d_cs_unmap
HRESULT *hr;
};
+struct wined3d_cs_upload_sub_resource
+{
+ enum wined3d_cs_op opcode;
+ struct wined3d_resource *resource;
+ unsigned int sub_resource_idx;
+ unsigned int size;
+ const void *data;
+};
+
struct wined3d_cs_blt_sub_resource
{
enum wined3d_cs_op opcode;
@@ -616,6 +637,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op)
WINED3D_TO_STR(WINED3D_CS_OP_COPY_UAV_COUNTER);
WINED3D_TO_STR(WINED3D_CS_OP_GENERATE_MIPMAPS);
WINED3D_TO_STR(WINED3D_CS_OP_EXECUTE_COMMAND_LIST);
+ WINED3D_TO_STR(WINED3D_CS_OP_UPLOAD_SUB_RESOURCE);
WINED3D_TO_STR(WINED3D_CS_OP_STOP);
#undef WINED3D_TO_STR
}
@@ -2342,7 +2364,7 @@ static void wined3d_cs_execute_command_list(struct wined3d_device_context *conte
op->list = list;
for (i = 0; i < list->resource_count; ++i)
- wined3d_resource_acquire(list->resources[i]);
+ wined3d_resource_acquire(list->resources[i].resource);
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
@@ -2463,6 +2485,28 @@ static HRESULT wined3d_cs_unmap(struct wined3d_device_context *context, struct w
return hr;
}
+static void wined3d_cs_exec_upload_sub_resource(struct wined3d_cs *cs, const void *data)
+{
+ const struct wined3d_cs_upload_sub_resource *op = data;
+ struct wined3d_resource *resource = op->resource;
+ unsigned int sub_resource_idx = op->sub_resource_idx;
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ if (FAILED(hr = resource->resource_ops->resource_sub_resource_map(resource,
+ sub_resource_idx, &map_desc, NULL, WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD)))
+ {
+ ERR("Failed to map resource, hr %#x.\n", hr);
+ return;
+ }
+
+ memcpy(map_desc.data, op->data, op->size);
+
+ resource->resource_ops->resource_sub_resource_unmap(resource, sub_resource_idx);
+
+ wined3d_resource_release(resource);
+}
+
static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_blt_sub_resource *op = data;
@@ -2870,6 +2914,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter,
/* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps,
/* WINED3D_CS_OP_EXECUTE_COMMAND_LIST */ wined3d_cs_exec_execute_command_list,
+ /* WINED3D_CS_OP_UPLOAD_SUB_RESOURCE */ wined3d_cs_exec_upload_sub_resource,
};
static void wined3d_cs_exec_execute_command_list(struct wined3d_cs *cs, const void *data)
@@ -3301,7 +3346,7 @@ struct wined3d_deferred_context
void *data;
SIZE_T resource_count, resources_capacity;
- struct wined3d_resource **resources;
+ struct wined3d_acquired_resource *resources;
/* List of command lists queued for execution on this context. A command
* list can be the only thing holding a pointer to another command list, so
@@ -3361,16 +3406,78 @@ static HRESULT wined3d_deferred_context_map(struct wined3d_device_context *conte
struct wined3d_resource *resource, unsigned int sub_resource_idx,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags)
{
- FIXME("context %p, resource %p, sub_resource_idx %u, map_desc %p, box %p, flags %#x, stub!\n",
- context, resource, sub_resource_idx, map_desc, box, flags);
- return E_NOTIMPL;
+ struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context);
+ struct wined3d_acquired_resource *acquired_resource;
+ unsigned int size;
+ HRESULT hr;
+
+ if (box)
+ {
+ ERR("Unexpected box.\n");
+ return E_INVALIDARG;
+ }
+
+ if (FAILED(hr = resource->resource_ops->resource_sub_resource_get_size(resource,
+ sub_resource_idx, &size, &map_desc->row_pitch, &map_desc->slice_pitch)))
+ return E_INVALIDARG;
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ struct wined3d_cs_upload_sub_resource *op;
+ void *sysmem;
+
+ if (!(sysmem = wined3d_allocate_sysmem(size)))
+ return E_OUTOFMEMORY;
+
+ if (!wined3d_array_reserve((void **)&deferred->resources, &deferred->resources_capacity,
+ deferred->resource_count + 1, sizeof(*deferred->resources)))
+ return E_OUTOFMEMORY;
+
+ acquired_resource = &deferred->resources[deferred->resource_count++];
+ acquired_resource->resource = resource;
+ wined3d_resource_incref(resource);
+ acquired_resource->sub_resource_idx = sub_resource_idx;
+ acquired_resource->sysmem = sysmem;
+
+ op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+ op->opcode = WINED3D_CS_OP_UPLOAD_SUB_RESOURCE;
+ op->resource = resource;
+ op->sub_resource_idx = sub_resource_idx;
+ op->size = size;
+ op->data = sysmem;
+
+ map_desc->data = sysmem;
+ return S_OK;
+ }
+ else if (flags & WINED3D_MAP_NOOVERWRITE)
+ {
+ int i = deferred->resource_count;
+
+ while (i--)
+ {
+ acquired_resource = &deferred->resources[i];
+
+ if (acquired_resource->resource == resource
+ && acquired_resource->sub_resource_idx == sub_resource_idx && acquired_resource->sysmem)
+ {
+ map_desc->data = acquired_resource->sysmem;
+ return S_OK;
+ }
+ }
+
+ return D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD;
+ }
+ else
+ {
+ WARN("Invalid flags %#x, returning E_INVALIDARG.\n", flags);
+ return E_INVALIDARG;
+ }
}
static HRESULT wined3d_deferred_context_unmap(struct wined3d_device_context *context,
struct wined3d_resource *resource, unsigned int sub_resource_idx)
{
- FIXME("context %p, resource %p, sub_resource_idx %u, stub!\n", context, resource, sub_resource_idx);
- return E_NOTIMPL;
+ return S_OK;
}
static void wined3d_deferred_context_update_sub_resource(struct wined3d_device_context *context,
@@ -3423,13 +3530,17 @@ static void wined3d_deferred_context_acquire_resource(struct wined3d_device_cont
struct wined3d_resource *resource)
{
struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context);
+ struct wined3d_acquired_resource *acquired_resource;
if (!wined3d_array_reserve((void **)&deferred->resources, &deferred->resources_capacity,
deferred->resource_count + 1, sizeof(*deferred->resources)))
return;
- deferred->resources[deferred->resource_count++] = resource;
+ acquired_resource = &deferred->resources[deferred->resource_count++];
+ acquired_resource->resource = resource;
wined3d_resource_incref(resource);
+ acquired_resource->sub_resource_idx = 0;
+ acquired_resource->sysmem = NULL;
}
static void wined3d_deferred_context_execute_command_list(struct wined3d_device_context *context,
@@ -3504,7 +3615,10 @@ void CDECL wined3d_deferred_context_destroy(struct wined3d_device_context *conte
TRACE("context %p.\n", context);
for (i = 0; i < deferred->resource_count; ++i)
- wined3d_resource_decref(deferred->resources[i]);
+ {
+ wined3d_resource_decref(deferred->resources[i].resource);
+ wined3d_free_sysmem(deferred->resources[i].sysmem);
+ }
heap_free(deferred->resources);
wined3d_state_destroy(deferred->c.state);
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 58e3e5c77fd..42e45a2745c 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -334,24 +334,32 @@ void CDECL wined3d_resource_preload(struct wined3d_resource *resource)
wined3d_cs_emit_preload_resource(resource->device->cs, resource);
}
-static BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource)
+void *wined3d_allocate_sysmem(SIZE_T size)
{
void **p;
- SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
+ static const SIZE_T align = RESOURCE_ALIGNMENT - 1 + sizeof(*p);
void *mem;
- if (!(mem = heap_alloc_zero(resource->size + align)))
+ if (!(mem = heap_alloc_zero(size + align)))
{
ERR("Failed to allocate system memory.\n");
- return FALSE;
+ return NULL;
}
p = (void **)(((ULONG_PTR)mem + align) & ~(RESOURCE_ALIGNMENT - 1)) - 1;
*p = mem;
- resource->heap_memory = ++p;
+ return ++p;
+}
- return TRUE;
+void wined3d_free_sysmem(void *mem)
+{
+ void **p = mem;
+
+ if (!p)
+ return;
+
+ heap_free(*(--p));
}
BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource)
@@ -359,17 +367,12 @@ BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource)
if (resource->heap_memory)
return TRUE;
- return wined3d_resource_allocate_sysmem(resource);
+ return !!(resource->heap_memory = wined3d_allocate_sysmem(resource->size));
}
void wined3d_resource_free_sysmem(struct wined3d_resource *resource)
{
- void **p = resource->heap_memory;
-
- if (!p)
- return;
-
- heap_free(*(--p));
+ wined3d_free_sysmem(resource->heap_memory);
resource->heap_memory = NULL;
}
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index c7a9b4da3e1..663503bdf39 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3506,6 +3506,30 @@ static void texture_resource_unload(struct wined3d_resource *resource)
resource_unload(&texture->resource);
}
+static HRESULT texture_resource_sub_resource_get_size(struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, unsigned int *size, unsigned int *row_pitch, unsigned int *slice_pitch)
+{
+ struct wined3d_texture *texture = texture_from_resource(resource);
+ unsigned int texture_level = sub_resource_idx % texture->level_count;
+ struct wined3d_texture_sub_resource *sub_resource;
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
+ return E_INVALIDARG;
+
+ if (resource->format_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
+ {
+ *row_pitch = wined3d_texture_get_level_width(texture, texture_level) * resource->format->byte_count;
+ *slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * (*row_pitch);
+ }
+ else
+ {
+ wined3d_texture_get_pitch(texture, texture_level, row_pitch, slice_pitch);
+ }
+
+ *size = sub_resource->size;
+ return S_OK;
+}
+
static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
{
@@ -3692,6 +3716,7 @@ static const struct wined3d_resource_ops texture_resource_ops =
texture_resource_decref,
texture_resource_preload,
texture_resource_unload,
+ texture_resource_sub_resource_get_size,
texture_resource_sub_resource_map,
texture_resource_sub_resource_unmap,
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8e3efccffc2..db6e1619e8f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4048,6 +4048,8 @@ struct wined3d_resource_ops
ULONG (*resource_decref)(struct wined3d_resource *resource);
void (*resource_preload)(struct wined3d_resource *resource);
void (*resource_unload)(struct wined3d_resource *resource);
+ HRESULT (*resource_sub_resource_get_size)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
+ unsigned int *size, unsigned int *row_pitch, unsigned int *slice_pitch);
HRESULT (*resource_sub_resource_map)(struct wined3d_resource *resource, unsigned int sub_resource_idx,
struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
HRESULT (*resource_sub_resource_unmap)(struct wined3d_resource *resource, unsigned int sub_resource_idx);
@@ -4131,6 +4133,9 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DEC
#define RESOURCE_ALIGNMENT 16
#define WINED3D_CONSTANT_BUFFER_ALIGNMENT 16
+void *wined3d_allocate_sysmem(SIZE_T size) DECLSPEC_HIDDEN;
+void wined3d_free_sysmem(void *mem) DECLSPEC_HIDDEN;
+
#define WINED3D_LOCATION_DISCARDED 0x00000001
#define WINED3D_LOCATION_SYSMEM 0x00000002
#define WINED3D_LOCATION_BUFFER 0x00000008
--
2.30.2

View File

@@ -1,3 +0,0 @@
Fixes: [42191] Multiple games require d3d11 deferred contexts (Diablo 3, Dark Souls 3, The Evil Within, Elex, Alien: Isolation, Assassin's Creed III)
Fixes: [43743] No 3D graphics in Wolcen: Lords of Mayhem
Fixes: [41636] Multiple DirectX 11 games need ID3D11Device1::CreateDeferredContext1 implementation (WWE 2K15, Dishonored: Death of the Outsider, Pro Evolution Soccer 2019, Shantae and the Pirate's Curse, Space Engineers)

View File

@@ -1,4 +1,4 @@
From 70c7589e029a19a3b048cdf5c222fb36e489ba69 Mon Sep 17 00:00:00 2001
From 4af235c5bc5797cae39578991b302b47052afcbb Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 14:40:43 -0500
Subject: [PATCH] ntdll, server: Implement NtCreateEvent().
@@ -77,12 +77,12 @@ index 87516e7597a..d9c7df967f8 100644
BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 1abc691811b..de4c75afcea 100644
index f5be91e09d4..b54874b5d3d 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -435,6 +435,10 @@ NTSTATUS WINAPI NtCreateEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_
struct object_attributes *objattr;
@@ -440,6 +440,10 @@ NTSTATUS WINAPI NtCreateEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_
*handle = 0;
if (type != NotificationEvent && type != SynchronizationEvent) return STATUS_INVALID_PARAMETER;
+
+ if (do_esync())
@@ -92,7 +92,7 @@ index 1abc691811b..de4c75afcea 100644
SERVER_START_REQ( create_event )
diff --git a/server/esync.c b/server/esync.c
index 226e70cd1ad..b9e0a455629 100644
index e41bbbf9349..f89f29150ea 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -203,6 +203,13 @@ struct semaphore
@@ -125,5 +125,5 @@ index 226e70cd1ad..b9e0a455629 100644
assert( 0 );
}
--
2.29.2
2.30.2

View File

@@ -1,4 +1,4 @@
From 8770d44fb2cdaf01cfd74321712b3b63a2906e31 Mon Sep 17 00:00:00 2001
From 1496c3a96452deeb4ca687bc61e2125bc82fff71 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 16:34:56 -0500
Subject: [PATCH] ntdll, server: Implement NtCreateMutant().
@@ -6,9 +6,9 @@ Subject: [PATCH] ntdll, server: Implement NtCreateMutant().
---
dlls/ntdll/unix/esync.c | 16 ++++++++++++++++
dlls/ntdll/unix/esync.h | 3 +++
dlls/ntdll/unix/sync.c | 3 +++
dlls/ntdll/unix/sync.c | 4 ++++
server/esync.c | 14 ++++++++++++++
4 files changed, 36 insertions(+)
4 files changed, 37 insertions(+)
diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c
index 88490e08ef9..df9eb2696a1 100644
@@ -59,13 +59,14 @@ index 8480a213b2a..38ebefc9eed 100644
BOOLEAN alertable, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 1d2e831964f..56292db271a 100644
index 47ab533d5c7..7e492320cee 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -597,6 +597,9 @@ NTSTATUS WINAPI NtCreateMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT
data_size_t len;
@@ -608,6 +608,10 @@ NTSTATUS WINAPI NtCreateMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT
struct object_attributes *objattr;
*handle = 0;
+
+ if (do_esync())
+ return esync_create_mutex( handle, access, attr, owned );
+
@@ -73,7 +74,7 @@ index 1d2e831964f..56292db271a 100644
SERVER_START_REQ( create_mutex )
diff --git a/server/esync.c b/server/esync.c
index ddee22432e5..12911fccb6a 100644
index ac59779a454..913104e3dd4 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -204,6 +204,13 @@ struct semaphore
@@ -105,5 +106,5 @@ index ddee22432e5..12911fccb6a 100644
assert( 0 );
}
--
2.28.0
2.30.2

View File

@@ -1,4 +1,4 @@
From a934f314a164256748e2e9764343504f7cf8050b Mon Sep 17 00:00:00 2001
From 7f04be3dd881287f1a74b7fe5829fa5917afa054 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 16:56:09 -0500
Subject: [PATCH] ntdll: Implement NtOpenSemaphore().
@@ -6,10 +6,10 @@ Subject: [PATCH] ntdll: Implement NtOpenSemaphore().
---
dlls/ntdll/unix/esync.c | 47 +++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/esync.h | 2 ++
dlls/ntdll/unix/sync.c | 3 +++
dlls/ntdll/unix/sync.c | 4 ++++
server/esync.c | 31 +++++++++++++++++++++++++++
server/protocol.def | 12 +++++++++++
5 files changed, 95 insertions(+)
5 files changed, 96 insertions(+)
diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c
index 6d8653cd107..8e7e50ce777 100644
@@ -90,13 +90,14 @@ index bee08ff857f..2738e8b7f87 100644
extern NTSTATUS esync_create_event( HANDLE *handle, ACCESS_MASK access,
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 64f96a32ccf..35f2ac95d36 100644
index a51462abeac..36322f6afb6 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -349,6 +349,9 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC
{
@@ -353,6 +353,10 @@ NTSTATUS WINAPI NtOpenSemaphore( HANDLE *handle, ACCESS_MASK access, const OBJEC
NTSTATUS ret;
*handle = 0;
+
+ if (do_esync())
+ return esync_open_semaphore( handle, access, attr );
+
@@ -104,7 +105,7 @@ index 64f96a32ccf..35f2ac95d36 100644
SERVER_START_REQ( open_semaphore )
diff --git a/server/esync.c b/server/esync.c
index 12911fccb6a..1703608263f 100644
index 913104e3dd4..da97c6c140b 100644
--- a/server/esync.c
+++ b/server/esync.c
@@ -412,6 +412,37 @@ DECL_HANDLER(create_esync)
@@ -146,10 +147,10 @@ index 12911fccb6a..1703608263f 100644
* server. The client should only read from (i.e. wait on) this object. */
DECL_HANDLER(get_esync_fd)
diff --git a/server/protocol.def b/server/protocol.def
index 789bc56e7f1..5b8f66ffd80 100644
index 776d3d72dc2..575cf291bb0 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3690,6 +3690,18 @@ enum esync_type
@@ -3750,6 +3750,18 @@ enum esync_type
unsigned int shm_idx;
@END
@@ -169,5 +170,5 @@ index 789bc56e7f1..5b8f66ffd80 100644
@REQ(get_esync_fd)
obj_handle_t handle; /* handle to the object */
--
2.28.0
2.30.2

View File

@@ -1,4 +1,4 @@
From 9898e1c47bdba4bda336b9c17a20d34d68e66215 Mon Sep 17 00:00:00 2001
From 96393a0cd6acfcb87d11488e726d4e294e646c4f Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 16:58:19 -0500
Subject: [PATCH] ntdll: Implement NtOpenEvent().
@@ -42,11 +42,11 @@ index 2738e8b7f87..da1b72d4413 100644
extern NTSTATUS esync_set_event( HANDLE handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 35f2ac95d36..9296b172f88 100644
index 36322f6afb6..6bc8200f46b 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -467,6 +467,9 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT
@@ -476,6 +476,9 @@ NTSTATUS WINAPI NtOpenEvent( HANDLE *handle, ACCESS_MASK access, const OBJECT_AT
*handle = 0;
if ((ret = validate_open_object_attributes( attr ))) return ret;
+ if (do_esync())
@@ -56,5 +56,5 @@ index 35f2ac95d36..9296b172f88 100644
{
req->access = access;
--
2.28.0
2.30.2

View File

@@ -1,4 +1,4 @@
From 7f91f35e896ffb63409c1d1a619565f35a65ef7f Mon Sep 17 00:00:00 2001
From 995f2ecab37c47bb3112d11ce2313d37711965ca Mon Sep 17 00:00:00 2001
From: Zebediah Figura <zfigura@codeweavers.com>
Date: Mon, 6 Jul 2020 16:59:35 -0500
Subject: [PATCH] ntdll: Implement NtOpenMutant().
@@ -42,11 +42,11 @@ index da1b72d4413..cb48e2cd022 100644
extern NTSTATUS esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
index 9296b172f88..4a97cdd32fd 100644
index 6bc8200f46b..c1c57caab40 100644
--- a/dlls/ntdll/unix/sync.c
+++ b/dlls/ntdll/unix/sync.c
@@ -632,6 +632,9 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A
@@ -646,6 +646,9 @@ NTSTATUS WINAPI NtOpenMutant( HANDLE *handle, ACCESS_MASK access, const OBJECT_A
*handle = 0;
if ((ret = validate_open_object_attributes( attr ))) return ret;
+ if (do_esync())
@@ -56,5 +56,5 @@ index 9296b172f88..4a97cdd32fd 100644
{
req->access = access;
--
2.28.0
2.30.2

View File

@@ -1,4 +1,4 @@
From 8a91b7a88d96f735f7236afeed90c376a18f0eea Mon Sep 17 00:00:00 2001
From b4010603ae2bab3a4fdc8b57efaebe47254eb168 Mon Sep 17 00:00:00 2001
From: Daniel Wendt <daniel.wendt@linux.com>
Date: Fri, 15 Nov 2013 12:52:37 +0100
Subject: [PATCH] gdi32: fix for rotated Arc, ArcTo, Chord and Pie drawing
@@ -6,15 +6,15 @@ Subject: [PATCH] gdi32: fix for rotated Arc, ArcTo, Chord and Pie drawing
Wine-Bug: http://bugs.winehq.org/show_bug.cgi?id=34579
---
dlls/gdi32/dibdrv/graphics.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
dlls/gdi32/dibdrv/graphics.c | 80 ++++++++++++++++++++++++++++++++++++
dlls/gdi32/gdi_private.h | 3 ++
2 files changed, 83 insertions(+)
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 7d71fbb..d269cc1 100644
index c6f11ae6a69..e4a5f7bab8b 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -313,6 +313,60 @@ static int get_arc_points( int arc_dir, const RECT *rect, POINT start, POINT end
@@ -312,6 +312,60 @@ static int get_arc_points( int arc_dir, const RECT *rect, POINT start, POINT end
return pos - count;
}
@@ -75,7 +75,7 @@ index 7d71fbb..d269cc1 100644
/* backend for arc functions; extra_lines is -1 for ArcTo, 0 for Arc, 1 for Chord, 2 for Pie */
static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT start_x, INT start_y, INT end_x, INT end_y, INT extra_lines )
@@ -325,6 +379,22 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -324,6 +378,22 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
BOOL ret = TRUE;
HRGN outline = 0, interior = 0;
@@ -98,7 +98,7 @@ index 7d71fbb..d269cc1 100644
if (!get_pen_device_rect( dc, pdev, &rect, left, top, right, bottom )) return TRUE;
width = rect.right - rect.left;
@@ -358,6 +428,16 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -357,6 +427,16 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
points[count].y = rect.top + height / 2;
count++;
}
@@ -116,17 +116,17 @@ index 7d71fbb..d269cc1 100644
{
HeapFree( GetProcessHeap(), 0, points );
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 920cd1e..4949187 100644
index 6d23e7e0ecc..e8e08d00b81 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -608,4 +608,7 @@ extern void free_heap_bits( struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
extern HMODULE gdi32_module DECLSPEC_HIDDEN;
@@ -208,4 +208,7 @@ extern BOOL EMFDC_StretchDIBits( DC_ATTR *dc_attr, INT x_dst, INT y_dst, INT wid
INT height_src, const void *bits, const BITMAPINFO *info,
UINT coloruse, DWORD rop ) DECLSPEC_HIDDEN;
+BOOL xform_has_rotate_and_uniform_scale_and_shear( const XFORM *xform ) DECLSPEC_HIDDEN;
+BOOL xform_decompose_rotation_and_translation( XFORM *xform, XFORM *rotation_and_translation ) DECLSPEC_HIDDEN;
+
#endif /* __WINE_GDI_PRIVATE_H */
--
1.9.1
2.30.2

View File

@@ -1,18 +1,18 @@
From b278711b2c76680e6e26a114f74d7f7c26ff6328 Mon Sep 17 00:00:00 2001
From 6ccddc7e2faf2dbde5f20d983e3f64e0cb8e2821 Mon Sep 17 00:00:00 2001
From: Daniel Wendt <daniel.wendt@linux.com>
Date: Tue, 10 Dec 2013 14:55:32 +0100
Subject: [PATCH] gdi32: fix for rotated ellipse
Bug: http://bugs.winehq.org/show_bug.cgi?id=35331
---
dlls/gdi32/dibdrv/graphics.c | 60 +++++++++++++++++++++++++++++++-------------
dlls/gdi32/dibdrv/graphics.c | 60 +++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 18 deletions(-)
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index d269cc1..447aab5 100644
index 5d246eea07f..2b33233dee9 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -1555,6 +1555,23 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -1534,6 +1534,23 @@ BOOL CDECL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bott
BOOL ret = TRUE;
HRGN outline = 0, interior = 0;
@@ -36,13 +36,13 @@ index d269cc1..447aab5 100644
if (!get_pen_device_rect( dc, pdev, &rect, left, top, right, bottom )) return TRUE;
pt[0].x = pt[0].y = 0;
@@ -1575,23 +1592,6 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
@@ -1554,23 +1571,6 @@ BOOL CDECL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bott
return FALSE;
}
- if (pdev->brush.style != BS_NULL &&
- !(interior = CreateRoundRectRgn( rect.left, rect.top, rect.right + 1, rect.bottom + 1,
- ellipse_width, ellipse_height )))
- !(interior = NtGdiCreateRoundRectRgn( rect.left, rect.top, rect.right + 1, rect.bottom + 1,
- ellipse_width, ellipse_height )))
- {
- HeapFree( GetProcessHeap(), 0, points );
- if (outline) DeleteObject( outline );
@@ -59,8 +59,8 @@ index d269cc1..447aab5 100644
-
count = ellipse_first_quadrant( ellipse_width, ellipse_height, points );
if (dc->ArcDirection == AD_CLOCKWISE)
@@ -1635,13 +1635,37 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
if (dc->attr->arc_direction == AD_CLOCKWISE)
@@ -1614,13 +1614,37 @@ BOOL CDECL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bott
}
count = end + 1;
@@ -95,10 +95,10 @@ index d269cc1..447aab5 100644
if (interior)
{
- CombineRgn( interior, interior, outline, RGN_DIFF );
- NtGdiCombineRgn( interior, interior, outline, RGN_DIFF );
ret = brush_region( pdev, interior );
DeleteObject( interior );
}
--
1.9.1
2.30.2

View File

@@ -1,3 +1,2 @@
Fixes: [22692] Add support for CopyFileEx progress callback
Fixes: [22690] Allow to cancel a file operation via progress callback
Depends: ntdll-FileDispositionInformation

View File

@@ -0,0 +1,90 @@
From 1adbc46410773bdd75d844280738be677bb75906 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Tue, 9 Mar 2021 16:53:09 -0500
Subject: [PATCH] winegstreamer: Activate source pad in push mode if it isn't
activated in pull mode.
Since our source pad is not part of any element, gstreamer won't end up activating it
directly through the state transition. Instead, if the downstream element doesn't
activate the source pad into pull mode during the transition to the READY state,
we activate our pad in push mode.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/wg_parser.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index cd12a23d0c8..9b4c9c1c9ed 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -61,7 +61,7 @@ struct wg_parser
pthread_mutex_t mutex;
pthread_cond_t init_cond;
- bool no_more_pads, has_duration, error;
+ bool no_more_pads, has_duration, error, pull_mode;
pthread_cond_t read_cond, read_done_cond;
struct
@@ -1358,9 +1358,12 @@ static gboolean src_activate_mode_cb(GstPad *pad, GstObject *parent, GstPadMode
GST_DEBUG("%s source pad for parser %p in %s mode.",
activate ? "Activating" : "Deactivating", parser, gst_pad_mode_get_name(mode));
+ parser->pull_mode = false;
+
switch (mode)
{
case GST_PAD_MODE_PULL:
+ parser->pull_mode = activate;
return TRUE;
case GST_PAD_MODE_PUSH:
return activate_push(pad, activate);
@@ -1636,6 +1639,8 @@ static void CDECL wg_parser_disconnect(struct wg_parser *parser)
pthread_mutex_unlock(&parser->mutex);
gst_element_set_state(parser->container, GST_STATE_NULL);
+ if (!parser->pull_mode)
+ gst_pad_set_active(parser->my_src, 0);
gst_pad_unlink(parser->my_src, parser->their_sink);
gst_object_unref(parser->my_src);
gst_object_unref(parser->their_sink);
@@ -1687,6 +1692,8 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser)
}
gst_element_set_state(parser->container, GST_STATE_PAUSED);
+ if (!parser->pull_mode)
+ gst_pad_set_active(parser->my_src, 1);
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
if (ret == GST_STATE_CHANGE_FAILURE)
{
@@ -1734,6 +1741,8 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser)
}
gst_element_set_state(parser->container, GST_STATE_PAUSED);
+ if (!parser->pull_mode)
+ gst_pad_set_active(parser->my_src, 1);
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
if (ret == GST_STATE_CHANGE_FAILURE)
{
@@ -1784,6 +1793,8 @@ static BOOL mpeg_audio_parser_init_gst(struct wg_parser *parser)
gst_pad_set_active(stream->my_sink, 1);
gst_element_set_state(parser->container, GST_STATE_PAUSED);
+ if (!parser->pull_mode)
+ gst_pad_set_active(parser->my_src, 1);
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
if (ret == GST_STATE_CHANGE_FAILURE)
{
@@ -1825,6 +1836,8 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser)
gst_pad_set_active(stream->my_sink, 1);
gst_element_set_state(parser->container, GST_STATE_PAUSED);
+ if (!parser->pull_mode)
+ gst_pad_set_active(parser->my_src, 1);
ret = gst_element_get_state(parser->container, NULL, NULL, -1);
if (ret == GST_STATE_CHANGE_FAILURE)
{
--
2.30.2

View File

@@ -0,0 +1,60 @@
From 2740496b0c1f878593899e6dc88390413bf835f1 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 10 Mar 2021 10:43:03 -0500
Subject: [PATCH] winegstreamer: Push stream-start and segment events in push
mode.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/wg_parser.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 9b4c9c1c9ed..879aece63b7 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1279,6 +1279,7 @@ static void *push_data(void *arg)
{
struct wg_parser *parser = arg;
GstBuffer *buffer;
+ GstSegment *segment;
guint max_size;
GST_DEBUG("Starting push thread.");
@@ -1291,6 +1292,12 @@ static void *push_data(void *arg)
max_size = parser->stop_offset ? parser->stop_offset : parser->file_size;
+ gst_pad_push_event(parser->my_src, gst_event_new_stream_start("wg_stream"));
+
+ segment = gst_segment_new();
+ gst_segment_init(segment, GST_FORMAT_BYTES);
+ gst_pad_push_event(parser->my_src, gst_event_new_segment(segment));
+
for (;;)
{
ULONG size;
@@ -1425,6 +1432,7 @@ static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event)
GstEvent *flush_event;
GstSeekFlags flags;
gint64 cur, stop;
+ GstSegment *seg;
guint32 seqnum;
gdouble rate;
@@ -1458,7 +1466,12 @@ static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event)
gst_event_set_seqnum(flush_event, seqnum);
gst_pad_push_event(parser->my_src, flush_event);
if (thread)
+ {
gst_pad_set_active(parser->my_src, 1);
+ seg = gst_segment_new();
+ gst_segment_init(seg, GST_FORMAT_BYTES);
+ gst_pad_push_event(parser->my_src, gst_event_new_segment(seg));
+ }
}
return TRUE;
--
2.30.2

View File

@@ -1,407 +0,0 @@
From: Derek Lesho <dlesho@codeweavers.com>
Subject: [PATCH resend 3/5] winegstreamer: Implement ::Process(Input/Output) for audio conversion transform.
Message-Id: <20210118193047.267366-3-dlesho@codeweavers.com>
Date: Mon, 18 Jan 2021 14:30:45 -0500
In-Reply-To: <20210118193047.267366-1-dlesho@codeweavers.com>
References: <20210118193047.267366-1-dlesho@codeweavers.com>
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/audioconvert.c | 188 ++++++++++++++++++++++++++++--
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 69 +++++++++++
3 files changed, 250 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 85f44dd8856..e16fc6f1a78 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -40,6 +40,8 @@ struct audio_converter
IMFMediaType *input_type;
IMFMediaType *output_type;
CRITICAL_SECTION cs;
+ BOOL inflight;
+ GstElement *container, *appsrc, *appsink;
};
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
@@ -85,6 +87,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
{
transform->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&transform->cs);
+ gst_object_unref(transform->container);
heap_free(transform);
}
@@ -295,6 +298,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->input_type)
{
IMFMediaType_Release(converter->input_type);
@@ -326,14 +332,17 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
if (!(input_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(input_caps);
-
if (flags & MFT_SET_TYPE_TEST_ONLY)
+ {
+ gst_caps_unref(input_caps);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->input_type)
hr = MFCreateMediaType(&converter->input_type);
@@ -341,12 +350,18 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
+ gst_caps_unref(input_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->input_type);
converter->input_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -375,6 +390,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->output_type)
{
IMFMediaType_Release(converter->output_type);
@@ -406,14 +424,17 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
if (!(output_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(output_caps);
-
if (flags & MFT_SET_TYPE_TEST_ONLY)
+ {
+ gst_caps_unref(output_caps);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->output_type)
hr = MFCreateMediaType(&converter->output_type);
@@ -421,12 +442,18 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
+ gst_caps_unref(output_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->output_type);
converter->output_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -538,17 +565,102 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+ GstBuffer *gst_buffer;
+ int ret;
- return E_NOTIMPL;
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_NOTACCEPTING;
+ }
+
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
+ {
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret);
+ gst_buffer_unref(gst_buffer);
+ if (ret != GST_FLOW_OK)
+ {
+ ERR("Couldn't push buffer ret, (%s)\n", gst_flow_get_name(ret));
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ converter->inflight = TRUE;
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_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);
+ GstSample *sample;
- return E_NOTIMPL;
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (!count)
+ return S_OK;
+
+ if (count != 1)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (samples[0].dwStreamID != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (!converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
+ }
+
+ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
+
+ converter->inflight = FALSE;
+
+ samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
+ gst_sample_unref(sample);
+ samples[0].dwStatus = S_OK;
+ samples[0].pEvents = NULL;
+ *status = 0;
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
}
static const IMFTransformVtbl audio_converter_vtbl =
@@ -583,6 +695,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
HRESULT audio_converter_create(REFIID riid, void **ret)
{
+ GstElement *audioconvert, *resampler;
struct audio_converter *object;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -596,6 +709,65 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+ object->container = gst_bin_new(NULL);
+
+ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
+ {
+ ERR("Failed to create appsrc, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsrc);
+
+ if (!(audioconvert = gst_element_factory_make("audioconvert", NULL)))
+ {
+ ERR("Failed to create audioconvert, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), audioconvert);
+
+ if (!(resampler = gst_element_factory_make("audioresample", NULL)))
+ {
+ ERR("Failed to create audioresample, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), resampler);
+
+ if (!(object->appsink = gst_element_factory_make("appsink", NULL)))
+ {
+ ERR("Failed to create appsink, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsink);
+
+ if (!gst_element_link(object->appsrc, audioconvert))
+ {
+ ERR("Failed to link appsrc to audioconvert\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(audioconvert, resampler))
+ {
+ ERR("Failed to link audioconvert to resampler\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(resampler, object->appsink))
+ {
+ ERR("Failed to link resampler to appsink\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
*ret = &object->IMFTransform_iface;
return S_OK;
}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 9518f721504..14b6a011ac2 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -82,6 +82,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
+GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index f300988fc5c..b2b5b247dac 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -865,3 +865,72 @@ done:
return out;
}
+
+GstBuffer *gst_buffer_from_mf_sample(IMFSample *mf_sample)
+{
+ GstBuffer *out = gst_buffer_new();
+ IMFMediaBuffer *mf_buffer = NULL;
+ LONGLONG duration, time;
+ DWORD buffer_count;
+ unsigned int i;
+ HRESULT hr;
+
+ if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration)))
+ goto fail;
+
+ if (FAILED(hr = IMFSample_GetSampleTime(mf_sample, &time)))
+ goto fail;
+
+ GST_BUFFER_DURATION(out) = duration;
+ GST_BUFFER_PTS(out) = time * 100;
+
+ if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count)))
+ goto fail;
+
+ for (i = 0; i < buffer_count; i++)
+ {
+ DWORD buffer_size;
+ GstMapInfo map_info;
+ GstMemory *memory;
+ BYTE *buf_data;
+
+ if (FAILED(hr = IMFSample_GetBufferByIndex(mf_sample, i, &mf_buffer)))
+ goto fail;
+
+ if (FAILED(hr = IMFMediaBuffer_GetCurrentLength(mf_buffer, &buffer_size)))
+ goto fail;
+
+ memory = gst_allocator_alloc(NULL, buffer_size, NULL);
+ gst_memory_resize(memory, 0, buffer_size);
+
+ if (!gst_memory_map(memory, &map_info, GST_MAP_WRITE))
+ {
+ hr = E_FAIL;
+ goto fail;
+ }
+
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL)))
+ goto fail;
+
+ memcpy(map_info.data, buf_data, buffer_size);
+
+ if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))
+ goto fail;
+
+ gst_memory_unmap(memory, &map_info);
+
+ gst_buffer_append_memory(out, memory);
+
+ IMFMediaBuffer_Release(mf_buffer);
+ mf_buffer = NULL;
+ }
+
+ return out;
+
+fail:
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
+ if (mf_buffer)
+ IMFMediaBuffer_Release(mf_buffer);
+ gst_buffer_unref(out);
+ return NULL;
+}
--
2.30.0

View File

@@ -0,0 +1,384 @@
From 915e18d44c16f08f27ea4bf0e8bb46221b055ce0 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 10 Mar 2021 13:09:51 -0500
Subject: [PATCH] winegstreamer: Introduce H.264 decoder transform.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/decode_transform.c | 301 +++++++++++++++++++
dlls/winegstreamer/gst_private.h | 2 +
dlls/winegstreamer/mfplat.c | 1 +
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
include/mfidl.idl | 1 +
6 files changed, 312 insertions(+)
create mode 100644 dlls/winegstreamer/decode_transform.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index 4d5dece64b3..7459cccf7e4 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -8,6 +8,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
audioconvert.c \
+ decode_transform.c \
main.c \
media_source.c \
mfplat.c \
diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
new file mode 100644
index 00000000000..f5d4763bde4
--- /dev/null
+++ b/dlls/winegstreamer/decode_transform.c
@@ -0,0 +1,301 @@
+/* GStreamer Decoder Transform
+ *
+ * Copyright 2021 Derek Lesho
+ *
+ * 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 "gst_private.h"
+
+#include "mfapi.h"
+#include "mferror.h"
+#include "mfobjects.h"
+#include "mftransform.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+struct mf_decoder
+{
+ IMFTransform IMFTransform_iface;
+ LONG refcount;
+};
+
+static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface)
+{
+ return CONTAINING_RECORD(iface, struct mf_decoder, IMFTransform_iface);
+}
+
+static HRESULT WINAPI mf_decoder_QueryInterface (IMFTransform *iface, REFIID riid, void **out)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *out = iface;
+ IMFTransform_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI mf_decoder_AddRef(IMFTransform *iface)
+{
+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+ ULONG refcount = InterlockedIncrement(&decoder->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI mf_decoder_Release(IMFTransform *iface)
+{
+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+ ULONG refcount = InterlockedDecrement(&decoder->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ heap_free(decoder);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI mf_decoder_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 mf_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
+{
+ TRACE("%p %p %p.\n", iface, inputs, outputs);
+
+ *inputs = *outputs = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI mf_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
+ DWORD output_size, DWORD *outputs)
+{
+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
+{
+ FIXME("%p, %p.\n", iface, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_DeleteInputStream(IMFTransform *iface, DWORD id)
+{
+ TRACE("%p, %u.\n", iface, id);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
+{
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_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 mf_decoder_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 mf_decoder_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 mf_decoder_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 mf_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
+{
+ FIXME("%p, %u, %p\n", iface, id, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags)
+{
+ FIXME("%p, %p.\n", iface, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_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 mf_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
+{
+ FIXME("%p, %u, %p.\n", iface, id, event);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
+{
+ FIXME("%p, %u %lu.\n", iface, message, param);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mf_decoder_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 mf_decoder_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 mf_decoder_vtbl =
+{
+ mf_decoder_QueryInterface,
+ mf_decoder_AddRef,
+ mf_decoder_Release,
+ mf_decoder_GetStreamLimits,
+ mf_decoder_GetStreamCount,
+ mf_decoder_GetStreamIDs,
+ mf_decoder_GetInputStreamInfo,
+ mf_decoder_GetOutputStreamInfo,
+ mf_decoder_GetAttributes,
+ mf_decoder_GetInputStreamAttributes,
+ mf_decoder_GetOutputStreamAttributes,
+ mf_decoder_DeleteInputStream,
+ mf_decoder_AddInputStreams,
+ mf_decoder_GetInputAvailableType,
+ mf_decoder_GetOutputAvailableType,
+ mf_decoder_SetInputType,
+ mf_decoder_SetOutputType,
+ mf_decoder_GetInputCurrentType,
+ mf_decoder_GetOutputCurrentType,
+ mf_decoder_GetInputStatus,
+ mf_decoder_GetOutputStatus,
+ mf_decoder_SetOutputBounds,
+ mf_decoder_ProcessEvent,
+ mf_decoder_ProcessMessage,
+ mf_decoder_ProcessInput,
+ mf_decoder_ProcessOutput,
+};
+
+HRESULT decode_transform_create(REFIID riid, void **obj)
+{
+ struct mf_decoder *object;
+
+ TRACE("%s, %p.\n", debugstr_guid(riid), obj);
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IMFTransform_iface.lpVtbl = &mf_decoder_vtbl;
+ object->refcount = 1;
+
+ *obj = &object->IMFTransform_iface;
+ return S_OK;
+}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 55a62361966..cdf90d52025 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -219,4 +219,6 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
+HRESULT decode_transform_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+
#endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index dcbd03137ba..4bff7ee9241 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -412,6 +412,7 @@ class_objects[] =
{ &CLSID_VideoProcessorMFT, &video_processor_create },
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
{ &CLSID_WINEAudioConverter, &audio_converter_create },
+ { &CLSID_CMSH264DecoderMFT, &decode_transform_create },
};
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
index 072ec90eea4..064a6872c79 100644
--- a/dlls/winegstreamer/winegstreamer_classes.idl
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
@@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {}
uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
]
coclass WINEAudioConverter { }
+
+[
+ threading(both),
+ uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d)
+]
+coclass CMSH264DecoderMFT { }
diff --git a/include/mfidl.idl b/include/mfidl.idl
index 5b16c08bb90..f28a0669804 100644
--- a/include/mfidl.idl
+++ b/include/mfidl.idl
@@ -1579,3 +1579,4 @@ cpp_quote("EXTERN_GUID(MF_XVP_CALLER_ALLOCATES_OUTPUT, 0x4a2cabc, 0x0cab, 0x40b1
cpp_quote("EXTERN_GUID(MF_XVP_SAMPLE_LOCK_TIMEOUT, 0xaa4ddb29, 0x5134, 0x4363, 0xac, 0x72, 0x83, 0xec, 0x4b, 0xc1, 0x04, 0x26);")
cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);")
+cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);")
--
2.30.2

View File

@@ -0,0 +1,157 @@
From 42278cb728ff00fdd44e5ca04a68d3fd34c79f15 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 10 Mar 2021 14:14:21 -0500
Subject: [PATCH] winegstreamer: Implement ::GetInputAvailableType for decode
transform.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/decode_transform.c | 60 +++++++++++++++++++++++++--
dlls/winegstreamer/gst_private.h | 6 ++-
dlls/winegstreamer/mfplat.c | 7 +++-
3 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
index f5d4763bde4..55a0c1c6c9b 100644
--- a/dlls/winegstreamer/decode_transform.c
+++ b/dlls/winegstreamer/decode_transform.c
@@ -29,10 +29,33 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+const GUID *h264_input_types[] = {&MFVideoFormat_H264};
+/* NV12 comes first https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order . thanks to @vitorhnn */
+const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12};
+
+static struct decoder_desc
+{
+ const GUID *major_type;
+ const GUID **input_types;
+ unsigned int input_types_count;
+ const GUID **output_types;
+ unsigned int output_types_count;
+} decoder_descs[] =
+{
+ { /* DECODER_TYPE_H264 */
+ &MFMediaType_Video,
+ h264_input_types,
+ ARRAY_SIZE(h264_input_types),
+ h264_output_types,
+ ARRAY_SIZE(h264_output_types),
+ },
+};
+
struct mf_decoder
{
IMFTransform IMFTransform_iface;
LONG refcount;
+ enum decoder_type type;
};
static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface)
@@ -163,9 +186,36 @@ static HRESULT WINAPI mf_decoder_AddInputStreams(IMFTransform *iface, DWORD stre
static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
{
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+ IMFMediaType *input_type;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %u, %p\n", decoder, id, index, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (index >= decoder_descs[decoder->type].input_types_count)
+ return MF_E_NO_MORE_TYPES;
+
+ if (FAILED(hr = MFCreateMediaType(&input_type)))
+ return hr;
+
+ if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type)))
+ {
+ IMFMediaType_Release(input_type);
+ return hr;
+ }
+
+ if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_SUBTYPE, decoder_descs[decoder->type].input_types[index])))
+ {
+ IMFMediaType_Release(input_type);
+ return hr;
+ }
+
+ *type = input_type;
+
+ return S_OK;
}
static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
@@ -284,11 +334,11 @@ static const IMFTransformVtbl mf_decoder_vtbl =
mf_decoder_ProcessOutput,
};
-HRESULT decode_transform_create(REFIID riid, void **obj)
+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type)
{
struct mf_decoder *object;
- TRACE("%s, %p.\n", debugstr_guid(riid), obj);
+ TRACE("%s, %p %u.\n", debugstr_guid(riid), obj, type);
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
@@ -296,6 +346,8 @@ HRESULT decode_transform_create(REFIID riid, void **obj)
object->IMFTransform_iface.lpVtbl = &mf_decoder_vtbl;
object->refcount = 1;
+ object->type = type;
+
*obj = &object->IMFTransform_iface;
return S_OK;
}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index cdf90d52025..2d2ebbda61f 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -219,6 +219,10 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
-HRESULT decode_transform_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+enum decoder_type
+{
+ DECODER_TYPE_H264,
+};
+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN;
#endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 4bff7ee9241..f8f83031b7e 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -402,6 +402,11 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a
static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
+static HRESULT h264_decoder_create(REFIID riid, void **ret)
+{
+ return decode_transform_create(riid, ret, DECODER_TYPE_H264);
+}
+
static const struct class_object
{
const GUID *clsid;
@@ -412,7 +417,7 @@ class_objects[] =
{ &CLSID_VideoProcessorMFT, &video_processor_create },
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
{ &CLSID_WINEAudioConverter, &audio_converter_create },
- { &CLSID_CMSH264DecoderMFT, &decode_transform_create },
+ { &CLSID_CMSH264DecoderMFT, &h264_decoder_create },
};
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
--
2.30.2

View File

@@ -0,0 +1,57 @@
From 360b07b3ba1bc9fdb8225b64bc4a1ada43256087 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 10 Mar 2021 14:23:09 -0500
Subject: [PATCH] winegstreamer: Implement ::GetOutputAvailableType for decode
transform.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/decode_transform.c | 31 +++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
index 55a0c1c6c9b..3c71fddd67c 100644
--- a/dlls/winegstreamer/decode_transform.c
+++ b/dlls/winegstreamer/decode_transform.c
@@ -221,9 +221,36 @@ static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWOR
static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
{
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+ IMFMediaType *output_type;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %u, %p\n", decoder, id, index, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (index >= decoder_descs[decoder->type].output_types_count)
+ return MF_E_NO_MORE_TYPES;
+
+ if (FAILED(hr = MFCreateMediaType(&output_type)))
+ return hr;
+
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type)))
+ {
+ IMFMediaType_Release(output_type);
+ return hr;
+ }
+
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, decoder_descs[decoder->type].output_types[index])))
+ {
+ IMFMediaType_Release(output_type);
+ return hr;
+ }
+
+ *type = output_type;
+
+ return S_OK;
}
static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
--
2.30.2

View File

@@ -0,0 +1,304 @@
From 328f8b7e095596cb11d86484665062591aebcf55 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Thu, 11 Mar 2021 12:33:02 -0500
Subject: [PATCH] winegstreamer: Implement ::SetInputType for decode transform.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/decode_transform.c | 80 ++++++++++++++++++++++++++-
dlls/winegstreamer/gst_private.h | 10 ++++
dlls/winegstreamer/mfplat.c | 17 +++++-
dlls/winegstreamer/quartz_parser.c | 1 +
dlls/winegstreamer/wg_parser.c | 76 +++++++++++++++++++++++++
5 files changed, 180 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
index 3c71fddd67c..f709ef32fc1 100644
--- a/dlls/winegstreamer/decode_transform.c
+++ b/dlls/winegstreamer/decode_transform.c
@@ -56,6 +56,8 @@ struct mf_decoder
IMFTransform IMFTransform_iface;
LONG refcount;
enum decoder_type type;
+ IMFMediaType *input_type;
+ CRITICAL_SECTION cs;
};
static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface)
@@ -99,6 +101,14 @@ static ULONG WINAPI mf_decoder_Release(IMFTransform *iface)
if (!refcount)
{
+ if (decoder->input_type)
+ {
+ IMFMediaType_Release(decoder->input_type);
+ decoder->input_type = NULL;
+ }
+
+ DeleteCriticalSection(&decoder->cs);
+
heap_free(decoder);
}
@@ -255,9 +265,73 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO
static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface);
+ struct wg_format input_format;
+ GUID major_type, subtype;
+ unsigned int i;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %p, %#x.\n", decoder, id, type, flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (!type)
+ {
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&decoder->cs);
+
+ if (decoder->input_type)
+ {
+ IMFMediaType_Release(decoder->input_type);
+ decoder->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&decoder->cs);
+
+ return S_OK;
+ }
+
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+ return MF_E_INVALIDTYPE;
+
+ if (!(IsEqualGUID(&major_type, decoder_descs[decoder->type].major_type)))
+ return MF_E_INVALIDTYPE;
+
+ for (i = 0; i < decoder_descs[decoder->type].input_types_count; i++)
+ {
+ if (IsEqualGUID(&subtype, decoder_descs[decoder->type].input_types[i]))
+ break;
+ if (i == decoder_descs[decoder->type].input_types_count)
+ return MF_E_INVALIDTYPE;
+ }
+
+ mf_media_type_to_wg_format(type, &input_format);
+ if (!input_format.major_type)
+ return MF_E_INVALIDTYPE;
+
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&decoder->cs);
+
+ hr = S_OK;
+
+ if (!decoder->input_type)
+ hr = MFCreateMediaType(&decoder->input_type);
+
+ if (SUCCEEDED(hr) && FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes*) decoder->input_type)))
+ {
+ IMFMediaType_Release(decoder->input_type);
+ decoder->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&decoder->cs);
+ return hr;
}
static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
@@ -375,6 +449,8 @@ HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type)
object->type = type;
+ InitializeCriticalSection(&object->cs);
+
*obj = &object->IMFTransform_iface;
return S_OK;
}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 2d2ebbda61f..215cf4577d4 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -97,9 +97,19 @@ struct wg_format
WG_VIDEO_FORMAT_YVYU,
WG_VIDEO_FORMAT_CINEPAK,
+
+ WG_VIDEO_FORMAT_H264,
} format;
uint32_t width, height;
uint32_t fps_n, fps_d;
+ union
+ {
+ struct
+ {
+ uint32_t profile;
+ uint32_t level;
+ } h264;
+ } compressed;
} video;
struct
{
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index f8f83031b7e..9d1cbd87746 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -533,6 +533,7 @@ video_formats[] =
{&MFVideoFormat_YUY2, WG_VIDEO_FORMAT_YUY2},
{&MFVideoFormat_YV12, WG_VIDEO_FORMAT_YV12},
{&MFVideoFormat_YVYU, WG_VIDEO_FORMAT_YVYU},
+ {&MFVideoFormat_H264, WG_VIDEO_FORMAT_H264},
};
static const struct
@@ -719,10 +720,22 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, struct wg_forma
if (IsEqualGUID(&subtype, video_formats[i].subtype))
{
format->u.video.format = video_formats[i].format;
- return;
+ break;
}
}
- FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype));
+ if (i == ARRAY_SIZE(video_formats))
+ FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype));
+
+ if (format->u.video.format == WG_VIDEO_FORMAT_H264)
+ {
+ UINT32 profile, level;
+
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile)))
+ format->u.video.compressed.h264.profile = profile;
+
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level)))
+ format->u.video.compressed.h264.level = level;
+ }
}
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 09a916d7f5c..fc1b72cd958 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -268,6 +268,7 @@ static unsigned int get_image_size(const struct wg_format *format)
return width * height * 3;
case WG_VIDEO_FORMAT_UNKNOWN:
+ case WG_VIDEO_FORMAT_H264:
break;
}
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 879aece63b7..1afe92f04ac 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -387,6 +387,22 @@ static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t
}
}
+static void wg_set_caps_from_wg_format(GstCaps *caps, const struct wg_format *format)
+{
+ switch (format->major_type)
+ {
+ case WG_MAJOR_TYPE_VIDEO:
+ {
+ gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video.width, NULL);
+ gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video.height, NULL);
+ gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video.fps_n, format->u.video.fps_d, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
static GstCaps *wg_format_to_caps_audio(const struct wg_format *format)
{
GstAudioChannelPosition positions[32];
@@ -428,6 +444,65 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
unsigned int i;
GstCaps *caps;
+ /* compressed types */
+
+ if (format->u.video.format == WG_VIDEO_FORMAT_H264)
+ {
+ const char *profile;
+ const char *level;
+
+ caps = gst_caps_new_empty_simple("video/x-h264");
+ wg_set_caps_from_wg_format(caps, format);
+
+ gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL);
+ gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL);
+
+ switch (format->u.video.compressed.h264.profile)
+ {
+ case /* eAVEncH264VProfile_Main */ 77: profile = "main"; break;
+ case /* eAVEncH264VProfile_High */ 100: profile = "high"; break;
+ case /* eAVEncH264VProfile_444 */ 244: profile = "high-4:4:4"; break;
+ default:
+ GST_ERROR("Unrecognized H.264 profile attribute %u\n", format->u.video.compressed.h264.profile);
+ /* fallthrough */
+ case 0: profile = NULL;
+ }
+
+ switch (format->u.video.compressed.h264.level)
+ {
+ case /* eAVEncH264VLevel1 */ 10: level = "1"; break;
+ case /* eAVEncH264VLevel1_1 */ 11: level = "1.1"; break;
+ case /* eAVEncH264VLevel1_2 */ 12: level = "1.2"; break;
+ case /* eAVEncH264VLevel1_3 */ 13: level = "1.3"; break;
+ case /* eAVEncH264VLevel2 */ 20: level = "2"; break;
+ case /* eAVEncH264VLevel2_1 */ 21: level = "2.1"; break;
+ case /* eAVEncH264VLevel2_2 */ 22: level = "2.2"; break;
+ case /* eAVEncH264VLevel3 */ 30: level = "3"; break;
+ case /* eAVEncH264VLevel3_1 */ 31: level = "3.1"; break;
+ case /* eAVEncH264VLevel3_2 */ 32: level = "3.2"; break;
+ case /* eAVEncH264VLevel4 */ 40: level = "4"; break;
+ case /* eAVEncH264VLevel4_1 */ 41: level = "4.1"; break;
+ case /* eAVEncH264VLevel4_2 */ 42: level = "4.2"; break;
+ case /* eAVEncH264VLevel5 */ 50: level = "5"; break;
+ case /* eAVEncH264VLevel5_1 */ 51: level = "5.1"; break;
+ case /* eAVEncH264VLevel5_2 */ 52: level = "5.2"; break;
+ default:
+ GST_ERROR("Unrecognized H.264 level attribute %u\n", format->u.video.compressed.h264.level);
+ /* fallthrough */
+ case 0: level = NULL;
+ }
+
+ if (profile)
+ gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL);
+
+ if (level)
+ gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL);
+
+ return caps;
+ }
+
+ /* uncompressed types */
+
if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN)
return NULL;
@@ -587,6 +662,7 @@ static void CDECL wg_parser_stream_enable(struct wg_parser_stream *stream, const
case WG_VIDEO_FORMAT_YVYU:
case WG_VIDEO_FORMAT_UNKNOWN:
case WG_VIDEO_FORMAT_CINEPAK:
+ case WG_VIDEO_FORMAT_H264:
gst_util_set_object_arg(G_OBJECT(stream->flip), "method", "none");
break;
}
--
2.30.2

Some files were not shown because too many files have changed in this diff Show More