[PATCH 3/5] quartz/avidec: Correctly implement avi_decompressor_source_get_media_type().

Zebediah Figura z.figura12 at gmail.com
Mon Mar 23 17:01:00 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/quartz/avidec.c       | 105 +++++++++++++++++++++++++++++++++++--
 dlls/quartz/tests/avidec.c |  19 +++++--
 2 files changed, 116 insertions(+), 8 deletions(-)

diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index 0837ae2b8da..7645b17558b 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -362,12 +362,111 @@ static HRESULT avi_decompressor_source_query_accept(struct strmbase_pin *iface,
 static HRESULT avi_decompressor_source_get_media_type(struct strmbase_pin *iface,
         unsigned int index, AM_MEDIA_TYPE *mt)
 {
+    static const struct
+    {
+        const GUID *subtype;
+        DWORD compression;
+        WORD bpp;
+    }
+    formats[] =
+    {
+        {&MEDIASUBTYPE_CLJR, mmioFOURCC('C','L','J','R'), 8},
+        {&MEDIASUBTYPE_UYVY, mmioFOURCC('U','Y','V','Y'), 16},
+        {&MEDIASUBTYPE_YUY2, mmioFOURCC('Y','U','Y','2'), 16},
+        {&MEDIASUBTYPE_RGB32, BI_RGB, 32},
+        {&MEDIASUBTYPE_RGB24, BI_RGB, 24},
+        {&MEDIASUBTYPE_RGB565, BI_BITFIELDS, 16},
+        {&MEDIASUBTYPE_RGB555, BI_RGB, 16},
+        {&MEDIASUBTYPE_RGB8, BI_RGB, 8},
+    };
+
     AVIDecImpl *filter = impl_from_strmbase_filter(iface->filter);
+    const VIDEOINFOHEADER *sink_format;
+    VIDEOINFO *format;
 
-    if (index)
+    if (!filter->sink.pin.peer)
         return VFW_S_NO_MORE_ITEMS;
-    CopyMediaType(mt, &filter->mt);
-    return S_OK;
+
+    sink_format = (VIDEOINFOHEADER *)filter->sink.pin.mt.pbFormat;
+
+    memset(mt, 0, sizeof(AM_MEDIA_TYPE));
+
+    if (index < ARRAY_SIZE(formats))
+    {
+        if (!(format = CoTaskMemAlloc(offsetof(VIDEOINFO, dwBitMasks[3]))))
+            return E_OUTOFMEMORY;
+        memset(format, 0, offsetof(VIDEOINFO, dwBitMasks[3]));
+
+        format->rcSource = sink_format->rcSource;
+        format->rcTarget = sink_format->rcTarget;
+        format->dwBitRate = sink_format->dwBitRate;
+        format->dwBitErrorRate = sink_format->dwBitErrorRate;
+        format->AvgTimePerFrame = sink_format->AvgTimePerFrame;
+
+        format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+        format->bmiHeader.biWidth = sink_format->bmiHeader.biWidth;
+        format->bmiHeader.biHeight = sink_format->bmiHeader.biHeight;
+        format->bmiHeader.biPlanes = sink_format->bmiHeader.biPlanes;
+        format->bmiHeader.biBitCount = formats[index].bpp;
+        format->bmiHeader.biCompression = formats[index].compression;
+        format->bmiHeader.biSizeImage = format->bmiHeader.biWidth
+                * format->bmiHeader.biHeight * formats[index].bpp / 8;
+
+        if (IsEqualGUID(formats[index].subtype, &MEDIASUBTYPE_RGB565))
+        {
+            format->dwBitMasks[iRED] = 0xf800;
+            format->dwBitMasks[iGREEN] = 0x07e0;
+            format->dwBitMasks[iBLUE] = 0x001f;
+            mt->cbFormat = offsetof(VIDEOINFO, dwBitMasks[3]);
+        }
+        else
+            mt->cbFormat = sizeof(VIDEOINFOHEADER);
+
+        mt->majortype = MEDIATYPE_Video;
+        mt->subtype = *formats[index].subtype;
+        mt->bFixedSizeSamples = TRUE;
+        mt->lSampleSize = format->bmiHeader.biSizeImage;
+        mt->formattype = FORMAT_VideoInfo;
+        mt->pbFormat = (BYTE *)format;
+
+        return S_OK;
+    }
+
+    if (index == ARRAY_SIZE(formats))
+    {
+        size_t size = ICDecompressGetFormatSize(filter->hvid, &sink_format->bmiHeader);
+
+        if (!size)
+            return VFW_S_NO_MORE_ITEMS;
+
+        mt->cbFormat = offsetof(VIDEOINFOHEADER, bmiHeader) + size;
+        if (!(format = CoTaskMemAlloc(mt->cbFormat)))
+            return E_OUTOFMEMORY;
+
+        format->rcSource = sink_format->rcSource;
+        format->rcTarget = sink_format->rcTarget;
+        format->dwBitRate = sink_format->dwBitRate;
+        format->dwBitErrorRate = sink_format->dwBitErrorRate;
+        format->AvgTimePerFrame = sink_format->AvgTimePerFrame;
+
+        if (ICDecompressGetFormat(filter->hvid, &sink_format->bmiHeader, &format->bmiHeader))
+        {
+            CoTaskMemFree(format);
+            return VFW_S_NO_MORE_ITEMS;
+        }
+
+        mt->majortype = MEDIATYPE_Video;
+        mt->subtype = MEDIATYPE_Video;
+        mt->subtype.Data1 = format->bmiHeader.biCompression;
+        mt->bFixedSizeSamples = TRUE;
+        mt->lSampleSize = format->bmiHeader.biSizeImage;
+        mt->formattype = FORMAT_VideoInfo;
+        mt->pbFormat = (BYTE *)format;
+
+        return S_OK;
+    }
+
+    return VFW_S_NO_MORE_ITEMS;
 }
 
 static HRESULT WINAPI avi_decompressor_source_DecideBufferSize(struct strmbase_source *iface,
diff --git a/dlls/quartz/tests/avidec.c b/dlls/quartz/tests/avidec.c
index 725e034ae27..6c29d33df29 100644
--- a/dlls/quartz/tests/avidec.c
+++ b/dlls/quartz/tests/avidec.c
@@ -584,7 +584,7 @@ static void test_media_types(void)
     ok(hr == S_OK, "Got hr %#x.\n", hr);
 
     hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
-    todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#x.\n", hr);
 
     IEnumMediaTypes_Release(enummt);
     IPin_Release(pin);
@@ -639,7 +639,7 @@ static void test_enum_media_types(void)
     ok(hr == S_OK, "Got hr %#x.\n", hr);
 
     hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
-    todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#x.\n", hr);
 
     hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
     ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -649,7 +649,7 @@ static void test_enum_media_types(void)
     ok(hr == S_OK, "Got hr %#x.\n", hr);
 
     hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
-    todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#x.\n", hr);
 
     hr = IEnumMediaTypes_Clone(enum1, &enum2);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -970,11 +970,11 @@ static void test_connect_pin(void)
     ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
     ok(compare_media_types(&testsource.source.pin.mt, &req_mt), "Media types didn't match.\n");
 
+    sink_bih = req_format.bmiHeader;
+
     hr = IPin_EnumMediaTypes(source, &enummt);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
 
-    sink_bih = req_format.bmiHeader;
-
     for (i = 0; i < 9; ++i)
     {
         static const struct
@@ -1023,6 +1023,15 @@ static void test_connect_pin(void)
                 "%u: Media types didn't match.\n", i);
         ok(!memcmp(pmt->pbFormat, &expect_format, sizeof(VIDEOINFOHEADER)),
                 "%u: Format blocks didn't match.\n", i);
+        if (i == 5)
+        {
+            const VIDEOINFO *format = (VIDEOINFO *)pmt->pbFormat;
+
+            ok(pmt->cbFormat == offsetof(VIDEOINFO, dwBitMasks[3]), "Got format size %u.\n", pmt->cbFormat);
+            ok(format->dwBitMasks[iRED] == 0xf800, "Got red bit mask %#x.\n", format->dwBitMasks[iRED]);
+            ok(format->dwBitMasks[iGREEN] == 0x07e0, "Got green bit mask %#x.\n", format->dwBitMasks[iGREEN]);
+            ok(format->dwBitMasks[iBLUE] == 0x001f, "Got blue bit mask %#x.\n", format->dwBitMasks[iBLUE]);
+        }
 
         hr = IPin_QueryAccept(source, pmt);
         ok(hr == (i == 8 ? S_OK : S_FALSE), "Got hr %#x.\n", hr);
-- 
2.25.1




More information about the wine-devel mailing list