From: Charlotte Pabst cpabst@codeweavers.com
--- dlls/mfsrcsnk/tests/mfsrcsnk.c | 8 +----- dlls/winegstreamer/media_source.c | 43 ++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/dlls/mfsrcsnk/tests/mfsrcsnk.c b/dlls/mfsrcsnk/tests/mfsrcsnk.c index e78fe8adbb8..d6a154b88c4 100644 --- a/dlls/mfsrcsnk/tests/mfsrcsnk.c +++ b/dlls/mfsrcsnk/tests/mfsrcsnk.c @@ -627,12 +627,10 @@ static void test_sample_times_at_rate(IMFMediaSource *source, FLOAT rate, BOOL t hr = MFGetService((IUnknown *)source, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, (void **)&rate_control); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFRateControl_SetRate(rate_control, thin, rate); - todo_wine_if(thin && hr == MF_E_THINNING_UNSUPPORTED) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFRateControl_Release(rate_control);
hr = wait_media_event(source, callback, MESourceRateChanged, 100, &value); - todo_wine_if(thin) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); todo_wine ok(value.vt == VT_R4, "got vt %u\n", value.vt); @@ -641,13 +639,11 @@ static void test_sample_times_at_rate(IMFMediaSource *source, FLOAT rate, BOOL t
hr = IMFMediaStream_RequestSample(stream, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (!winetest_platform_is_wine) - { + hr = wait_media_event(stream, callback, MEStreamThinMode, 100, &value); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(value.vt == VT_INT, "got vt %u\n", value.vt); ok(value.iVal == thin, "Unexpected thin %d\n", value.iVal); - }
winetest_push_context("sample 1");
@@ -656,7 +652,6 @@ static void test_sample_times_at_rate(IMFMediaSource *source, FLOAT rate, BOOL t ok(value.vt == VT_UNKNOWN, "got vt %u\n", value.vt); hr = IMFSample_GetSampleTime((IMFSample *)value.punkVal, &time); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(time == expect_times[2], "Unexpected time %s.\n", debugstr_time(time)); hr = IMFSample_GetSampleDuration((IMFSample *)value.punkVal, &time); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -679,7 +674,6 @@ static void test_sample_times_at_rate(IMFMediaSource *source, FLOAT rate, BOOL t ok(value.vt == VT_UNKNOWN, "got vt %u\n", value.vt); hr = IMFSample_GetSampleTime((IMFSample *)value.punkVal, &time); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(time == (thin ? expect_times_thin[2 * i] : expect_times[2 * i]), "Unexpected time %s.\n", debugstr_time(time)); hr = IMFSample_GetSampleDuration((IMFSample *)value.punkVal, &time); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index ab842b3e438..c1dcb0dffa0 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -137,6 +137,7 @@ struct media_stream DWORD stream_id; BOOL active; BOOL eos; + BOOL thin; };
enum source_async_op @@ -202,6 +203,7 @@ struct media_source SOURCE_SHUTDOWN, } state; float rate; + BOOL thin;
HANDLE read_thread; bool read_thread_shutdown; @@ -795,12 +797,39 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) { struct media_source *source = impl_from_IMFMediaSource(stream->media_source); struct wg_parser_buffer buffer; + PROPVARIANT param; + HRESULT hr;
TRACE("%p, %p\n", stream, token);
while (wg_parser_stream_get_buffer(source->wg_parser, stream->wg_stream, &buffer)) { - HRESULT hr = media_stream_send_sample(stream, &buffer, token); + if (stream->thin != source->thin) + { + param.vt = VT_INT; + param.iVal = source->thin; + if (FAILED(hr = IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamThinMode, &GUID_NULL, S_OK, ¶m))) + WARN("Failed to queue MEStreamThinMode event, hr %#lx\n", hr); + stream->thin = source->thin; + + if (!source->thin && buffer.has_pts) + { + wg_parser_stream_seek(stream->wg_stream, 1.0, buffer.pts, 0, + AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning); + /* gstreamer gives us the next buffer twice, once with duration=0, discard */ + wg_parser_stream_get_buffer(source->wg_parser, stream->wg_stream, &buffer); + wg_parser_stream_release_buffer(stream->wg_stream); + continue; + } + } + + if (source->thin && buffer.delta) + { + wg_parser_stream_release_buffer(stream->wg_stream); + continue; + } + + hr = media_stream_send_sample(stream, &buffer, token); if (hr != S_FALSE) return hr; } @@ -1285,16 +1314,16 @@ static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, B if (rate < 0.0f) return MF_E_REVERSE_UNSUPPORTED;
- if (thin) - return MF_E_THINNING_UNSUPPORTED; - if (FAILED(hr = IMFRateSupport_IsRateSupported(&source->IMFRateSupport_iface, thin, rate, NULL))) return hr;
EnterCriticalSection(&source->cs); source->rate = rate; + source->thin = thin; LeaveCriticalSection(&source->cs);
+ wg_parser_set_thin(source->wg_parser, thin); + return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceRateChanged, &GUID_NULL, S_OK, NULL); }
@@ -1304,11 +1333,10 @@ static HRESULT WINAPI media_source_rate_control_GetRate(IMFRateControl *iface, B
TRACE("%p, %p, %p.\n", iface, thin, rate);
- if (thin) - *thin = FALSE; - EnterCriticalSection(&source->cs); *rate = source->rate; + if (thin) + *thin = source->thin; LeaveCriticalSection(&source->cs);
return S_OK; @@ -1734,6 +1762,7 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc IMFByteStream_AddRef(context->stream); object->file_size = context->file_size; object->rate = 1.0f; + object->thin = FALSE; InitializeCriticalSectionEx(&object->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");