Commit 9f9201c9 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

quartz/avidec: Correctly implement avi_decompressor_source_get_media_type().

parent 0be0b38a
......@@ -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,
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment