From: Brendan McGrath bmcgrath@codeweavers.com
This fixes a latency issue with audio, particular when played with 4k video.
With a single queue, only one sample request can be processed at a time. So, for example, if a video sample takes 40ms to be delivered, then all pending audio samples will be delayed 40ms. This can lead to the audio PTS lagging the presentation clock and being dropped. --- dlls/winegstreamer/media_source.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 3b5469932f3..595e26d8992 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -137,6 +137,8 @@ struct media_stream DWORD stream_id; BOOL active; BOOL eos; + + DWORD async_stream_queue; };
enum source_async_op @@ -548,7 +550,7 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) command->u.request_sample.stream = stream; command->u.request_sample.token = stream->token_queue[i];
- hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, op); + hr = MFPutWorkItem(stream->async_stream_queue, &source->async_commands_callback, op); IUnknown_Release(op); } if (FAILED(hr)) @@ -961,6 +963,7 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface) IMFStreamDescriptor_Release(stream->descriptor); IMFMediaEventQueue_Release(stream->event_queue); flush_token_queue(stream, FALSE); + MFUnlockWorkQueue(stream->async_stream_queue); free(stream); }
@@ -1075,7 +1078,7 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown IUnknown_AddRef(token); command->u.request_sample.token = token;
- hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, op); + hr = MFPutWorkItem(stream->async_stream_queue, &source->async_commands_callback, op); IUnknown_Release(op); }
@@ -1682,6 +1685,13 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc goto fail; }
+ if (FAILED(hr = MFAllocateWorkQueue(&stream->async_stream_queue))) + { + IMFStreamDescriptor_Release(descriptor); + IMFMediaStream_Release(&stream->IMFMediaStream_iface); + goto fail; + } + object->duration = max(object->duration, wg_parser_stream_get_duration(wg_stream)); IMFStreamDescriptor_AddRef(descriptor); object->descriptors[i] = descriptor; @@ -1704,6 +1714,7 @@ fail: struct media_stream *stream = object->streams[object->stream_count]; IMFStreamDescriptor_Release(object->descriptors[object->stream_count]); IMFMediaStream_Release(&stream->IMFMediaStream_iface); + MFUnlockWorkQueue(stream->async_stream_queue); } free(object->descriptors); free(object->streams);