From: Elizabeth Figura zfigura@codeweavers.com
We cannot write into the old samples; the downstream filter may still be using them. In particular, dsoundrender now holds onto samples while rendering them from an extra thread.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57587 --- dlls/qasf/dmowrapper.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/qasf/dmowrapper.c b/dlls/qasf/dmowrapper.c index bcedbdd23fa..7c6358b6029 100644 --- a/dlls/qasf/dmowrapper.c +++ b/dlls/qasf/dmowrapper.c @@ -253,9 +253,15 @@ static HRESULT process_output(struct dmo_wrapper *filter, IMediaObject *dmo) { more_data = FALSE;
+ if (FAILED(hr = get_output_samples(filter))) + return hr; + if (FAILED(IMediaObject_ProcessOutput(dmo, DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, filter->source_count, buffers, &status))) + { + release_output_samples(filter); break; + }
for (i = 0; i < filter->source_count; ++i) { @@ -289,13 +295,12 @@ static HRESULT process_output(struct dmo_wrapper *filter, IMediaObject *dmo) release_output_samples(filter); return hr; } - IMediaSample_SetActualDataLength(sample, 0); } - } + + release_output_samples(filter); } while (more_data);
- release_output_samples(filter); return hr; }
@@ -326,15 +331,10 @@ static HRESULT WINAPI dmo_wrapper_sink_Receive(struct strmbase_sink *iface, IMed /* Calling Discontinuity() might change the DMO's mind about whether it * has more data to process. The DirectX documentation explicitly * states that we should call ProcessOutput() again in this case. */ - if (FAILED(hr = get_output_samples(filter))) - goto out; if ((hr = process_output(filter, dmo)) != S_OK) goto out; }
- if (FAILED(hr = get_output_samples(filter))) - goto out; - if (IMediaSample_IsSyncPoint(sample) == S_OK) flags |= DMO_INPUT_DATA_BUFFERF_SYNCPOINT;
@@ -373,8 +373,7 @@ static HRESULT dmo_wrapper_sink_eos(struct strmbase_sink *iface) if (FAILED(hr = IMediaObject_Discontinuity(dmo, index))) ERR("Discontinuity() failed, hr %#lx.\n", hr);
- if (SUCCEEDED(get_output_samples(filter))) - process_output(filter, dmo); + process_output(filter, dmo);
if (FAILED(hr = IMediaObject_Flush(dmo))) ERR("Flush() failed, hr %#lx.\n", hr);