Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
February 2022
- 87 participants
- 3239 messages
Re: [PATCH vkd3d v2 4/7] vkd3d-shader/hlsl: Parse left shift.
by Francisco Casas
Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
Note to self: We have to remember to apply (· & x11111) to
the 2nd operand if we add this op to constant folding.
February 24, 2022 3:45 PM, "Zebediah Figura" <zfigura(a)codeweavers.com> wrote:
> From: Giovanni Mascellani <gmascellani(a)codeweavers.com>
>
> Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> ---
> v2: Use check_integer_type(); constify the "loc" parameter.
>
> libs/vkd3d-shader/hlsl.y | 45 +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
> index 4cdb471e8..7c7c89efb 100644
> --- a/libs/vkd3d-shader/hlsl.y
> +++ b/libs/vkd3d-shader/hlsl.y
> @@ -1171,6 +1171,49 @@ static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx,
> struct l
> return list1;
> }
>
> +static struct hlsl_ir_expr *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs,
> + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2,
> + const struct vkd3d_shader_location *loc)
> +{
> + enum hlsl_base_type base = arg1->data_type->base_type;
> + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0};
> + struct hlsl_type *return_type, *integer_type;
> + enum hlsl_type_class type;
> + unsigned int dimx, dimy;
> +
> + check_integer_type(ctx, arg1);
> + check_integer_type(ctx, arg2);
> +
> + if (base == HLSL_TYPE_BOOL)
> + base = HLSL_TYPE_INT;
> +
> + if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy))
> + return NULL;
> +
> + return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy);
> + integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy);
> +
> + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, return_type, loc)))
> + return NULL;
> +
> + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, integer_type, loc)))
> + return NULL;
> +
> + return add_expr(ctx, instrs, op, args, return_type, loc);
> +}
> +
> +static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct
> list *list2,
> + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc)
> +{
> + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2);
> +
> + list_move_tail(list1, list2);
> + vkd3d_free(list2);
> + add_binary_shift_expr(ctx, list1, op, arg1, arg2, loc);
> +
> + return list1;
> +}
> +
> static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
> {
> static const enum hlsl_ir_expr_op ops[] =
> @@ -3637,7 +3680,7 @@ shift_expr:
> add_expr
> | shift_expr OP_LEFTSHIFT add_expr
> {
> - hlsl_fixme(ctx, &@$, "Left shift.");
> + $$ = add_binary_shift_expr_merge(ctx, $1, $3, HLSL_OP2_LSHIFT, &@2);
> }
> | shift_expr OP_RIGHTSHIFT add_expr
> {
> --
> 2.35.1
Feb. 28, 2022
[PATCH 3/3] winegstreamer: Return S_OK from WMA decoder ProcessMessage.
by Rémi Bernon
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winegstreamer/wma_decoder.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 6ee43e19414..57b0f204f9e 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -515,7 +515,7 @@ static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFM
static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
{
FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param);
- return E_NOTIMPL;
+ return S_OK;
}
static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
--
2.34.1
Feb. 28, 2022
[PATCH 2/3] winegstreamer: Introduce new wg_transform_(push|read)_data functions.
by Rémi Bernon
And use it to implement WMA decoder Process(Input|Output).
The test output is different because ffmpeg WMA decoder outputs data in
a different way as native. The data seems valid audio nonetheless, and
it shouldn't matter too much.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/mf/tests/mf.c | 43 ++---------
dlls/winegstreamer/gst_private.h | 5 ++
dlls/winegstreamer/main.c | 30 ++++++++
dlls/winegstreamer/mfplat.c | 49 ++++++++++++
dlls/winegstreamer/unix_private.h | 2 +
dlls/winegstreamer/unixlib.h | 30 ++++++++
dlls/winegstreamer/wg_parser.c | 3 +
dlls/winegstreamer/wg_transform.c | 119 +++++++++++++++++++++++++++++-
dlls/winegstreamer/wma_decoder.c | 33 ++++++++-
9 files changed, 270 insertions(+), 44 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 0ab46445d9a..be09c6040fe 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6205,22 +6205,18 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data, wma_block_size / 2);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
ret = IMFSample_Release(sample);
ok(ret == 0, "Release returned %u\n", ret);
sample = create_sample(wma_encoded_data, wma_block_size + 1);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
ret = IMFSample_Release(sample);
ok(ret == 0, "Release returned %u\n", ret);
sample = create_sample(wma_encoded_data, wma_block_size);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr);
ret = IMFSample_Release(sample);
todo_wine
@@ -6243,7 +6239,6 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data, wma_block_size);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr);
ret = IMFSample_Release(sample);
ok(ret == 0, "Release returned %u\n", ret);
@@ -6270,38 +6265,12 @@ static void test_wma_decoder(void)
IMFSample_Release(outputs[0].pSample);
IMFSample_Release(outputs[1].pSample);
- i = 1;
status = 0xdeadbeef;
output_info.cbSize = sizeof(wma_decoded_data);
sample = create_sample(NULL, output_info.cbSize);
memset(&output, 0, sizeof(output));
output.pSample = sample;
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
- while (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
- {
- ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
- ok(output.pSample == sample, "got pSample %p\n", output.pSample);
- ok(output.dwStatus == 0, "got dwStatus %#x\n", output.dwStatus);
- ok(status == 0, "got status %#x\n", status);
- check_sample(sample, NULL, 0, NULL);
- ret = IMFSample_Release(sample);
- ok(ret == 0, "Release returned %u\n", ret);
-
- sample = create_sample(wma_encoded_data + i * wma_block_size, wma_block_size);
- hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
- ret = IMFSample_Release(sample);
- ok(ret == 1, "Release returned %u\n", ret);
- i++;
-
- status = 0xdeadbeef;
- sample = create_sample(NULL, output_info.cbSize);
- memset(&output, 0, sizeof(output));
- output.pSample = sample;
- hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
- }
-
- todo_wine
ok(hr == S_OK, "ProcessOutput returned %#x\n", hr);
ok(output.pSample == sample, "got pSample %p\n", output.pSample);
@@ -6314,7 +6283,8 @@ static void test_wma_decoder(void)
"got dwStatus %#x\n", output.dwStatus);
ok(status == 0, "got status %#x\n", status);
if (output.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE ||
- broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)))
+ broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) ||
+ !strcmp(winetest_platform, "wine"))
{
check_sample(sample, wma_decoded_data, sizeof(wma_decoded_data), NULL);
i += sizeof(wma_decoded_data);
@@ -6333,10 +6303,11 @@ static void test_wma_decoder(void)
output.pSample = sample;
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
}
- todo_wine
- ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i);
+ if (!strcmp(winetest_platform, "wine"))
+ ok(i == 0x10000, "ProcessOutput produced %#x bytes\n", i);
+ else
+ ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i);
- todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
ok(output.pSample == sample, "got pSample %p\n", output.pSample);
ok(output.dwStatus == 0, "got dwStatus %#x\n", output.dwStatus);
@@ -6349,7 +6320,6 @@ static void test_wma_decoder(void)
memset(&output, 0, sizeof(output));
output.pSample = sample;
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
- todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
ok(output.pSample == sample, "got pSample %p\n", output.pSample);
ok(output.dwStatus == 0 ||
@@ -6362,7 +6332,6 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data, wma_block_size);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
- todo_wine
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
ret = IMFTransform_Release(transform);
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 2cbba09f9a7..e5870bc3b5d 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -96,6 +96,8 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate,
struct wg_transform *wg_transform_create(const struct wg_format *input_format,
const struct wg_format *output_format);
void wg_transform_destroy(struct wg_transform *transform);
+HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample);
+HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample);
unsigned int wg_format_get_max_size(const struct wg_format *format);
@@ -116,6 +118,9 @@ extern HRESULT mfplat_DllRegisterServer(void);
IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format);
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
+HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out);
+void mf_destroy_wg_sample(struct wg_sample *wg_sample);
+
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj);
HRESULT audio_converter_create(REFIID riid, void **ret);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 327d144499e..8a41df6b223 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -263,6 +263,36 @@ void wg_transform_destroy(struct wg_transform *transform)
__wine_unix_call(unix_handle, unix_wg_transform_destroy, transform);
}
+HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample)
+{
+ struct wg_transform_push_data_params params =
+ {
+ .transform = transform,
+ .sample = sample,
+ };
+ NTSTATUS status;
+
+ if ((status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms)))
+ return HRESULT_FROM_NT(status);
+
+ return params.result;
+}
+
+HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample)
+{
+ struct wg_transform_read_data_params params =
+ {
+ .transform = transform,
+ .sample = sample,
+ };
+ NTSTATUS status;
+
+ if ((status = __wine_unix_call(unix_handle, unix_wg_transform_read_data, ¶ms)))
+ return HRESULT_FROM_NT(status);
+
+ return params.result;
+}
+
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
if (reason == DLL_PROCESS_ATTACH)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 9b3fc429d32..82e926d673d 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -827,3 +827,52 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
else
FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));
}
+
+struct mf_sample
+{
+ IMFSample *sample;
+ IMFMediaBuffer *media_buffer;
+ struct wg_sample wg_sample;
+};
+
+HRESULT mf_create_wg_sample(IMFSample *sample, struct wg_sample **out)
+{
+ DWORD current_length, max_length;
+ struct mf_sample *mf_sample;
+ BYTE *buffer;
+ HRESULT hr;
+
+ if (!(mf_sample = calloc(1, sizeof(*mf_sample))))
+ return E_OUTOFMEMORY;
+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &mf_sample->media_buffer)))
+ goto out;
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_sample->media_buffer, &buffer, &max_length, ¤t_length)))
+ goto out;
+
+ IMFSample_AddRef((mf_sample->sample = sample));
+ mf_sample->wg_sample.data = buffer;
+ mf_sample->wg_sample.size = current_length;
+ mf_sample->wg_sample.max_size = max_length;
+
+ TRACE("Created mf_sample %p for sample %p.\n", mf_sample, sample);
+ *out = &mf_sample->wg_sample;
+ return S_OK;
+
+out:
+ if (mf_sample->media_buffer)
+ IMFMediaBuffer_Release(mf_sample->media_buffer);
+ free(mf_sample);
+ return hr;
+}
+
+void mf_destroy_wg_sample(struct wg_sample *wg_sample)
+{
+ struct mf_sample *mf_sample = CONTAINING_RECORD(wg_sample, struct mf_sample, wg_sample);
+
+ IMFMediaBuffer_Unlock(mf_sample->media_buffer);
+ IMFMediaBuffer_SetCurrentLength(mf_sample->media_buffer, wg_sample->size);
+ IMFMediaBuffer_Release(mf_sample->media_buffer);
+
+ IMFSample_Release(mf_sample->sample);
+ free(mf_sample);
+}
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h
index d3f32484ee6..7bce8263aaf 100644
--- a/dlls/winegstreamer/unix_private.h
+++ b/dlls/winegstreamer/unix_private.h
@@ -34,5 +34,7 @@ extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDE
extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN;
+extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN;
+extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
#endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index 3dfa30b4889..e1c0ec3f3b7 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -103,6 +103,19 @@ struct wg_format
} u;
};
+enum wg_sample_flag
+{
+ WG_SAMPLE_FLAG_INCOMPLETE = 1,
+};
+
+struct wg_sample
+{
+ UINT32 flags;
+ UINT32 max_size;
+ UINT32 size;
+ BYTE *data;
+};
+
struct wg_parser_buffer
{
/* pts and duration are in 100-nanosecond units. */
@@ -216,6 +229,20 @@ struct wg_transform_create_params
const struct wg_format *output_format;
};
+struct wg_transform_push_data_params
+{
+ struct wg_transform *transform;
+ struct wg_sample *sample;
+ HRESULT result;
+};
+
+struct wg_transform_read_data_params
+{
+ struct wg_transform *transform;
+ struct wg_sample *sample;
+ HRESULT result;
+};
+
enum unix_funcs
{
unix_wg_parser_create,
@@ -244,6 +271,9 @@ enum unix_funcs
unix_wg_transform_create,
unix_wg_transform_destroy,
+
+ unix_wg_transform_push_data,
+ unix_wg_transform_read_data,
};
#endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 46a298f13c1..df563e9336e 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1589,4 +1589,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_transform_create),
X(wg_transform_destroy),
+
+ X(wg_transform_push_data),
+ X(wg_transform_read_data),
};
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 45f8588b9f1..6e272634653 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -35,7 +35,7 @@
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
-#include "dshow.h"
+#include "mferror.h"
#include "unix_private.h"
@@ -48,15 +48,24 @@ struct wg_transform
GstPad *my_src, *my_sink;
GstPad *their_sink, *their_src;
GstSegment segment;
+ GstBuffer *input;
+
+ pthread_mutex_t mutex;
+ GstBuffer *output;
};
static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer)
{
struct wg_transform *transform = gst_pad_get_element_private(pad);
- GST_INFO("transform %p, buffer %p.", transform, buffer);
+ GST_LOG("transform %p, buffer %p.", transform, buffer);
- gst_buffer_unref(buffer);
+ pthread_mutex_lock(&transform->mutex);
+ if (transform->output)
+ transform->output = gst_buffer_append(transform->output, buffer);
+ else
+ transform->output = buffer;
+ pthread_mutex_unlock(&transform->mutex);
return GST_FLOW_OK;
}
@@ -65,12 +74,18 @@ NTSTATUS wg_transform_destroy(void *args)
{
struct wg_transform *transform = args;
+ if (transform->input)
+ gst_buffer_unref(transform->input);
+ if (transform->output)
+ gst_buffer_unref(transform->output);
+
gst_element_set_state(transform->container, GST_STATE_NULL);
g_object_unref(transform->their_sink);
g_object_unref(transform->their_src);
g_object_unref(transform->container);
g_object_unref(transform->my_sink);
g_object_unref(transform->my_src);
+ pthread_mutex_destroy(&transform->mutex);
free(transform);
return STATUS_SUCCESS;
@@ -278,6 +293,8 @@ NTSTATUS wg_transform_create(void *args)
gst_caps_unref(sink_caps);
gst_caps_unref(src_caps);
+ pthread_mutex_init(&transform->mutex, NULL);
+
GST_INFO("Created winegstreamer transform %p.", transform);
params->transform = transform;
return STATUS_SUCCESS;
@@ -304,3 +321,99 @@ out:
GST_ERROR("Failed to create winegstreamer transform.");
return status;
}
+
+NTSTATUS wg_transform_push_data(void *args)
+{
+ struct wg_transform_push_data_params *params = args;
+ struct wg_transform *transform = params->transform;
+ struct wg_sample *sample = params->sample;
+ GstBuffer *buffer;
+
+ if (transform->input)
+ {
+ GST_INFO("Refusing %u bytes, a buffer is already queued", sample->size);
+ params->result = MF_E_NOTACCEPTING;
+ return STATUS_SUCCESS;
+ }
+
+ if (!(buffer = gst_buffer_new_and_alloc(sample->size)))
+ {
+ GST_ERROR("Failed to allocate input buffer");
+ return STATUS_NO_MEMORY;
+ }
+ gst_buffer_fill(buffer, 0, sample->data, sample->size);
+ transform->input = buffer;
+
+ GST_INFO("Copied %u bytes from sample %p to input buffer", sample->size, sample);
+ params->result = S_OK;
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS read_transform_output_data(struct wg_transform *transform,
+ struct wg_sample *sample)
+{
+ GstBuffer *buffer = transform->output;
+ GstMapInfo info;
+
+ if (!gst_buffer_map(buffer, &info, GST_MAP_READ))
+ {
+ GST_ERROR("Failed to map buffer %p", buffer);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (sample->max_size >= info.size)
+ sample->size = info.size;
+ else
+ {
+ sample->flags |= WG_SAMPLE_FLAG_INCOMPLETE;
+ sample->size = sample->max_size;
+ }
+
+ memcpy(sample->data, info.data, sample->size);
+ gst_buffer_unmap(buffer, &info);
+ gst_buffer_resize(buffer, sample->size, -1);
+
+ if (info.size <= sample->size)
+ {
+ gst_buffer_unref(transform->output);
+ transform->output = NULL;
+ }
+
+ GST_INFO("Copied %u bytes, sample %p, flags %#x", sample->size, sample, sample->flags);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS wg_transform_read_data(void *args)
+{
+ struct wg_transform_read_data_params *params = args;
+ struct wg_transform *transform = params->transform;
+ struct wg_sample *sample = params->sample;
+ GstFlowReturn ret;
+ NTSTATUS status;
+
+ if (!transform->input)
+ GST_DEBUG("Not input buffer queued");
+ else if ((ret = gst_pad_push(transform->my_src, transform->input)))
+ {
+ GST_ERROR("Failed to push transform input, error %d", ret);
+ return STATUS_UNSUCCESSFUL;
+ }
+ transform->input = NULL;
+
+ sample->size = 0;
+ pthread_mutex_lock(&transform->mutex);
+ if (transform->output)
+ {
+ params->result = S_OK;
+ status = read_transform_output_data(transform, sample);
+ }
+ else
+ {
+ params->result = MF_E_TRANSFORM_NEED_MORE_INPUT;
+ status = STATUS_SUCCESS;
+ GST_INFO("Cannot read %u bytes, no output available", sample->max_size);
+ }
+ pthread_mutex_unlock(&transform->mutex);
+
+ return status;
+}
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index a35da1cdc70..6ee43e19414 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -521,10 +521,11 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
{
struct wma_decoder *decoder = impl_from_IMFTransform(iface);
+ struct wg_sample *wg_sample;
MFT_INPUT_STREAM_INFO info;
HRESULT hr;
- FIXME("iface %p, id %lu, sample %p, flags %#lx stub!\n", iface, id, sample, flags);
+ TRACE("iface %p, id %lu, sample %p, flags %#lx.\n", iface, id, sample, flags);
if (!decoder->wg_transform)
return MF_E_TRANSFORM_TYPE_NOT_SET;
@@ -532,7 +533,17 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS
if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info)))
return hr;
- return E_NOTIMPL;
+ if (FAILED(hr = mf_create_wg_sample(sample, &wg_sample)))
+ return hr;
+
+ /* WMA transform uses fixed size input samples and ignores samples with invalid sizes */
+ if (wg_sample->size % info.cbSize)
+ hr = S_OK;
+ else
+ hr = wg_transform_push_data(decoder->wg_transform, wg_sample);
+
+ mf_destroy_wg_sample(wg_sample);
+ return hr;
}
static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
@@ -540,9 +551,10 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
{
struct wma_decoder *decoder = impl_from_IMFTransform(iface);
MFT_OUTPUT_STREAM_INFO info;
+ struct wg_sample *wg_sample;
HRESULT hr;
- FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status);
+ TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status);
if (count > 1)
return E_INVALIDARG;
@@ -561,7 +573,20 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
return MF_E_TRANSFORM_NEED_MORE_INPUT;
}
- return E_NOTIMPL;
+ if (FAILED(hr = mf_create_wg_sample(samples[0].pSample, &wg_sample)))
+ return hr;
+
+ wg_sample->size = 0;
+ if (wg_sample->max_size < info.cbSize)
+ hr = MF_E_BUFFERTOOSMALL;
+ else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, wg_sample)))
+ {
+ if (wg_sample->flags & WG_SAMPLE_FLAG_INCOMPLETE)
+ samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE;
+ }
+
+ mf_destroy_wg_sample(wg_sample);
+ return hr;
}
static const IMFTransformVtbl transform_vtbl =
--
2.34.1
Feb. 28, 2022
[PATCH 1/3] winegstreamer: Implement WMA decoder Process(Input|Output) error checks.
by Rémi Bernon
Checking that WMA decoder ignores any incorrectly sized input sample.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
I believe this approach works best and doesn't suffer from any of the
potential troubles the queue would introduce. It should also be fully
synchronous in the general case, although I kept the mutex to be safe.
For now, one input buffer can be queued at a time, which is how the WMA
decoder transform works, and the output buffers are appended to each
other, although they are normally also produced one at a time.
Later, and to satisfy the requirements of the H264 transform and the
expectations of CoD: BO3, I will change the input to a GstBufferList
with a length limit.
Even for the zero-copy optimization, I was able to validate that it's
still possible, and even simpler to implement as we now do all the
processing in ProcessOutput.
We can then later consider adding some asynchronicity using queues, but
I'm not sure it is going to be useful, and may even cause more problems
than it's worth.
dlls/mf/tests/mf.c | 23 +++++++++++++---------
dlls/winegstreamer/wma_decoder.c | 33 ++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index e61442bb512..0ab46445d9a 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6031,6 +6031,7 @@ static void test_wma_decoder(void)
MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_WMAudioV8};
MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_Float};
MFT_OUTPUT_STREAM_INFO output_info;
+ MFT_OUTPUT_DATA_BUFFER outputs[2];
MFT_INPUT_STREAM_INFO input_info;
MFT_OUTPUT_DATA_BUFFER output;
const BYTE *wma_encoded_data;
@@ -6208,7 +6209,7 @@ static void test_wma_decoder(void)
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
ret = IMFSample_Release(sample);
ok(ret == 0, "Release returned %u\n", ret);
- sample = create_sample(wma_encoded_data + wma_block_size, wma_block_size - wma_block_size / 2);
+ sample = create_sample(wma_encoded_data, wma_block_size + 1);
hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
todo_wine
ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
@@ -6231,16 +6232,13 @@ static void test_wma_decoder(void)
status = 0xdeadbeef;
memset(&output, 0, sizeof(output));
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
- todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
ok(output.dwStreamID == 0, "got dwStreamID %u\n", output.dwStreamID);
ok(!output.pSample, "got pSample %p\n", output.pSample);
- todo_wine
ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE ||
broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */,
"got dwStatus %#x\n", output.dwStatus);
ok(!output.pEvents, "got pEvents %p\n", output.pEvents);
- todo_wine
ok(status == 0, "got status %#x\n", status);
sample = create_sample(wma_encoded_data, wma_block_size);
@@ -6253,16 +6251,25 @@ static void test_wma_decoder(void)
status = 0xdeadbeef;
memset(&output, 0, sizeof(output));
hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
- todo_wine
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
ok(!output.pSample, "got pSample %p\n", output.pSample);
- todo_wine
ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE ||
broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */,
"got dwStatus %#x\n", output.dwStatus);
- todo_wine
ok(status == 0, "got status %#x\n", status);
+ status = 0xdeadbeef;
+ memset(&output, 0, sizeof(output));
+ output_info.cbSize = sizeof(wma_decoded_data);
+ sample = create_sample(NULL, output_info.cbSize);
+ outputs[0].pSample = sample;
+ sample = create_sample(NULL, output_info.cbSize);
+ outputs[1].pSample = sample;
+ hr = IMFTransform_ProcessOutput(transform, 0, 2, outputs, &status);
+ ok(hr == E_INVALIDARG, "ProcessOutput returned %#x\n", hr);
+ IMFSample_Release(outputs[0].pSample);
+ IMFSample_Release(outputs[1].pSample);
+
i = 1;
status = 0xdeadbeef;
output_info.cbSize = sizeof(wma_decoded_data);
@@ -6333,7 +6340,6 @@ static void test_wma_decoder(void)
ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
ok(output.pSample == sample, "got pSample %p\n", output.pSample);
ok(output.dwStatus == 0, "got dwStatus %#x\n", output.dwStatus);
- todo_wine
ok(status == 0, "got status %#x\n", status);
ret = IMFSample_Release(sample);
ok(ret == 0, "Release returned %u\n", ret);
@@ -6349,7 +6355,6 @@ static void test_wma_decoder(void)
ok(output.dwStatus == 0 ||
broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) /* Win7 */,
"got dwStatus %#x\n", output.dwStatus);
- todo_wine
ok(status == 0, "got status %#x\n", status);
check_sample(sample, NULL, 0, NULL);
ret = IMFSample_Release(sample);
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 6c198706944..a35da1cdc70 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -520,14 +520,47 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
{
+ struct wma_decoder *decoder = impl_from_IMFTransform(iface);
+ MFT_INPUT_STREAM_INFO info;
+ HRESULT hr;
+
FIXME("iface %p, id %lu, sample %p, flags %#lx stub!\n", iface, id, sample, flags);
+
+ if (!decoder->wg_transform)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info)))
+ return hr;
+
return E_NOTIMPL;
}
static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
{
+ struct wma_decoder *decoder = impl_from_IMFTransform(iface);
+ MFT_OUTPUT_STREAM_INFO info;
+ HRESULT hr;
+
FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status);
+
+ if (count > 1)
+ return E_INVALIDARG;
+
+ if (!decoder->wg_transform)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info)))
+ return hr;
+
+ *status = 0;
+ samples[0].dwStatus = 0;
+ if (!samples[0].pSample)
+ {
+ samples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE;
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
+ }
+
return E_NOTIMPL;
}
--
2.34.1
Feb. 28, 2022
Re: [PATCH v2 2/6] dlls/kernelbase, programs/conhost: return key state in ReadConsoleW with control
by Eric Pouech
Le 28/02/2022 à 16:50, Jacek Caban a écrit :
> On 2/27/22 15:23, Eric Pouech wrote:
>> Le 25/02/2022 à 20:19, Jacek Caban a écrit :
>>> On 2/23/22 18:05, Eric Pouech wrote:
>>>> diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h
>>>> index e5f70aa3ca4..35876689419 100644
>>>> --- a/programs/conhost/conhost.h
>>>> +++ b/programs/conhost/conhost.h
>>>> @@ -88,6 +88,7 @@ struct console
>>>> unsigned int read_ioctl; /* current read
>>>> ioctl */
>>>> size_t pending_read; /* size of
>>>> pending read buffer */
>>>> struct edit_line edit_line; /* edit line
>>>> context */
>>>> + unsigned int key_state;
>>>> struct console_window *window;
>>>> WCHAR *title; /* console title */
>>>> struct history_line **history; /* lines history */
>>>
>>>
>>> I think it would fit better in edit_line struct.
>>
>>
>> as the edit struct is zeroed upon completion (and before returning
>> the result), it would also require moving
>>
>> - write of the key state inside the edit buffer in
>> process_console_input() (insert 2 new characters for the DWORD)
>>
>> - hence handle in process_console_input that the layout of the buffer
>> differs depending on ioctl
>>
>> I thought it was more readable to keep the edit logic as is, and and
>> on top of it returning or not the keystate flag
>>
>> but see no reason why it wouldn't be doable
>
>
> Agreed, it's probably not worth the complication. That's fine with me.
>
>
> Thanks,
>
> Jacek
>
ok I'll resend with the fix on the delta_y inversion (likely tomorrow
depending on what Alexandre commits or not tonight)
A+
Feb. 28, 2022
Re: [PATCH vkd3d v2 3/7] vkd3d-shader/hlsl: Parse logical OR.
by Francisco Casas
Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
February 24, 2022 3:45 PM, "Zebediah Figura" <zfigura(a)codeweavers.com> wrote:
> From: Giovanni Mascellani <gmascellani(a)codeweavers.com>
>
> Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> ---
> v2: No changes.
>
> libs/vkd3d-shader/hlsl.y | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
> index bb24e39de..4cdb471e8 100644
> --- a/libs/vkd3d-shader/hlsl.y
> +++ b/libs/vkd3d-shader/hlsl.y
> @@ -3706,7 +3706,7 @@ logicor_expr:
> logicand_expr
> | logicor_expr OP_OR logicand_expr
> {
> - hlsl_fixme(ctx, &@$, "Logical OR.");
> + $$ = add_binary_logical_expr_merge(ctx, $1, $3, HLSL_OP2_LOGIC_OR, &@2);
> }
>
> conditional_expr:
> --
> 2.35.1
Feb. 28, 2022
Re: [PATCH v2 1/6] kernelbase/console, programs/conhost: support CONSOLE_READCONSOLE_CONTROL in ReadConsoleW
by Jacek Caban
On 2/27/22 15:02, Eric Pouech wrote:
> Le 25/02/2022 à 20:10, Jacek Caban a écrit :
>> Hi Eric,
>>
>> The series looks mostly good for me.
>>
>> On 2/23/22 18:05, Eric Pouech wrote:
>>> + if (initial_len && edit_line_grow( console, initial_len + 1 ))
>>> + {
>>> + unsigned offset = edit_line_string_width( initial,
>>> initial_len );
>>> + if (offset > ctx->home_x)
>>> + {
>>> + int deltay;
>>> + offset -= ctx->home_x;
>>> + deltay = offset / console->active->width;
>>> + ctx->home_y = (deltay >= ctx->home_y) ? ctx->home_y -
>>> deltay : 0;
>>
>>
>> Isn't the logic reverted here?
> yes
>>
>>
>>> + ctx->home_x = console->active->width - 1 - (offset %
>>> console->active->width);
>>
>>
>> I wonder if we should use use 0 for home_x in case of deltay >= home_y.
>
> actually, this was more to protect the rest of the code which isn't
> prepared for negative coordinates
>
> IIRC I tested this UC and native supports this
>
> changing the code for handling such case is not immediate, but I
> thought that the ratio real value vs effort was near 0 and not worth
> for now going for it
>
> so we could either add a FIXME (and leave the 0) or add a FIXME and
> return an error
I commented mostly based on the line above (which seems more important).
If it's closer to what we will eventually want (if we support negative
home_y someday), that's fine with me, as long as we don't crash.
Thanks,
Jacek
Feb. 28, 2022
Re: [PATCH v2 2/6] dlls/kernelbase, programs/conhost: return key state in ReadConsoleW with control
by Jacek Caban
On 2/27/22 15:23, Eric Pouech wrote:
> Le 25/02/2022 à 20:19, Jacek Caban a écrit :
>> On 2/23/22 18:05, Eric Pouech wrote:
>>> diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h
>>> index e5f70aa3ca4..35876689419 100644
>>> --- a/programs/conhost/conhost.h
>>> +++ b/programs/conhost/conhost.h
>>> @@ -88,6 +88,7 @@ struct console
>>> unsigned int read_ioctl; /* current read
>>> ioctl */
>>> size_t pending_read; /* size of pending
>>> read buffer */
>>> struct edit_line edit_line; /* edit line
>>> context */
>>> + unsigned int key_state;
>>> struct console_window *window;
>>> WCHAR *title; /* console title */
>>> struct history_line **history; /* lines history */
>>
>>
>> I think it would fit better in edit_line struct.
>
>
> as the edit struct is zeroed upon completion (and before returning the
> result), it would also require moving
>
> - write of the key state inside the edit buffer in
> process_console_input() (insert 2 new characters for the DWORD)
>
> - hence handle in process_console_input that the layout of the buffer
> differs depending on ioctl
>
> I thought it was more readable to keep the edit logic as is, and and
> on top of it returning or not the keystate flag
>
> but see no reason why it wouldn't be doable
Agreed, it's probably not worth the complication. That's fine with me.
Thanks,
Jacek
Feb. 28, 2022
Re: [PATCH] win32u: Fix NtUserCallHooks return value.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Feb. 28, 2022