From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/mf_test.h | 7 +++ dlls/mf/tests/transform.c | 118 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+)
diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index 47b05e14777..488acac0c35 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -37,6 +37,13 @@ extern HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceMa extern BOOL has_video_processor; void init_functions(void);
+static const BYTE test_h264_sequence_header[] = +{ + 0x00, 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0b, 0x96, 0x56, 0x31, 0xb4, + 0x20, 0x00, 0x00, 0x7d, 0x20, 0x00, 0x1d, 0x4c, 0x01, 0xb4, 0x11, 0x08, + 0xa7, 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x3c, 0x80, +}; + struct attribute_desc { const GUID *key; diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index faddbce7da7..156b15f3804 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3602,6 +3602,123 @@ static IMFSample *next_h264_sample_(int line, const BYTE **h264_buf, ULONG *h264 return create_sample(sample_data, *h264_buf - sample_data); }
+static void test_h264_encoder(void) +{ + static const DWORD actual_width = 96, actual_height = 96; + const GUID *const class_id = &CLSID_MSH264EncoderMFT; + const struct transform_info expect_mft_info = + { + .name = L"H264 Encoder MFT", + .major_type = &MFMediaType_Video, + .inputs = + { + {.subtype = &MFVideoFormat_IYUV}, + {.subtype = &MFVideoFormat_YV12}, + {.subtype = &MFVideoFormat_NV12}, + {.subtype = &MFVideoFormat_YUY2}, + }, + .outputs = + { + {.subtype = &MFVideoFormat_H264}, + }, + }; + static const struct attribute_desc expect_transform_attributes[] = + { + ATTR_UINT32(MFT_ENCODER_SUPPORTS_CONFIG_EVENT, 1), + {0}, + }; + const struct attribute_desc input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + {0}, + }; + const struct attribute_desc output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), + ATTR_UINT32(MF_MT_AVG_BITRATE, 193540), + ATTR_UINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive), + {0}, + }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), + {0}, + }; + const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), + ATTR_UINT32(MF_MT_AVG_BITRATE, 193540), + ATTR_BLOB(MF_MT_MPEG_SEQUENCE_HEADER, test_h264_sequence_header, sizeof(test_h264_sequence_header)), + {0}, + }; + static const MFT_OUTPUT_STREAM_INFO expect_output_info = {.cbSize = 0x8000}; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_H264}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_NV12}; + IMFTransform *transform; + HRESULT hr; + ULONG ret; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + winetest_push_context("h264enc"); + + if (!has_video_processor) + { + win_skip("Skipping inconsistent h264 encoder tests on Win7.\n"); + winetest_pop_context(); + return; + } + + if (!check_mft_enum(MFT_CATEGORY_VIDEO_ENCODER, &input_type, &output_type, class_id)) + goto failed; + check_mft_get_info(class_id, &expect_mft_info); + + if (FAILED(hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, + &IID_IMFTransform, (void **)&transform))) + goto failed; + + check_interface(transform, &IID_IMFTransform, TRUE); + check_interface(transform, &IID_IMediaObject, FALSE); + check_interface(transform, &IID_IPropertyStore, FALSE); + check_interface(transform, &IID_IPropertyBag, FALSE); + + check_mft_get_attributes(transform, expect_transform_attributes, FALSE); + check_mft_get_input_stream_info(transform, S_OK, NULL); + check_mft_get_output_stream_info(transform, S_OK, NULL); + + check_mft_set_output_type_required(transform, output_type_desc); + check_mft_set_output_type(transform, output_type_desc, S_OK); + + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type(transform, expect_input_type_desc); + + check_mft_get_output_current_type(transform, expect_output_type_desc); + + check_mft_get_input_stream_info(transform, S_OK, NULL); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info); + + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %lu\n", ret); + +failed: + winetest_pop_context(); + CoUninitialize(); +} + static void test_h264_decoder(void) { const GUID *const class_id = &CLSID_MSH264DecoderMFT; @@ -8456,6 +8573,7 @@ START_TEST(transform) test_wma_decoder(); test_wma_decoder_dmo_input_type(); test_wma_decoder_dmo_output_type(); + test_h264_encoder(); test_h264_decoder(); test_wmv_encoder(); test_wmv_decoder();