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 | 40 +++++++++++++++---------------- dlls/winegstreamer/h264_decoder.c | 16 +++++++++++++ dlls/winegstreamer/mfplat.c | 25 +++++++++++++++++++ dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/wg_format.c | 3 ++- dlls/winegstreamer/wg_transform.c | 23 ++++++++++++++++++ 6 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 81bfafbda04..4f55a67f30b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6842,70 +6842,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, 60000, 1000), - ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), /* 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, .todo = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), }, { 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, 60000, 1000), - ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), /* 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, .todo = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), }, { 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, 60000, 1000), - ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), /* 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, .todo = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), }, { 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, 60000, 1000), - ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), /* 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, .todo = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), }, { 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, 60000, 1000), - ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE), - ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2, .todo_value = TRUE), - ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), /* 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, .todo = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), }, };
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index f97b6cf18c2..e39b9340be1 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -173,6 +173,22 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType return hr; }
+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)) + && !IsRectEmpty(&wg_format->u.video.padding)) + { + MFVideoArea aperture = + { + .OffsetX = {.value = wg_format->u.video.padding.left}, + .OffsetY = {.value = wg_format->u.video.padding.top}, + .Area.cx = wg_format->u.video.width - wg_format->u.video.padding.right - wg_format->u.video.padding.left, + .Area.cy = wg_format->u.video.height - wg_format->u.video.padding.bottom - wg_format->u.video.padding.top, + }; + + if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + (BYTE *)&aperture, sizeof(aperture)))) + return hr; + } + return S_OK; }
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 2e53afb0542..0226e7a2e45 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -688,6 +688,20 @@ static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format * IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
+ if (!IsRectEmpty(&format->u.video.padding)) + { + MFVideoArea aperture = + { + .OffsetX = {.value = format->u.video.padding.left}, + .OffsetY = {.value = format->u.video.padding.top}, + .Area.cx = format->u.video.width - format->u.video.padding.right - format->u.video.padding.left, + .Area.cy = format->u.video.height - format->u.video.padding.bottom - format->u.video.padding.top, + }; + + IMFMediaType_SetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE, + (BYTE *)&aperture, sizeof(aperture)); + } + return type; } } @@ -770,7 +784,9 @@ static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *sub static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *subtype, struct wg_format *format) { UINT64 frame_rate, frame_size; + MFVideoArea aperture; unsigned int i; + UINT32 size;
if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) { @@ -784,6 +800,15 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *sub format->u.video.fps_n = 1; format->u.video.fps_d = 1;
+ if (SUCCEEDED(IMFMediaType_GetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, + sizeof(aperture), &size)) && size == sizeof(aperture)) + { + format->u.video.padding.left = aperture.OffsetX.value; + format->u.video.padding.top = aperture.OffsetY.value; + format->u.video.padding.right = format->u.video.width - aperture.Area.cx - aperture.OffsetX.value; + format->u.video.padding.bottom = format->u.video.height - aperture.Area.cy - aperture.OffsetY.value; + } + if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate) { format->u.video.fps_n = (UINT32)(frame_rate >> 32); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index e8cdfaf7217..f334a168bd1 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -68,6 +68,7 @@ struct wg_format } format; int32_t width, height; uint32_t fps_n, fps_d; + RECT padding; } video; struct { diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 4cebeac9182..3b568ea2fec 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -552,7 +552,8 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) /* Do not compare FPS. */ return a->u.video.format == b->u.video.format && a->u.video.width == b->u.video.width - && abs(a->u.video.height) == abs(b->u.video.height); + && abs(a->u.video.height) == abs(b->u.video.height) + && EqualRect( &a->u.video.padding, &b->u.video.padding ); }
assert(0); diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 447639342ae..9a5a70d3d39 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -695,8 +695,31 @@ NTSTATUS wg_transform_read_data(void *args) gst_sample_set_info(transform->output_sample, NULL);
if (format) + { + gsize plane_align = transform->output_plane_align; + GstVideoAlignment align; + GstVideoInfo info; + wg_format_from_caps(format, output_caps);
+ if (format->major_type == WG_MAJOR_TYPE_VIDEO + && gst_video_info_from_caps(&info, output_caps) + && align_video_info_planes(plane_align, &info, &align)) + { + GST_INFO("Returning video alignment left %u, top %u, right %u, bottom %u.", align.padding_left, + align.padding_top, align.padding_right, align.padding_bottom); + + format->u.video.padding.left = align.padding_left; + format->u.video.width += format->u.video.padding.left; + format->u.video.padding.right = align.padding_right; + format->u.video.width += format->u.video.padding.right; + format->u.video.padding.top = align.padding_top; + format->u.video.height += format->u.video.padding.top; + format->u.video.padding.bottom = align.padding_bottom; + format->u.video.height += format->u.video.padding.bottom; + } + } + params->result = MF_E_TRANSFORM_STREAM_CHANGE; GST_INFO("Format changed detected, returning no output"); return STATUS_SUCCESS;