[PATCH v2 0/1] MR10369: mf: Handle ENDOFSEGMENT marker in SAR.
Windows renders silence once the ENDOFSEGMENT marker is received. This allows the presentation time source to continue counting up at the end of an audio stream. This is required when the PTS of the last video sample is greater than the PTS of the last audio sample. -- v2: mf: Handle ENDOFSEGMENT marker in SAR. https://gitlab.winehq.org/wine/wine/-/merge_requests/10369
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/mf/sar.c | 23 ++++++++++++++++++++--- dlls/mf/tests/mf.c | 1 - 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index 0ad8b195a0e..a19806f774d 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -37,6 +37,7 @@ enum audio_renderer_flags SAR_SAMPLE_REQUESTED = 0x4, SAR_SEEKING = 0x8, SAR_REPORT_SEEK_TIME = 0x10, + SAR_ADDING_SILENCE = 0x20, }; enum queued_object_type @@ -2061,6 +2062,9 @@ static void audio_renderer_render(struct audio_renderer *renderer, IMFAsyncResul { if (obj->type == OBJECT_TYPE_MARKER) { + if (obj->u.marker.type == MFSTREAMSINK_MARKER_ENDOFSEGMENT) + renderer->flags |= SAR_ADDING_SILENCE; + IMFMediaEventQueue_QueueEventParamVar(renderer->stream_event_queue, MEStreamSinkMarker, &GUID_NULL, S_OK, &obj->u.marker.context); } @@ -2088,6 +2092,7 @@ static void audio_renderer_render(struct audio_renderer *renderer, IMFAsyncResul if (dst_frames && SUCCEEDED(hr = IAudioRenderClient_GetBuffer(renderer->audio_render_client, dst_frames, &dst))) { + renderer->flags &= ~SAR_ADDING_SILENCE; memcpy(dst, src + obj->u.sample.frame_offset * renderer->frame_size, dst_frames * renderer->frame_size); @@ -2120,10 +2125,22 @@ static void audio_renderer_render(struct audio_renderer *renderer, IMFAsyncResul release_pending_object(obj); } - if (list_empty(&renderer->queue) && !(renderer->flags & SAR_SAMPLE_REQUESTED)) + if (list_empty(&renderer->queue)) { - IMFMediaEventQueue_QueueEventParamVar(renderer->stream_event_queue, MEStreamSinkRequestSample, &GUID_NULL, S_OK, NULL); - renderer->flags |= SAR_SAMPLE_REQUESTED; + if (!(renderer->flags & SAR_SAMPLE_REQUESTED)) + { + IMFMediaEventQueue_QueueEventParamVar(renderer->stream_event_queue, MEStreamSinkRequestSample, &GUID_NULL, S_OK, NULL); + renderer->flags |= SAR_SAMPLE_REQUESTED; + } + + if (renderer->flags & SAR_ADDING_SILENCE && + SUCCEEDED(IAudioClient_GetBufferSize(renderer->audio_client, &max_frames)) && + SUCCEEDED(IAudioClient_GetCurrentPadding(renderer->audio_client, &pad_frames)) && + (max_frames -= pad_frames) && + SUCCEEDED(IAudioRenderClient_GetBuffer(renderer->audio_render_client, max_frames, &dst))) + { + IAudioRenderClient_ReleaseBuffer(renderer->audio_render_client, max_frames, AUDCLNT_BUFFERFLAGS_SILENT); + } } if (FAILED(hr = MFPutWaitingWorkItem(renderer->buffer_ready_event, 0, result, &renderer->buffer_ready_key))) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index fbf82f2ad2f..7aca38c7fd2 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -7346,7 +7346,6 @@ if (time_source) } /* Time is now greater than 300000 as, due to the ENDOFSEGMENT marker, SAR will now insert silence and continue the timer */ - todo_wine ok(time > 300000, "Unexpected time %I64d.\n", time); /* No new samples are requested after the marker */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10369
v2: - removed code not really relevant to handling the `ENDOFSEGMENT` marker (it was more related to discontinuities) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10369#note_132704
Nikolay Sivov (@nsivov) commented about dlls/mf/sar.c:
- renderer->flags |= SAR_SAMPLE_REQUESTED; + if (!(renderer->flags & SAR_SAMPLE_REQUESTED)) + { + IMFMediaEventQueue_QueueEventParamVar(renderer->stream_event_queue, MEStreamSinkRequestSample, &GUID_NULL, S_OK, NULL); + renderer->flags |= SAR_SAMPLE_REQUESTED; + } + + if (renderer->flags & SAR_ADDING_SILENCE && + SUCCEEDED(IAudioClient_GetBufferSize(renderer->audio_client, &max_frames)) && + SUCCEEDED(IAudioClient_GetCurrentPadding(renderer->audio_client, &pad_frames)) && + (max_frames -= pad_frames) && + SUCCEEDED(IAudioRenderClient_GetBuffer(renderer->audio_render_client, max_frames, &dst))) + { + IAudioRenderClient_ReleaseBuffer(renderer->audio_render_client, max_frames, AUDCLNT_BUFFERFLAGS_SILENT); + } } Please move this to a helper, for readability sake.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10369#note_132791
participants (3)
-
Brendan McGrath -
Brendan McGrath (@redmcg) -
Nikolay Sivov (@nsivov)