From: Charlotte Pabst cpabst@codeweavers.com
--- dlls/mfsrcsnk/tests/mfsrcsnk.c | 9 ++------ dlls/winegstreamer/media_source.c | 35 ++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/dlls/mfsrcsnk/tests/mfsrcsnk.c b/dlls/mfsrcsnk/tests/mfsrcsnk.c index e78fe8adbb8..af6e8ff674d 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,7 @@ 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 + todo_wine_if(!thin) 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 36c7850b858..e93fbbbad64 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 @@ -199,6 +200,8 @@ struct media_source SOURCE_SHUTDOWN, } state; float rate; + BOOL thin; + BOOL prev_thin;
HANDLE read_thread; bool read_thread_shutdown; @@ -712,12 +715,13 @@ static HRESULT media_source_stop(struct media_source *source) return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceStopped, &GUID_NULL, S_OK, NULL); }
-static HRESULT media_stream_send_sample(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token) +static HRESULT media_stream_send_sample(struct media_stream *stream, const struct wg_parser_buffer *wg_buffer, IUnknown *token, BOOL thin) { IMFSample *sample = NULL; IMFMediaBuffer *buffer; HRESULT hr; BYTE *data; + PROPVARIANT param;
if (FAILED(hr = MFCreateMemoryBuffer(wg_buffer->size, &buffer))) return hr; @@ -749,6 +753,15 @@ static HRESULT media_stream_send_sample(struct media_stream *stream, const struc if (token && FAILED(hr = IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token))) goto out;
+ if (stream->thin != thin) + { + param.vt = VT_INT; + param.iVal = 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 = thin; + } + hr = IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample, &GUID_NULL, S_OK, (IUnknown *)sample);
@@ -801,12 +814,20 @@ 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; + HRESULT hr;
TRACE("%p, %p\n", stream, token);
while (stream_get_buffer(stream, &buffer)) { - HRESULT hr = media_stream_send_sample(stream, &buffer, token); + if ((source->thin || source->prev_thin) && buffer.delta) + { + wg_parser_stream_release_buffer(stream->wg_stream); + continue; + } + if (source->prev_thin != source->thin) source->prev_thin = source->thin; + + hr = media_stream_send_sample(stream, &buffer, token, source->thin); if (hr != S_FALSE) return hr; } @@ -1294,14 +1315,12 @@ 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);
return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceRateChanged, &GUID_NULL, S_OK, NULL); @@ -1313,11 +1332,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; @@ -1661,6 +1679,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");