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
June 2022
- 68 participants
- 3274 messages
[PATCH v2 5/6] winegstreamer: Check H264 ProcessOutput sample against actual image size.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)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(a)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;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
[PATCH v2 4/6] winegstreamer: Use H264 input media type frame size when specified.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)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(a)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;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
[PATCH v2 3/6] winegstreamer: Implement H264 SetOutputType by reconfiguring the pipeline.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)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(a)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;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
[PATCH v2 2/6] winegstreamer: Release wg_transform output sample when too small.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)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;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
[PATCH v2 1/6] mf/tests: Add todo_wine for newer FFmpeg versions.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)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);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
[PATCH v2 0/6] MR302: winegstreamer: Some wg_transform H264 fixes for Mortal Kombat 11 and Yakuza 4.
by Rémi Bernon
--
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.
https://gitlab.winehq.org/wine/wine/-/merge_requests/302
June 23, 2022
Re: [PATCH v2 0/1] MR303: win32u: Don't report cloned monitors in EnumDisplayMonitors(). - approved
by Zhiyi Zhang (@zhiyi)
This merge request was approved by Zhiyi Zhang.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/303
June 23, 2022
[PATCH v2 1/1] win32u: Don't report cloned monitors in EnumDisplayMonitors().
by Arkadiusz Hiler
From: Arkadiusz Hiler <ahiler(a)codeweavers.com>
Based on:
ca39b1c22dfa ("user32: Don't report mirrored slave monitors in EnumDisplayMonitors.")
2affb854e524 ("user32: Change slave to a more neutral word.")
Which seems to got lost during:
318673405c62 ("win32u: Move NtUserEnumDisplayMonitors implementation from user32.")
Fixes regression with Elite Dangerous launcher freezing when cloned
displays are present.
Signed-off-by: Arkadiusz Hiler <ahiler(a)codeweavers.com>
---
dlls/win32u/sysparams.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index a8c1d977c7d..0a9cb76cb6d 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -1249,9 +1249,10 @@ static BOOL update_display_cache_from_registry(void)
DWORD adapter_id, monitor_id, monitor_count = 0, size;
KEY_BASIC_INFORMATION key;
struct adapter *adapter;
- struct monitor *monitor;
+ struct monitor *monitor, *monitor2;
HANDLE mutex = NULL;
NTSTATUS status;
+ BOOL is_cloned;
BOOL ret;
/* If user driver did initialize the registry, then exit */
@@ -1295,6 +1296,22 @@ static BOOL update_display_cache_from_registry(void)
break;
}
+ is_cloned = FALSE;
+ LIST_FOR_EACH_ENTRY(monitor2, &monitors, struct monitor, entry)
+ {
+ if (EqualRect(&monitor2->rc_monitor, &monitor->rc_monitor))
+ {
+ is_cloned = TRUE;
+ break;
+ }
+ }
+
+ if (is_cloned)
+ {
+ free( monitor );
+ continue;
+ }
+
monitor->handle = UlongToHandle( ++monitor_count );
list_add_tail( &monitors, &monitor->entry );
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/303
June 23, 2022
[PATCH v2 0/1] MR303: win32u: Don't report cloned monitors in EnumDisplayMonitors().
by Arek Hiler (@ivyl)
Based on:
ca39b1c22dfa ("user32: Don't report mirrored slave monitors in EnumDisplayMonitors.")
2affb854e524 ("user32: Change slave to a more neutral word.")
Which seems to got lost during:
318673405c62 ("win32u: Move NtUserEnumDisplayMonitors implementation from user32.")
Fixes regression with Elite Dangerous launcher freezing when cloned
displays are present.
Signed-off-by: Arkadiusz Hiler <ahiler(a)codeweavers.com>
CC: @zhiyi @jacek
--
v2: win32u: Don't report cloned monitors in EnumDisplayMonitors().
https://gitlab.winehq.org/wine/wine/-/merge_requests/303
June 23, 2022
Re: [PATCH 0/1] MR303: win32u: Don't report cloned monitors in EnumDisplayMonitors().
by Zhiyi Zhang (@zhiyi)
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
> break;
> }
>
> + is_cloned = FALSE;
> + LIST_FOR_EACH_ENTRY(monitor2, &monitors, struct monitor, entry)
> + {
> + if (EqualRect(&monitor2->rc_monitor, &monitor->rc_monitor))
> + {
> + is_cloned = TRUE;
> + break;
> + }
> + }
> +
> + if (is_cloned)
> + continue;
If the monitor to be added is the last monitor and is a cloned replica, this will leak the monitor pointer.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/303#note_2552
June 23, 2022