From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/transform.c | 142 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 7 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index b02c69b357e..f246919f125 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -74,6 +74,16 @@ struct media_buffer BYTE data[]; };
+struct buffer2d_desc +{ + DWORD width; + DWORD height; + DWORD fourCC; + BOOL flip; + LONG stride; + DWORD length; +}; + static inline struct media_buffer *impl_from_IMediaBuffer(IMediaBuffer *iface) { return CONTAINING_RECORD(iface, struct media_buffer, IMediaBuffer_iface); @@ -2047,6 +2057,56 @@ static IMFSample *create_sample(const BYTE *data, ULONG size) return sample; }
+static IMFSample *create_2d_sample(const BYTE *data, ULONG size, const struct buffer2d_desc *buffer2d_desc) +{ + IMFMediaBuffer *media_buffer; + IMF2DBuffer2 *buffer2d2; + BYTE *buffer, *scanline; + IMFSample *sample; + DWORD length; + LONG stride; + HRESULT hr; + ULONG ret; + + hr = MFCreateSample(&sample); + ok(hr == S_OK, "MFCreateSample returned %#lx\n", hr); + hr = MFCreate2DMediaBuffer(buffer2d_desc->width, buffer2d_desc->height, buffer2d_desc->fourCC, buffer2d_desc->flip, &media_buffer); + ok(hr == S_OK, "MFCreateMemoryBuffer returned %#lx\n", hr); + hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, &length); + ok(length == size, "got 1d length %lu, expected %lu\n", length, size); + ok(hr == S_OK, "Lock returned %#lx\n", hr); + if (data) memcpy(buffer, data, size); + hr = IMFMediaBuffer_Unlock(media_buffer); + ok(hr == S_OK, "Unlock returned %#lx\n", hr); + hr = IMFMediaBuffer_QueryInterface(media_buffer, &IID_IMF2DBuffer2, (void**)&buffer2d2); + ok(hr == S_OK, "QueryInterface IMF2DBuffer2 returned %#lx\n", hr); + hr = IMF2DBuffer2_Lock2DSize(buffer2d2, MF2DBuffer_LockFlags_Write, &scanline, &stride, &buffer, &length); + ok(hr == S_OK, "Lock2D returned %#lx\n", hr); + ok(stride == buffer2d_desc->stride, "got stride %lu, expected %lu\n", stride, buffer2d_desc->stride); + ok(length == buffer2d_desc->length, "got 2d length %lu, expected %lu\n", length, buffer2d_desc->length); + if (!data) memset(buffer, 0xcd, length); + hr = IMF2DBuffer2_Unlock2D(buffer2d2); + ok(hr == S_OK, "Unlock2D returned %#lx\n", hr); + hr = IMFMediaBuffer_SetCurrentLength(media_buffer, data ? size : 0); + ok(hr == S_OK, "SetCurrentLength returned %#lx\n", hr); + hr = IMFSample_AddBuffer(sample, media_buffer); + ok(hr == S_OK, "AddBuffer returned %#lx\n", hr); + ret = IMF2DBuffer2_Release(buffer2d2); + ok(ret == 2, "IMF2DBuffer2 Release returned %lu\n", ret); + ret = IMFMediaBuffer_Release(media_buffer); + ok(ret == 1, "Release returned %lu\n", ret); + + return sample; +} + +static IMFSample *create_sample_type(BOOL use_2d_buffer, const BYTE *data, ULONG size, const struct buffer2d_desc *buffer2d_desc) +{ + if (use_2d_buffer) + return create_2d_sample(data, size, buffer2d_desc); + + return create_sample(data, size); +} + static void test_aac_encoder(void) { const GUID *const class_id = &CLSID_AACMFTEncoder; @@ -7379,7 +7439,7 @@ failed: CoUninitialize(); }
-static void test_video_processor(void) +static void test_video_processor(BOOL use_2d_buffer) { const GUID *const class_id = &CLSID_VideoProcessorMFT; const struct transform_info expect_mft_info = @@ -7512,6 +7572,7 @@ static void test_video_processor(void)
static const MFVideoArea actual_aperture = {.Area={82,84}}; static const DWORD actual_width = 96, actual_height = 96; + static const DWORD nv12_aligned_width = 128; const struct attribute_desc rgb32_with_aperture[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), @@ -7606,6 +7667,51 @@ static void test_video_processor(void) ATTR_RATIO(MF_MT_FRAME_SIZE, 82, 84, .required = TRUE), {0}, }; + const struct buffer2d_desc nv12_default_stride_2d = { + .width = actual_width, + .height = actual_height, + .fourCC = MFVideoFormat_NV12.Data1, + .stride = nv12_aligned_width, + .length = nv12_aligned_width * actual_height * 3 / 2, + }; + const struct buffer2d_desc rgb32_negative_stride_2d = { + .width = actual_width, + .height = actual_height, + .fourCC = MFVideoFormat_RGB32.Data1, + .flip = TRUE, + .stride = -actual_width * 4, + .length = actual_width * actual_height * 4, + }; + const struct buffer2d_desc rgb32_positive_stride_2d = { + .width = actual_width, + .height = actual_height, + .fourCC = MFVideoFormat_RGB32.Data1, + .stride = actual_width * 4, + .length = actual_width * actual_height * 4, + }; + const struct buffer2d_desc rgb32_no_aperture_2d = { + .width = 82, + .height = 84, + .fourCC = MFVideoFormat_RGB32.Data1, + .flip = TRUE, + .stride = -actual_width * 4, + .length = actual_width * 84 * 4, + }; + const struct buffer2d_desc rgb555_negative_stride_2d = { + .width = actual_width, + .height = actual_height, + .fourCC = MFVideoFormat_RGB555.Data1, + .flip = TRUE, + .stride = -actual_width * 2, + .length = actual_width * actual_height * 2, + }; + const struct buffer2d_desc rgb555_positive_stride_2d = { + .width = actual_width, + .height = actual_height, + .fourCC = MFVideoFormat_RGB555.Data1, + .stride = actual_width * 2, + .length = actual_width * actual_height * 2, + }; const MFT_OUTPUT_STREAM_INFO initial_output_info = {0}; const MFT_INPUT_STREAM_INFO initial_input_info = {0}; MFT_OUTPUT_STREAM_INFO output_info = {0}; @@ -7677,6 +7783,8 @@ static void test_video_processor(void) const WCHAR *output_bitmap; ULONG delta; BOOL broken; + const struct buffer2d_desc *input_2d_desc; + const struct buffer2d_desc *output_2d_desc; } video_processor_tests[] = { @@ -7684,96 +7792,115 @@ static void test_video_processor(void) .input_type_desc = nv12_default_stride, .input_bitmap = L"nv12frame.bmp", .output_type_desc = rgb32_default_stride, .output_bitmap = L"rgb32frame-flip.bmp", .output_sample_desc = &rgb32_sample_desc, .delta = 2, /* Windows returns 0, Wine needs 2 */ + .input_2d_desc = &nv12_default_stride_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = nv12_default_stride, .input_bitmap = L"nv12frame.bmp", .output_type_desc = rgb32_negative_stride, .output_bitmap = L"rgb32frame-flip.bmp", .output_sample_desc = &rgb32_sample_desc, .delta = 2, /* Windows returns 0, Wine needs 2 */ + .input_2d_desc = &nv12_default_stride_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = nv12_default_stride, .input_bitmap = L"nv12frame.bmp", .output_type_desc = rgb32_positive_stride, .output_bitmap = L"rgb32frame.bmp", .output_sample_desc = &rgb32_sample_desc, .delta = 6, + .input_2d_desc = &nv12_default_stride_2d, .output_2d_desc = &rgb32_positive_stride_2d, }, { .input_type_desc = rgb32_default_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = nv12_default_stride, .output_bitmap = L"nv12frame-flip.bmp", .output_sample_desc = &nv12_sample_desc, .delta = 2, /* Windows returns 0, Wine needs 2 */ + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &nv12_default_stride_2d, }, { .input_type_desc = rgb32_negative_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = nv12_default_stride, .output_bitmap = L"nv12frame-flip.bmp", .output_sample_desc = &nv12_sample_desc, .delta = 2, /* Windows returns 0, Wine needs 2 */ + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &nv12_default_stride_2d, }, { .input_type_desc = rgb32_positive_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = nv12_default_stride, .output_bitmap = L"nv12frame.bmp", .output_sample_desc = &nv12_sample_desc, .delta = 2, /* Windows returns 1, Wine needs 2 */ + .input_2d_desc = &rgb32_positive_stride_2d, .output_2d_desc = &nv12_default_stride_2d, }, { .input_type_desc = rgb32_negative_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_negative_stride, .output_bitmap = L"rgb32frame.bmp", .output_sample_desc = &rgb32_sample_desc, + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = rgb32_negative_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_positive_stride, .output_bitmap = L"rgb32frame-flip.bmp", .output_sample_desc = &rgb32_sample_desc, .delta = 3, /* Windows returns 3 */ + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb32_positive_stride_2d, }, { .input_type_desc = rgb32_positive_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_negative_stride, .output_bitmap = L"rgb32frame-flip.bmp", .output_sample_desc = &rgb32_sample_desc, .delta = 3, /* Windows returns 3 */ + .input_2d_desc = &rgb32_positive_stride_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = rgb32_positive_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_positive_stride, .output_bitmap = L"rgb32frame.bmp", .output_sample_desc = &rgb32_sample_desc, + .input_2d_desc = &rgb32_positive_stride_2d, .output_2d_desc = &rgb32_positive_stride_2d, }, { .input_type_desc = rgb32_with_aperture, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_with_aperture, .output_bitmap = L"rgb32frame.bmp", - .output_sample_desc = &rgb32_sample_desc, .broken = TRUE /* old Windows version incorrectly rescale */ + .output_sample_desc = &rgb32_sample_desc, .broken = TRUE, /* old Windows version incorrectly rescale */ + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = rgb32_default_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb555_default_stride, .output_bitmap = L"rgb555frame.bmp", .output_sample_desc = &rgb555_sample_desc, + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb555_negative_stride_2d, }, { .input_type_desc = rgb32_default_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb555_negative_stride, .output_bitmap = L"rgb555frame.bmp", .output_sample_desc = &rgb555_sample_desc, + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb555_negative_stride_2d, }, { .input_type_desc = rgb32_default_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb555_positive_stride, .output_bitmap = L"rgb555frame-flip.bmp", .output_sample_desc = &rgb555_sample_desc, .delta = 3, /* Windows returns 0, Wine needs 3 */ + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb555_positive_stride_2d, }, { .input_type_desc = rgb555_default_stride, .input_bitmap = L"rgb555frame.bmp", .output_type_desc = rgb555_positive_stride, .output_bitmap = L"rgb555frame-flip.bmp", .output_sample_desc = &rgb555_sample_desc, .delta = 4, /* Windows returns 0, Wine needs 4 */ + .input_2d_desc = &rgb555_negative_stride_2d, .output_2d_desc = &rgb555_positive_stride_2d, }, { .input_type_desc = nv12_with_aperture, .input_bitmap = L"nv12frame.bmp", .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, .delta = 2, /* Windows returns 0, Wine needs 2 */ + .input_2d_desc = &nv12_default_stride_2d, .output_2d_desc = &rgb32_no_aperture_2d, }, { .input_type_desc = rgb32_no_aperture, .input_bitmap = L"rgb32frame-crop-flip.bmp", .output_type_desc = rgb32_with_aperture, .output_bitmap = L"rgb32frame-flip.bmp", - .output_sample_desc = &rgb32_sample_desc, .broken = TRUE /* old Windows version incorrectly rescale */ + .output_sample_desc = &rgb32_sample_desc, .broken = TRUE, /* old Windows version incorrectly rescale */ + .input_2d_desc = &rgb32_no_aperture_2d, .output_2d_desc = &rgb32_negative_stride_2d, }, { .input_type_desc = rgb32_with_aperture, .input_bitmap = L"rgb32frame-flip.bmp", .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, + .input_2d_desc = &rgb32_negative_stride_2d, .output_2d_desc = &rgb32_no_aperture_2d, }, { .input_type_desc = rgb32_with_aperture_positive_stride, .input_bitmap = L"rgb32frame.bmp", .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, .delta = 3, /* Windows returns 3 */ + .input_2d_desc = &rgb32_positive_stride_2d, .output_2d_desc = &rgb32_no_aperture_2d, }, };
@@ -8176,7 +8303,7 @@ static void test_video_processor(void) ok(input_data_len == input_info.cbSize, "got length %lu\n", input_data_len); input_data += length;
- input_sample = create_sample(input_data, input_data_len); + input_sample = create_sample_type(use_2d_buffer, input_data, input_data_len, test->input_2d_desc); hr = IMFSample_SetSampleTime(input_sample, 0); ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); hr = IMFSample_SetSampleDuration(input_sample, 10000000); @@ -8193,7 +8320,7 @@ static void test_video_processor(void) hr = MFCreateCollection(&output_samples); ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr);
- output_sample = create_sample(NULL, output_info.cbSize); + output_sample = create_sample_type(use_2d_buffer, NULL, output_info.cbSize, test->output_2d_desc); hr = check_mft_process_output(transform, output_sample, &output_status);
ok(hr == S_OK || broken(hr == MF_E_SHUTDOWN) /* w8 */, "ProcessOutput returned %#lx\n", hr); @@ -8214,7 +8341,7 @@ static void test_video_processor(void) ok(ret <= test->delta || broken(test->broken), "got %lu%% diff\n", ret); IMFCollection_Release(output_samples);
- output_sample = create_sample(NULL, output_info.cbSize); + output_sample = create_sample_type(use_2d_buffer, NULL, output_info.cbSize, test->output_2d_desc); hr = check_mft_process_output(transform, output_sample, &output_status); ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); @@ -9747,7 +9874,8 @@ START_TEST(transform) test_wmv_decoder_media_object(); test_audio_convert(); test_color_convert(); - test_video_processor(); + test_video_processor(FALSE); + test_video_processor(TRUE); test_mp3_decoder(); test_iv50_encoder(); test_iv50_decoder();