From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index fcf642859d5..2762e88281a 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -105,6 +105,7 @@ struct test_media_stream IMFStreamDescriptor *sd; IMFMediaEventQueue *event_queue; BOOL is_new; + LONGLONG sample_duration, sample_time; };
static struct test_media_stream *impl_from_IMFMediaStream(IMFMediaStream *iface) @@ -211,8 +212,25 @@ static HRESULT WINAPI test_media_stream_RequestSample(IMFMediaStream *iface, IUn
hr = MFCreateSample(&sample); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IMFSample_SetSampleTime(sample, 123); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (stream->sample_duration) + { + hr = IMFSample_SetSampleDuration(sample, stream->sample_duration); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_SetSampleTime(sample, stream->sample_time); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + stream->sample_time += stream->sample_duration; + } + else + { + hr = IMFSample_SetSampleTime(sample, 123); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_SetSampleDuration(sample, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + if (token) IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token);
@@ -888,9 +906,12 @@ skip_read_sample:
static void test_source_reader_from_media_source(void) { + static const DWORD expected_sample_order[10] = {0, 0, 1, 1, 0, 0, 0, 0, 1, 0}; + struct async_callback *callback; IMFSourceReader *reader; IMFMediaSource *source; + struct test_source *test_source; IMFMediaType *media_type; HRESULT hr; DWORD actual_index, stream_flags; @@ -964,6 +985,19 @@ static void test_source_reader_from_media_source(void) IMFSample_Release(sample); }
+ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_ANY_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!stream_flags, "Unexpected stream flags %#lx.\n", stream_flags); + ok(timestamp == 123, "Unexpected timestamp.\n"); + ok(!!sample, "Expected sample object.\n"); + + /* Once the last read sample of all streams has the same timestamp value, the reader will + continue reading from the first stream until its timestamp increases. */ + todo_wine ok(!actual_index, "%d: Unexpected stream index %lu.\n", TEST_SOURCE_NUM_STREAMS + 1, actual_index); + + IMFSample_Release(sample); + IMFSourceReader_Release(reader); IMFMediaSource_Release(source);
@@ -1172,6 +1206,39 @@ static void test_source_reader_from_media_source(void) IMFMediaSource_Release(source);
fail_request_sample = FALSE; + + /* MF_SOURCE_READER_ANY_STREAM with streams of different sample sizes */ + source = create_test_source(2); + ok(!!source, "Failed to create test source.\n"); + + test_source = impl_from_IMFMediaSource(source); + test_source->streams[0]->sample_duration = 100000; + test_source->streams[1]->sample_duration = 400000; + + hr = MFCreateSourceReaderFromMediaSource(source, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSourceReader_SetStreamSelection(reader, 1, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* The source reader picks the stream whose last sample had the lower timestamp */ + for (i = 0; i < ARRAY_SIZE(expected_sample_order); i++) + { + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_ANY_STREAM, 0, &actual_index, &stream_flags, ×tamp, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!stream_flags, "Unexpected stream flags %#lx.\n", stream_flags); + ok(!!sample, "Expected sample object.\n"); + todo_wine_if (actual_index != expected_sample_order[i]) + ok (actual_index == expected_sample_order[i], "Got sample %u from unexpected stream %lu, expected %lu.\n", + i, actual_index, expected_sample_order[i]); + IMFSample_Release(sample); + } + + IMFSourceReader_Release(reader); + IMFMediaSource_Release(source); }
static void test_reader_d3d9(void)
From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/mfreadwrite/reader.c | 34 ++++++++++++++++++++------------- dlls/mfreadwrite/tests/mfplat.c | 5 ++--- 2 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index b1175479dec..76348458fac 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -92,6 +92,7 @@ struct media_stream unsigned int flags; unsigned int requests; unsigned int responses; + LONGLONG last_sample_ts; struct source_reader *reader; };
@@ -160,7 +161,6 @@ struct source_reader IUnknown *device_manager; unsigned int first_audio_stream_index; unsigned int first_video_stream_index; - unsigned int last_read_index; DWORD stream_count; unsigned int flags; DWORD queue; @@ -459,6 +459,8 @@ static HRESULT source_reader_queue_response(struct source_reader *reader, struct
source_reader_response_ready(reader, response);
+ stream->last_sample_ts = timestamp; + return S_OK; }
@@ -1101,10 +1103,11 @@ static BOOL source_reader_get_read_result(struct source_reader *reader, struct m
static HRESULT source_reader_get_next_selected_stream(struct source_reader *reader, DWORD *stream_index) { - unsigned int i, first_selected = ~0u, requests = ~0u; + unsigned int i, first_selected = ~0u; BOOL selected, stream_drained; + LONGLONG min_ts = MAXLONGLONG;
- for (i = (reader->last_read_index + 1) % reader->stream_count; ; i = (i + 1) % reader->stream_count) + for (i = 0; i < reader->stream_count; ++i) { stream_drained = reader->streams[i].state == STREAM_STATE_EOS && !reader->streams[i].responses; selected = SUCCEEDED(source_reader_get_stream_selection(reader, i, &selected)) && selected; @@ -1114,24 +1117,20 @@ static HRESULT source_reader_get_next_selected_stream(struct source_reader *read if (first_selected == ~0u) first_selected = i;
- /* Try to balance pending reads. */ - if (!stream_drained && reader->streams[i].requests < requests) + /* Pick the stream whose last sample had the lowest timestamp. */ + if (!stream_drained && reader->streams[i].last_sample_ts < min_ts) { - requests = reader->streams[i].requests; + min_ts = reader->streams[i].last_sample_ts; *stream_index = i; } } - - if (i == reader->last_read_index) - break; }
/* If all selected streams reached EOS, use first selected. */ if (first_selected != ~0u) { - if (requests == ~0u) + if (min_ts == MAXLONGLONG) *stream_index = first_selected; - reader->last_read_index = *stream_index; }
return first_selected == ~0u ? MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED : S_OK; @@ -1499,7 +1498,12 @@ static HRESULT WINAPI src_reader_SetStreamSelection(IMFSourceReader *iface, DWOR }
if (selection_changed) - reader->last_read_index = reader->stream_count - 1; + { + for (i = 0; i < reader->stream_count; ++i) + { + reader->streams[i].last_sample_ts = 0; + } + }
LeaveCriticalSection(&reader->cs);
@@ -1911,6 +1915,11 @@ static HRESULT WINAPI src_reader_SetCurrentPosition(IMFSourceReader *iface, REFG
if (SUCCEEDED(hr)) { + for (i = 0; i < reader->stream_count; ++i) + { + reader->streams[i].last_sample_ts = 0; + } + if (reader->async_callback) { if (SUCCEEDED(hr = source_reader_create_async_op(SOURCE_READER_ASYNC_SEEK, &command))) @@ -2357,7 +2366,6 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri /* At least one major type has to be set. */ object->first_audio_stream_index = reader_get_first_stream_index(object->descriptor, &MFMediaType_Audio); object->first_video_stream_index = reader_get_first_stream_index(object->descriptor, &MFMediaType_Video); - object->last_read_index = object->stream_count - 1;
if (object->first_audio_stream_index == MF_SOURCE_READER_INVALID_STREAM_INDEX && object->first_video_stream_index == MF_SOURCE_READER_INVALID_STREAM_INDEX) diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 2762e88281a..c36e1a7e04d 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -994,7 +994,7 @@ static void test_source_reader_from_media_source(void)
/* Once the last read sample of all streams has the same timestamp value, the reader will continue reading from the first stream until its timestamp increases. */ - todo_wine ok(!actual_index, "%d: Unexpected stream index %lu.\n", TEST_SOURCE_NUM_STREAMS + 1, actual_index); + ok(!actual_index, "%d: Unexpected stream index %lu.\n", TEST_SOURCE_NUM_STREAMS + 1, actual_index);
IMFSample_Release(sample);
@@ -1231,8 +1231,7 @@ static void test_source_reader_from_media_source(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(!stream_flags, "Unexpected stream flags %#lx.\n", stream_flags); ok(!!sample, "Expected sample object.\n"); - todo_wine_if (actual_index != expected_sample_order[i]) - ok (actual_index == expected_sample_order[i], "Got sample %u from unexpected stream %lu, expected %lu.\n", + ok (actual_index == expected_sample_order[i], "Got sample %u from unexpected stream %lu, expected %lu.\n", i, actual_index, expected_sample_order[i]); IMFSample_Release(sample); }
This merge request was approved by Nikolay Sivov.