Fixes the todos in !8034.
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/tests/transform.c | 3 +-- dlls/winegstreamer/wg_transform.c | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 9bac63779b8..f82dfa1b090 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -9333,7 +9333,7 @@ static void test_video_processor(BOOL use_2d_buffer) .output_buffer_desc = use_2d_buffer ? nv12_crop : NULL, .output_sample_desc = &nv12_crop_sample_desc, .output_sample_2d_desc = &nv12_crop_sample_2d_desc, .delta = 2, /* Windows returns 1, Wine needs 2 */ - .todo = TRUE, /* Would need special handling to convert gstreamer NV12 buffer to Windows alignment */ + .todo = use_2d_buffer, }, };
@@ -9773,7 +9773,6 @@ static void test_video_processor(BOOL use_2d_buffer) output_sample = create_sample_(NULL, output_info.cbSize, test->output_buffer_desc); hr = check_mft_process_output(transform, output_sample, &output_status);
- todo_wine_if(test->output_sample_desc == &nv12_crop_sample_desc) ok(hr == S_OK || broken(hr == MF_E_SHUTDOWN) /* w8 */, "ProcessOutput returned %#lx\n", hr); if (hr != S_OK) { diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 9ca3368ecb9..0702eb4cc2e 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -107,6 +107,7 @@ static struct wg_transform *get_transform(wg_transform_t trans) static void align_video_info_planes(MFVideoInfo *video_info, gsize plane_align, GstVideoInfo *info, GstVideoAlignment *align) { + bool fix_nv12 = !plane_align && info->finfo->format == GST_VIDEO_FORMAT_NV12 && (info->width & 3) && (info->width & 3) != 3; const MFVideoArea *aperture = &video_info->MinimumDisplayAperture;
gst_video_alignment_reset(align); @@ -129,9 +130,24 @@ static void align_video_info_planes(MFVideoInfo *video_info, gsize plane_align, align->padding_bottom = top; }
- align->stride_align[0] = plane_align; - - gst_video_info_align(info, align); + /* TODO: set NV12 GstVideoInfo correctly when padding is present */ + if (fix_nv12 && !align->padding_left && !align->padding_top && !align->padding_right && !align->padding_bottom) + { + /* NV12 minimum stride alignment is 2, and Windows expects 2, + * but gst_video_info_align() imposes a minimum of 4. */ + gint aligned_height = GST_ROUND_UP_2(info->height); + info->stride[0] = GST_ROUND_UP_2(info->width); + info->stride[1] = info->stride[0]; + info->offset[0] = 0; + info->offset[1] = info->stride[0] * aligned_height; + info->size = info->offset[1] + info->stride[0] * aligned_height / 2; + align->stride_align[0] = 1; + } + else + { + align->stride_align[0] = plane_align; + gst_video_info_align(info, align); + }
if (video_info->VideoFlags & MFVideoFlag_BottomUpLinearRep) { @@ -206,12 +222,16 @@ static WgVideoBufferPool *wg_video_buffer_pool_create(GstCaps *caps, gsize plane { WgVideoBufferPool *pool; GstStructure *config; + gsize max_size;
if (!(pool = g_object_new(wg_video_buffer_pool_get_type(), NULL))) return NULL;
gst_video_info_from_caps(&pool->info, caps); + max_size = pool->info.size; align_video_info_planes(video_info, plane_align, &pool->info, align); + /* GStreamer assumes NV12 frames will have a stride alignment of 4, but we use 2 */ + max_size = max(max_size, pool->info.size);
if (!(config = gst_buffer_pool_get_config(GST_BUFFER_POOL(pool)))) GST_ERROR("Failed to get %"GST_PTR_FORMAT" config.", pool); @@ -221,7 +241,7 @@ static WgVideoBufferPool *wg_video_buffer_pool_create(GstCaps *caps, gsize plane gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); gst_buffer_pool_config_set_video_alignment(config, align);
- gst_buffer_pool_config_set_params(config, caps, pool->info.size, 0, 0); + gst_buffer_pool_config_set_params(config, caps, max_size, 0, 0); gst_buffer_pool_config_set_allocator(config, allocator, NULL); if (!gst_buffer_pool_set_config(GST_BUFFER_POOL(pool), config)) GST_ERROR("Failed to set %"GST_PTR_FORMAT" config.", pool);