You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4b6879f30f | ||
|
94337e021c | ||
|
05c42b1df2 | ||
|
1bc4da9d59 | ||
|
16476ce303 | ||
|
bdb9f49c3e | ||
|
82118b0d67 | ||
|
00985bf311 | ||
|
3c8c7910e7 | ||
|
069adfd1b0 | ||
|
c91c63a5da | ||
|
f7c80250ec | ||
|
b059114710 | ||
|
f27610e7e7 | ||
|
9da0fe04d3 | ||
|
dc38777093 | ||
|
b57bf86ec0 | ||
|
4e99d1b2a8 | ||
|
8ad669e434 | ||
|
52dd338148 | ||
|
f841424edd | ||
|
5e8fbbf200 | ||
|
183fd3e089 | ||
|
092f3b1ed1 | ||
|
e59eb7639a | ||
|
a0716c9cfe | ||
|
fcf7b80107 | ||
|
163f74fe61 | ||
|
ce643e9d2a | ||
|
f18cff9e7a | ||
|
f5fe9c0c89 | ||
|
c6e832ee03 | ||
|
a7ae280480 | ||
|
8988a92bee | ||
|
260734214e | ||
|
1a3b158f0b | ||
|
1af6d6980c | ||
|
1c9c21dc1c | ||
|
0dd44a250f | ||
|
9bf50b7e1f | ||
|
9c8608eea6 | ||
|
fd5866f6f1 |
@@ -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
|
||||
|
||||
|
@@ -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 );
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
Reference in New Issue
Block a user