-- v2: winegstreamer: Use an atomic queue for wg_transform input buffers. winegstreamer: Check H264 ProcessOutput sample against actual image size. winegstreamer: Use H264 input media type frame size when specified. winegstreamer: Implement H264 SetOutputType by reconfiguring the pipeline. winegstreamer: Release wg_transform output sample when too small. mf/tests: Add todo_wine for newer FFmpeg versions.
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 2f3ee3151da..5f26b1a6238 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -5911,7 +5911,7 @@ static void check_sample_pcm16_(int line, IMFSample *sample, const BYTE *expect_ if (expect - value + 512 > 1024) break; }
- todo_wine_if(todo) + todo_wine_if(todo && i < length / 2) ok_(__FILE__, line)(i == length, "unexpected buffer data\n");
if (output_file) WriteFile(output_file, buffer, length, &length, NULL); @@ -6544,6 +6544,9 @@ static void test_wma_decoder(void) hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
winetest_pop_context(); + + /* some FFmpeg version request more input to complete decoding */ + if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT && i == 2) break; } todo_wine ok(wmadec_data_len == 0, "missing %#lx bytes\n", wmadec_data_len);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117481
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: mf:mf prints too much data (39704 bytes)
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf prints too much data (44524 bytes)
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/wg_transform.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index e05432f6ac7..b0048fad644 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -314,10 +314,15 @@ static struct wg_sample *transform_request_sample(gsize size, void *context)
GST_LOG("size %#zx, context %p", size, transform);
- sample = InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL); - if (!sample || sample->max_size < size) + if (!(sample = InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL))) return NULL;
+ if (sample->max_size < size) + { + InterlockedDecrement(&sample->refcount); + return NULL; + } + return sample; }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 11 ++--- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/h264_decoder.c | 23 +++++++++- dlls/winegstreamer/main.c | 13 ++++++ dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.h | 7 ++++ dlls/winegstreamer/wg_parser.c | 1 + dlls/winegstreamer/wg_transform.c | 70 +++++++++++++++++++++++++++++++ 8 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 5f26b1a6238..afe85ddbf3c 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -7333,7 +7333,7 @@ static void test_h264_decoder(void) todo_wine ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr);
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) + while (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { hr = IMFTransform_ProcessInput(transform, 0, sample, 0); ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); @@ -7341,16 +7341,14 @@ static void test_h264_decoder(void) ok(ret <= 1, "Release returned %lu\n", ret); sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len); hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); - todo_wine + todo_wine_if(hr == MF_E_TRANSFORM_NEED_MORE_INPUT) ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr); }
ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID); ok(!!output.pSample, "got pSample %p\n", output.pSample); - todo_wine ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE, "got dwStatus %#lx\n", output.dwStatus); ok(!output.pEvents, "got pEvents %p\n", output.pEvents); - todo_wine ok(status == MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS, "got status %#lx\n", status); hr = IMFSample_GetTotalLength(output.pSample, &length); ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); @@ -7373,17 +7371,16 @@ static void test_h264_decoder(void) memset(&output, 0, sizeof(output)); output.pSample = create_sample(NULL, actual_width * actual_height * 2); hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); - todo_wine ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID); ok(!!output.pSample, "got pSample %p\n", output.pSample); ok(output.dwStatus == 0, "got dwStatus %#lx\n", output.dwStatus); ok(!output.pEvents, "got pEvents %p\n", output.pEvents); ok(status == 0, "got status %#lx\n", status); - if (hr != S_OK) goto skip_i420_tests;
hr = IMFSample_GetSampleTime(output.pSample, &time); ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + todo_wine_if(time == 1334666) /* when VA-API plugin is used */ ok(time - 333666 <= 2, "got time %I64d\n", time);
duration = 0xdeadbeef; @@ -7419,7 +7416,6 @@ static void test_h264_decoder(void)
check_sample(output.pSample, i420_frame_data, output_file);
-skip_i420_tests: ret = IMFSample_Release(output.pSample); ok(ret == 0, "Release returned %lu\n", ret);
@@ -7430,6 +7426,7 @@ skip_i420_tests: memset(&output, 0, sizeof(output)); output.pSample = create_sample(NULL, actual_width * actual_height * 2); hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + todo_wine_if(hr == S_OK) /* when VA-API plugin is used */ ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID); ok(!!output.pSample, "got pSample %p\n", output.pSample); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 8348d2e8360..14a52df5921 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -102,6 +102,7 @@ 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); +bool wg_transform_set_format(struct wg_transform *transform, struct wg_format *format);
unsigned int wg_format_get_max_size(const struct wg_format *format);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 012a7060f29..1a9dcbd561c 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -467,7 +467,28 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF IMFMediaType_Release(decoder->output_type); IMFMediaType_AddRef((decoder->output_type = type));
- if (FAILED(hr = try_create_wg_transform(decoder))) + if (decoder->wg_transform) + { + struct wg_format output_format; + mf_media_type_to_wg_format(decoder->output_type, &output_format); + + /* Don't force any specific size, H264 streams already have the metadata for it + * and will generate a MF_E_TRANSFORM_STREAM_CHANGE result later. + */ + output_format.u.video.width = 0; + output_format.u.video.height = 0; + output_format.u.video.fps_d = 0; + output_format.u.video.fps_n = 0; + + if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN + || !wg_transform_set_format(decoder->wg_transform, &output_format)) + { + IMFMediaType_Release(decoder->output_type); + decoder->output_type = NULL; + return MF_E_INVALIDMEDIATYPE; + } + } + else if (FAILED(hr = try_create_wg_transform(decoder))) { IMFMediaType_Release(decoder->output_type); decoder->output_type = NULL; diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index fc7b9d73285..fb2e8865089 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -348,6 +348,19 @@ HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample return params.result; }
+bool wg_transform_set_format(struct wg_transform *transform, struct wg_format *format) +{ + struct wg_transform_set_format_params params = + { + .transform = transform, + .format = format, + }; + + TRACE("transform %p, format %p.\n", transform, format); + + return !__wine_unix_call(unix_handle, unix_wg_transform_set_format, ¶ms); +} + BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { if (reason == DLL_PROCESS_ATTACH) diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index e9f472986ae..3a6b162c500 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -34,6 +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_set_format(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 860a8ab2a52..ed02f025b05 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -263,6 +263,12 @@ struct wg_transform_read_data_params HRESULT result; };
+struct wg_transform_set_format_params +{ + struct wg_transform *transform; + const struct wg_format *format; +}; + enum unix_funcs { unix_wg_parser_create, @@ -291,6 +297,7 @@ enum unix_funcs
unix_wg_transform_create, unix_wg_transform_destroy, + unix_wg_transform_set_format,
unix_wg_transform_push_data, unix_wg_transform_read_data, diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 7d55897aa0a..a4aa945a708 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1625,6 +1625,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_transform_create), X(wg_transform_destroy), + X(wg_transform_set_format),
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 b0048fad644..b90fde70519 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -173,6 +173,31 @@ static gboolean transform_sink_query_cb(GstPad *pad, GstObject *parent, GstQuery g_object_unref(pool); return true; } + + case GST_QUERY_CAPS: + { + GstCaps *caps, *filter, *temp; + gchar *str; + + gst_query_parse_caps(query, &filter); + caps = gst_caps_ref(transform->output_caps); + + if (filter) + { + temp = gst_caps_intersect(caps, filter); + gst_caps_unref(caps); + caps = temp; + } + + str = gst_caps_to_string(caps); + GST_INFO("Returning caps %s", str); + g_free(str); + + gst_query_set_caps_result(query, caps); + gst_caps_unref(caps); + return true; + } + default: GST_WARNING("Ignoring "%s" query.", gst_query_type_get_name(query->type)); break; @@ -525,6 +550,51 @@ out: return status; }
+NTSTATUS wg_transform_set_format(void *args) +{ + struct wg_transform_set_format_params *params = args; + struct wg_transform *transform = params->transform; + GstSample *sample; + GstEvent *event; + GstCaps *caps; + gchar *str; + + if (!(caps = wg_format_to_caps(params->format))) + { + GST_ERROR("Failed to convert format to caps."); + return STATUS_UNSUCCESSFUL; + } + + if (gst_caps_is_always_compatible(transform->output_caps, caps)) + { + gst_caps_unref(caps); + return STATUS_SUCCESS; + } + + gst_caps_unref(transform->output_caps); + transform->output_caps = caps; + + if (!gst_pad_set_caps(transform->my_sink, caps) + || !(event = gst_event_new_reconfigure()) + || !gst_pad_push_event(transform->my_sink, event)) + { + GST_ERROR("Failed to reconfigure transform."); + return STATUS_UNSUCCESSFUL; + } + + str = gst_caps_to_string(caps); + GST_INFO("Configured new caps %s.", str); + g_free(str); + + if (transform->output_sample) + gst_sample_unref(transform->output_sample); + while ((sample = gst_atomic_queue_pop(transform->output_queue))) + gst_sample_unref(sample); + transform->output_sample = NULL; + + return STATUS_SUCCESS; +} + static void wg_sample_free_notify(void *arg) { struct wg_sample *sample = arg;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117483
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: mf:mf prints too much data (39708 bytes)
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf prints too much data (39776 bytes)
From: Rémi Bernon rbernon@codeweavers.com
Updating the internal stream format frame size accordingly.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 87 +++++++++++++++++-------------- dlls/winegstreamer/h264_decoder.c | 7 +++ 2 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index afe85ddbf3c..7b598ba7dac 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6674,14 +6674,17 @@ static void test_h264_decoder(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264_ES), }, }; - static const media_type_desc default_outputs[] = + static const DWORD input_width = 120, input_height = 248; + static const DWORD align_input_width = (input_width + 15) & ~15; + static const DWORD align_input_height = (input_height + 15) & ~15; + const media_type_desc default_outputs[] = { { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 1920), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, input_width), ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), @@ -6691,7 +6694,7 @@ static void test_h264_decoder(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 1920), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, input_width), ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), @@ -6701,7 +6704,7 @@ static void test_h264_decoder(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 1920), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, input_width), ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), @@ -6711,7 +6714,7 @@ static void test_h264_decoder(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 1920), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, input_width), ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), @@ -6721,97 +6724,98 @@ static void test_h264_decoder(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 3840), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, input_width * 2), ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), }, }; - static const media_type_desc default_outputs_extra[] = + const media_type_desc default_outputs_extra[] = { { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3110400), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, input_width * input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3110400), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, input_width * input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3110400), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, input_width * input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3110400), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, input_width * input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 4147200), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, input_width * input_height * 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), }, }; - static const media_type_desc default_outputs_win7[] = + const media_type_desc default_outputs_win7[] = { { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3133440), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, align_input_width * align_input_height * 3 / 2), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3133440), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, align_input_width * align_input_height * 3 / 2), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3133440), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, align_input_width * align_input_height * 3 / 2), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3133440), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, align_input_width * align_input_height * 3 / 2), }, { - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 4177920), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, align_input_width * align_input_height * 2), }, }; - static const struct attribute_desc input_type_desc[] = + const struct attribute_desc input_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), {0}, }; - static const struct attribute_desc minimal_output_type_desc[] = + const struct attribute_desc minimal_output_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), {0}, }; - static const struct attribute_desc output_type_desc[] = + const struct attribute_desc output_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1080), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 2, 1), ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 3840), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3840 * 1080 * 3 / 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3840 * input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), {0}, }; - static const struct attribute_desc output_type_desc_win7[] = + const struct attribute_desc output_type_desc_win7[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), - ATTR_RATIO(MF_MT_FRAME_SIZE, 1920, 1088), + ATTR_RATIO(MF_MT_FRAME_SIZE, align_input_width, align_input_height), ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000), ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 2, 1), ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 3840), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3840 * 1088 * 3 / 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3840 * align_input_height * 3 / 2), ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), {0}, }; @@ -7017,6 +7021,9 @@ static void test_h264_decoder(void) init_media_type(media_type, input_type_desc, 2); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, -1); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 1, "Release returned %lu\n", ret);
@@ -7026,7 +7033,8 @@ static void test_h264_decoder(void) ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); ok(output_info.dwFlags == flags, "got dwFlags %#lx\n", output_info.dwFlags); todo_wine - ok(output_info.cbSize == 1920 * 1080 * 2 || broken(output_info.cbSize == 1920 * 1088 * 2) /* Win7 */, + ok(output_info.cbSize == input_width * input_height * 2 + || broken(output_info.cbSize == align_input_width * align_input_height * 2) /* Win7 */, "got cbSize %#lx\n", output_info.cbSize); ok(output_info.cbAlignment == 0, "got cbAlignment %#lx\n", output_info.cbAlignment);
@@ -7113,7 +7121,8 @@ static void test_h264_decoder(void) ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); ok(output_info.dwFlags == flags, "got dwFlags %#lx\n", output_info.dwFlags); todo_wine - ok(output_info.cbSize == 1920 * 1080 * 2 || broken(output_info.cbSize == 1920 * 1088 * 2) /* Win7 */, + ok(output_info.cbSize == input_width * input_height * 2 + || broken(output_info.cbSize == align_input_width * align_input_height * 2) /* Win7 */, "got cbSize %#lx\n", output_info.cbSize); ok(output_info.cbAlignment == 0, "got cbAlignment %#lx\n", output_info.cbAlignment);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 1a9dcbd561c..2ece7dee5b1 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -401,6 +401,7 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM { struct h264_decoder *decoder = impl_from_IMFTransform(iface); GUID major, subtype; + UINT64 frame_size; HRESULT hr; ULONG i;
@@ -429,6 +430,12 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM IMFMediaType_Release(decoder->input_type); IMFMediaType_AddRef((decoder->input_type = type));
+ if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) + { + decoder->wg_format.u.video.width = frame_size >> 32; + decoder->wg_format.u.video.height = (UINT32)frame_size; + } + return S_OK; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117484
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001
=== w7u_adm (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001
=== w7u_el (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001
=== debian11 (32 bit report) ===
Report validation errors: mf:mf prints too much data (39752 bytes)
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf prints too much data (39740 bytes)
From: Rémi Bernon rbernon@codeweavers.com
Instead of maximum output sample size returned from GetOutputStreamInfo.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 2 +- dlls/winegstreamer/h264_decoder.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 7b598ba7dac..77cf40e971b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -7254,7 +7254,7 @@ static void test_h264_decoder(void)
status = 0; memset(&output, 0, sizeof(output)); - output.pSample = create_sample(NULL, actual_width * actual_height * 2); + output.pSample = create_sample(NULL, actual_width * actual_height * 3 / 2); hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID); diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 2ece7dee5b1..561a3c1578c 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -581,10 +581,11 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) { struct h264_decoder *decoder = impl_from_IMFTransform(iface); - MFT_OUTPUT_STREAM_INFO info; struct wg_sample *wg_sample; struct wg_format wg_format; + UINT32 sample_size; UINT64 frame_rate; + GUID subtype; HRESULT hr;
TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status); @@ -592,9 +593,6 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, if (count != 1) return E_INVALIDARG;
- if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info))) - return hr; - if (!decoder->wg_transform) return MF_E_TRANSFORM_TYPE_NOT_SET;
@@ -602,10 +600,16 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, samples[0].dwStatus = 0; if (!samples[0].pSample) return E_INVALIDARG;
+ if (FAILED(hr = IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &subtype))) + return hr; + if (FAILED(hr = MFCalculateImageSize(&subtype, decoder->wg_format.u.video.width, + decoder->wg_format.u.video.height, &sample_size))) + return hr; + if (FAILED(hr = wg_sample_create_mf(samples[0].pSample, &wg_sample))) return hr;
- if (wg_sample->max_size < info.cbSize) + if (wg_sample->max_size < sample_size) { wg_sample_release(wg_sample); return MF_E_BUFFERTOOSMALL;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117485
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001
=== w7u_adm (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 0858:mf: unhandled exception c0000005 at 7797227C
=== w7u_el (32 bit report) ===
mf: mf.c:7051: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7051: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7051: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7079: Test failed: SetOutputType returned 0. mf.c:7082: Test failed: SetOutputType returned 0xc00d36b4. mf.c:7100: Test failed: out 0: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 0: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 1: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 1: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 2: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 2: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 3: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 3: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 44640 mf.c:7100: Test failed: out 4: "MF_MT_FRAME_SIZE" mismatch, type 21, value 120:248 mf.c:7100: Test failed: out 4: "MF_MT_SAMPLE_SIZE" mismatch, type 19, value 59520 mf.c:7226: Test failed: out 0: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 1: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 2: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 3: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001 mf.c:7226: Test failed: out 4: "MF_MT_FRAME_RATE" mismatch, type 21, value 30000:1001
=== w1064v1507 (64 bit report) ===
Report validation errors: mf:mf crashed (c0000374)
=== debian11 (32 bit report) ===
Report validation errors: mf:mf prints too much data (39732 bytes)
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf prints too much data (39794 bytes)
From: Rémi Bernon rbernon@codeweavers.com
And push them one by one until an output buffer is generated, to avoid generating multiple output buffers without a backing wg_sample.
This makes zero-copy more efficient for games which queue multiple input buffers before checking output, such as Yakuza 4.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/wg_transform.c | 40 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index b90fde70519..73bec6d35e4 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -51,10 +51,10 @@ struct wg_transform GstPad *my_src, *my_sink; GstPad *their_sink, *their_src; GstSegment segment; - GstBufferList *input; guint input_max_length; guint output_plane_align; struct wg_sample *output_wg_sample; + GstAtomicQueue *input_queue; GstAtomicQueue *output_queue; GstSample *output_sample; bool output_caps_changed; @@ -240,9 +240,11 @@ NTSTATUS wg_transform_destroy(void *args) { struct wg_transform *transform = args; GstSample *sample; + GstBuffer *buffer;
- if (transform->input) - gst_buffer_list_unref(transform->input); + while ((buffer = gst_atomic_queue_pop(transform->input_queue))) + gst_buffer_unref(buffer); + gst_atomic_queue_unref(transform->input_queue);
gst_element_set_state(transform->container, GST_STATE_NULL);
@@ -371,7 +373,7 @@ NTSTATUS wg_transform_create(void *args) return STATUS_NO_MEMORY; if (!(transform->container = gst_bin_new("wg_transform"))) goto out; - if (!(transform->input = gst_buffer_list_new())) + if (!(transform->input_queue = gst_atomic_queue_new(8))) goto out; if (!(transform->output_queue = gst_atomic_queue_new(8))) goto out; @@ -538,8 +540,8 @@ out: wg_allocator_destroy(transform->allocator); if (transform->output_queue) gst_atomic_queue_unref(transform->output_queue); - if (transform->input) - gst_buffer_list_unref(transform->input); + if (transform->input_queue) + gst_atomic_queue_unref(transform->input_queue); if (transform->container) { gst_element_set_state(transform->container, GST_STATE_NULL); @@ -610,7 +612,7 @@ NTSTATUS wg_transform_push_data(void *args) GstBuffer *buffer; guint length;
- length = gst_buffer_list_length(transform->input); + length = gst_atomic_queue_length(transform->input_queue); if (length >= transform->input_max_length) { GST_INFO("Refusing %u bytes, %u buffers already queued", sample->size, length); @@ -636,7 +638,7 @@ NTSTATUS wg_transform_push_data(void *args) GST_BUFFER_DURATION(buffer) = sample->duration * 100; if (!(sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)) GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); - gst_buffer_list_insert(transform->input, -1, buffer); + gst_atomic_queue_push(transform->input_queue, buffer);
params->result = S_OK; return STATUS_SUCCESS; @@ -791,9 +793,8 @@ NTSTATUS wg_transform_read_data(void *args) struct wg_transform *transform = params->transform; struct wg_sample *sample = params->sample; struct wg_format *format = params->format; + GstBuffer *output_buffer, *input_buffer; GstFlowReturn ret = GST_FLOW_OK; - GstBuffer *output_buffer; - GstBufferList *input; GstCaps *output_caps; bool discard_data; NTSTATUS status; @@ -802,17 +803,14 @@ NTSTATUS wg_transform_read_data(void *args) InterlockedIncrement(&sample->refcount); InterlockedExchangePointer((void **)&transform->output_wg_sample, sample);
- if (!gst_buffer_list_length(transform->input)) - GST_DEBUG("Not input buffer queued"); - else if ((input = gst_buffer_list_new())) + while (!transform->output_sample && ret == GST_FLOW_OK) { - ret = gst_pad_push_list(transform->my_src, transform->input); - transform->input = input; - } - else - { - GST_ERROR("Failed to allocate new input queue"); - ret = GST_FLOW_ERROR; + if ((input_buffer = gst_atomic_queue_pop(transform->input_queue))) + ret = gst_pad_push(transform->my_src, input_buffer); + transform->output_sample = gst_atomic_queue_pop(transform->output_queue); + + if (!input_buffer) + break; }
/* Remove the sample so transform_request_sample cannot use it */ @@ -826,7 +824,7 @@ NTSTATUS wg_transform_read_data(void *args) return STATUS_UNSUCCESSFUL; }
- if (!transform->output_sample && !(transform->output_sample = gst_atomic_queue_pop(transform->output_queue))) + if (!transform->output_sample) { sample->size = 0; params->result = MF_E_TRANSFORM_NEED_MORE_INPUT;
v2: Fix compilation by removing `static` qualifier.