From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 25 +++++++++----- dlls/winegstreamer/wg_transform.c | 55 ++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index ef0bec60ed5..3e902aa67f3 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3910,12 +3910,12 @@ static void test_h264_encoder(void) 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)), + ATTR_BLOB(MF_MT_MPEG_SEQUENCE_HEADER, test_h264_sequence_header, sizeof(test_h264_sequence_header), .todo = TRUE), ATTR_UINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive), ATTR_UINT32(test_attr_guid, 0), {0}, }; - static const MFT_OUTPUT_STREAM_INFO expect_output_info[] = {{.cbSize = 0x8000}, {.cbSize = 0x3bc400}}; + MFT_OUTPUT_STREAM_INFO output_info, expect_output_info[] = {{.cbSize = 0x8000}, {.cbSize = 0x3bc400}}; MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_H264}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_NV12}; IMFMediaType *media_type; @@ -3940,10 +3940,7 @@ static void test_h264_encoder(void) check_mft_get_info(class_id, &expect_mft_info);
hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform); - todo_wine ok(hr == S_OK, "CoCreateInstance returned %#lx.\n", hr); - if (hr != S_OK) - goto failed;
check_interface(transform, &IID_IMFTransform, TRUE); check_interface(transform, &IID_IMediaObject, FALSE); @@ -3977,8 +3974,13 @@ static void test_h264_encoder(void)
check_mft_set_output_type_required(transform, output_type_desc); check_mft_set_output_type(transform, output_type_desc, S_OK); - check_mft_get_output_current_type(transform, expect_output_type_desc); - check_mft_get_output_stream_info(transform, S_OK, &expect_output_info[0]); + check_mft_get_output_current_type_(__LINE__, transform, expect_output_type_desc, FALSE, TRUE); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + check_member(output_info, expect_output_info[0], "%#lx", dwFlags); + todo_wine + check_member(output_info, expect_output_info[0], "%#lx", cbSize); + check_member(output_info, expect_output_info[0], "%#lx", cbAlignment);
/* Input types can now be enumerated. */ i = -1; @@ -4032,7 +4034,14 @@ static void test_h264_encoder(void) if (IsEqualGUID(test_attributes[i].key, &MF_MT_FRAME_SIZE)) check_mft_get_output_stream_info(transform, S_OK, &expect_output_info[1]); else - check_mft_get_output_stream_info(transform, S_OK, &expect_output_info[0]); + { + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + check_member(output_info, expect_output_info[0], "%#lx", dwFlags); + todo_wine + check_member(output_info, expect_output_info[0], "%#lx", cbSize); + check_member(output_info, expect_output_info[0], "%#lx", cbAlignment); + }
winetest_pop_context(); } diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 75f58fb5a9b..a5a03c72040 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -69,6 +69,11 @@ static struct wg_transform *get_transform(wg_transform_t trans) return (struct wg_transform *)(ULONG_PTR)trans; }
+static bool mime_is_raw(const gchar *mime) +{ + return !strcmp(mime, "audio/x-raw") || !strcmp(mime, "video/x-raw"); +} + static void align_video_info_planes(MFVideoInfo *video_info, gsize plane_align, GstVideoInfo *info, GstVideoAlignment *align) { @@ -562,6 +567,24 @@ static bool transform_create_converter_elements(struct wg_transform *transform, return true; }
+static bool transform_create_encoder_elements(struct wg_transform *transform, + const gchar *output_mime, GstElement **first, GstElement **last) +{ + GstElement *element; + GstCaps *src_caps; + bool ret; + + if (!(src_caps = gst_caps_new_empty_simple(output_mime))) + return false; + + ret = (element = find_element(GST_ELEMENT_FACTORY_TYPE_ENCODER, NULL, src_caps)) + && append_element(transform->container, element, first, last); + + gst_caps_unref(src_caps); + + return ret; +} + NTSTATUS wg_transform_create(void *args) { struct wg_transform_create_params *params = args; @@ -624,12 +647,34 @@ NTSTATUS wg_transform_create(void *args) gst_pad_set_query_function(transform->my_sink, transform_sink_query_cb); gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb);
- if (strcmp(input_mime, "audio/x-raw") && strcmp(input_mime, "video/x-raw") - && !transform_create_decoder_elements(transform, input_mime, output_mime, &first, &last)) - goto out; - - if (!transform_create_converter_elements(transform, output_mime, &first, &last)) + /* Create gstreamer elements. */ + if (mime_is_raw(input_mime) && mime_is_raw(output_mime)) + { + /* Converter transform. */ + if (!transform_create_converter_elements(transform, output_mime, &first, &last)) + goto out; + } + else if (!mime_is_raw(input_mime) && mime_is_raw(output_mime)) + { + /* Decoder transform. */ + if (!transform_create_decoder_elements(transform, input_mime, output_mime, &first, &last)) + goto out; + if (!transform_create_converter_elements(transform, output_mime, &first, &last)) + goto out; + } + else if (mime_is_raw(input_mime) && !mime_is_raw(output_mime)) + { + /* Encoder transform. */ + if (!transform_create_converter_elements(transform, input_mime, &first, &last)) + goto out; + if (!transform_create_encoder_elements(transform, output_mime, &first, &last)) + goto out; + } + else + { + GST_ERROR("Unsupported transform from %s to %s.", input_mime, output_mime); goto out; + }
if (!link_src_to_element(transform->my_src, first)) goto out;