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 | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 166a357409a..f36b168e658 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6643,9 +6643,7 @@ static void test_h264_decoder(void) goto failed;
hr = IMFTransform_GetAttributes(transform, &attributes); - todo_wine ok(hr == S_OK, "GetAttributes returned %#lx\n", hr); - if (hr != S_OK) MFCreateAttributes(&attributes, 0); hr = IMFAttributes_SetUINT32(attributes, &MF_LOW_LATENCY, 1); ok(hr == S_OK, "SetUINT32 returned %#lx\n", hr); IMFAttributes_Release(attributes); diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 2fafaea4fff..fdc0d6addeb 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -119,7 +119,7 @@ static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD i static HRESULT WINAPI transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) { FIXME("iface %p, attributes %p stub!\n", iface, attributes); - return E_NOTIMPL; + return MFCreateAttributes(attributes, 0); }
static HRESULT WINAPI transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes)
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 | 3 --- dlls/winegstreamer/h264_decoder.c | 38 +++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index f36b168e658..09efdc0c75f 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6715,7 +6715,6 @@ static void test_h264_decoder(void) hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == E_INVALIDARG, "SetInputType returned %#lx.\n", hr); init_media_type(media_type, input_type_desc, 1); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); @@ -6723,10 +6722,8 @@ static void test_h264_decoder(void) ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); init_media_type(media_type, input_type_desc, 2); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); - todo_wine ok(ret == 1, "Release returned %lu\n", ret);
flags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE; diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index fdc0d6addeb..318998d02a3 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -28,10 +28,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+static const GUID *const h264_decoder_input_types[] = +{ + &MFVideoFormat_H264, + &MFVideoFormat_H264_ES, +}; + struct h264_decoder { IMFTransform IMFTransform_iface; LONG refcount; + IMFMediaType *input_type; };
static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) @@ -77,7 +84,11 @@ static ULONG WINAPI transform_Release(IMFTransform *iface) TRACE("iface %p decreasing refcount to %lu.\n", decoder, refcount);
if (!refcount) + { + if (decoder->input_type) + IMFMediaType_Release(decoder->input_type); free(decoder); + }
return refcount; } @@ -163,8 +174,31 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { - FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); - return E_NOTIMPL; + struct h264_decoder *decoder = impl_from_IMFTransform(iface); + GUID major, subtype; + HRESULT hr; + ULONG i; + + TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags); + + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || + FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return E_INVALIDARG; + + if (!IsEqualGUID(&major, &MFMediaType_Video)) + return MF_E_INVALIDMEDIATYPE; + + for (i = 0; i < ARRAY_SIZE(h264_decoder_input_types); ++i) + if (IsEqualGUID(&subtype, h264_decoder_input_types[i])) + break; + if (i == ARRAY_SIZE(h264_decoder_input_types)) + return MF_E_INVALIDMEDIATYPE; + + if (decoder->input_type) + IMFMediaType_Release(decoder->input_type); + IMFMediaType_AddRef((decoder->input_type = type)); + + return S_OK; }
static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110452
Your paranoid android.
=== w7u_adm (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
This adds some todo_wine because we were not enumerating any media type before, and we do now.
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 | 59 +++++++------ dlls/winegstreamer/h264_decoder.c | 133 +++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 33 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 09efdc0c75f..7e0cb777327 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -106,14 +106,16 @@ struct attribute_desc const char *name; PROPVARIANT value; BOOL ratio; + BOOL todo; + BOOL todo_value; }; typedef struct attribute_desc media_type_desc[32];
-#define ATTR_GUID(k, g) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}} -#define ATTR_UINT32(k, v) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}} -#define ATTR_BLOB(k, p, n) {.key = &k, .name = #k, {.vt = VT_VECTOR | VT_UI1, .caub = {.pElems = (void *)p, .cElems = n}}} -#define ATTR_RATIO(k, n, d) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.HighPart = n, .LowPart = d}}, .ratio = TRUE} -#define ATTR_UINT64(k, v) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.QuadPart = v}}} +#define ATTR_GUID(k, g, ...) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}, __VA_ARGS__ } +#define ATTR_UINT32(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}, __VA_ARGS__ } +#define ATTR_BLOB(k, p, n, ...) {.key = &k, .name = #k, {.vt = VT_VECTOR | VT_UI1, .caub = {.pElems = (void *)p, .cElems = n}}, __VA_ARGS__ } +#define ATTR_RATIO(k, n, d, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.HighPart = n, .LowPart = d}}, .ratio = TRUE, __VA_ARGS__ } +#define ATTR_UINT64(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.QuadPart = v}}, __VA_ARGS__ }
#define check_media_type(a, b, c) check_attributes_(__LINE__, (IMFAttributes *)a, b, c) #define check_attributes(a, b, c) check_attributes_(__LINE__, a, b, c) @@ -127,6 +129,7 @@ static void check_attributes_(int line, IMFAttributes *attributes, const struct for (i = 0; i < limit && desc[i].key; ++i) { hr = IMFAttributes_GetItem(attributes, desc[i].key, &value); + todo_wine_if(desc[i].todo) ok_(__FILE__, line)(hr == S_OK, "%s missing, hr %#lx\n", debugstr_a(desc[i].name), hr); if (hr != S_OK) continue;
@@ -153,6 +156,7 @@ static void check_attributes_(int line, IMFAttributes *attributes, const struct }
ret = PropVariantCompareEx(&value, &desc[i].value, 0, 0); + todo_wine_if(desc[i].todo_value) ok_(__FILE__, line)(ret == 0, "%s mismatch, type %u, value %s\n", debugstr_a(desc[i].name), value.vt, buffer); } @@ -6545,70 +6549,70 @@ static void test_h264_decoder(void) 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_RATIO(MF_MT_FRAME_SIZE, 80, 80), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80), + ATTR_RATIO(MF_MT_FRAME_SIZE, 80, 80, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600, .todo_value = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80, .todo_value = TRUE), /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */ ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), - ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE), }, { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), 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_RATIO(MF_MT_FRAME_SIZE, 80, 80), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80), + ATTR_RATIO(MF_MT_FRAME_SIZE, 80, 80, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600, .todo_value = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80, .todo_value = TRUE), /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */ ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), - ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE), }, { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), 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_RATIO(MF_MT_FRAME_SIZE, 80, 80), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80), + ATTR_RATIO(MF_MT_FRAME_SIZE, 80, 80, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600, .todo_value = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80, .todo_value = TRUE), /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */ ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), - ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE), }, { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), 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_RATIO(MF_MT_FRAME_SIZE, 80, 80), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80), + ATTR_RATIO(MF_MT_FRAME_SIZE, 80, 80, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 9600, .todo_value = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 80, .todo_value = TRUE), /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */ ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), - ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE), }, { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), 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_RATIO(MF_MT_FRAME_SIZE, 80, 80), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, 12800), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 160), + ATTR_RATIO(MF_MT_FRAME_SIZE, 80, 80, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 12800, .todo_value = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 160, .todo_value = TRUE), /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */ ATTR_UINT32(MF_MT_INTERLACE_MODE, 7), ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), - ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE), }, };
@@ -6651,7 +6655,6 @@ static void test_h264_decoder(void) /* no output type is available before an input type is set */
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); - todo_wine ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr);
/* setting output media type first doesn't work */ @@ -6755,9 +6758,7 @@ static void test_h264_decoder(void) ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); } - todo_wine ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); - todo_wine ok(i == 5, "%lu output media types\n", i);
/* check required output media type attributes */ @@ -6929,9 +6930,7 @@ static void test_h264_decoder(void) ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); } - todo_wine ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); - todo_wine ok(i == 5, "%lu output media types\n", i);
/* and generate a new one as well in a temporary directory */ diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 318998d02a3..c84f84ece28 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -33,6 +33,14 @@ static const GUID *const h264_decoder_input_types[] = &MFVideoFormat_H264, &MFVideoFormat_H264_ES, }; +static const GUID *const h264_decoder_output_types[] = +{ + &MFVideoFormat_NV12, + &MFVideoFormat_YV12, + &MFVideoFormat_IYUV, + &MFVideoFormat_I420, + &MFVideoFormat_YUY2, +};
struct h264_decoder { @@ -46,6 +54,95 @@ static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) return CONTAINING_RECORD(iface, struct h264_decoder, IMFTransform_iface); }
+static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type) +{ + UINT32 value, width, height; + UINT64 ratio; + GUID subtype; + HRESULT hr; + + if (FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype))) + return hr; + + if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &ratio))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_SIZE, &ratio))) + ratio = (UINT64)1920 << 32 | 1080; + if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ratio))) + return hr; + } + width = ratio >> 32; + height = ratio; + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_RATE, &ratio))) + ratio = (UINT64)30000 << 32 | 1001; + if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ratio))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio))) + ratio = (UINT64)1 << 32 | 1; + if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL))) + { + if ((!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_SAMPLE_SIZE, &value))) && + FAILED(hr = MFCalculateImageSize(&subtype, width, height, &value))) + return hr; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, value))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_DEFAULT_STRIDE, NULL))) + { + if ((!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_DEFAULT_STRIDE, &value))) && + FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG *)&value))) + return hr; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, value))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_INTERLACE_MODE, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) + value = MFVideoInterlace_MixedInterlaceOrProgressive; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_INTERLACE_MODE, value))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) + value = 1; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_VIDEO_ROTATION, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) + value = 0; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_VIDEO_ROTATION, value))) + return hr; + } + + if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) + { + if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) + value = 1; + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) + return hr; + } + + return S_OK; +} + static HRESULT WINAPI transform_QueryInterface(IMFTransform *iface, REFIID iid, void **out) { struct h264_decoder *decoder = impl_from_IMFTransform(iface); @@ -168,8 +265,38 @@ static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type) { - FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); - return E_NOTIMPL; + struct h264_decoder *decoder = impl_from_IMFTransform(iface); + IMFMediaType *media_type; + const GUID *output_type; + HRESULT hr; + + TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type); + + if (!decoder->input_type) + return MF_E_TRANSFORM_TYPE_NOT_SET; + + *type = NULL; + + if (index >= ARRAY_SIZE(h264_decoder_output_types)) + return MF_E_NO_MORE_TYPES; + output_type = h264_decoder_output_types[index]; + + if (FAILED(hr = MFCreateMediaType(&media_type))) + return hr; + + if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) + goto done; + if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, output_type))) + goto done; + + hr = fill_output_media_type(media_type, NULL); + +done: + if (SUCCEEDED(hr)) + IMFMediaType_AddRef((*type = media_type)); + + IMFMediaType_Release(media_type); + return hr; }
static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) @@ -182,7 +309,7 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags);
if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || - FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) return E_INVALIDARG;
if (!IsEqualGUID(&major, &MFMediaType_Video))
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Required by Shadow Warrior 2.
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 | 23 +++++++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 7e0cb777327..95b78fd39fb 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6708,9 +6708,7 @@ static void test_h264_decoder(void) ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); } - todo_wine ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); - todo_wine ok(i == 2 || broken(i == 1) /* Win7 */, "%lu input media types\n", i);
/* check required input media type attributes */ diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index c84f84ece28..c587b6d185e 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -258,8 +258,27 @@ static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD strea static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type) { - FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); - return E_NOTIMPL; + IMFMediaType *media_type; + const GUID *subtype; + HRESULT hr; + + TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type); + + *type = NULL; + + if (index >= ARRAY_SIZE(h264_decoder_input_types)) + return MF_E_NO_MORE_TYPES; + subtype = h264_decoder_input_types[index]; + + if (FAILED(hr = MFCreateMediaType(&media_type))) + return hr; + + if (SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)) && + SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, subtype))) + IMFMediaType_AddRef((*type = media_type)); + + IMFMediaType_Release(media_type); + return hr; }
static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id,
Signed-off-by: Nikolay Sivov nsivov@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 | 3 --- dlls/winegstreamer/h264_decoder.c | 39 +++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 95b78fd39fb..e58d8278b82 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6663,7 +6663,6 @@ static void test_h264_decoder(void) ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); init_media_type(media_type, default_outputs[0], -1); hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - todo_wine ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %lu\n", ret); @@ -6784,10 +6783,8 @@ static void test_h264_decoder(void) init_media_type(media_type, output_type_desc_win7, ARRAY_SIZE(output_type_desc_win7) - 1); hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); } - todo_wine ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); - todo_wine ok(ret == 1, "Release returned %lu\n", ret);
flags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE; diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index c587b6d185e..2f4b42ed101 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -47,6 +47,7 @@ struct h264_decoder IMFTransform IMFTransform_iface; LONG refcount; IMFMediaType *input_type; + IMFMediaType *output_type; };
static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) @@ -184,6 +185,8 @@ static ULONG WINAPI transform_Release(IMFTransform *iface) { if (decoder->input_type) IMFMediaType_Release(decoder->input_type); + if (decoder->output_type) + IMFMediaType_Release(decoder->output_type); free(decoder); }
@@ -340,6 +343,12 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM if (i == ARRAY_SIZE(h264_decoder_input_types)) return MF_E_INVALIDMEDIATYPE;
+ if (decoder->output_type) + { + IMFMediaType_Release(decoder->output_type); + decoder->output_type = NULL; + } + if (decoder->input_type) IMFMediaType_Release(decoder->input_type); IMFMediaType_AddRef((decoder->input_type = type)); @@ -349,8 +358,34 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { - FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); - return E_NOTIMPL; + struct h264_decoder *decoder = impl_from_IMFTransform(iface); + GUID major, subtype; + HRESULT hr; + ULONG i; + + TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags); + + if (!decoder->input_type) + return MF_E_TRANSFORM_TYPE_NOT_SET; + + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || + FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return hr; + + if (!IsEqualGUID(&major, &MFMediaType_Video)) + return MF_E_INVALIDMEDIATYPE; + + for (i = 0; i < ARRAY_SIZE(h264_decoder_output_types); ++i) + if (IsEqualGUID(&subtype, h264_decoder_output_types[i])) + break; + if (i == ARRAY_SIZE(h264_decoder_output_types)) + return MF_E_INVALIDMEDIATYPE; + + if (decoder->output_type) + IMFMediaType_Release(decoder->output_type); + IMFMediaType_AddRef((decoder->output_type = type)); + + return S_OK; }
static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=110451
Your paranoid android.
=== w7u_adm (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally