[PATCH 4/7] mfreadwrite: Partially implement setting output media types for reader.

Nikolay Sivov nsivov at codeweavers.com
Mon Apr 1 05:24:04 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfreadwrite/main.c | 128 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 121 insertions(+), 7 deletions(-)

diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c
index 9bed20144f..2e1d24c21c 100644
--- a/dlls/mfreadwrite/main.c
+++ b/dlls/mfreadwrite/main.c
@@ -72,6 +72,11 @@ HRESULT WINAPI DllUnregisterServer(void)
     return __wine_unregister_resources( mfinstance );
 }
 
+struct media_stream
+{
+    IMFMediaType *current;
+};
+
 typedef struct source_reader
 {
     IMFSourceReader IMFSourceReader_iface;
@@ -83,6 +88,9 @@ typedef struct source_reader
     DWORD first_video_stream_index;
     IMFSourceReaderCallback *async_callback;
     BOOL shutdown_on_release;
+    struct media_stream *streams;
+    DWORD stream_count;
+    CRITICAL_SECTION cs;
 } srcreader;
 
 struct sink_writer
@@ -214,6 +222,7 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
 {
     struct source_reader *reader = impl_from_IMFSourceReader(iface);
     ULONG refcount = InterlockedDecrement(&reader->refcount);
+    unsigned int i;
 
     TRACE("%p, refcount %d.\n", iface, refcount);
 
@@ -226,6 +235,14 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
         if (reader->descriptor)
             IMFPresentationDescriptor_Release(reader->descriptor);
         IMFMediaSource_Release(reader->source);
+
+        for (i = 0; i < reader->stream_count; ++i)
+        {
+            if (reader->streams[i].current)
+                IMFMediaType_Release(reader->streams[i].current);
+        }
+        heap_free(reader->streams);
+        DeleteCriticalSection(&reader->cs);
         heap_free(reader);
     }
 
@@ -344,17 +361,70 @@ static HRESULT WINAPI src_reader_GetNativeMediaType(IMFSourceReader *iface, DWOR
 
 static HRESULT WINAPI src_reader_GetCurrentMediaType(IMFSourceReader *iface, DWORD index, IMFMediaType **type)
 {
-    srcreader *This = impl_from_IMFSourceReader(iface);
-    FIXME("%p, 0x%08x, %p\n", This, index, type);
-    return E_NOTIMPL;
+    struct source_reader *reader = impl_from_IMFSourceReader(iface);
+    HRESULT hr;
+
+    TRACE("%p, %#x, %p.\n", iface, index, type);
+
+    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;
+        default:
+            ;
+    }
+
+    if (index >= reader->stream_count)
+        return MF_E_INVALIDSTREAMNUMBER;
+
+    if (FAILED(hr = MFCreateMediaType(type)))
+        return hr;
+
+    EnterCriticalSection(&reader->cs);
+
+    hr = IMFMediaType_CopyAllItems(reader->streams[index].current, (IMFAttributes *)*type);
+
+    LeaveCriticalSection(&reader->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI src_reader_SetCurrentMediaType(IMFSourceReader *iface, DWORD index, DWORD *reserved,
         IMFMediaType *type)
 {
-    srcreader *This = impl_from_IMFSourceReader(iface);
-    FIXME("%p, 0x%08x, %p, %p\n", This, index, reserved, type);
-    return E_NOTIMPL;
+    struct source_reader *reader = impl_from_IMFSourceReader(iface);
+    HRESULT hr;
+
+    TRACE("%p, %#x, %p, %p.\n", iface, index, reserved, type);
+
+    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;
+        default:
+            ;
+    }
+
+    if (index >= reader->stream_count)
+        return MF_E_INVALIDSTREAMNUMBER;
+
+    /* FIXME: validate passed type and current presentation state. */
+
+    EnterCriticalSection(&reader->cs);
+
+    hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)reader->streams[index].current);
+
+    LeaveCriticalSection(&reader->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI src_reader_SetCurrentPosition(IMFSourceReader *iface, REFGUID format, REFPROPVARIANT position)
@@ -533,7 +603,8 @@ static DWORD reader_get_first_stream_index(IMFPresentationDescriptor *descriptor
 static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttributes *attributes,
         BOOL shutdown_on_release, REFIID riid, void **out)
 {
-    srcreader *object;
+    struct source_reader *object;
+    unsigned int i;
     HRESULT hr;
 
     object = heap_alloc_zero(sizeof(*object));
@@ -545,10 +616,53 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
     object->refcount = 1;
     object->source = source;
     IMFMediaSource_AddRef(object->source);
+    InitializeCriticalSection(&object->cs);
 
     if (FAILED(hr = IMFMediaSource_CreatePresentationDescriptor(object->source, &object->descriptor)))
         goto failed;
 
+    if (FAILED(hr = IMFPresentationDescriptor_GetStreamDescriptorCount(object->descriptor, &object->stream_count)))
+        goto failed;
+
+    if (!(object->streams = heap_alloc_zero(object->stream_count * sizeof(*object->streams))))
+    {
+        hr = E_OUTOFMEMORY;
+        goto failed;
+    }
+
+    /* Set initial current media types. */
+    for (i = 0; i < object->stream_count; ++i)
+    {
+        IMFMediaTypeHandler *handler;
+        IMFStreamDescriptor *sd;
+        IMFMediaType *src_type;
+        BOOL selected;
+
+        if (FAILED(hr = MFCreateMediaType(&object->streams[i].current)))
+            break;
+
+        if (FAILED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(object->descriptor, i, &selected, &sd)))
+            break;
+
+        hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
+        IMFStreamDescriptor_Release(sd);
+        if (FAILED(hr))
+            break;
+
+        hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &src_type);
+        IMFMediaTypeHandler_Release(handler);
+        if (FAILED(hr))
+            break;
+
+        hr = IMFMediaType_CopyAllItems(src_type, (IMFAttributes *)object->streams[i].current);
+        IMFMediaType_Release(src_type);
+        if (FAILED(hr))
+            break;
+    }
+
+    if (FAILED(hr))
+        goto failed;
+
     /* 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);
-- 
2.20.1




More information about the wine-devel mailing list