[PATCH 1/4] mfreadwrite: Add partial implementation of ReadSample().

Nikolay Sivov nsivov at codeweavers.com
Mon Apr 22 02:52:27 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfreadwrite/main.c         | 109 ++++++++++++++++++++++++++++++--
 dlls/mfreadwrite/tests/mfplat.c |   7 ++
 2 files changed, 109 insertions(+), 7 deletions(-)

diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c
index 43dfd4e9ed..8145e5b0ed 100644
--- a/dlls/mfreadwrite/main.c
+++ b/dlls/mfreadwrite/main.c
@@ -79,13 +79,21 @@ struct sample
     IMFSample *sample;
 };
 
+enum media_stream_state
+{
+    STREAM_STATE_READY = 0,
+    STREAM_STATE_EOS,
+};
+
 struct media_stream
 {
     IMFMediaStream *stream;
     IMFMediaType *current;
     DWORD id;
     CRITICAL_SECTION cs;
+    CONDITION_VARIABLE sample_event;
     struct list samples;
+    enum media_stream_state state;
 };
 
 typedef struct source_reader
@@ -359,6 +367,8 @@ static HRESULT source_reader_media_sample_handler(struct source_reader *reader,
             list_add_tail(&reader->streams[i].samples, &pending_sample->entry);
             LeaveCriticalSection(&reader->streams[i].cs);
 
+            WakeAllConditionVariable(&reader->streams[i].sample_event);
+
             break;
         }
     }
@@ -698,14 +708,98 @@ static HRESULT WINAPI src_reader_SetCurrentPosition(IMFSourceReader *iface, REFG
     return IMFMediaSource_Start(reader->source, reader->descriptor, format, position);
 }
 
-static HRESULT WINAPI src_reader_ReadSample(IMFSourceReader *iface, DWORD index,
-        DWORD flags, DWORD *actualindex, DWORD *sampleflags, LONGLONG *timestamp,
-        IMFSample **sample)
+static IMFSample *media_stream_pop_sample(struct media_stream *stream, DWORD *stream_flags)
 {
-    srcreader *This = impl_from_IMFSourceReader(iface);
-    FIXME("%p, 0x%08x, 0x%08x, %p, %p, %p, %p\n", This, index, flags, actualindex,
-          sampleflags, timestamp, sample);
-    return E_NOTIMPL;
+    IMFSample *ret = NULL;
+    struct list *head;
+
+    if ((head = list_head(&stream->samples)))
+    {
+        struct sample *pending_sample = LIST_ENTRY(head, struct sample, entry);
+        ret = pending_sample->sample;
+        list_remove(&pending_sample->entry);
+        heap_free(pending_sample);
+    }
+
+    *stream_flags = stream->state == STREAM_STATE_EOS ? MF_SOURCE_READERF_ENDOFSTREAM : 0;
+
+    return ret;
+}
+
+static HRESULT WINAPI src_reader_ReadSample(IMFSourceReader *iface, DWORD index, DWORD flags, DWORD *actual_index,
+        DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample)
+{
+    struct source_reader *reader = impl_from_IMFSourceReader(iface);
+    HRESULT hr;
+
+    TRACE("%p, %#x, %#x, %p, %p, %p, %p\n", iface, index, flags, actual_index, stream_flags, timestamp, sample);
+
+    switch (index)
+    {
+        case MF_SOURCE_READER_FIRST_VIDEO_STREAM:
+            index = reader->first_video_stream_index;
+            break;
+        case MF_SOURCE_READER_FIRST_AUDIO_STREAM:
+            index = reader->first_audio_stream_index;
+            break;
+        case MF_SOURCE_READER_ANY_STREAM:
+            FIXME("Non-specific requests are not supported.\n");
+            return E_NOTIMPL;
+        default:
+            ;
+    }
+
+    /* FIXME: probably should happen once */
+    IMFMediaSource_Start(reader->source, reader->descriptor, NULL, NULL);
+
+    if (reader->async_callback)
+    {
+        FIXME("Async mode is not implemented.\n");
+        return E_NOTIMPL;
+    }
+    else
+    {
+        struct media_stream *stream;
+
+        if (!stream_flags || !sample)
+            return E_POINTER;
+
+        if (actual_index)
+            *actual_index = index;
+
+        *sample = NULL;
+
+        if (index >= reader->stream_count)
+        {
+            *stream_flags = MF_SOURCE_READERF_ERROR;
+            return MF_E_INVALIDSTREAMNUMBER;
+        }
+
+        stream = &reader->streams[index];
+
+        EnterCriticalSection(&stream->cs);
+
+        if (!(flags & MF_SOURCE_READER_CONTROLF_DRAIN))
+        {
+            while (list_empty(&stream->samples) && stream->state != STREAM_STATE_EOS)
+            {
+                if (stream->stream)
+                {
+                    if (FAILED(hr = IMFMediaStream_RequestSample(stream->stream, NULL)))
+                        WARN("Sample request failed, hr %#x.\n", hr);
+                }
+                SleepConditionVariableCS(&stream->sample_event, &stream->cs, INFINITE);
+            }
+        }
+
+        *sample = media_stream_pop_sample(stream, stream_flags);
+
+        LeaveCriticalSection(&stream->cs);
+
+        TRACE("Got sample %p.\n", *sample);
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI src_reader_Flush(IMFSourceReader *iface, DWORD index)
@@ -922,6 +1016,7 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
             break;
 
         InitializeCriticalSection(&object->streams[i].cs);
+        InitializeConditionVariable(&object->streams[i].sample_event);
         list_init(&object->streams[i].samples);
     }
 
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c
index 29e8e08eb7..b86fb060fd 100644
--- a/dlls/mfreadwrite/tests/mfplat.c
+++ b/dlls/mfreadwrite/tests/mfplat.c
@@ -315,6 +315,13 @@ todo_wine
     ok(actual_index == MF_SOURCE_READER_FIRST_VIDEO_STREAM, "Unexpected stream index %u\n", actual_index);
     ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected stream flags %#x.\n", stream_flags);
 
+    hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &stream_flags, &timestamp,
+            &sample);
+    ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, &timestamp, &sample);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
     hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags,
             &timestamp, &sample);
     ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr);
-- 
2.20.1




More information about the wine-devel mailing list