From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/h264data.bin | Bin 3465 -> 8659 bytes dlls/mf/tests/resource.rc | 2 +- dlls/mf/tests/transform.c | 51 +++++++++++++++++++++++++++++- dlls/winegstreamer/wg_transform.c | 23 ++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/h264data.bin b/dlls/mf/tests/h264data.bin index a97ed63f2056e7f7b668bb96251c0a50690f1893..f552f277928e7b01e79a42cd29b1662c36a6a9f2 100644 GIT binary patch delta 436 zcmeB_zU(|9lH1V0Lc!QD)zC7{a$<@uqw&T`Wjvc5SWmD62`P5vRh}yxb7uO8_(=T! zcWr5a+5-j#21d>RAi+5AWR_z+1MkfVMr^4aO$==NCmS-`*2g$y8~sYZrXHlbw9)v; zv)93s8|U}E=`?#^Ju9Q1owNPOiyLRetyX!J{O|~9bILf%+7kG1o~)M$_s;AJ#=v!w z{quD6W#{opy4GH{%3J(qsXW8uf}Dv9Um8r?nQnUI!*g@db?yr*r!Ka;aOd)*gYTY* ziR?>yAS};#DOO<;&~207Fw2WK%QLX+A~`g%1nkhsyVw*NGbSr?igC8N3hGGwXJFTv z{F|+e@#f@PEP9MOlNYkvO|IkQp8Sfvf$_%VYz`?f?+2?iP{kS!oyqsvxhH$GNekaZ zGTR;;2sb7RaykH2?P3F~;+ogyDvI9%nHyk341gi&IC~EylsWW)f!wpf_u%Artg6Vi J%>NAuY5)qAo7DgS
delta 72 zcmccY+$lXFlH0)2R3RxbHPytxU}B0cqtV7mWjt)g|NmWE8Zh}DyDMY)<Q_#S>8Y-w bIuidG*mW2f7#KMNfCS_GZCQ@>47@i1bY&KK
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index d9595c68980..ab1fb7ecbb0 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -55,7 +55,7 @@ mp3encdata.bin RCDATA mp3encdata.bin mp3decdata.bin RCDATA mp3decdata.bin
/* Generated with: - * gst-launch-1.0 videotestsrc num-buffers=120 pattern=smpte100 ! \ + * gst-launch-1.0 videotestsrc num-buffers=360 pattern=smpte100 ! \ * video/x-raw,format=I420,width=84,height=82,framerate=30000/1001 ! \ * videoflip method=clockwise ! videoconvert ! \ * x264enc ! filesink location=dlls/mf/tests/h264data.bin diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index e43b1627789..6a4653cccee 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4379,7 +4379,7 @@ static void test_h264_decoder(void) ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); } ok(i == 2, "got %lu iterations\n", i); - ok(h264_encoded_data_len == 2425, "got h264_encoded_data_len %lu\n", h264_encoded_data_len); + ok(h264_encoded_data_len == 7619, "got h264_encoded_data_len %lu\n", h264_encoded_data_len); ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr); ok(output_status == MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE, "got output[0].dwStatus %#lx\n", output_status); hr = IMFSample_GetTotalLength(output_sample, &length); @@ -8368,6 +8368,7 @@ static void test_h264_with_dxgi_manager(void) .attributes = output_sample_attributes, .sample_time = 333667, .sample_duration = 333667, .buffer_count = 1, .buffers = &output_buffer_desc_nv12, + .todo_time = TRUE, /* _SetInputType() / _SetOutputType() type resets the output sample timestamp on Windows. */ };
IMFDXGIDeviceManager *manager = NULL; @@ -8522,6 +8523,54 @@ static void test_h264_with_dxgi_manager(void) ok(info.dwFlags == (MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES), "got %#lx.\n", info.dwFlags);
+ hr = get_next_h264_output_sample(transform, &input_sample, NULL, output, &data, &data_len); + ok(hr == S_OK, "got %#lx\n", hr); + ok(output[0].dwStatus == 0, "got %#lx.\n", status); + sample = output[0].pSample; + IMFSample_Release(sample); + + /* Set input and output type trying to change output frame size (results in MF_E_TRANSFORM_STREAM_CHANGE with + * frame size reset. */ + hr = MFCreateMediaType(&type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFVideoFormat_H264); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, 1088 | (1920ull << 32)); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetInputType(transform, 0, type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(type); + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, ((UINT64)1920) << 32 | 1088); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(type); + + hr = get_next_h264_output_sample(transform, &input_sample, NULL, output, &data, &data_len); + ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "got %#lx\n", hr); + ok(!output[0].pSample, "got %p.\n", output[0].pSample); + + /* Need to set output type with matching size now, or that hangs on Windows. */ + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size); + ok(hr == S_OK, "got %#lx\n", hr); + width = frame_size >> 32; + height = frame_size & 0xffffffff; + ok(width == aligned_width, "got %u.\n", width); + ok(height == aligned_height, "got %u.\n", height); + hr = IMFTransform_SetOutputType(transform, 0, type, 0); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(type); + hr = get_next_h264_output_sample(transform, &input_sample, NULL, output, &data, &data_len); ok(hr == S_OK, "got %#lx\n", hr); ok(output[0].dwStatus == 0, "got %#lx.\n", status); diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index a71d0efb7d3..1ed5593900c 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -610,6 +610,7 @@ NTSTATUS wg_transform_set_output_format(void *args) struct wg_transform_set_output_format_params *params = args; struct wg_transform *transform = get_transform(params->transform); const struct wg_format *format = params->format; + bool frame_size_changed = 0; GstSample *sample; GstCaps *caps;
@@ -618,6 +619,12 @@ NTSTATUS wg_transform_set_output_format(void *args) GST_ERROR("Failed to convert format %p to caps.", format); return STATUS_UNSUCCESSFUL; } + + if (format->major_type == WG_MAJOR_TYPE_VIDEO) + { + frame_size_changed = format->u.video.width != transform->output_format.u.video.width + || format->u.video.height != transform->output_format.u.video.height; + } transform->output_format = *format;
GST_INFO("transform %p output caps %"GST_PTR_FORMAT, transform, caps); @@ -625,6 +632,22 @@ NTSTATUS wg_transform_set_output_format(void *args) if (transform_output_caps_is_compatible(transform, caps)) { gst_caps_unref(caps); + if (frame_size_changed) + { + GST_TRACE("Caps are compatible but frame size changed.\n"); + if (!gst_pad_peer_query(transform->my_src, transform->drain_query)) + { + GST_ERROR("Failed to drain transform %p.", transform); + return STATUS_UNSUCCESSFUL; + } + if (!(sample = transform->output_sample)) + sample = gst_atomic_queue_peek(transform->output_queue); + + if (sample) + GST_MINI_OBJECT_FLAG_SET(sample, GST_SAMPLE_FLAG_WG_CAPS_CHANGED); + else + transform->output_caps_changed = 1; + } return STATUS_SUCCESS; }