-- v2: mfreadwrite/reader: Send MFT_MESSAGE_NOTIFY_START_OF_STREAM on start or seek. winegstreamer/video_decoder: Generate timestamps relative to the first input sample.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/video_decoder.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/video_decoder.c b/dlls/winegstreamer/video_decoder.c index 3e91e55a779..53d9e00b137 100644 --- a/dlls/winegstreamer/video_decoder.c +++ b/dlls/winegstreamer/video_decoder.c @@ -796,6 +796,10 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_ case MFT_MESSAGE_COMMAND_FLUSH: return wg_transform_flush(decoder->wg_transform);
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM: + decoder->sample_time = -1; + return S_OK; + default: FIXME("Ignoring message %#x.\n", message); return S_OK; @@ -811,6 +815,9 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS if (!decoder->wg_transform) return MF_E_TRANSFORM_TYPE_NOT_SET;
+ if (decoder->sample_time == -1 && FAILED(IMFSample_GetSampleTime(sample, (LONGLONG *)&decoder->sample_time))) + decoder->sample_time = 0; + return wg_transform_push_mf(decoder->wg_transform, sample, decoder->wg_sample_queue); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 0e0ba10b076..d4eb294acdd 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -957,6 +957,22 @@ static HRESULT source_reader_flush_transform_samples(struct source_reader *reade return next ? source_reader_flush_transform_samples(reader, stream, next) : S_OK; }
+static HRESULT source_reader_notify_transform(struct source_reader *reader, struct media_stream *stream, + struct transform_entry *entry, UINT message) +{ + struct transform_entry *next = NULL; + struct list *ptr; + HRESULT hr; + + if ((ptr = list_next(&stream->transforms, &entry->entry))) + next = LIST_ENTRY(ptr, struct transform_entry, entry); + + if (FAILED(hr = IMFTransform_ProcessMessage(entry->transform, message, 0))) + WARN("Failed to notify transform %p message %#x, hr %#lx\n", entry->transform, message, hr); + + return next ? source_reader_notify_transform(reader, stream, next, message) : S_OK; +} + static HRESULT source_reader_process_sample(struct source_reader *reader, struct media_stream *stream, IMFSample *sample) { @@ -1030,6 +1046,7 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re MediaEventType event_type; LONGLONG timestamp; PROPVARIANT value; + struct list *ptr; unsigned int i; HRESULT hr; DWORD id; @@ -1053,9 +1070,6 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re switch (event_type) { case MEEndOfStream: - { - struct list *ptr; - stream->state = STREAM_STATE_EOS; stream->flags &= ~STREAM_FLAG_SAMPLE_REQUESTED;
@@ -1070,10 +1084,16 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re source_reader_queue_response(reader, stream, S_OK, MF_SOURCE_READERF_ENDOFSTREAM, 0, NULL);
break; - } case MEStreamSeeked: case MEStreamStarted: stream->state = STREAM_STATE_READY; + + if ((ptr = list_head(&stream->transforms))) + { + struct transform_entry *entry = LIST_ENTRY(ptr, struct transform_entry, entry); + if (FAILED(hr = source_reader_notify_transform(reader, stream, entry, MFT_MESSAGE_NOTIFY_START_OF_STREAM))) + WARN("Failed to drain pending samples, hr %#lx.\n", hr); + } break; case MEStreamStopped: stream->flags |= STREAM_FLAG_STOPPED;
v2: Don't implement drain for the audio decoder, native doesn't. I don't remember for sure but I don't think it was strictly required.
Anything wrong with this?