[PATCH v4 3/5] quartz/avidec: Correctly implement avi_decompressor_source_get_media_type().
Zebediah Figura
z.figura12 at gmail.com
Tue Mar 24 10:44:47 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 d873c34d63e..57e0edd2746 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