From 66de5a8ee8e6c6c78a9b2bfff1d5c33e5889d555 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 25 Mar 2020 14:39:57 +0300 Subject: [PATCH] mfreadwrite: Make pending response reader structure more generic. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mfreadwrite/main.c | 104 ++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index 8c994273cb9..3faa6c6ee01 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -72,9 +72,13 @@ HRESULT WINAPI DllUnregisterServer(void) return __wine_unregister_resources( mfinstance ); } -struct sample +struct stream_response { struct list entry; + HRESULT status; + DWORD stream_index; + DWORD stream_flags; + LONGLONG timestamp; IMFSample *sample; }; @@ -96,9 +100,10 @@ struct media_stream IMFMediaType *current; IMFTransform *decoder; DWORD id; + unsigned int index; CRITICAL_SECTION cs; CONDITION_VARIABLE sample_event; - struct list samples; + struct list responses; enum media_stream_state state; BOOL selected; BOOL presented; @@ -366,18 +371,21 @@ static ULONG WINAPI source_reader_stream_events_callback_Release(IMFAsyncCallbac return IMFSourceReader_Release(&reader->IMFSourceReader_iface); } -static void source_reader_queue_sample(struct media_stream *stream, IMFSample *sample) +static void source_reader_queue_response(struct media_stream *stream, HRESULT status, DWORD stream_index, + DWORD stream_flags, LONGLONG timestamp, IMFSample *sample) { - struct sample *pending_sample; + struct stream_response *response; - if (!sample) - return; + response = heap_alloc_zero(sizeof(*response)); + response->status = status; + response->stream_index = stream_index; + response->stream_flags = stream_flags; + response->timestamp = timestamp; + response->sample = sample; + if (response->sample) + IMFSample_AddRef(response->sample); - pending_sample = heap_alloc(sizeof(*pending_sample)); - pending_sample->sample = sample; - IMFSample_AddRef(pending_sample->sample); - - list_add_tail(&stream->samples, &pending_sample->entry); + list_add_tail(&stream->responses, &response->entry); } static HRESULT source_reader_pull_stream_samples(struct media_stream *stream) @@ -385,6 +393,7 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream) MFT_OUTPUT_STREAM_INFO stream_info = { 0 }; MFT_OUTPUT_DATA_BUFFER out_buffer; IMFMediaBuffer *buffer; + LONGLONG timestamp; DWORD status; HRESULT hr; @@ -420,7 +429,11 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream) break; } - source_reader_queue_sample(stream, out_buffer.pSample); + timestamp = 0; + if (FAILED(IMFSample_GetSampleTime(out_buffer.pSample, ×tamp))) + WARN("Sample time wasn't set.\n"); + + source_reader_queue_response(stream, S_OK /* FIXME */, stream->index, 0, timestamp, out_buffer.pSample); if (out_buffer.pSample) IMFSample_Release(out_buffer.pSample); if (out_buffer.pEvents) @@ -432,11 +445,16 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream) static HRESULT source_reader_process_sample(struct media_stream *stream, IMFSample *sample) { + LONGLONG timestamp; HRESULT hr; if (!stream->decoder) { - source_reader_queue_sample(stream, sample); + timestamp = 0; + if (FAILED(IMFSample_GetSampleTime(sample, ×tamp))) + WARN("Sample time wasn't set.\n"); + + source_reader_queue_response(stream, S_OK, stream->index, 0, timestamp, sample); return S_OK; } @@ -667,7 +685,7 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) for (i = 0; i < reader->stream_count; ++i) { struct media_stream *stream = &reader->streams[i]; - struct sample *ptr, *next; + struct stream_response *ptr, *next; if (stream->stream) IMFMediaStream_Release(stream->stream); @@ -677,9 +695,10 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) IMFTransform_Release(stream->decoder); DeleteCriticalSection(&stream->cs); - LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->samples, struct sample, entry) + LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->responses, struct stream_response, entry) { - IMFSample_Release(ptr->sample); + if (ptr->sample) + IMFSample_Release(ptr->sample); list_remove(&ptr->entry); heap_free(ptr); } @@ -1089,22 +1108,18 @@ static HRESULT WINAPI src_reader_SetCurrentPosition(IMFSourceReader *iface, REFG return IMFMediaSource_Start(reader->source, reader->descriptor, format, position); } -static IMFSample *media_stream_pop_sample(struct media_stream *stream, DWORD *stream_flags) +static struct stream_response *media_stream_pop_response(struct media_stream *stream) { - IMFSample *ret = NULL; + struct stream_response *response = NULL; struct list *head; - if ((head = list_head(&stream->samples))) + if ((head = list_head(&stream->responses))) { - struct sample *pending_sample = LIST_ENTRY(head, struct sample, entry); - ret = pending_sample->sample; - list_remove(&pending_sample->entry); - heap_free(pending_sample); + response = LIST_ENTRY(head, struct stream_response, entry); + list_remove(&response->entry); } - *stream_flags = (!ret && stream->state == STREAM_STATE_EOS) ? MF_SOURCE_READERF_ENDOFSTREAM : 0; - - return ret; + return response; } static HRESULT source_reader_start_source(struct source_reader *reader) @@ -1145,6 +1160,7 @@ static HRESULT source_reader_start_source(struct source_reader *reader) static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD index, DWORD flags, DWORD *actual_index, DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample) { + struct stream_response *response; struct media_stream *stream; DWORD stream_index; HRESULT hr = S_OK; @@ -1155,6 +1171,9 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind *sample = NULL; + if (timestamp) + *timestamp = 0; + switch (index) { case MF_SOURCE_READER_FIRST_VIDEO_STREAM: @@ -1179,8 +1198,6 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind *stream_flags = MF_SOURCE_READERF_ERROR; if (actual_index) *actual_index = index; - if (timestamp) - *timestamp = 0; return hr; } @@ -1195,7 +1212,7 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind { if (!(flags & MF_SOURCE_READER_CONTROLF_DRAIN)) { - while (list_empty(&stream->samples) && stream->state != STREAM_STATE_EOS) + while (list_empty(&stream->responses) && stream->state != STREAM_STATE_EOS) { if (stream->stream) { @@ -1206,21 +1223,25 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind } } - *sample = media_stream_pop_sample(stream, stream_flags); + if ((response = media_stream_pop_response(stream))) + { + *stream_flags = response->stream_flags; + if (timestamp) + *timestamp = response->timestamp; + *sample = response->sample; + if (*sample) + IMFSample_AddRef(*sample); + } + else + { + *stream_flags = list_empty(&stream->responses) && stream->state == STREAM_STATE_EOS ? + MF_SOURCE_READERF_ENDOFSTREAM : 0; + } } LeaveCriticalSection(&stream->cs); - TRACE("Got sample %p.\n", *sample); - - if (timestamp) - { - /* TODO: it's possible timestamp has to be set for some events. - For MEEndOfStream it's correct to return 0. */ - *timestamp = 0; - if (*sample) - IMFSample_GetSampleTime(*sample, timestamp); - } + TRACE("Got sample %p, flags %#x.\n", *sample, *stream_flags); return hr; } @@ -1466,9 +1487,10 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri if (FAILED(hr)) break; + object->streams[i].index = i; InitializeCriticalSection(&object->streams[i].cs); InitializeConditionVariable(&object->streams[i].sample_event); - list_init(&object->streams[i].samples); + list_init(&object->streams[i].responses); } if (FAILED(hr))